Arduino - Serial Communication not working - c

I'm having problem getting in to the second Serial.available loop of my code located in the Package. Please, let me know, if you see anything wrong with the code.
Arduino Code
Inputs:
1. "Package" -> I get +1 back from the Serial Monitor
2. "5&12!23!34!59!70!" -> I get 0 back from the Serial Monitor. For this one, I'm supposed to see, 5 12 23 34 59 70
Please, let me know, if you see anything wrong in this code and why is the Serial.available not functional in the Package?
String incoming;
String readIncoming;
int i=0;
typedef struct {
int npins;
int addr[512];
}
measureList;
measureList list;
void setup() {
Serial.begin(9600);
Serial.println("Serial conection started");
incoming = ""; list.npins = 6;
}
void loop() {
while(Serial.available() > 0) {
incoming = Serial.readString();
if(incoming == "HI") { Serial.println("Steven"); }
if(incoming == "SampleAll") { SampleAll(); }
if(incoming == "Package") { Serial.println("+1"); Package(); }
}
}
void Package(void)
{
while(1)
{
if(Serial.available()>0 & i<= list.npins)
{
char recieved = Serial.read();
if (recieved != '&' & i == 0){incoming = incoming + recieved;}
if (recieved == '&' & i == 0){list.npins = incoming.toInt(); Serial.println(list.npins); incoming=""; i = 1;}
if (recieved != '!' & recieved != '&' & i > 0){incoming = incoming + recieved; }
if (recieved == '!' & recieved != '&' & i > 0){ list.addr[i] = incoming.toInt(); Serial.println(list.addr[i]);incoming = ""; i = i + 1;}
if (i == list.npins) {break;}
}
}
}

Related

CAN frame over MQTT (need to convert hex string to byte array)

