Kuvée / COBS

Dependents:   Nucleo_cobs_test

Committer:
glansberry
Date:
Tue Jul 21 19:31:41 2015 -0400
Revision:
2:64fdac5efaa1
Parent:
1:2b84a7482df6
Child:
3:41c9f2bbeeb2
Modified to return an error on decoding if the buffer will be overrun

Who changed what in which revision?

UserRevisionLine numberNew contents of line
glansberry 0:736db4334c89 1 /* Consistent Overhead Byte Stuffing (COBS)
glansberry 0:736db4334c89 2 by Stuart Cheshire and Mary Baker
glansberry 0:736db4334c89 3
glansberry 0:736db4334c89 4 reference: http://conferences.sigcomm.org/sigcomm/1997/papers/p062.pdf
glansberry 0:736db4334c89 5
glansberry 0:736db4334c89 6
glansberry 0:736db4334c89 7 COBS is a byte stuffing algorithm that encodes data bytes into a sequence that is easily
glansberry 0:736db4334c89 8 decoded, but simple to identify when blocks of data start. The idea is elegant. The sequence starts with
glansberry 0:736db4334c89 9 a zero, followed by the number of bytes until the next zero, in that location is the number of bytes again, etc.
glansberry 0:736db4334c89 10 To keep a data stream synchronized, all one must do is watch for the zeros, which will never occur except when
glansberry 0:736db4334c89 11 a new byte sequence is starting.
glansberry 0:736db4334c89 12
glansberry 0:736db4334c89 13 */
glansberry 0:736db4334c89 14 #include "COBS.h"
glansberry 0:736db4334c89 15 /*
glansberry 0:736db4334c89 16 * StuffData byte stuffs “length” bytes of
glansberry 0:736db4334c89 17 * data at the location pointed to by “ptr”,
glansberry 0:736db4334c89 18 * writing the output to the location pointed
glansberry 0:736db4334c89 19 * to by “dst”.
glansberry 0:736db4334c89 20 */
glansberry 0:736db4334c89 21 #define FinishBlock(X) \
glansberry 0:736db4334c89 22 (*code_ptr = (X), \
glansberry 0:736db4334c89 23 code_ptr = dst++, \
glansberry 0:736db4334c89 24 code = 0x01)
glansberry 0:736db4334c89 25
glansberry 1:2b84a7482df6 26 /* Stuff the data into an array
glansberry 1:2b84a7482df6 27 Note: the ptr and dst buffers cannot be the same */
glansberry 0:736db4334c89 28 void COBS::StuffData(unsigned char *ptr, unsigned long length, unsigned char *dst)
glansberry 0:736db4334c89 29 {
glansberry 0:736db4334c89 30 const unsigned char *end = ptr + length;
glansberry 0:736db4334c89 31 unsigned char *code_ptr = dst++;
glansberry 0:736db4334c89 32 unsigned char code = 0x01;
glansberry 0:736db4334c89 33 while (ptr < end)
glansberry 0:736db4334c89 34 {
glansberry 0:736db4334c89 35 if (*ptr == 0) FinishBlock(code);
glansberry 0:736db4334c89 36 else
glansberry 0:736db4334c89 37 {
glansberry 0:736db4334c89 38 *dst++ = *ptr;
glansberry 0:736db4334c89 39 code++;
glansberry 0:736db4334c89 40 if (code == 0xFF) FinishBlock(code);
glansberry 0:736db4334c89 41 }
glansberry 0:736db4334c89 42 ptr++;
glansberry 0:736db4334c89 43 }
glansberry 0:736db4334c89 44
glansberry 0:736db4334c89 45 FinishBlock(code);
glansberry 0:736db4334c89 46 }
glansberry 0:736db4334c89 47
glansberry 0:736db4334c89 48 /*
glansberry 0:736db4334c89 49 * UnStuffData decodes “length” bytes of
glansberry 0:736db4334c89 50 * data at the location pointed to by “ptr”,
glansberry 0:736db4334c89 51 * writing the output to the location pointed
glansberry 0:736db4334c89 52 * to by “dst”.
glansberry 0:736db4334c89 53 */
glansberry 2:64fdac5efaa1 54 int COBS::UnStuffData(unsigned char *ptr, unsigned long length, unsigned char *dst)
glansberry 0:736db4334c89 55 {
glansberry 0:736db4334c89 56 const unsigned char *end = ptr + length;
glansberry 0:736db4334c89 57 while (ptr < end)
glansberry 0:736db4334c89 58 {
glansberry 0:736db4334c89 59 int i, code = *ptr++;
glansberry 2:64fdac5efaa1 60 if (ptr+code > end) return 1; //if we will overun the end of the buffer exit
glansberry 2:64fdac5efaa1 61 //this is most likely to happen when decoding a malformed message
glansberry 2:64fdac5efaa1 62 for (i=1; i<code; i++) *dst++ = *ptr++;
glansberry 0:736db4334c89 63 if (code < 0xFF) *dst++ = 0;
glansberry 0:736db4334c89 64 }
glansberry 2:64fdac5efaa1 65 return 0;
glansberry 2:64fdac5efaa1 66 }