Skip to content

Commit 960f25b

Browse files
authored
chore:update note-c (#45)
1 parent 66986cd commit 960f25b

File tree

9 files changed

+177
-15
lines changed

9 files changed

+177
-15
lines changed

src/note-c/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ clean up inconsistent whitespace )
1818
* by closing [issues][]
1919
* by reviewing patches
2020

21-
[issues]: https://blues.github.com/note-c/issues
21+
[issues]: https://github.com/blues/note-c/issues
2222

2323
## Submitting an Issue
2424

src/note-c/n_const.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ const char *c_true = "true";
1919
const char *c_nullstring = "";
2020
const char *c_newline = "\r\n";
2121
const char *c_mem = "mem";
22-
const char *c_timeout = "timeout";
22+
const char *c_iotimeout = "timeout {io}";
2323
const char *c_err = "err";
2424
const char *c_req = "req";
2525
const char *c_cmd = "cmd";
2626
const char *c_bad = "bad";
27+
const char *c_iobad = "bad {io}";
28+
const char *c_ioerr = "{io}";

src/note-c/n_helpers.c

+24-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ static uint32_t timeBaseSetAtMs = 0;
2929
static JTIME timeBaseSec = 0;
3030
static bool timeBaseSetManually = false;
3131
static uint32_t suppressionTimerSecs = 10;
32+
static uint32_t refreshTimerSecs = 86400;
3233
static uint32_t timeTimer = 0;
34+
static uint32_t timeRefreshTimer = 0;
3335
static bool zoneStillUnavailable = true;
3436
static bool zoneForceRefresh = false;
3537
static char curZone[10] = {0};
@@ -100,6 +102,19 @@ JTIME NoteTime()
100102
return NoteTimeST();
101103
}
102104