I am implementing a MQTT communication. I want to send CAN frames over MQTT through a graphical interfaces (realized in python). I am able to send messages from the GUI to one topic and I am able to see messages arrived on the same topic (using paho library) when I use the board. The function is below and the topic is diagnostic_request/topic:
void onMessageArrived
(
const char* topic,
const uint8_t* payload,
size_t payloadLen,
void* context
)
{
//LE_FATAL("The publisher received a message!");
//GIMP
char payloadStr[payloadLen + 1];
memcpy(payloadStr, payload, payloadLen);
payloadStr[payloadLen] = '\0';
LE_INFO("Received message! topic: \"%s\", payload: \"%s\"", topic, payloadStr);
//GIMP principio di conversione
if (strcmp(subscribeTopic, topic)==0)
LE_INFO("Sei sul topic di richiesta diagnostica!");
can_send();
}
At this point I have a difficulty. My can_send function (that works!) is:
int can_send(void)
{
const char* subscribeTopic = "diagnostic_request/topic";
LE_FATAL_IF(
mqtt_Subscribe(MQTTSession, subscribeTopic, MQTT_QOS0_TRANSMIT_ONCE) != LE_OK,
"failed to subscribe to %s",
subscribeTopic);
LE_INFO("Subscribed to topic (%s)", subscribeTopic);
int nbytesWrite;
// USE SEND STANDARD FRAME
frameWrite.can_id = 0x750; //codice identificativo di una richiesta diagnostica per centralina simulata
frameWrite.can_id &= CAN_SFF_MASK;
frameWrite.can_dlc = 8;
//strcpy((char *)frameWrite.data, "MGATE");
frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;
if ((nbytesWrite = write(sdw, &frameWrite, sizeof(frameWrite))) != sizeof(frameWrite))
{
canwrite = false;
LE_INFO ("Writing error, nbytesWrite = %d", nbytesWrite);
return SOCK_WRITING_ERROR;
}
canwrite = true;
return 0;
}
So I have to call can_send in the onMessageArrived function when is statement is ok. I am able to see when I send a publish on diagnostic_request/topic. The only problem is to send the payloadStr value to the can_send function and unpackage it in the frameWrite.data[]. Can someone help me to understand how to modify the can_send function in order that the values
frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;
are values that I send through mqtt in the payloadStr? I send a string of 8 bytes but I can't unpackage it.
Any help will be appreciated
Regards
Taking the approach of "write the test first".....
int convertNybble (char const hex)
{
if (hex >= '0' && hex <= '9')
{
return hex - '0';
}
else if (hex >= 'a' && hex <= 'f')
{
return 10 + (hex - 'a');
}
else if (hex >= 'A' && hex <= 'F')
{
return 10 + (hex - 'A');
}
return -1; // invalid hex character
}
#define ERR_NOT_EVEN_NUMBER_OF_DIGITS -1
#define ERR_STRING_TOO_LONG -2
#define ERR_INVALID_CHAR -3
int preparePayload(char const* hexString, unsigned char* canBuffer, size_t const bufLen)
{
size_t hexLen = strlen(hexString);
if (0 != (hexLen % 2))
{
// Expect an even number of digits.
return ERR_NOT_EVEN_NUMBER_OF_DIGITS;
}
size_t payloadLen = hexLen / 2;
// buffer will contain payload-length, followed by payload data.
// so payloadLen+1 must be able to fit into bufLen - fail if payloadLen+1 > bufLen, which is the same as payloadLen >= bufLen
if (payloadLen >= bufLen)
{
// will not be able to fit the decoded string into the payload buffer
return ERR_STRING_TOO_LONG;
}
unsigned char* bufEnd = canBuffer;
bufEnd += bufLen;
*canBuffer++ = (unsigned char)payloadLen;
while (payloadLen > 0)
{
payloadLen--;
int hexDigit[2];
hexDigit[0] = convertNybble(*hexString++);
hexDigit[1] = convertNybble(*hexString++);
if ((hexDigit[0] < 0) || (hexDigit[1] < 0))
{
return ERR_INVALID_CHAR;
}
*canBuffer++ = (hexDigit[0] << 4) | hexDigit[1];
}
// fill any leftovers with zero
while (canBuffer < bufEnd)
{
*canBuffer++ = 0;
}
return (0);
}
int performTests()
{
char const* testStr[5] =
{
"12345",
"0123456789ABCDEF",
"#ABC",
"0AF9",
"0123456789ABCD"
};
#define MARKER 0xFF
#define PAYLOAD_LEN 8
unsigned char payload[PAYLOAD_LEN+1];
payload[PAYLOAD_LEN] = MARKER;
int decodeResult = preparePayload(testStr[0], payload, PAYLOAD_LEN);
if (ERR_NOT_EVEN_NUMBER_OF_DIGITS != decodeResult) { return -1; } //not expected result
decodeResult = preparePayload(testStr[1], payload, PAYLOAD_LEN);
if (ERR_STRING_TOO_LONG != decodeResult) { return -1; }
decodeResult = preparePayload(testStr[2], payload, PAYLOAD_LEN);
if (ERR_INVALID_CHAR != decodeResult) { return -1; }
// here we are checking the character decoding
decodeResult = preparePayload(testStr[3], payload, PAYLOAD_LEN);
if (0 != decodeResult) { return -1; }
if (payload[0] != 2) { return -1; }
if (payload[1] != 0x0A) { return -1; }
if (payload[2] != 0xF9) { return -1; }
if (payload[3] != 0) { return -1; }
if (payload[7] != 0) { return -1; }
// payload contains - 02 0a f9 00 00 00 00 00 00
// here we are checking the limit of the payload capacity
decodeResult = preparePayload(testStr[4], payload, PAYLOAD_LEN);
if (0 != decodeResult) { return -1; }
// payload contains - 07 01 23 45 67 89 ab cd
// check we haven't overrun the buffer
if (payload[8] != MARKER) { return -1; }
// all tests pass
return 0;
}
int main()
{
int testResult = performTests();
return testResult;
}
You can then embody the decoder as follows:
convertNybble, preparePayload etc as above....
int canbusSend(unsigned char const* canbusPayload)
{
//etc
// - copy payloadBytes to frameWrite.data....
//etc
}
void onMessageArrived
(
const char* topic,
const uint8_t* mqttPayload,
size_t payloadLen,
void* context
)
{
#define CANBUS_PAYLOAD_BUFFER_LEN 8
unsigned char canbusPayload[CANBUS_PAYLOAD_BUFFER_LEN];
int decodeResult = preparePayload((char const*)mqttPayload, canbusPayload, CANBUS_PAYLOAD_BUFFER_LEN);
if (0 == decodeResult)
{
int canbusSendResult = canbusSend(canbusPayload);
// TODO : report error if failed
}
else
{
//TODO : report error
}
}

Sending a string with 000 at beginning in C

