Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions n_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,14 @@ const char *_i2cNoteTransaction(const char *request, size_t reqLen, char **respo
// Lock over the entire transaction
_LockI2C();

err = _i2cChunkedTransmit((uint8_t *)request, reqLen, true);
if (err) {
_UnlockI2C();
return err;
// Do not attempt to send a zero-length request
if (reqLen > 0) {
err = _i2cChunkedTransmit((uint8_t *)request, reqLen, true);
if (err) {
NOTE_C_LOG_ERROR(err);
_UnlockI2C();
return err;
}
}

// If no reply expected, we're done
Expand All @@ -101,6 +105,7 @@ const char *_i2cNoteTransaction(const char *request, size_t reqLen, char **respo
return NULL;
}

// Wait for something to become available
_delayIO();

// Allocate a buffer for input, noting that we always put the +1 in the
Expand All @@ -118,7 +123,7 @@ const char *_i2cNoteTransaction(const char *request, size_t reqLen, char **respo
if (jsonbufAllocLen) {
jsonbuf = (uint8_t *)_Malloc(jsonbufAllocLen + 1);
if (jsonbuf == NULL) {
const char *err = ERRSTR("transaction: jsonbuf malloc failed", c_mem);
err = ERRSTR("transaction: jsonbuf malloc failed", c_mem);
NOTE_C_LOG_ERROR(err);
_UnlockI2C();
return err;
Expand All @@ -131,16 +136,17 @@ const char *_i2cNoteTransaction(const char *request, size_t reqLen, char **respo
uint32_t jsonbufAvailLen = (jsonbufAllocLen - jsonbufLen);

// Append into the json buffer
const char *err = _i2cChunkedReceive((uint8_t *)(jsonbuf + jsonbufLen), &jsonbufAvailLen, true, (CARD_INTRA_TRANSACTION_TIMEOUT_SEC * 1000), &available);
err = _i2cChunkedReceive((uint8_t *)(jsonbuf + jsonbufLen), &jsonbufAvailLen, true, (CARD_INTRA_TRANSACTION_TIMEOUT_SEC * 1000), &available);
if (err) {
if (jsonbuf) {
_Free(jsonbuf);
}
NOTE_C_LOG_ERROR(ERRSTR("error occured during receive", c_iobad));
NOTE_C_LOG_ERROR(ERRSTR(err, c_iobad));
_UnlockI2C();
return err;
}
jsonbufLen += jsonbufAvailLen;
jsonbuf[jsonbufLen] = '\0';

if (available) {
// When more bytes are available than we have buffer to accommodate
Expand All @@ -152,7 +158,7 @@ const char *_i2cNoteTransaction(const char *request, size_t reqLen, char **respo
jsonbufAllocLen += (ALLOC_CHUNK * ((available / ALLOC_CHUNK) + ((available % ALLOC_CHUNK) > 0)));
uint8_t *jsonbufNew = (uint8_t *)_Malloc(jsonbufAllocLen + 1);
if (jsonbufNew == NULL) {
const char *err = ERRSTR("transaction: jsonbuf grow malloc failed", c_mem);
err = ERRSTR("transaction: jsonbuf grow malloc failed", c_mem);
NOTE_C_LOG_ERROR(err);
if (jsonbuf) {
_Free(jsonbuf);
Expand Down
91 changes: 52 additions & 39 deletions n_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include <stdlib.h>
#include <limits.h>

#include "n_lib.h"

Expand All @@ -33,21 +34,26 @@
/**************************************************************************/
const char *_serialNoteTransaction(const char *request, size_t reqLen, char **response, uint32_t timeoutMs)
{
// Strip off the newline and optional carriage return characters. This
// allows for standardized output to be reapplied.
reqLen--; // remove newline
if (request[reqLen - 1] == '\r') {
reqLen--; // remove carriage return if it exists
}
const char *err = NULL;

// Do not attempt to send a zero-length request
if (reqLen > 0) {
// Strip off the newline and optional carriage return characters. This
// allows for standardized output to be reapplied.
reqLen--; // remove newline
if (request[reqLen - 1] == '\r') {
reqLen--; // remove carriage return if it exists
}

const char *err = _serialChunkedTransmit((uint8_t *)request, reqLen, true);
if (err) {
NOTE_C_LOG_ERROR(err);
return err;
}
err = _serialChunkedTransmit((uint8_t *)request, reqLen, true);
if (err) {
NOTE_C_LOG_ERROR(err);
return err;
}

// Append the carriage return and newline to the transaction.
_SerialTransmit((uint8_t *)c_newline, c_newline_len, true);
// Append the carriage return and newline to the transaction.
_SerialTransmit((uint8_t *)c_newline, c_newline_len, true);
}

// If no reply expected, we're done
if (response == NULL) {
Expand Down Expand Up @@ -75,7 +81,7 @@ const char *_serialNoteTransaction(const char *request, size_t reqLen, char **re
uint32_t jsonbufAllocLen = ALLOC_CHUNK;
uint8_t *jsonbuf = (uint8_t *)_Malloc(jsonbufAllocLen + 1);
if (jsonbuf == NULL) {
const char *err = ERRSTR("transaction: jsonbuf malloc failed", c_mem);
err = ERRSTR("transaction: jsonbuf malloc failed", c_mem);
NOTE_C_LOG_ERROR(err);
return err;
}
Expand All @@ -86,13 +92,16 @@ const char *_serialNoteTransaction(const char *request, size_t reqLen, char **re
uint32_t jsonbufAvailLen = (jsonbufAllocLen - jsonbufLen);

// Append into the json buffer
const char *err = _serialChunkedReceive((uint8_t *)(jsonbuf + jsonbufLen), &jsonbufAvailLen, true, (CARD_INTRA_TRANSACTION_TIMEOUT_SEC * 1000), &available);
err = _serialChunkedReceive((uint8_t *)(jsonbuf + jsonbufLen), &jsonbufAvailLen, true, (CARD_INTRA_TRANSACTION_TIMEOUT_SEC * 1000), &available);
if (err) {
_Free(jsonbuf);
NOTE_C_LOG_ERROR(ERRSTR("error occured during receive", c_iobad));
if (jsonbuf) {
_Free(jsonbuf);
}
NOTE_C_LOG_ERROR(ERRSTR(err, c_iobad));
return err;
}
jsonbufLen += jsonbufAvailLen;
jsonbuf[jsonbufLen] = '\0';

if (available) {
// When more bytes are available than we have buffer to accommodate
Expand All @@ -104,20 +113,26 @@ const char *_serialNoteTransaction(const char *request, size_t reqLen, char **re
jsonbufAllocLen += (ALLOC_CHUNK * ((available / ALLOC_CHUNK) + ((available % ALLOC_CHUNK) > 0)));
uint8_t *jsonbufNew = (uint8_t *)_Malloc(jsonbufAllocLen + 1);
if (jsonbufNew == NULL) {
const char *err = ERRSTR("transaction: jsonbuf grow malloc failed", c_mem);
err = ERRSTR("transaction: jsonbuf grow malloc failed", c_mem);
NOTE_C_LOG_ERROR(err);
_Free(jsonbuf);
if (jsonbuf) {
_Free(jsonbuf);
}
return err;
}
memcpy(jsonbufNew, jsonbuf, jsonbufLen);
_Free(jsonbuf);
if (jsonbuf) {
memcpy(jsonbufNew, jsonbuf, jsonbufLen);
_Free(jsonbuf);
}
jsonbuf = jsonbufNew;
NOTE_C_LOG_DEBUG("additional receive buffer chunk allocated");
}
} while (available);

// Null-terminate it, using the +1 space that we'd allocated in the buffer
jsonbuf[jsonbufLen] = '\0';
if (jsonbuf) {
jsonbuf[jsonbufLen] = '\0';
}

// Return it
*response = (char *)jsonbuf;
Expand Down Expand Up @@ -281,30 +296,28 @@ const char *_serialChunkedReceive(uint8_t *buffer, uint32_t *size, bool delay, u
/**************************************************************************/
const char *_serialChunkedTransmit(uint8_t *buffer, uint32_t size, bool delay)
{
#if CARD_REQUEST_SERIAL_SEGMENT_MAX_LEN > SIZE_MAX
# error "CARD_REQUEST_SERIAL_SEGMENT_MAX_LEN exceeds SIZE_MAX. Use I2C interface instead."
#endif

// Transmit the request in segments so as not to overwhelm the Notecard's
// interrupt buffers
uint32_t segOff = 0;
uint32_t segLeft = size;

if (sizeof(size_t) != 4) { // Give the compiler a hint to eliminate the code
// Ensure truncation does not occur on 16-bit microcontrollers
const size_t castSize = (size_t)size;
if (castSize != size) {
const char *err = ERRSTR("Cannot transmit provided size; limit to `size_t`", c_iobad);
NOTE_C_LOG_ERROR(err);
return err;
}
}
for (uint32_t segRem = size, segOff = 0; segRem > 0; ) {
size_t segLen;

while (true) {
size_t segLen = segLeft;
if (segLen > CARD_REQUEST_SERIAL_SEGMENT_MAX_LEN) {
// Set the segment length to the max or the remainder, whichever is less
if (segRem > CARD_REQUEST_SERIAL_SEGMENT_MAX_LEN) {
segLen = CARD_REQUEST_SERIAL_SEGMENT_MAX_LEN;
} else {
segLen = (size_t)segRem;
}

_SerialTransmit(&buffer[segOff], segLen, false);
segOff += segLen;
segLeft -= segLen;
if (segLeft == 0) {

// Check here to avoid an unnecessary delay at the end of the last segment
segRem -= segLen;
if (segRem == 0) {
break;
}
if (delay) {
Expand Down
Loading