105+
//**************************************************************************/
106+
/*!
107+
@brief Set the number of minutes between refreshes of the time
108+
from the Notecard, to help minimize clock drift on this host.
109+
Set this to 0 for no auto-refresh; it defaults to daily.
110+
@returns Nothing
111+
*/
112+
/**************************************************************************/
113+
void NoteTimeRefreshMins(uint32_t mins)
114+
{
115+
refreshTimerSecs = mins * 60;
116+
}
117+
103118
//**************************************************************************/
104119
/*!
105120
@brief Set the time.
@@ -201,9 +216,14 @@ JTIME NoteTimeST()
201216
timeBaseSetAtMs = nowMs;
202217
}
203218

219+
// If it's time to refresh the time, do so
220+
if (refreshTimerSecs != 0 && timerExpiredSecs(&timeRefreshTimer, refreshTimerSecs)) {
221+
timeTimer = 0;
222+
}
223+
204224
// If we haven't yet fetched the time, or if we still need the timezone, do so with a suppression
205225
// timer so that we don't hammer the module before it's had a chance to connect to the network to fetch time.
206-
if (!timeBaseSetManually && (timeBaseSec == 0 || zoneStillUnavailable || zoneForceRefresh)) {
226+
if (!timeBaseSetManually && (timeTimer == 0 || timeBaseSec == 0 || zoneStillUnavailable || zoneForceRefresh)) {
207227
if (timerExpiredSecs(&timeTimer, suppressionTimerSecs)) {
208228

209229
// Request time and zone info from the card
@@ -213,10 +233,8 @@ JTIME NoteTimeST()
213233
JTIME seconds = JGetInt(rsp, "time");
214234
if (seconds != 0) {
215235

216-
// Set the time if it hasn't yet been set
217-
if (timeBaseSec == 0) {
218-
setTime(seconds);
219-
}
236+
// Set the time
237+
setTime(seconds);
220238

221239
// Get the zone
222240
char *z = JGetString(rsp, "zone");
@@ -246,7 +264,7 @@ JTIME NoteTimeST()
246264
}
247265

248266
// Adjust the base time by the number of seconds that have elapsed since the base.
249-
JTIME adjustedTime = timeBaseSec + ((nowMs - timeBaseSetAtMs) / 1000);
267+
JTIME adjustedTime = timeBaseSec + (int32_t) (((int64_t) nowMs - (int64_t) timeBaseSetAtMs) / 1000);
250268

251269
// Done
252270
return adjustedTime;

src/note-c/n_i2c.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ const char *i2cNoteTransaction(char *json, char **jsonResponse)
175175
#ifdef ERRDBG
176176
_Debug("reply to request didn't arrive from module in time\n");
177177
#endif
178-
return ERRSTR("notecard request or response was lost",c_timeout);
178+
return ERRSTR("request or response was lost {io}",c_iotimeout);
179179
}
180180

181181
// Delay, simply waiting for the Note to process the request

src/note-c/n_lib.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ extern const char *c_newline;
113113
extern const char *c_mem;
114114
#define c_mem_len 3
115115

116-
extern const char *c_timeout;
117-
#define c_timeout_len 7
116+
extern const char *c_iotimeout;
117+
#define c_iotimeout_len 12
118118

119119
extern const char *c_err;
120120
#define c_err_len 3
@@ -128,6 +128,12 @@ extern const char *c_cmd;
128128
extern const char *c_bad;
129129
#define c_bad_len 3
130130

131+
extern const char *c_iobad;
132+
#define c_iobad_len 8
133+
134+
extern const char *c_ioerr;
135+
#define c_ioerr_len 4
136+
131137

132138
// Readability wrappers. Anything starting with _ is simply calling the wrapper
133139
// function.

src/note-c/n_request.c

+126-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,70 @@ bool NoteRequest(J *req)
123123
return success;
124124
}
125125

126+
/**************************************************************************/
127+
/*!
128+
@brief Send a request to the Notecard.
129+
Frees the request structure from memory after sending the request.
130+
Retries the request for up to the specified timeoutSeconds if there is
131+
no response, or if the response indicates an io error.
132+
@param req
133+
The `J` cJSON request object.
134+
timeoutSeconds
135+
Upper limit for retries if there is no response, or if the
136+
response contains an io error.
137+
@returns a boolean. Returns `true` if successful or `false` if an error
138+
occurs, such as an out-of-memory or if an error was returned from
139+
the transaction in the c_err field.
140+
*/
141+
/**************************************************************************/
142+
bool NoteRequestWithRetry(J *req, uint32_t timeoutSeconds)
143+
{
144+
// Exit if null request. This allows safe execution of the form NoteRequest(NoteNewRequest("xxx"))
145+
if (req == NULL) {
146+
return false;
147+
}
148+
149+
J *rsp;
150+
151+
// Calculate expiry time in milliseconds
152+
uint32_t expiresMs = _GetMs() + (timeoutSeconds * 1000);
153+
154+
while(true) {
155+
// Execute the transaction
156+
rsp = NoteTransaction(req);
157+
158+
// Loop if there is no response, or if there is an io error
159+
if ( (rsp == NULL) || JContainsString(rsp, c_err, c_ioerr)) {
160+
161+
// Free error response
162+
if (rsp != NULL) {
163+
JDelete(rsp);
164+
}
165+
} else {
166+
167+
// Exit loop on non-null response without io error
168+
break;
169+
}
170+
171+
// Exit loop on timeout
172+
if (_GetMs() >= expiresMs) {
173+
break;
174+
}
175+
}
176+
177+
// Free the request
178+
JDelete(req);
179+
180+
// If there is no response return false
181+
if (rsp == NULL) {
182+
return false;
183+
}
184+
// Check for a transaction error, and exit
185+
bool success = JIsNullString(rsp, c_err);
186+
JDelete(rsp);
187+
return success;
188+
}
189+
126190
/**************************************************************************/
127191
/*!
128192
@brief Send a request to the Notecard and return the response.
@@ -150,6 +214,67 @@ J *NoteRequestResponse(J *req)
150214
return rsp;
151215
}
152216

217+
/**************************************************************************/
218+
/*!
219+
@brief Send a request to the Notecard and return the response.
220+
Frees the request structure from memory after sending the request.
221+
Retries the request for up to the specified timeoutSeconds if there is
222+
no response, or if the response indicates an io error.
223+
@param req
224+
The `J` cJSON request object.
225+
timeoutSeconds
226+
Upper limit for retries if there is no response, or if the
227+
response contains an io error.
228+
@returns a `J` cJSON object with the response, or NULL if there is
229+
insufficient memory.
230+
*/
231+
/**************************************************************************/
232+
J *NoteRequestResponseWithRetry(J *req, uint32_t timeoutSeconds)
233+
{
234+
// Exit if null request. This allows safe execution of the form NoteRequestResponse(NoteNewRequest("xxx"))
235+
if (req == NULL) {
236+
return NULL;
237+
}
238+
239+
J *rsp;
240+
241+
// Calculate expiry time in milliseconds
242+
uint32_t expiresMs = _GetMs() + (timeoutSeconds * 1000);
243+
244+
while(true) {
245+
// Execute the transaction
246+
rsp = NoteTransaction(req);
247+
248+
// Loop if there is no response, or if there is an io error
249+
if ( (rsp == NULL) || JContainsString(rsp, c_err, c_ioerr)) {
250+
251+
// Free error response
252+
if (rsp != NULL) {
253+
JDelete(rsp);
254+
}
255+
} else {
256+
257+
// Exit loop on non-null response without io error
258+
break;
259+
}
260+
261+
// Exit loop on timeout
262+
if (_GetMs() >= expiresMs) {
263+
break;
264+
}
265+
}
266+
267+
// Free the request
268+
JDelete(req);
269+
270+
if (rsp == NULL) {
271+
return NULL;
272+
}
273+
274+
// Return the response
275+
return rsp;
276+
}
277+
153278
/**************************************************************************/
154279
/*!
155280
@brief Given a JSON string, send a request to the Notecard.
@@ -264,7 +389,7 @@ J *NoteTransaction(J *req)
264389
_Debug("invalid JSON: ");
265390
_Debug(responseJSON);
266391
_Free(responseJSON);
267-
J *rsp = errDoc(ERRSTR("unrecognized response from card",c_bad));
392+
J *rsp = errDoc(ERRSTR("unrecognized response from card {io}",c_iobad));
268393
_UnlockNote();
269394
return rsp;
270395
}

src/note-c/n_serial.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const char *serialNoteTransaction(char *json, char **jsonResponse)
6060
#ifdef ERRDBG
6161
_Debug("reply to request didn't arrive from module in time\n");
6262
#endif
63-
return ERRSTR("transaction timeout",c_timeout);
63+
return ERRSTR("transaction timeout {io}",c_iotimeout);
6464
}
6565
_DelayMs(10);
6666
}
@@ -90,7 +90,7 @@ const char *serialNoteTransaction(char *json, char **jsonResponse)
9090
_Debug("\n");
9191
#endif
9292
_Free(jsonbuf);
93-
return ERRSTR("transaction incomplete",c_timeout);
93+
return ERRSTR("transaction incomplete {io}",c_iotimeout);
9494
}
9595
_DelayMs(1);
9696
continue;
@@ -103,7 +103,7 @@ const char *serialNoteTransaction(char *json, char **jsonResponse)
103103
_Debug("invalid data received on serial port from notecard\n");
104104
#endif
105105
_Free(jsonbuf);
106-
return ERRSTR("serial communications error",c_timeout);
106+
return ERRSTR("serial communications error {io}",c_iotimeout);
107107
}
108108

109109
// Append into the json buffer

src/note-c/n_str.c

+8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
* will be copied. Always NUL terminates (unless siz == 0).
2828
* Returns strlen(src); if retval >= siz, truncation occurred.
2929
*/
30+
#if defined(_MSC_VER)
31+
size_t strlcpy(char *dst, const char *src, size_t siz)
32+
#else
3033
__attribute__((weak)) size_t strlcpy(char *dst, const char *src, size_t siz)
34+
#endif
3135
{
3236
char *d = dst;
3337
const char *s = src;
@@ -61,7 +65,11 @@ __attribute__((weak)) size_t strlcpy(char *dst, const char *src, size_t siz)
6165
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
6266
* If retval >= siz, truncation occurred.
6367
*/
68+
#if defined(_MSC_VER)
69+
size_t strlcat(char *dst, const char *src, size_t siz)
70+
#else
6471
__attribute__((weak)) size_t strlcat(char *dst, const char *src, size_t siz)
72+
#endif
6573
{
6674
char *d = dst;
6775
const char *s = src;

src/note-c/note.h

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ void NoteResetRequired(void);
103103
J *NoteNewRequest(const char *request);
104104
J *NoteNewCommand(const char *request);
105105
J *NoteRequestResponse(J *req);
106+
J *NoteRequestResponseWithRetry(J *req, uint32_t timeoutSeconds);
106107
char *NoteRequestResponseJSON(char *reqJSON);
107108
void NoteSuspendTransactionDebug(void);
108109
void NoteResumeTransactionDebug(void);
@@ -113,6 +114,7 @@ void NoteResumeTransactionDebug(void);
113114
#define SYNCSTATUS_LEVEL_ALL -1
114115
bool NoteDebugSyncStatus(int pollFrequencyMs, int maxLevel);
115116
bool NoteRequest(J *req);
117+
bool NoteRequestWithRetry(J *req, uint32_t timeoutms);
116118
#define NoteResponseError(rsp) (!JIsNullString(rsp, "err"))
117119
#define NoteResponseErrorContains(rsp, errstr) (JContainsString(rsp, "err", errstr))
118120
#define NoteDeleteResponse(rsp) JDelete(rsp)
@@ -206,6 +208,7 @@ bool NoteTimeValid(void);
206208
bool NoteTimeValidST(void);
207209
JTIME NoteTime(void);
208210
JTIME NoteTimeST(void);
211+
void NoteTimeRefreshMins(uint32_t mins);
209212
void NoteTimeSet(JTIME secondsUTC, int offset, char *zone, char *country, char *area);
210213
bool NoteLocalTimeST(uint16_t *retYear, uint8_t *retMonth, uint8_t *retDay, uint8_t *retHour, uint8_t *retMinute, uint8_t *retSecond, char **retWeekday, char **retZone);
211214
bool NoteRegion(char **retCountry, char **retArea, char **retZone, int *retZoneOffset);

0 commit comments

Comments
 (0)