I posted this problem a couple of hours ago, but unfortunately, the details was not clear. i've added the code and some explanation.
i have a string like this to send through socket: "000f45546874684498765" as you see the first 3 numbers are zero, when the C compiler comes to this 000 it thinks these zeros are the finishing of the string. any suggestion?
proc_socketgps(s32 TaskId)
while (1)
{
Ql_Sleep(socket_timer);
if (is_socket_success == TRUE)
{
APP_DEBUG("start socket connect\r\n");
APP_DEBUG("m_tcp_state :%d\r\n", m_tcp_state);
APP_DEBUG("STATE_SOC_SEND :%d\r\n", STATE_SOC_SEND);
APP_DEBUG("m_socketid :%d\r\n", m_socketid);
proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22"));
}
static void proc_handle(unsigned char *pData, s32 len)
char *p = NULL;
s32 iret;
u8 srvport[10];
//command: Set_APN_Param=<APN>,<username>,<password>
p = Ql_strstr(pData, "Set_APN_Param=");
if (p)
{
Ql_memset(m_apn, 0, 10);
if (Analyse_Command(pData, 1, '>', m_apn))
{
APP_DEBUG("<--APN Parameter Error.-->\r\n");
return;
}
Ql_memset(m_userid, 0, 10);
if (Analyse_Command(pData, 2, '>', m_userid))
{
APP_DEBUG("<--APN Username Parameter Error.-->\r\n");
return;
}
Ql_memset(m_passwd, 0, 10);
if (Analyse_Command(pData, 3, '>', m_passwd))
{
APP_DEBUG("<--APN Password Parameter Error.-->\r\n");
return;
}
APP_DEBUG("<--Set APN Parameter Successfully<%s>,<%s>,<%s>.-->\r\n", m_apn, m_userid, m_passwd);
return;
}
//command: Set_Srv_Param=<srv ip>,<srv port>
p = Ql_strstr(pData, "Set_Srv_Param=");
if (p)
{
Ql_memset(m_SrvADDR, 0, SRVADDR_BUFFER_LEN);
if (Analyse_Command(pData, 1, '>', m_SrvADDR))
{
APP_DEBUG("<--Server Address Parameter Error.-->\r\n");
return;
}
Ql_memset(srvport, 0, 10);
if (Analyse_Command(pData, 2, '>', srvport))
{
APP_DEBUG("<--Server Port Parameter Error.-->\r\n");
return;
}
m_SrvPort = Ql_atoi(srvport);
APP_DEBUG("<--Set TCP Server Parameter Successfully<%s>,<%d>.-->\r\n", m_SrvADDR, m_SrvPort);
m_tcp_state = STATE_NW_GET_SIMSTATE;
APP_DEBUG("<--Restart the TCP connection process.-->\r\n");
return;
}
//if not command,send it to server
m_pCurrentPos = m_send_buf;
Ql_strcpy(m_pCurrentPos + m_remain_len, pData);
m_remain_len = Ql_strlen(m_pCurrentPos);
if (!Ql_strlen(m_send_buf)) //no data need to send
break;
m_tcp_state = STATE_SOC_SENDING;
do
{
ret = Ql_SOC_Send(m_socketid, m_pCurrentPos, m_remain_len);
APP_DEBUG("Message Data :%s", m_pCurrentPos);
APP_DEBUG("<--Send data,socketid=%d,number of bytes sent=%d-->\r\n", m_socketid, ret);
if (ret == m_remain_len) //send compelete
{
m_remain_len = 0;
m_pCurrentPos = NULL;
m_nSentLen += ret;
m_tcp_state = STATE_SOC_ACK;
break;
}
else if ((ret <= 0) && (ret == SOC_WOULDBLOCK))
{
//waiting CallBack_socket_write, then send data;
break;
}
else if (ret <= 0)
{
APP_DEBUG("<--Send data failure,ret=%d.-->\r\n", ret);
APP_DEBUG("<-- Close socket.-->\r\n");
Ql_SOC_Close(m_socketid); //error , Ql_SOC_Close
m_socketid = -1;
m_remain_len = 0;
m_pCurrentPos = NULL;
if (ret == SOC_BEARER_FAIL)
{
m_tcp_state = STATE_GPRS_DEACTIVATE;
}
else
{
m_tcp_state = STATE_GPRS_GET_DNSADDRESS;
}
break;
}
else if (ret < m_remain_len) //continue send, do not send all data
{
m_remain_len -= ret;
m_pCurrentPos += ret;
m_nSentLen += ret;
}
} while (1);
break;
the code has been added to the question. firs socket gets open and gets connected to the server. this function >> proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22")); sends hexadecimal string, however i think c consider this part "\x00" as end of the string ! and the data won't be sent ! I already tested that if I remove "\x00" from the row above it works like a charm !

Why does SChannel TLS limit a message to 32kb

I am working on using SChannel to build a client/server program. One of the things I would like to do is have file sharing. I found some example code of a client program using Schannel to communicate and I am wondering why the max size of a message is 32kb. Here is the example function that does the receiving
int tls_handshake(tls_ctx *c, tls_session *s) {
DWORD flags_in, flags_out;
SecBuffer ib[2], ob[1];
SecBufferDesc in, out;
int len;
// send initial hello
if (!tls_hello(c, s)) {
return 0;
}
flags_in = ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY |
ISC_RET_EXTENDED_ERROR |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_MANUAL_CRED_VALIDATION;
c->ss = SEC_I_CONTINUE_NEEDED;
s->buflen = 0;
while (c->ss == SEC_I_CONTINUE_NEEDED ||
c->ss == SEC_E_INCOMPLETE_MESSAGE ||
c->ss == SEC_I_INCOMPLETE_CREDENTIALS)
{
if (c->ss == SEC_E_INCOMPLETE_MESSAGE)
{
// receive data from server
len = recv(s->sck, &s->buf[s->buflen], s->maxlen - s->buflen, 0);
// socket error?
if (len == SOCKET_ERROR) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
// server disconnected?
} else if (len==0) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
}
// increase buffer position
s->buflen += len;
}
// inspect what we've received
//tls_hex_dump(s->buf, s->buflen);
// input data
ib[0].pvBuffer = s->buf;
ib[0].cbBuffer = s->buflen;
ib[0].BufferType = SECBUFFER_TOKEN;
// empty buffer
ib[1].pvBuffer = NULL;
ib[1].cbBuffer = 0;
ib[1].BufferType = SECBUFFER_VERSION;
in.cBuffers = 2;
in.pBuffers = ib;
in.ulVersion = SECBUFFER_VERSION;
// output from schannel
ob[0].pvBuffer = NULL;
ob[0].cbBuffer = 0;
ob[0].BufferType = SECBUFFER_VERSION;
out.cBuffers = 1;
out.pBuffers = ob;
out.ulVersion = SECBUFFER_VERSION;
c->ss = c->sspi->
InitializeSecurityContextA(
&s->cc, &s->ctx, NULL, flags_in, 0,
SECURITY_NATIVE_DREP, &in, 0, NULL,
&out, &flags_out, NULL);
// what have we got so far?
if (c->ss == SEC_E_OK ||
c->ss == SEC_I_CONTINUE_NEEDED ||
(FAILED(c->ss) && (flags_out & ISC_RET_EXTENDED_ERROR)))
{
// response for server?
if (ob[0].cbBuffer != 0 && ob[0].pvBuffer) {
// send response
tls_send(s->sck, ob[0].pvBuffer, ob[0].cbBuffer);
// free response
c->sspi->FreeContextBuffer(ob[0].pvBuffer);
ob[0].pvBuffer = NULL;
}
}
// incomplete message? continue reading
if (c->ss==SEC_E_INCOMPLETE_MESSAGE) continue;
// completed handshake?
if (c->ss==SEC_E_OK) {
s->established = 1;
// If the "extra" buffer contains data, this is encrypted application
// protocol layer stuff and needs to be saved. The application layer
// will decrypt it later with DecryptMessage.
if (ib[1].BufferType == SECBUFFER_EXTRA) {
DEBUG_PRINT(" [ we have extra data after handshake.\n");
memmove(s->pExtra.pvBuffer,
&s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->pExtra.cbBuffer = ib[1].cbBuffer;
s->pExtra.BufferType = SECBUFFER_TOKEN;
} else {
// no extra data encountered
s->pExtra.pvBuffer = NULL;
s->pExtra.cbBuffer = 0;
s->pExtra.BufferType = SECBUFFER_EMPTY;
}
break;
}
// some other error
if(FAILED(c->ss)) break;
// Copy any leftover data from the "extra" buffer, and go around again.
if(ib[1].BufferType == SECBUFFER_EXTRA) {
memmove(s->buf, &s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->buflen = ib[1].cbBuffer;
DEBUG_PRINT(" [ we have %i bytes of extra data.\n", s->buflen);
tls_hex_dump(s->buf, s->buflen);
} else {
s->buflen = 0;
}
}
return c->ss==SEC_E_OK ? 1 : 0;
}
The code comes from a Github I found here: https://github.com/odzhan/shells/blob/master/s6/tls.c
Inside one of his header files he defines
#define TLS_MAX_BUFSIZ 32768
I have also read in other places that this is a limit with TLS. Is it possible to increase that limit? What happens if I need to receive more then that? Like a large file?

Circular Buffer Reader, I'm stuck

I am trying to implement a circular buffer, I'm writing to it just fine, all the received data is there, but something about my function to read from it doesn't work. No data gets saved into MtoHSdata.
The data I'm trying to read has a Start (>) and End (<) symbol, and is supposed to be sent via USART1.
Read data function:
void MtoHS(struct remoteM *Buff)
{
BYTE k = 0;
static BYTE st = 1;
switch (st)
{
case 1:
{
if ((*Buff).wr != (*Buff).re)
{
(*Buff).re = ((*Buff).re + 1) % (*Buff).max;
if ((*Buff).Buffer[(*Buff).re] == '>') // > == Start Symbol
{
k = 0;
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re];
}
else if ((*Buff).Buffer[(*Buff).re] == '<') // < == End Symbol
{
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re];
st = 5;
}
else
{
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re]; // Data
k++;
}
}
}
break;
/* When End Symbol was read, send data to M */
case 5:
{
BYTE i = 0;
while (MtoHSdata[i] != '<')
{
USART_SendData(USART1, MtoHSdata[i]);
i++;
}
}
break;
default:
{
st = 1;
}
}
return;
}
Write data function (interrupt):
void USART1_IRQHandler(void)
{
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
uint16_t byteM = 0;
USART_GetITStatus(USART1, USART_IT_ORE);
byteM = USART_ReceiveData(USART1);
pRXD5->Buffer[pRXD5->wr] = byteM;
pRXD5->wr = (pRXD5->wr + 1) % pRXD5->max;
}
return;
}
I'm calling MtoHS function with the parameter 'pRXD5'.
Could anyone please tell me what I'm doing wrong?

