SingingCat 0
application
encoder.c
1#include <coms/coms.h>
2#include "main-header.h"
3#include <platform-header.h>
4
5//#define CNWDEBUGCOM printf
6
7#ifndef CNWDEBUGCOM
8#define CNWDEBUGCOM(a, ...) noop()
9#endif
10
11
12int add_uint8(byte *buf, int bufsize, int *offset, uint32_t value) {
13 if (bufsize - *offset < 2) {
14 return 4;
15 }
16 buf[*offset] = value & 0xFF;
17 *offset = *offset + 1;
18 return 0;
19}
20
21int add_uint16(byte *buf, int bufsize, int *offset, uint32_t value) {
22 if (bufsize - *offset < 3) {
23 return 3;
24 }
25 int i;
26
27 for (i = 0; i < 2; i++) {
28 buf[*offset] = value & 0xFF;
29 value = value >> 8;
30 *offset = *offset + 1;
31 }
32 return 0;
33}
34
35
36int add_uint32(byte *buf, int bufsize, int *offset, uint32_t value) {
37 if (bufsize - *offset < 5) {
38 return 5;
39 }
40 int i;
41
42 for (i = 0; i < 4; i++) {
43 buf[*offset] = value & 0xFF;
44 value = value >> 8;
45 *offset = *offset + 1;
46 }
47 return 0;
48}
49
50
51int add_uint64(byte *buf, int bufsize, int *offset, uint64_t value) {
52 if (bufsize - *offset < 9) {
53 return 2;
54 }
55 int i;
56
57 for (i = 0; i < 8; i++) {
58 buf[*offset] = value & 0xFF;
59 value = value >> 8;
60 *offset = *offset + 1;
61 }
62 return 0;
63}
64/*
65 * \brief encode "com" into on-the-wire format. return 0 - ok, otherwise error. buf will not include '{' or '}'
66 * bufsize will be set to the length of the command in buf.
67 * buf will not be 'escaped'
68 */
69int encode(byte *buf, int *bufsize, struct command *com) {
70 int err;
71
72 CNWDEBUGCOM("-------- Encoding --------\n");
73
74 if (*bufsize < 37) {
75 return 1;
76 }
77 int offset = 0;
78
79 buf[offset++] = 'b';
80 buf[offset++] = 1; // version
81 buf[offset++] = 0; //length, placeholder
82 buf[offset++] = 0; //length, placeholder
83 buf[offset++] = 0; //chksum, placeholder
84 buf[offset++] = 0; //chksum, placeholder
85 if ((err = add_uint64(buf, *bufsize, &offset, (uint64_t)com->sender)) != 0) {
86 return err;
87 }
88 if ((err = add_uint64(buf, *bufsize, &offset, (uint64_t)com->recipient)) != 0) {
89 return err;
90 }
91 if ((err = add_uint64(buf, *bufsize, &offset, (uint64_t)com->target)) != 0) {
92 return err;
93 }
94 if ((err = add_uint32(buf, *bufsize, &offset, (uint32_t)com->index)) != 0) {
95 return err;
96 }
97 if ((err = add_uint8(buf, *bufsize, &offset, com->com)) != 0) {
98 return err;
99 }
100 if ((err = add_uint8(buf, *bufsize, &offset, com->flags)) != 0) {
101 return err;
102 }
103 if ((err = add_uint8(buf, *bufsize, &offset, com->argctr)) != 0) {
104 return err;
105 }
106
107 // encode args
108 int i;
109
110 for (i = 0; i < com->argctr; i++) {
111 byte *arg = (byte *)get_arg_new(com, i);
112 if (arg == NULL) {
113 return 8;
114 }
115 int argsize = get_arg_size_inmem(com, i); // length in memory. (this is normally same as "on-the-wire", except arrays are terminated with NUL
116 int header = 0;
117 if (arg[1] & (1 << 7)) {
118 header = -1; // do not copy the NUL terminator, thus decrement length by one
119 }
120
121 if ((offset + argsize) >= *bufsize) {
122 return 7;
123 }
124 int j;
125 for (j = 0; j < argsize + header; j++) {
126 buf[offset++] = arg[j];
127 }
128 }
129 // args are encoded
130
131 int temp = 2;
132
133 add_uint16(buf, *bufsize, &temp, offset); // fix length
134 uint16_t chk = 0;
135
136 for (i = 0; i < offset; i++) {
137 chk = chk + (chk ^ ((uint16_t)buf[i]));
138 }
139 add_uint16(buf, *bufsize, &temp, chk); // fix checksum
140
141 *bufsize = offset;
142 return 0;
143}
144
145int typesize(uint8_t type) {
146 if ((type == 1) || (type == 5)) {
147 return 1;
148 }
149 if ((type == 2) || (type = 6)) {
150 return 2;
151 }
152 if ((type == 3) || (type = 7)) {
153 return 4;
154 }
155 if ((type == 4) || (type = 8)) {
156 return 8;
157 }
158 printf("WARNING - got a type %i\n", type);
159 return 0;
160}
161
162// return total length (inc. type and array size) in bytes of field
163int fieldlen(uint8_t fieldtype, uint8_t array_size) {
164 uint8_t ts = typesize(fieldtype & ~(1 << 7));
165
166 if (fieldtype & (1 << 7)) {
167 return ts * array_size; // type, num elements
168 }
169 return ts; // add fieldtype
170}
171// return total length (inc. type and array size) in bytes in memory (aka how many to skip to arrive at next field)
172int fieldlen_inmem(uint8_t fieldtype, uint8_t array_size) {
173 int t = fieldlen(fieldtype, array_size);
174
175 if (fieldtype & (1 << 7)) {
176 return t + 4; // add fieldnum type,array,size+trailing 0
177 }
178 return t + 2; // add fieldnum,fieldtype
179}
int get_arg_size_inmem(const struct command *com, int index)
given an argument by index [0..n], will returns the number in bytes this argument takes up in memory....
const byte * get_arg_new(const struct command *com, int index)
given an argument by index[0..n], will returns a pointer to it. This will include the fieldnumber and...
int com
Definition: command.h:22
long target
Definition: command.h:16
long recipient
Definition: command.h:15
int index
Definition: command.h:13
uint8_t flags
Definition: command.h:23
uint8_t argctr
Definition: command.h:24
long sender
Definition: command.h:14