-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathnote.h
More file actions
2198 lines (1756 loc) · 72.1 KB
/
note.h
File metadata and controls
2198 lines (1756 loc) · 72.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*!
@file note.h
Written by Ray Ozzie and Blues Inc. team.
Copyright (c) 2019 Blues Inc. MIT License. Use of this source code is
governed by licenses granted by the copyright holder including that found in
the
<a href="https://github.com/blues/note-c/blob/master/LICENSE">LICENSE</a>
file.
This library bundles the <a href="https://github.com/DaveGamble/cJSON">cJSON
JSON parser library</a>.
*/
#pragma once
#if defined(__GNUC__) || defined(__clang__)
#define NOTE_C_DEPRECATED __attribute__((__deprecated__))
#elif defined(_MSC_VER)
#define NOTE_C_DEPRECATED __declspec(deprecated)
#else
#define NOTE_C_DEPRECATED
#define NOTE_C_NO_DEPRECATED_ATTR
#endif // __GNUC__ || __clang__
// In case they're not yet defined
#include <float.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
enum {
NOTE_C_INTERFACE_NONE = 0,
NOTE_C_INTERFACE_SERIAL,
NOTE_C_INTERFACE_I2C,
};
#define _NOTE_C_STRINGIZE(x) #x
#define NOTE_C_STRINGIZE(x) _NOTE_C_STRINGIZE(x)
#define NOTE_C_VERSION_MAJOR 2
#define NOTE_C_VERSION_MINOR 5
#define NOTE_C_VERSION_PATCH 6
#define NOTE_C_VERSION NOTE_C_STRINGIZE(NOTE_C_VERSION_MAJOR) "." NOTE_C_STRINGIZE(NOTE_C_VERSION_MINOR) "." NOTE_C_STRINGIZE(NOTE_C_VERSION_PATCH)
// If double and float are the same size, then we must be on a small MCU. Turn
// on NOTE_C_LOW_MEM to conserve memory.
#if defined(FLT_MAX_EXP) && defined(DBL_MAX_EXP)
#if (FLT_MAX_EXP == DBL_MAX_EXP)
#define NOTE_C_LOW_MEM
#define NOTE_C_SINGLE_PRECISION
#endif
#elif defined(__FLT_MAX_EXP__) && defined(__DBL_MAX_EXP__)
#if (__FLT_MAX_EXP__ == __DBL_MAX_EXP__)
#define NOTE_C_LOW_MEM
#define NOTE_C_SINGLE_PRECISION
#endif
#else
// cppcheck-suppress preprocessorErrorDirective
#error What are floating point exponent length symbols for this compiler?
#endif
// NOTE_LOWMEM is the old name of NOTE_C_LOW_MEM. If NOTE_LOWMEM is defined,
// we define NOTE_C_LOW_MEM as well, for backwards compatibility. NOTE_FLOAT is
// also no longer used internally, but used to be defined when NOTE_LOWMEM was
// defined. It's also preserved here for backwards compatibility.
#ifdef NOTE_LOWMEM
#define NOTE_C_LOW_MEM
#define NOTE_FLOAT
#endif
#ifdef NOTE_C_LOW_MEM
#define ERRSTR(x,y) (y)
#define NOTE_C_LOG_DEBUG(msg) do { } while (0)
#else
#define ERRSTR(x,y) (x)
#endif // NOTE_C_LOW_MEM
/*!
@brief The floating point type used for JSON handling in note-c.
*/
#ifdef NOTE_C_SINGLE_PRECISION
typedef float JNUMBER;
#else
typedef double JNUMBER;
#endif
/*!
@brief The signed integer type used for JSON handling in note-c.
*/
typedef int64_t JINTEGER;
#define JINTEGER_MIN INT64_MIN
#define JINTEGER_MAX INT64_MAX
/*!
@brief The unsigned integer type used for JSON handling in note-c.
*/
typedef uint64_t JUINTEGER;
// UNIX Epoch time (also known as POSIX time) is the number of seconds that have elapsed since
// 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC). In this project, it always
// originates from the Notecard, which synchronizes the time from both the cell network and GPS.
typedef JUINTEGER JTIME;
// C-callable functions
#ifdef __cplusplus
extern "C" {
#endif
// cJSON wrappers
#include "n_cjson.h"
// Notecard hook functions
/*!
@typedef delayMsFn
@brief The type for the millisecond delay hook.
@param ms The number of milliseconds to delay for.
*/
typedef void (*delayMsFn) (uint32_t ms);
/*!
@typedef freeFn
@brief The type for the memory freeing hook.
@param mem Pointer to the memory to free.
*/
typedef void (*freeFn) (void * mem);
/*!
@typedef getMsFn
@brief The type for the millisecond counter hook.
@returns The value of the millisecond counter.
*/
typedef uint32_t (*getMsFn) (void);
/*!
@typedef debugOutputFn
@brief The type for the debug output hook.
@param text The debug text to output.
@returns Number of characters written, or 0 on failure.
*/
typedef size_t (*debugOutputFn) (const char *text);
#ifdef NOTE_C_HEARTBEAT_CALLBACK
/*!
@typedef heartbeatFn
@brief The type for a heartbeat notification
@param heartbeatJson The heartbeat status received
@param context User context passed to the heartbeat function
@returns `true` if the heartbeat processing should abandon the transaction.
*/
typedef bool (*heartbeatFn) (const char *heartbeatJson, void *context);
#endif
/*!
@typedef i2cReceiveFn
@brief The type for the I2C receive hook.
This hook is used to receive a buffer of bytes from the Notecard.
@param address The I2C address of the Notecard sending the data to receive.
@param rxBuf A buffer to hold the data received from the Notecard.
@param rxBufSize The size, in bytes, of rxBuf.
@param available The number of bytes remaining to be received, if any.
@returns NULL on success and an error string on failure.
*/
typedef const char * (*i2cReceiveFn) (uint16_t address, uint8_t* rxBuf,
uint16_t rxBufSize, uint32_t *available);
/*!
@typedef i2cResetFn
@brief The type for the I2C reset hook.
This hook is used to reset the I2C peripheral used to communicate with the
Notecard.
@param address The I2C address of the Notecard.
*/
typedef bool (*i2cResetFn) (uint16_t address);
/*!
@typedef i2cTransmitFn
@brief The type for the I2C transmit hook.
This hook is used to send a buffer of bytes to the Notecard.
@param address The I2C address of the Notecard to transmit the data to.
@param txBuf A buffer of bytes to transmit to the Notecard.
@param txBufSize The size, in bytes, of `txBuf`.
@returns NULL on success and an error string on failure.
*/
typedef const char * (*i2cTransmitFn) (uint16_t address, uint8_t* txBuf,
uint16_t txBufSize);
/*!
@typedef mallocFn
@brief The type for the memory allocation hook.
@param size The number of bytes to allocate.
@returns A pointer to the newly allocated memory or NULL on failure.
*/
typedef void * (*mallocFn) (size_t size);
/*!
@typedef mutexFn
@brief The type for the various mutex (i.e. lock/unlock) hooks.
*/
typedef void (*mutexFn) (void);
/*!
@typedef serialAvailableFn
@brief The type for the serial available hook.
@return `true` if there's data to read and `false` otherwise.
*/
typedef bool (*serialAvailableFn) (void);
/*!
@typedef serialReceiveFn
@brief The type for the serial receive hook.
@return The received byte.
*/
typedef char (*serialReceiveFn) (void);
/*!
@typedef serialResetFn
@brief The type for the serial reset hook.
This hook is used to reset the serial peripheral used to communicate with the
Notecard.
@returns `true` on success and `false` on failure.
*/
typedef bool (*serialResetFn) (void);
/*!
@typedef serialTransmitFn
@brief The type for the serial transmit hook.
@param txBuf A buffer of bytes to transmit to the Notecard.
@param txBufSize The size, in bytes, of `txBuf`.
@param flush If true, flush the serial peripheral's transmit buffer.
*/
typedef void (*serialTransmitFn) (uint8_t *txBuf, size_t txBufSize, bool flush);
/*!
@typedef txnStartFn
@brief The type for the transaction start hook.
@param timeoutMs Transaction timeout in milliseconds.
@returns `true` if the transaction was started successfully, `false` otherwise.
*/
typedef bool (*txnStartFn) (uint32_t timeoutMs);
/*!
@typedef txnStopFn
@brief The type for the transaction stop hook.
*/
typedef void (*txnStopFn) (void);
// External API
/*!
@brief Reset the Notecard, clearing any error state.
@returns `true` if the reset was successful, `false` otherwise.
*/
bool NoteReset(void);
/*!
@brief Mark that a Notecard reset is required on the next transaction.
This function sets an internal flag indicating that the Notecard should be
reset before the next communication attempt.
*/
void NoteResetRequired(void);
#define NoteNewBody JCreateObject
#define NoteAddBodyToObject(a, b) JAddItemToObject(a, "body", b)
#define NoteGetBody(a) JGetObject(a, "body")
/*!
@brief Create a new request JSON object.
Creates a dynamically allocated `J` object with one field `"req"` whose value
is the passed in request string.
@param request The name of the Notecard API request (e.g., "card.version").
@returns A pointer to a newly allocated JSON object with the "req" field
populated, or NULL on failure.
*/
J *NoteNewRequest(const char *request);
/*!
@brief Create a new command JSON object.
Create a dynamically allocated `J` object with one field `"cmd"` whose value is
the passed in request string. Commands are similar to requests, but the
Notecard does not send a response.
@param request The name of the Notecard API command (e.g., "card.restart").
@returns A pointer to a newly allocated JSON object with the "cmd" field
populated, or NULL on failure.
*/
J *NoteNewCommand(const char *request);
/*!
@brief Send a request to the Notecard and return the response.
The passed in request object is always freed, regardless of if the request was
successful or not.
@param req Pointer to a `J` request object.
@returns A `J` object with the response or NULL if there was an error sending
the request.
@see NoteResponseError to check the response for errors.
*/
J *NoteRequestResponse(J *req);
/*!
@brief Send a request to the Notecard, retrying until it succeeds or times out,
then return the response.
The passed in request object is always freed, regardless of if the request was
successful or not.
@param req Pointer to a `J` request object.
@param timeoutSeconds Time limit for retries, in seconds.
@returns A `J` object with the response or NULL if there was an error sending
the request.
@note Timeouts may occur when either there is no response, or if the response
contains an I/O error.
@see NoteResponseError to check the response for errors.
*/
J *NoteRequestResponseWithRetry(J *req, uint32_t timeoutSeconds);
/*!
@brief Send a request to the Notecard and return the response as JSON string.
Unlike NoteRequestResponse, this function expects the request to be a valid
JSON C-string, rather than a `J` object. The string is expected to be
newline-terminated, otherwise the call produces undefined behavior. The
response is returned as a dynamically allocated JSON C-string. The response
is newline-terminated, just like the request. The caller is responsible for
freeing the response string. If the request was a command (i.e. it uses "cmd"
instead of "req"), this function returns NULL, since commands do not have
a response.
@param reqJSON A valid newline-terminated JSON C-string containing the request.
@returns A newline-terminated JSON C-string with the response, or NULL
if there was no response or if there was an error.
@note When a "cmd" is sent, it is not possible to determine if an error occurred.
@note Unlike the `NoteRequest*` functions, this function does not automatically
free the request JSON string. It is not possible to know if the parameter
is a string literal. As such, it is the caller's responsibility to manage
the memory associated with the request string.
*/
char * NoteRequestResponseJSON(const char *reqJSON);
NOTE_C_DEPRECATED void NoteSuspendTransactionDebug(void);
NOTE_C_DEPRECATED void NoteResumeTransactionDebug(void);
#define SYNCSTATUS_LEVEL_MAJOR 0
#define SYNCSTATUS_LEVEL_MINOR 1
#define SYNCSTATUS_LEVEL_DETAILED 2
#define SYNCSTATUS_LEVEL_ALGORITHMIC 3
#define SYNCSTATUS_LEVEL_ALL -1
/*!
@brief Enable debug output for sync status monitoring.
@param pollFrequencyMs How often to poll for sync status, in milliseconds.
@param maxLevel Maximum detail level for sync status output.
@returns `true` if debugging was enabled successfully, `false` otherwise.
*/
bool NoteDebugSyncStatus(int pollFrequencyMs, int maxLevel);
/*!
@brief Send a request to the Notecard.
The passed in request object is always freed, regardless of if the request was
successful or not. The response from the Notecard, if any, is freed and not
returned to the caller.
@param req Pointer to a `J` request object.
@returns `true` if successful and `false` if an error occurs (e.g. out of
memory or the response from the Notecard has an "err" field). If req
is a command rather than a request, a `true` return value indicates
that the command was sent without error. However, since the Notecard
sends no response to commands, it does not guarantee that the
command was received and processed by the Notecard.
@see NoteRequestResponse if you need to work with the response.
*/
bool NoteRequest(J *req);
/*!
@brief Send a request to the Notecard, retrying until it succeeds or times out.
The passed in request object is always freed, regardless of if the request was
successful or not. The response from the Notecard, if any, is freed and not
returned to the caller.
@param req Pointer to a `J` request object.
@param timeoutSeconds Time limit for retries, in seconds, if there is no
response, or if the response contains an I/O error.
@returns `true` if successful and `false` if an error occurs (e.g. out of
memory or the response from the Notecard has an "err" field).
@see NoteRequestResponseWithRetry if you need to work with the response.
*/
bool NoteRequestWithRetry(J *req, uint32_t timeoutSeconds);
/*!
@brief Set the request timeout for Notecard transactions.
Provides control for transactions which must be tailored based upon the nature
of the transaction being performed.
@param overrideSecs The timeout in seconds (0 for default).
@returns The previous timeout value that was overridden.
*/
uint32_t NoteSetRequestTimeout(uint32_t overrideSecs);
/*!
@brief Check if the Notecard response contains an error.
@param rsp The response to check.
@returns `true` if there's an error and `false` if there's not.
*/
#define NoteResponseError(rsp) (!JIsNullString(rsp, "err"))
#define NoteResponseErrorContains(rsp, errstr) (JContainsString(rsp, "err", errstr))
/*!
@brief Free a response from the Notecard.
@param rsp The response to free.
*/
#define NoteDeleteResponse(rsp) JDelete(rsp)
/*!
@brief Send a request to the Notecard and return the response.
This function doesn't free the passed in request object. The caller is
responsible for freeing it.
@param req Pointer to a `J` request object.
@returns A `J` object with the response or NULL if there was an error sending
the request.
@see NoteResponseError to check the response for errors.
*/
J *NoteTransaction(J *req);
/*!
@brief Check if an error string contains a specific error type.
@param errstr The error string to check.
@param errtype The error type to search for in errstr.
@returns `true` if the error string contains the specified error type,
`false` otherwise.
@note Only Notecard errors enclosed in `{}` (e.g. `{io}` for an I/O error)
are guaranteed by the API.
*/
bool NoteErrorContains(const char *errstr, const char *errtype);
/*!
@brief Clean up an error string by removing all bracketed tags.
Notecard errors are enclosed in `{}` (e.g. `{io}` for an I/O error). This
function takes the input string and removes all bracketed errors from it,
meaning it removes any substrings matching the pattern `{some error string}`,
including the braces.
@param errbuf A C-string to to clean of errors.
*/
void NoteErrorClean(char *errbuf);
/*!
@brief Set the debug output function hook.
@param fn Pointer to the debug output function.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnDebugOutput(debugOutputFn fn);
/*!
@brief Get the currently set debug output function hook.
@param fn Pointer to store the current debug output function pointer.
*/
void NoteGetFnDebugOutput(debugOutputFn *fn);
#ifdef NOTE_C_HEARTBEAT_CALLBACK
/*!
@brief Set the heartbeat callback function.
@param fn Pointer to the heartbeat callback function.
@param context User context to pass to the heartbeat function.
*/
void NoteSetFnHeartbeat(heartbeatFn fn, void *context);
/*!
@brief Get the currently set heartbeat callback function.
@param fn Pointer to store the current heartbeat function pointer.
@param context Pointer to store the current heartbeat context pointer.
*/
void NoteGetFnHeartbeat(heartbeatFn *fn, void **context);
#endif
/*!
@brief Set the transaction hook functions.
@param startFn Function to call when starting a transaction.
@param stopFn Function to call when stopping a transaction.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnTransaction(txnStartFn startFn, txnStopFn stopFn);
/*!
@brief Get the platform-specific transaction hook functions.
@param startFn Pointer to store the current transaction start function.
@param stopFn Pointer to store the current transaction stop function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnTransaction(txnStartFn *startFn, txnStopFn *stopFn);
/*!
@brief Set the mutex functions for I2C and Notecard access protection.
@param lockI2Cfn Function to lock I2C access.
@param unlockI2Cfn Function to unlock I2C access.
@param lockNotefn Function to lock Notecard access.
@param unlockNotefn Function to unlock Notecard access.
*/
void NoteSetFnMutex(mutexFn lockI2Cfn, mutexFn unlockI2Cfn, mutexFn lockNotefn,
mutexFn unlockNotefn);
/*!
@brief Get the currently set mutex functions for I2C and Notecard.
@param lockI2Cfn Pointer to store the current I2C lock function.
@param unlockI2Cfn Pointer to store the current I2C unlock function.
@param lockNotefn Pointer to store the current Note lock function.
@param unlockNotefn Pointer to store the current Note unlock function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnMutex(mutexFn *lockI2Cfn, mutexFn *unlockI2Cfn, mutexFn *lockNotefn,
mutexFn *unlockNotefn);
/*!
@brief Set the I2C mutex functions.
@param lockI2Cfn Function to lock I2C access.
@param unlockI2Cfn Function to unlock I2C access.
*/
void NoteSetFnI2CMutex(mutexFn lockI2Cfn, mutexFn unlockI2Cfn);
/*!
@brief Get the currently set I2C mutex functions.
@param lockI2Cfn Pointer to store the current I2C lock function.
@param unlockI2Cfn Pointer to store the current I2C unlock function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnI2CMutex(mutexFn *lockI2Cfn, mutexFn *unlockI2Cfn);
/*!
@brief Set the Notecard mutex functions.
@param lockFn Function to lock Notecard access.
@param unlockFn Function to unlock Notecard access.
*/
void NoteSetFnNoteMutex(mutexFn lockFn, mutexFn unlockFn);
/*!
@brief Get the currently set Notecard mutex functions.
@param lockFn Pointer to store the current Notecard lock function.
@param unlockFn Pointer to store the current Notecard unlock function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnNoteMutex(mutexFn *lockFn, mutexFn *unlockFn);
/*!
@brief Set the default system functions (memory allocation, delay, timing).
@param mallocfn The platform-specific function for memory allocation.
@param freefn The platform-specific function for memory deallocation.
@param delayfn The platform-specific function for millisecond delays.
@param millisfn The platform-specific function to get millisecond counter.
@note These functions are used if no other system functions are set.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnDefault(mallocFn mallocfn, freeFn freefn, delayMsFn delayfn,
getMsFn millisfn);
/*!
@brief Set the system hook functions (memory allocation, delay, timing).
@param mallocHook The platform-specific function for memory allocation.
@param freeHook The platform-specific function for memory deallocation.
@param delayMsHook The platform-specific function for millisecond delays.
@param getMsHook The platform-specific function to get millisecond counter.
@note This function overrides any previously set system functions.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFn(mallocFn mallocHook, freeFn freeHook, delayMsFn delayMsHook,
getMsFn getMsHook);
/*!
@brief Get the platform-specific memory and timing hook functions.
@param mallocHook Pointer to store the current memory allocation function.
@param freeHook Pointer to store the current memory deallocation function.
@param delayMsHook Pointer to store the current delay function.
@param getMsHook Pointer to store the current millisecond counter function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFn(mallocFn *mallocHook, freeFn *freeHook, delayMsFn *delayMsHook,
getMsFn *getMsHook);
/*!
@brief Set the platform-specific serial communication hook functions.
@param resetFn The platform-specific function to reset the serial peripheral.
@param transmitFn The platform-specific function to transmit data via serial.
@param availFn The platform-specific function to check if serial data is available.
@param receiveFn The platform-specific function to receive serial data.
@note This function overrides any previously set serial functions.
@note This operation will set the active interface to serial.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnSerial(serialResetFn resetFn, serialTransmitFn transmitFn,
serialAvailableFn availFn, serialReceiveFn receiveFn);
/*!
@brief Set the default serial communication hook functions.
@param resetFn The platform-specific function to reset the serial peripheral.
@param transmitFn The platform-specific function to transmit data via serial.
@param availFn The platform-specific function to check if serial data is available.
@param receiveFn The platform-specific function to receive serial data.
@note These functions are used if no other serial functions are set.
@note This operation will set the active interface to serial, if unset.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnSerialDefault(serialResetFn resetFn, serialTransmitFn transmitFn,
serialAvailableFn availFn, serialReceiveFn receiveFn);
/*!
@brief Get the platform-specific serial communication hook functions.
@param resetFn Pointer to store the current serial reset function.
@param transmitFn Pointer to store the current serial transmit function.
@param availFn Pointer to store the current serial available function.
@param receiveFn Pointer to store the current serial receive function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnSerial(serialResetFn *resetFn, serialTransmitFn *transmitFn,
serialAvailableFn *availFn, serialReceiveFn *receiveFn);
/*!
@brief Set the platform-specific I2C communication hook functions, address and MTU.
@param notecardAddr I2C address of the Notecard (0 for default).
@param maxTransmitSize Maximum number of bytes to transmit in a single I2C segment (0 for default).
@param resetFn The platform-specific function to reset the I2C peripheral.
@param transmitFn The platform-specific function to transmit data via I2C.
@param receiveFn The platform-specific function to receive data via I2C.
@note This function overrides any previously set I2C functions.
@note This operation will set the active interface to I2C.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnI2C(uint32_t notecardAddr, uint32_t maxTransmitSize,
i2cResetFn resetFn, i2cTransmitFn transmitFn,
i2cReceiveFn receiveFn);
/*!
@brief Set the default I2C communication hook functions.
@param notecardAddr I2C address of the Notecard (0 for default).
@param maxTransmitSize Maximum number of bytes to transmit in a single I2C segment (0 for default).
@param resetFn The platform-specific function to reset the I2C peripheral.
@param transmitFn The platform-specific function to transmit data via I2C.
@param receiveFn The platform-specific function to receive data via I2C.
@note These functions are used if no other I2C functions are set.
@note This operation will set the active interface to I2C, if unset.
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetFnI2CDefault(uint32_t notecardAddr, uint32_t maxTransmitSize,
i2cResetFn resetFn, i2cTransmitFn transmitFn,
i2cReceiveFn receiveFn);
/*!
@brief Get the platform-specific I2C communication hook functions.
@param notecardAddr Pointer to store the current Notecard I2C address.
@param maxTransmitSize Pointer to store the current maximum transmit size.
@param resetFn Pointer to store the current I2C reset function.
@param transmitFn Pointer to store the current I2C transmit function.
@param receiveFn Pointer to store the current I2C receive function.
@note Any of the passed in pointers can be NULL if the caller is not
interested in that particular function pointer.
*/
void NoteGetFnI2C(uint32_t *notecardAddr, uint32_t *maxTransmitSize,
i2cResetFn *resetFn, i2cTransmitFn *transmitFn,
i2cReceiveFn *receiveFn);
/*!
@brief Set the active communication interface.
@param interface The desired interface to use. One of:
- NOTE_C_INTERFACE_NONE (default)
- NOTE_C_INTERFACE_SERIAL
- NOTE_C_INTERFACE_I2C
@note This operation will lock Notecard access while in progress, if Notecard
mutex functions have been set.
*/
void NoteSetActiveInterface(int interface);
/*!
@brief Get the currently active communication interface.
@returns The active interface (NOTE_C_INTERFACE_SERIAL, NOTE_C_INTERFACE_I2C, or NOTE_C_INTERFACE_NONE).
*/
int NoteGetActiveInterface(void);
/*!
@brief Disable all Notecard communication functions.
This function sets all hook functions to disabled/stub implementations.
*/
void NoteSetFnDisabled(void);
/*!
@brief Set the I2C address for Notecard communication.
@param i2cAddr The I2C address to use for the Notecard.
*/
void NoteSetI2CAddress(uint32_t i2cAddr);
/*!
@brief Set the MTU for I2C communication with the Notecard.
The MTU is the maximum number of bytes that can be sent to or received
from the Notecard in a single I2C transaction.
@param i2cMtu The maximum transmission unit (MTU) for I2C communication.
*/
void NoteSetI2CMtu(uint32_t i2cMtu);
/*!
@brief Get the current I2C address for Notecard communication.
@param [out] i2cAddr Pointer to store the current I2C address.
*/
void NoteGetI2CAddress(uint32_t *i2cAddr);
/*!
@brief Get the current MTU for I2C communication with the Notecard.
The MTU is the maximum number of bytes that can be sent to or received
from the Notecard in a single I2C transaction.
@param [out] i2cMtu Pointer to store the current I2C MTU.
*/
void NoteGetI2CMtu(uint32_t *i2cMtu);
// The Notecard, whose default I2C address is below, uses a serial-to-i2c
// protocol whose "byte count" must fit into a single byte and which must not
// include a 2-byte header field. This is why the maximum that can be
// transmitted by note-c in a single I2C I/O is 255 - 2 = 253 bytes.
/*!
@brief The default I2C address of the Notecard.
*/
#define NOTE_I2C_ADDR_DEFAULT 0x17
// Serial-to-i2c protocol header size in bytes
#ifndef NOTE_I2C_HEADER_SIZE
# define NOTE_I2C_HEADER_SIZE 2
#endif
// Maximum bytes capable of being transmitted in a single read/write operation
#ifdef NOTE_I2C_MAX_MAX
# ifdef NOTE_I2C_MTU_MAX
# undef NOTE_I2C_MTU_MAX
# endif
#else
# ifdef NOTE_I2C_MTU_MAX
# define NOTE_I2C_MAX_MAX NOTE_I2C_MTU_MAX
# else
# define NOTE_I2C_MAX_MAX (UCHAR_MAX - NOTE_I2C_HEADER_SIZE)
# endif
#endif
#ifndef NOTE_I2C_MTU_MAX
# define NOTE_I2C_MTU_MAX NOTE_I2C_MAX_MAX
#endif
// In ARDUINO implementations, which to date is the largest use of this library,
// the Wire package is implemented in a broad variety of ways by different
// vendors. The default implementation has a mere 32-byte static I2C buffer,
// which means that the maximum to be transmitted in a single I/O (given our
// 2-byte serial-to-i2c protocol header) is 30 bytes. However, if we know
// the specific platform (such as STM32DUINO) we can relax this restriction.
#ifdef NOTE_I2C_MAX_DEFAULT
// user is overriding it at compile time
# ifdef NOTE_I2C_MTU_DEFAULT
# undef NOTE_I2C_MTU_DEFAULT
# endif
#else
# if defined(NOTE_I2C_MTU_DEFAULT)
// user is overriding it at compile time
# define NOTE_I2C_MAX_DEFAULT NOTE_I2C_MTU_DEFAULT
# elif defined(ARDUINO_ARCH_STM32)
// we know that stm32duino dynamically allocates I/O buffer
# define NOTE_I2C_MAX_DEFAULT NOTE_I2C_MTU_MAX
# else
// default to what's known to be safe for all Arduino implementations
/*!
@brief The maximum number of bytes to request from or transmit to the Notecard
in a single chunk.
*/
# define NOTE_I2C_MAX_DEFAULT 30
# endif
#endif
#ifndef NOTE_I2C_MTU_DEFAULT
# define NOTE_I2C_MTU_DEFAULT NOTE_I2C_MAX_DEFAULT
#endif
// User agent
/*!
@brief Get the current user agent JSON object.
@returns A JSON object containing user agent information, or NULL on failure.
*/
J *NoteUserAgent(void);
/*!
@brief Update the user agent with additional information.
@param ua JSON object containing user agent updates to merge.
*/
void NoteUserAgentUpdate(J *ua);
/*!
@brief Set the user agent string.
@param agent The user agent string to set.
*/
void NoteSetUserAgent(char *agent);
/*!
@brief Set the operating system information in the user agent.
@param os_name The operating system name.
@param os_platform The operating system platform.
@param os_family The operating system family.
@param os_version The operating system version.
*/
void NoteSetUserAgentOS(char *os_name, char *os_platform, char *os_family, char *os_version);
/*!
@brief Set the CPU information in the user agent.
@param cpu_mem Available CPU memory in kilobytes.
@param cpu_mhz CPU speed in MHz.
@param cpu_cores Number of CPU cores.
@param cpu_vendor CPU vendor name.
@param cpu_name CPU model name.
*/
void NoteSetUserAgentCPU(int cpu_mem, int cpu_mhz, int cpu_cores, char *cpu_vendor, char *cpu_name);
// Calls to the functions set above
/*!
@brief Output a debug message.
@param msg The debug message to output.
*/
void NoteDebug(const char *msg);
/*!
@brief Output a debug message followed by a newline.
@param msg The debug message to output.
*/
void NoteDebugln(const char *msg);
/*!
@brief Output a debug message with an integer value appended, terminated by
a newline.
@param msg The debug message to output.
@param n The integer value to append to the message.
*/
void NoteDebugIntln(const char *msg, int n);
/*!
@brief Output a formatted debug message.
@param format The printf-style format string.
@param ... Variable arguments for the format string.
*/
void NoteDebugf(const char *format, ...);
#define NOTE_C_LOG_LEVEL_ERROR 0
#define NOTE_C_LOG_LEVEL_WARN 1
#define NOTE_C_LOG_LEVEL_INFO 2
#define NOTE_C_LOG_LEVEL_DEBUG 3
/*!
@brief Output a debug message with a specified log level.
@param level The log level for this message.
@param msg The debug message to output.
@note The message will be dropped if the specified level is less than
or equal to the current log level.
@note See the NOTE_C_LOG_LEVEL_* macros for possible values.
*/
void NoteDebugWithLevel(uint8_t level, const char *msg);
/*!
@brief Output a debug message with a specified log level, followed by a newline.
@param level The log level for this message.
@param msg The debug message to output.
@note The message will be dropped if the specified level is less than
or equal to the current log level.
@note See the NOTE_C_LOG_LEVEL_* macros for possible values.
*/
void NoteDebugWithLevelLn(uint8_t level, const char *msg);
#ifdef NOTE_C_LOG_SHOW_FILE_AND_LINE
#define NOTE_C_LOG_FILE_AND_LINE(lvl) do { \
NoteDebugWithLevel(lvl, __FILE__ ":" NOTE_C_STRINGIZE(__LINE__) " "); \
} while (0);
#else
#define NOTE_C_LOG_FILE_AND_LINE(lvl)
#endif
#ifndef NOTE_C_LOG_ERROR
#define NOTE_C_LOG_ERROR(msg) do { \
NOTE_C_LOG_FILE_AND_LINE(NOTE_C_LOG_LEVEL_ERROR); \
NoteDebugWithLevel(NOTE_C_LOG_LEVEL_ERROR, "[ERROR] "); \
NoteDebugWithLevelLn(NOTE_C_LOG_LEVEL_ERROR, msg); \
} while (0)
#endif
#ifndef NOTE_C_LOG_WARN
#define NOTE_C_LOG_WARN(msg) do { \
NOTE_C_LOG_FILE_AND_LINE(NOTE_C_LOG_LEVEL_WARN); \
NoteDebugWithLevel(NOTE_C_LOG_LEVEL_WARN, "[WARN] "); \
NoteDebugWithLevelLn(NOTE_C_LOG_LEVEL_WARN, msg); \
} while (0)
#endif
#ifndef NOTE_C_LOG_INFO
#define NOTE_C_LOG_INFO(msg) do { \
NOTE_C_LOG_FILE_AND_LINE(NOTE_C_LOG_LEVEL_INFO); \
NoteDebugWithLevel(NOTE_C_LOG_LEVEL_INFO, "[INFO] "); \
NoteDebugWithLevelLn(NOTE_C_LOG_LEVEL_INFO, msg); \
} while (0)
#endif
#ifndef NOTE_C_LOG_DEBUG
#define NOTE_C_LOG_DEBUG(msg) do { \
NOTE_C_LOG_FILE_AND_LINE(NOTE_C_LOG_LEVEL_DEBUG); \
NoteDebugWithLevel(NOTE_C_LOG_LEVEL_DEBUG, "[DEBUG] "); \