WaitForMultipleObjects - how to properly handle stdin and sockets (FTP client)

I am writing a simple C FTP client. I have some problems with receiving data from both FTP (21) and FTP-DATA (passive) sockets. That's my main program loop:
input_handles[0] = GetStdHandle(STD_INPUT_HANDLE);
input_handles[1] = WSACreateEvent();
input_handles[2] = INVALID_HANDLE_VALUE;
WSAEventSelect(connection->socket, input_handles[1], FD_READ);
while (1) {
wait_result = WaitForMultipleObjectsEx(num_in_handles, input_handles, FALSE, INFINITE, FALSE);
if (wait_result == WAIT_OBJECT_0) {
fgets(input_line, input_len, stdin);
ftp_cmd(connection, input_line);
if (_strnicmp(input_line, "QUIT", 4) == 0) {
WSACloseEvent(input_handles[1]);
break;
}
}
if(wait_result == WAIT_OBJECT_0 + 1 || wait_result == WAIT_OBJECT_0 + 2) {
if (WaitForSingleObject(input_handles[1], 0) == WAIT_OBJECT_0) {
ftp_recv(connection, &cmd_output);
if (cmd_output != NULL) {
printf(cmd_output);
if (strncmp(cmd_output, "227", 3) == 0) { // 227 - enter passive mode
CHECK_ERROR(ftp_passive(connection, cmd_output, &input_handles[2]));
num_in_handles = 3;
}
if(strncmp(cmd_output, "226", 3) == 0) { // 226 - exit passive mode
ftp_passive_close(connection, &input_handles[2]);
num_in_handles = 2;
}
SAFE_FREE(cmd_output);
}
}
if(num_in_handles == 3 && WaitForSingleObject(input_handles[2], 0) == WAIT_OBJECT_0) {
ftp_recv_pasv(connection, &cmd_output);
if (cmd_output != NULL)
printf(cmd_output);
SAFE_FREE(cmd_output);
// WORKS GOOD WITH THIS UNCOMMENTED
//ftp_passive_close(connection, &input_handles[2]);
//num_in_handles = 2;
}
}
}
ftp_passive() opens a socket to the address given by server and creates WSA event (input_handles[2]). ftp_passive_close() closes this socket and event.
I have no idea why it works with the commented fragment. When it's commented, my client doesn't receive any more data from any socket.
What's wrong with my code?

Resources