| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -14,16 +14,33 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define TF_MAX(a, b) ((a)>(b)?(a):(b)) | 
					 | 
					 | 
					 | 
					#define TF_MAX(a, b) ((a)>(b)?(a):(b)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define TF_MIN(a, b) ((a)<(b)?(a):(b)) | 
					 | 
					 | 
					 | 
					#define TF_MIN(a, b) ((a)<(b)?(a):(b)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					#define TF_TRY(func) do { if(!(func)) return false; } while (0) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// TODO It would be nice to have per-instance configurable checksum types, but that would
 | 
					 | 
					 | 
					 | 
					// TODO It would be nice to have per-instance configurable checksum types, but that would
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// mandate configurable field sizes unless we use u32 everywhere (and possibly shorten
 | 
					 | 
					 | 
					 | 
					// mandate configurable field sizes unless we use u32 everywhere (and possibly shorten
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// it when encoding to the buffer). I don't really like this idea so much. -MP
 | 
					 | 
					 | 
					 | 
					// it when encoding to the buffer). I don't really like this idea so much. -MP
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#if TF_USE_MUTEX==0 | 
					 | 
					 | 
					 | 
					#if !TF_USE_MUTEX | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // Not thread safe lock implementation, used if user did not provide a better one.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // This is less reliable than a real mutex, but will catch most bugs caused by
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    // inappropriate use fo the API.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /** Claim the TX interface before composing and sending a frame */ | 
					 | 
					 | 
					 | 
					    /** Claim the TX interface before composing and sending a frame */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static inline void TF_ClaimTx(TinyFrame *tf) { (void)tf; } | 
					 | 
					 | 
					 | 
					    static bool TF_ClaimTx(TinyFrame *tf) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (tf->soft_lock) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            TF_Error("TF already locked for tx!"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tf->soft_lock = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /** Free the TX interface after composing and sending a frame */ | 
					 | 
					 | 
					 | 
					    /** Free the TX interface after composing and sending a frame */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static inline void TF_ReleaseTx(TinyFrame *tf) { (void)tf; } | 
					 | 
					 | 
					 | 
					    static void TF_ReleaseTx(TinyFrame *tf) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tf->soft_lock = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#endif | 
					 | 
					 | 
					 | 
					#endif | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//region Checksums
 | 
					 | 
					 | 
					 | 
					//region Checksums
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -190,9 +207,12 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//endregion
 | 
					 | 
					 | 
					 | 
					//endregion
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/** Init with a user-allocated buffer */ | 
					 | 
					 | 
					 | 
					/** Init with a user-allocated buffer */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void _TF_FN TF_InitStatic(TinyFrame *tf, TF_Peer peer_bit) | 
					 | 
					 | 
					 | 
					bool _TF_FN TF_InitStatic(TinyFrame *tf, TF_Peer peer_bit) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (tf == NULL) return; | 
					 | 
					 | 
					 | 
					    if (tf == NULL) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        TF_Error("TF_InitStatic() failed, tf is null."); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Zero it out, keeping user config
 | 
					 | 
					 | 
					 | 
					    // Zero it out, keeping user config
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint32_t usertag = tf->usertag; | 
					 | 
					 | 
					 | 
					    uint32_t usertag = tf->usertag; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -204,12 +224,18 @@ void _TF_FN TF_InitStatic(TinyFrame *tf, TF_Peer peer_bit) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    tf->userdata = userdata; | 
					 | 
					 | 
					 | 
					    tf->userdata = userdata; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    tf->peer_bit = peer_bit; | 
					 | 
					 | 
					 | 
					    tf->peer_bit = peer_bit; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/** Init with malloc */ | 
					 | 
					 | 
					 | 
					/** Init with malloc */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					TinyFrame * _TF_FN TF_Init(TF_Peer peer_bit) | 
					 | 
					 | 
					 | 
					TinyFrame * _TF_FN TF_Init(TF_Peer peer_bit) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TinyFrame *tf = malloc(sizeof(TinyFrame)); | 
					 | 
					 | 
					 | 
					    TinyFrame *tf = malloc(sizeof(TinyFrame)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (!tf) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        TF_Error("TF_Init() failed, out of memory."); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        return NULL; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_InitStatic(tf, peer_bit); | 
					 | 
					 | 
					 | 
					    TF_InitStatic(tf, peer_bit); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return tf; | 
					 | 
					 | 
					 | 
					    return tf; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -492,9 +518,9 @@ static void _TF_FN TF_HandleReceivedMessage(TinyFrame *tf) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//endregion Listeners
 | 
					 | 
					 | 
					 | 
					//endregion Listeners
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/** Handle a received byte buffer */ | 
					 | 
					 | 
					 | 
					/** Handle a received byte buffer */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void _TF_FN TF_Accept(TinyFrame *tf, const uint8_t *buffer, size_t count) | 
					 | 
					 | 
					 | 
					void _TF_FN TF_Accept(TinyFrame *tf, const uint8_t *buffer, uint32_t count) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t i; | 
					 | 
					 | 
					 | 
					    uint32_t i; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (i = 0; i < count; i++) { | 
					 | 
					 | 
					 | 
					    for (i = 0; i < count; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        TF_AcceptChar(tf, buffer[i]); | 
					 | 
					 | 
					 | 
					        TF_AcceptChar(tf, buffer[i]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -714,13 +740,13 @@ void _TF_FN TF_AcceptChar(TinyFrame *tf, unsigned char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param msg - message written to the buffer | 
					 | 
					 | 
					 | 
					 * @param msg - message written to the buffer | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used by the frame, 0 on failure | 
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used by the frame, 0 on failure | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */ | 
					 | 
					 | 
					 | 
					 */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static inline size_t _TF_FN TF_ComposeHead(TinyFrame *tf, uint8_t *outbuff, TF_Msg *msg) | 
					 | 
					 | 
					 | 
					static inline uint32_t _TF_FN TF_ComposeHead(TinyFrame *tf, uint8_t *outbuff, TF_Msg *msg) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    int8_t si = 0; // signed small int
 | 
					 | 
					 | 
					 | 
					    int8_t si = 0; // signed small int
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_ID id = 0; | 
					 | 
					 | 
					 | 
					    TF_ID id = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_CKSUM cksum = 0; | 
					 | 
					 | 
					 | 
					    TF_CKSUM cksum = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t pos = 0; // can be needed to grow larger than TF_LEN
 | 
					 | 
					 | 
					 | 
					    uint32_t pos = 0; // can be needed to grow larger than TF_LEN
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    (void)cksum; | 
					 | 
					 | 
					 | 
					    (void)cksum; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -769,13 +795,13 @@ static inline size_t _TF_FN TF_ComposeHead(TinyFrame *tf, uint8_t *outbuff, TF_M | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param cksum - checksum variable, used for all calls to TF_ComposeBody. Must be reset before first use! (CKSUM_RESET(cksum);) | 
					 | 
					 | 
					 | 
					 * @param cksum - checksum variable, used for all calls to TF_ComposeBody. Must be reset before first use! (CKSUM_RESET(cksum);) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used | 
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */ | 
					 | 
					 | 
					 | 
					 */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static size_t _TF_FN TF_ComposeBody(uint8_t *outbuff, | 
					 | 
					 | 
					 | 
					static uint32_t _TF_FN TF_ComposeBody(uint8_t *outbuff, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                    const uint8_t *data, TF_LEN data_len, | 
					 | 
					 | 
					 | 
					                                    const uint8_t *data, TF_LEN data_len, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                    TF_CKSUM *cksum) | 
					 | 
					 | 
					 | 
					                                    TF_CKSUM *cksum) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_LEN i = 0; | 
					 | 
					 | 
					 | 
					    TF_LEN i = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t pos = 0; | 
					 | 
					 | 
					 | 
					    uint32_t pos = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (i = 0; i < data_len; i++) { | 
					 | 
					 | 
					 | 
					    for (i = 0; i < data_len; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        b = data[i]; | 
					 | 
					 | 
					 | 
					        b = data[i]; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -793,11 +819,11 @@ static size_t _TF_FN TF_ComposeBody(uint8_t *outbuff, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param cksum - checksum variable used for the body | 
					 | 
					 | 
					 | 
					 * @param cksum - checksum variable used for the body | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used | 
					 | 
					 | 
					 | 
					 * @return nr of bytes in outbuff used | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */ | 
					 | 
					 | 
					 | 
					 */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static size_t _TF_FN TF_ComposeTail(uint8_t *outbuff, TF_CKSUM *cksum) | 
					 | 
					 | 
					 | 
					static uint32_t _TF_FN TF_ComposeTail(uint8_t *outbuff, TF_CKSUM *cksum) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    int8_t si = 0; // signed small int
 | 
					 | 
					 | 
					 | 
					    int8_t si = 0; // signed small int
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
					 | 
					 | 
					 | 
					    uint8_t b = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t pos = 0; | 
					 | 
					 | 
					 | 
					    uint32_t pos = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#if TF_CKSUM_TYPE != TF_CKSUM_NONE | 
					 | 
					 | 
					 | 
					#if TF_CKSUM_TYPE != TF_CKSUM_NONE | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    CKSUM_FINALIZE(*cksum); | 
					 | 
					 | 
					 | 
					    CKSUM_FINALIZE(*cksum); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -807,57 +833,83 @@ static size_t _TF_FN TF_ComposeTail(uint8_t *outbuff, TF_CKSUM *cksum) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/**
 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * Send a message | 
					 | 
					 | 
					 | 
					 * Begin building a frame | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * | 
					 | 
					 | 
					 | 
					 * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param tf - instance | 
					 | 
					 | 
					 | 
					 * @param tf - instance | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param msg - message object | 
					 | 
					 | 
					 | 
					 * @param msg - message to send | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param listener - ID listener, or NULL | 
					 | 
					 | 
					 | 
					 * @param listener - response listener or NULL | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @param timeout - listener timeout, 0 is none | 
					 | 
					 | 
					 | 
					 * @param timeout - listener timeout ticks, 0 = indefinite | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @return true if sent | 
					 | 
					 | 
					 | 
					 * @return success (mutex claimed and listener added, if any) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */ | 
					 | 
					 | 
					 | 
					 */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static bool _TF_FN TF_SendFrame(TinyFrame *tf, TF_Msg *msg, TF_Listener listener, TF_TICKS timeout) | 
					 | 
					 | 
					 | 
					static bool _TF_FN TF_SendFrame_Begin(TinyFrame *tf, TF_Msg *msg, TF_Listener listener, TF_TICKS timeout) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t len = 0; | 
					 | 
					 | 
					 | 
					    TF_TRY(TF_ClaimTx(tf)); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t remain = 0; | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    size_t sent = 0; | 
					 | 
					 | 
					 | 
					    tf->tx_pos = (uint32_t) TF_ComposeHead(tf, tf->sendbuf, msg); // frame ID is incremented here if it's not a response
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_CKSUM cksum = 0; | 
					 | 
					 | 
					 | 
					    tf->tx_len = msg->len; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_ClaimTx(tf); | 
					 | 
					 | 
					 | 
					    if (listener) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        TF_TRY(TF_AddIdListener(tf, msg, listener, timeout)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    len = TF_ComposeHead(tf, tf->sendbuf, msg); | 
					 | 
					 | 
					 | 
					    CKSUM_RESET(tf->tx_cksum); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (listener) TF_AddIdListener(tf, msg, listener, timeout); | 
					 | 
					 | 
					 | 
					    return true; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    CKSUM_RESET(cksum); | 
					 | 
					 | 
					 | 
					static void _TF_FN TF_SendFrame_Chunk(TinyFrame *tf, const uint8_t *buff, uint32_t length) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t remain; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t chunk; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint32_t sent = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    remain = msg->len; | 
					 | 
					 | 
					 | 
					    remain = length; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    while (remain > 0) { | 
					 | 
					 | 
					 | 
					    while (remain > 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        size_t chunk = TF_MIN(TF_SENDBUF_LEN - len, remain); | 
					 | 
					 | 
					 | 
					        // Write what can fit in the tx buffer
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        len += TF_ComposeBody(tf->sendbuf+len, msg->data+sent, (TF_LEN) chunk, &cksum); | 
					 | 
					 | 
					 | 
					        chunk = TF_MIN(TF_SENDBUF_LEN - tf->tx_pos, remain); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tf->tx_pos += TF_ComposeBody(tf->sendbuf+tf->tx_pos, buff+sent, (TF_LEN) chunk, &tf->tx_cksum); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        remain -= chunk; | 
					 | 
					 | 
					 | 
					        remain -= chunk; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sent += chunk; | 
					 | 
					 | 
					 | 
					        sent += chunk; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Flush if the buffer is full and we have more to send
 | 
					 | 
					 | 
					 | 
					        // Flush if the buffer is full
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (remain > 0 && len == TF_SENDBUF_LEN) { | 
					 | 
					 | 
					 | 
					        if (tf->tx_pos == TF_SENDBUF_LEN) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, len); | 
					 | 
					 | 
					 | 
					            TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, tf->tx_pos); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            len = 0; | 
					 | 
					 | 
					 | 
					            tf->tx_pos = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void _TF_FN TF_SendFrame_End(TinyFrame *tf) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Checksum only if message had a body
 | 
					 | 
					 | 
					 | 
					    // Checksum only if message had a body
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (msg->len > 0) { | 
					 | 
					 | 
					 | 
					    if (tf->tx_len > 0) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Flush if checksum wouldn't fit in the buffer
 | 
					 | 
					 | 
					 | 
					        // Flush if checksum wouldn't fit in the buffer
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (TF_SENDBUF_LEN - len < sizeof(TF_CKSUM)) { | 
					 | 
					 | 
					 | 
					        if (TF_SENDBUF_LEN - tf->tx_pos < sizeof(TF_CKSUM)) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, len); | 
					 | 
					 | 
					 | 
					            TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, tf->tx_pos); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            len = 0; | 
					 | 
					 | 
					 | 
					            tf->tx_pos = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Add checksum, flush what remains to be sent
 | 
					 | 
					 | 
					 | 
					        // Add checksum, flush what remains to be sent
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        len += TF_ComposeTail(tf->sendbuf + len, &cksum); | 
					 | 
					 | 
					 | 
					        tf->tx_pos += TF_ComposeTail(tf->sendbuf + tf->tx_pos, &tf->tx_cksum); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, len); | 
					 | 
					 | 
					 | 
					    TF_WriteImpl(tf, (const uint8_t *) tf->sendbuf, tf->tx_pos); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_ReleaseTx(tf); | 
					 | 
					 | 
					 | 
					    TF_ReleaseTx(tf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * Send a message | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * @param tf - instance | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * @param msg - message object | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * @param listener - ID listener, or NULL | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * @param timeout - listener timeout, 0 is none | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 * @return true if sent | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static bool _TF_FN TF_SendFrame(TinyFrame *tf, TF_Msg *msg, TF_Listener listener, TF_TICKS timeout) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    TF_TRY(TF_SendFrame_Begin(tf, msg, listener, timeout)); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    TF_SendFrame_Chunk(tf, msg->data, msg->len); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    TF_SendFrame_End(tf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return true; | 
					 | 
					 | 
					 | 
					    return true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -923,7 +975,7 @@ bool _TF_FN TF_RenewIdListener(TinyFrame *tf, TF_ID id) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/** Timebase hook - for timeouts */ | 
					 | 
					 | 
					 | 
					/** Timebase hook - for timeouts */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void _TF_FN TF_Tick(TinyFrame *tf) | 
					 | 
					 | 
					 | 
					void _TF_FN TF_Tick(TinyFrame *tf) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    TF_COUNT i = 0; | 
					 | 
					 | 
					 | 
					    TF_COUNT i; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    struct TF_IdListener_ *lst; | 
					 | 
					 | 
					 | 
					    struct TF_IdListener_ *lst; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // increment parser timeout (timeout is handled when receiving next byte)
 | 
					 | 
					 | 
					 | 
					    // increment parser timeout (timeout is handled when receiving next byte)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |