summaryrefslogtreecommitdiff
path: root/gm_platform/fw/cobs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gm_platform/fw/cobs.c')
-rw-r--r--gm_platform/fw/cobs.c95
1 files changed, 7 insertions, 88 deletions
diff --git a/gm_platform/fw/cobs.c b/gm_platform/fw/cobs.c
index 22dcac0..041dd8f 100644
--- a/gm_platform/fw/cobs.c
+++ b/gm_platform/fw/cobs.c
@@ -2,87 +2,11 @@
#include "serial.h"
#include "cobs.h"
-/*@ requires \valid(dst + (0..dstlen-1));
- @ requires \valid_read(src + (0..srclen-1));
- @ requires \separated(dst + (0..dstlen-1), src + (0..srclen-1));
- @
- @ behavior valid:
- @ assumes 0 <= srclen <= 254;
- @ assumes 0 <= dstlen <= 65535;
- @ assumes dstlen >= srclen+2;
- @ assigns dst[0..srclen+1];
- @ ensures \forall integer i; (0 <= i < srclen && \old(src[i]) != 0) ==> dst[i+1] == src[i];
- @ ensures \result == srclen+2;
- @ ensures \forall integer i; 0 <= i <= srclen ==> dst[i] != 0;
- @ ensures dst[srclen+1] == 0;
- @
- @ behavior invalid:
- @ assumes srclen < 0 || srclen > 254
- @ || dstlen < 0 || dstlen > 65535
- @ || dstlen < srclen+2;
- @ assigns \nothing;
- @ ensures \result == -1;
- @
- @ complete behaviors;
- @ disjoint behaviors;
- @*/
-ssize_t cobs_encode(char *dst, size_t dstlen, char *src, size_t srclen) {
- if (dstlen > 65535 || srclen > 254)
- return -1;
- //@ assert 0 <= dstlen <= 65535 && 0 <= srclen <= 254;
-
- if (dstlen < srclen+2)
- return -1;
- //@ assert 0 <= srclen < srclen+2 <= dstlen;
-
- size_t p = 0;
- /*@ loop invariant 0 <= p <= srclen+1;
- @ loop invariant \forall integer i; 0 <= i < p ==> dst[i] != 0;
- @ loop invariant \forall integer i; 0 < i < p ==> (src[i-1] != 0 ==> dst[i] == src[i-1]);
- @ loop assigns p, dst[0..srclen+1];
- @ loop variant srclen-p+1;
- @*/
- while (p <= srclen) {
-
- char val;
- if (p != 0 && src[p-1] != 0) {
- val = src[p-1];
-
- } else {
- size_t q = p;
- /*@ loop invariant 0 <= p <= q <= srclen;
- @ loop invariant \forall integer i; p <= i < q ==> src[i] != 0;
- @ loop assigns q;
- @ loop variant srclen-q;
- @*/
- while (q < srclen && src[q] != 0)
- q++;
- //@ assert q == srclen || src[q] == 0;
- //@ assert q <= srclen <= 254;
- val = (char)q-p+1;
- //@ assert val != 0;
- }
-
- dst[p] = val;
- p++;
- }
-
- dst[p] = 0;
- //@ assert p == srclen+1;
-
- return srclen+2;
-}
-
-int cobs_encode_usart(char *src, size_t srclen) {
+int cobs_encode_usart(int (*output)(char), char *src, size_t srclen) {
if (srclen > 254)
return -1;
- //@ assert 0 <= srclen <= 254;
size_t p = 0;
- /*@ loop invariant 0 <= p <= srclen+1;
- @ loop assigns p;
- @ loop variant srclen-p+1;
- @*/
while (p <= srclen) {
char val;
@@ -91,25 +15,20 @@ int cobs_encode_usart(char *src, size_t srclen) {
} else {
size_t q = p;
- /*@ loop invariant 0 <= p <= q <= srclen;
- @ loop invariant \forall integer i; p <= i < q ==> src[i] != 0;
- @ loop assigns q;
- @ loop variant srclen-q;
- @*/
while (q < srclen && src[q] != 0)
q++;
- //@ assert q == srclen || src[q] == 0;
- //@ assert q <= srclen <= 254;
val = (char)q-p+1;
- //@ assert val != 0;
}
- usart_putc(val);
+ int rv = output(val);
+ if (rv)
+ return rv;
p++;
}
- usart_putc(0);
- //@ assert p == srclen+1;
+ int rv = output(0);
+ if (rv)
+ return rv;
return 0;
}