discoverpixy
chirp.hpp
1 #ifndef CHIRP_HPP
2 #define CHIRP_HPP
3 
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include "link.h"
8 
9 #define ALIGN(v, n) v = v&((n)-1) ? (v&~((n)-1))+(n) : v
10 #define FOURCC(a, b, c, d) (((uint32_t)a<<0)|((uint32_t)b<<8)|((uint32_t)c<<16)|((uint32_t)d<<24))
11 
12 #define CRP_RES_OK 0
13 #define CRP_RES_ERROR -1
14 #define CRP_RES_ERROR_RECV_TIMEOUT LINK_RESULT_ERROR_RECV_TIMEOUT
15 #define CRP_RES_ERROR_SEND_TIMEOUT LINK_RESULT_ERROR_SEND_TIMEOUT
16 #define CRP_RES_ERROR_CRC -2
17 #define CRP_RES_ERROR_PARSE -3
18 #define CRP_RES_ERROR_MAX_NAK -4
19 #define CRP_RES_ERROR_MEMORY -5
20 #define CRP_RES_ERROR_NOT_CONNECTED -6
21 
22 #define CRP_MAX_NAK 3
23 #define CRP_RETRIES 3
24 #define CRP_HEADER_TIMEOUT 1000
25 #define CRP_DATA_TIMEOUT 500
26 #define CRP_IDLE_TIMEOUT 500
27 #define CRP_SEND_TIMEOUT 1000
28 #define CRP_MAX_ARGS 10
29 #define CRP_BUFSIZE 0x80
30 #define CRP_BUFPAD 8
31 #define CRP_PROCTABLE_LEN 0x40
32 
33 #define CRP_START_CODE 0xaaaa5555
34 
35 #define CRP_CALL 0x80
36 #define CRP_RESPONSE 0x40
37 #define CRP_INTRINSIC 0x20
38 #define CRP_DATA 0x10
39 #define CRP_XDATA 0x18 // data not associated with no associated procedure)
40 #define CRP_CALL_ENUMERATE (CRP_CALL | CRP_INTRINSIC | 0x00)
41 #define CRP_CALL_INIT (CRP_CALL | CRP_INTRINSIC | 0x01)
42 #define CRP_CALL_ENUMERATE_INFO (CRP_CALL | CRP_INTRINSIC | 0x02)
43 
44 #define CRP_ACK 0x59
45 #define CRP_NACK 0x95
46 #define CRP_MAX_HEADER_LEN 64
47 
48 #define CRP_ARRAY 0x80 // bit
49 #define CRP_FLT 0x10 // bit
50 #define CRP_NO_COPY (0x10 | 0x20)
51 #define CRP_HINT 0x40 // bit
52 #define CRP_NULLTERM_ARRAY (0x20 | CRP_ARRAY) // bits
53 #define CRP_INT8 0x01
54 #define CRP_UINT8 0x01
55 #define CRP_INT16 0x02
56 #define CRP_UINT16 0x02
57 #define CRP_INT32 0x04
58 #define CRP_UINT32 0x04
59 #define CRP_FLT32 (CRP_FLT | 0x04)
60 #define CRP_FLT64 (CRP_FLT | 0x08)
61 #define CRP_STRING (CRP_NULLTERM_ARRAY | CRP_INT8)
62 #define CRP_TYPE_HINT 0x64 // type hint identifier
63 #define CRP_INTS8 (CRP_INT8 | CRP_ARRAY)
64 #define CRP_INTS16 (CRP_INT16 | CRP_ARRAY)
65 #define CRP_INTS32 (CRP_INT32 | CRP_ARRAY)
66 #define CRP_UINTS8 CRP_INTS8
67 #define CRP_UINTS8_NO_COPY (CRP_INTS8 | CRP_NO_COPY)
68 #define CRP_UINTS16_NO_COPY (CRP_INTS16 | CRP_NO_COPY)
69 #define CRP_UINTS32_NO_COPY (CRP_INTS32 | CRP_NO_COPY)
70 #define CRP_UINTS16 CRP_INTS16
71 #define CRP_UINTS32 CRP_INTS32
72 #define CRP_FLTS32 (CRP_FLT32 | CRP_ARRAY)
73 #define CRP_FLTS64 (CRP_FLT64 | CRP_ARRAY)
74 #define CRP_HINT8 (CRP_INT8 | CRP_HINT)
75 #define CRP_HINT16 (CRP_INT16 | CRP_HINT)
76 #define CRP_HINT32 (CRP_INT32 | CRP_HINT)
77 #define CRP_HINTS8 (CRP_INT8 | CRP_ARRAY | CRP_HINT)
78 #define CRP_HINTS16 (CRP_INT16 | CRP_ARRAY | CRP_HINT)
79 #define CRP_HINTS32 (CRP_INT32 | CRP_ARRAY | CRP_HINT)
80 #define CRP_HFLTS32 (CRP_FLT32 | CRP_ARRAY | CRP_HINT)
81 #define CRP_HFLTS64 (CRP_FLT64 | CRP_ARRAY | CRP_HINT)
82 #define CRP_HSTRING (CRP_STRING | CRP_HINT)
83 // CRP_HTYPE is for arg lists which are uint8_t arrays
84 #define CRP_HTYPE(v) CRP_TYPE_HINT, (uint8_t)(v>>0&0xff), (uint8_t)(v>>8&0xff), (uint8_t)(v>>16&0xff), (uint8_t)(v>>24&0xff)
85 
86 // regular call args
87 #define INT8(v) CRP_INT8, v
88 #define UINT8(v) CRP_INT8, v
89 #define INT16(v) CRP_INT16, v
90 #define UINT16(v) CRP_INT16, v
91 #define INT32(v) CRP_INT32, v
92 #define UINT32(v) CRP_INT32, v
93 #define FLT32(v) CRP_FLT32, v
94 #define FLT64(v) CRP_FLT64, v
95 #define STRING(s) CRP_STRING, s
96 #define INTS8(len, a) CRP_INTS8, len, a
97 #define UINTS8(len, a) CRP_INTS8, len, a
98 #define UINTS8_NO_COPY(len) CRP_UINTS8_NO_COPY, len
99 #define UINTS16_NO_COPY(len) CRP_UINTS16_NO_COPY, len
100 #define UINTS32_NO_COPY(len) CRP_UINTS32_NO_COPY, len
101 #define INTS16(len, a) CRP_INTS16, len, a
102 #define UINTS16(len, a) CRP_INTS16, len, a
103 #define INTS32(len, a) CRP_INTS32, len, a
104 #define UINTS32(len, a) CRP_INTS32, len, a
105 #define FLTS32(len, a) CRP_FLTS32, len, a
106 #define FLTS64(len, a) CRP_FLTS64, len, a
107 
108 // hint call args
109 #define HINT8(v) CRP_HINT8, v
110 #define UHINT8(v) CRP_HINT8, v
111 #define HINT16(v) CRP_HINT16, v
112 #define UHINT16(v) CRP_HINT16, v
113 #define HINT32(v) CRP_HINT32, v
114 #define UHINT32(v) CRP_HINT32, v
115 #define HFLT32(v) CRP_HFLT32, v
116 #define HFLT64(v) CRP_HFLT64, v
117 #define HSTRING(s) CRP_HSTRING, s
118 #define HINTS8(len, a) CRP_HINTS8, len, a
119 #define UHINTS8(len, a) CRP_HINTS8, len, a
120 #define HINTS16(len, a) CRP_HINTS16, len, a
121 #define UHINTS16(len, a) CRP_HINTS16, len, a
122 #define HINTS32(len, a) CRP_HINTS32, len, a
123 #define UHINTS32(len, a) CRP_HINTS32, len, a
124 #define HFLTS32(len, a) CRP_HFLTS32, len, a
125 #define HFLTS64(len, a) CRP_HFLTS64, len, a
126 #define HTYPE(v) CRP_TYPE_HINT, v
127 
128 #define INT8_IN(v) int8_t & v
129 #define UINT8_IN(v) uint8_t & v
130 #define INT16_IN(v) int16_t & v
131 #define UINT16_IN(v) uint16_t & v
132 #define INT32_IN(v) int32_t & v
133 #define UINT32_IN(v) uint32_t & v
134 #define FLT32_IN(v) float & v
135 #define FLT64_IN(v) double & v
136 #define STRING_IN(s) const char * s
137 #define INTS8_IN(len, a) uint32_t & len, int8_t * a
138 #define UINTS8_IN(len, a) uint32_t & len, uint8_t * a
139 #define INTS16_IN(len, a) uint32_t & len, int16_t * a
140 #define UINTS16_IN(len, a) uint32_t & len, uint16_t * a
141 #define INTS32_IN(len, a) uint32_t & len, int32_t * a
142 #define UINTS32_IN(len, a) uint32_t & len, uint32_t * a
143 #define FLTS32_IN(len, a) uint32_t & len, float * a
144 #define FLTS64_IN(len, a) uint32_t & len, double * a
145 
146 #ifndef END
147 #ifdef __x86_64__
148 #define END (int64_t)0
149 #else
150 #define END 0
151 #endif
152 #endif
153 #define END_OUT_ARGS END
154 #define END_IN_ARGS END
155 
156 // service types
157 #define SYNC 0
158 #define ASYNC 0x01 // bit
159 #define RETURN_ARRAY 0x02 // bit
160 #define SYNC_RETURN_ARRAY (SYNC | RETURN_ARRAY)
161 
162 #define CRP_RETURN(chirp, ...) chirp->assemble(0, __VA_ARGS__, END)
163 #define CRP_SEND_XDATA(chirp, ...) chirp->assemble(CRP_XDATA, __VA_ARGS__, END)
164 #define callSync(...) call(SYNC, __VA_ARGS__, END)
165 #define callAsync(...) call(ASYNC, __VA_ARGS__, END)
166 #define callSyncArray(...) call(SYNC_RETURN_ARRAY, __VA_ARGS__, END)
167 
168 class Chirp;
169 
170 typedef int16_t ChirpProc; // negative values are invalid
171 
172 typedef uint32_t (*ProcPtr)(Chirp *);
173 
175 {
176  char *procName;
177  ProcPtr procPtr;
178  uint8_t argTypes[CRP_MAX_ARGS];
179  char *procInfo;
180 };
181 
183 {
184  uint8_t argTypes[CRP_MAX_ARGS];
185  char *procInfo;
186 };
187 
188 struct ProcInfo
189 {
190  char *procName;
191  uint8_t *argTypes;
192  char *procInfo;
193 };
194 
196 {
197  const char *procName;
198  ProcPtr procPtr;
199  ChirpProc chirpProc;
200  const ProcTableExtension *extension;
201 };
202 
203 class Chirp
204 {
205 public:
206  Chirp(bool hinterested=false, bool client=false, Link *link=NULL);
207  ~Chirp();
208 
209  virtual int init(bool connect);
210  int setLink(Link *link);
211  ChirpProc getProc(const char *procName, ProcPtr callback=0);
212  int setProc(const char *procName, ProcPtr proc, ProcTableExtension *extension=NULL);
213  int getProcInfo(ChirpProc proc, ProcInfo *info);
214  int registerModule(const ProcModule *module);
215  void setSendTimeout(uint32_t timeout);
216  void setRecvTimeout(uint32_t timeout);
217 
218  int call(uint8_t service, ChirpProc proc, ...);
219  int call(uint8_t service, ChirpProc proc, va_list args);
220  static uint8_t getType(const void *arg);
221  int service(bool all=true);
222  int assemble(uint8_t type, ...);
223  bool connected();
224 
225  // utility methods
226  static int serialize(Chirp *chirp, uint8_t *buf, uint32_t bufSize, ...);
227  static int deserialize(uint8_t *buf, uint32_t len, ...);
228  static int vserialize(Chirp *chirp, uint8_t *buf, uint32_t bufSize, va_list *args);
229  static int vdeserialize(uint8_t *buf, uint32_t len, va_list *args);
230  static int deserializeParse(uint8_t *buf, uint32_t len, void *args[]);
231  static int loadArgs(va_list *args, void *recvArgs[]);
232  static int getArgList(uint8_t *buf, uint32_t len, uint8_t *argList);
233  int useBuffer(uint8_t *buf, uint32_t len);
234 
235  static uint16_t calcCrc(uint8_t *buf, uint32_t len);
236 
237 protected:
238  int remoteInit(bool connect);
239  int recvChirp(uint8_t *type, ChirpProc *proc, void *args[], bool wait=false); // null pointer terminates
240  virtual int handleChirp(uint8_t type, ChirpProc proc, const void *args[]); // null pointer terminates
241  virtual void handleXdata(const void *data[]) {(void)data;}
242  virtual int sendChirp(uint8_t type, ChirpProc proc);
243 
244  uint8_t *m_buf;
245  uint8_t *m_bufSave;
246  uint32_t m_len;
247  uint32_t m_offset;
248  uint32_t m_bufSize;
249  bool m_errorCorrected;
250  bool m_sharedMem;
251  bool m_hinformer;
252  bool m_hinterested;
253  bool m_client;
254  uint32_t m_headerLen;
255  uint16_t m_headerTimeout;
256  uint16_t m_dataTimeout;
257  uint16_t m_idleTimeout;
258  uint16_t m_sendTimeout;
259 
260 private:
261  int sendHeader(uint8_t type, ChirpProc proc);
262  int sendFull(uint8_t type, ChirpProc proc);
263  int sendData();
264  int sendAck(bool ack); // false=nack
265  int sendChirpRetry(uint8_t type, ChirpProc proc);
266  int recvHeader(uint8_t *type, ChirpProc *proc, bool wait);
267  int recvFull(uint8_t *type, ChirpProc *proc, bool wait);
268  int recvData();
269  int recvAck(bool *ack, uint16_t timeout); // false=nack
270  int32_t handleEnumerate(char *procName, ChirpProc *callback);
271  int32_t handleInit(uint16_t *blkSize, uint8_t *hintSource);
272  int32_t handleEnumerateInfo(ChirpProc *proc);
273  int vassemble(va_list *args);
274  void restoreBuffer();
275 
276  ChirpProc updateTable(const char *procName, ProcPtr procPtr);
277  ChirpProc lookupTable(const char *procName);
278  int realloc(uint32_t min=0);
279  int reallocTable();
280 
281  Link *m_link;
282  ProcTableEntry *m_procTable;
283  uint16_t m_procTableSize;
284  uint16_t m_blkSize;
285  uint8_t m_maxNak;
286  uint8_t m_retries;
287  bool m_call;
288  bool m_connected;
289 };
290 
291 #endif // CHIRP_H
Definition: chirp.hpp:182
Definition: chirp.hpp:195
Definition: chirp.hpp:203
Definition: chirp.hpp:174
Definition: chirp.hpp:188