comparison src/cmd_proto.c @ 1:f7c60e525801

cptest and cp_ping.py to test cmd_proto.c.
author Thinker K.F. Li <thinker@branda.to>
date Sat, 21 Feb 2009 20:20:06 +0800
parents
children e410832c3280
comparison
equal deleted inserted replaced
0:a0ce8ebf2f18 1:f7c60e525801
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "cmd_proto.h"
5
6 enum {
7 ST_WAIT_MAGIC0,
8 ST_WAIT_MAGIC1,
9 ST_WAIT_SEQ,
10 ST_WAIT_LEN,
11 ST_WAIT_DATA,
12 ST_WAIT_CSUM
13 };
14
15 cmd_proto_t *cmd_proto_new(void) {
16 cmd_proto_t *cp;
17
18 cp = (cmd_proto_t *)malloc(sizeof(cmd_proto_t) + 512);
19 if(cp == NULL)
20 return NULL;
21
22 memset(cp, 0, sizeof(cmd_proto_t));
23 cp->bufs[0] = ((char *)cp) + sizeof(cmd_proto_t);
24 cp->bufs[1] = ((char *)cp) + sizeof(cmd_proto_t) + 256;
25 cp->cmds[0].data = cp->bufs[0] + 1;
26 cp->cmds[1].data = cp->bufs[1] + 1;
27
28 return cp;
29 }
30
31 void cmd_proto_free(cmd_proto_t *cp) {
32 free(cp);
33 }
34
35 cp_cmd_t BAD_CMD;
36 cp_cmd_t CSUM_ERR_CMD;
37
38 static
39 cp_cmd_t *make_cmd(cmd_proto_t *cp) {
40 char *buf = cp->bufs[cp->receiving];
41 cp_cmd_t *cmd;
42 int i;
43
44 if(buf[0] <= 0 || buf[0] >= CPCMD_MAX)
45 return &BAD_CMD;
46
47 cmd = cp->cmds + cp->receiving;
48
49 cmd->seq = cp->seq;
50 cmd->code = buf[0];
51 cmd->data_sz = cp->len - 1;
52
53 cp->receiving ^= 1;
54
55 return cmd;
56 }
57
58 #define CSUM_ADD(csum, c) \
59 do { \
60 csum = ((((csum) << 3) | ((csum) >> 5)) ^ (c)) & 0xff; \
61 } while(0)
62
63 cp_cmd_t *cmd_proto_rcv(cmd_proto_t *cp, int c) {
64 int i, csum;
65 char *buf;
66 cp_cmd_t *cmd = NULL;
67
68 switch(cp->status) {
69 case ST_WAIT_MAGIC0:
70 if(c == CP_MAGIC[0])
71 cp->status = ST_WAIT_MAGIC1;
72 break;
73
74 case ST_WAIT_MAGIC1:
75 if(c == CP_MAGIC[1])
76 cp->status = ST_WAIT_SEQ;
77 else if(c != CP_MAGIC[0])
78 cp->status = ST_WAIT_MAGIC0;
79 break;
80
81 case ST_WAIT_SEQ:
82 cp->seq = c;
83 cp->status = ST_WAIT_LEN;
84 break;
85
86 case ST_WAIT_LEN:
87 cp->len = c;
88 if(c > 0) {
89 cp->status = ST_WAIT_DATA;
90 cp->cnt = 0;
91 } else
92 cp->status = ST_WAIT_CSUM;
93 break;
94
95 case ST_WAIT_DATA:
96 cp->bufs[cp->receiving][cp->cnt++] = c;
97 if(cp->cnt >= cp->len)
98 cp->status = ST_WAIT_CSUM;
99 break;
100
101 case ST_WAIT_CSUM:
102 csum = 0;
103 buf = cp->bufs[cp->receiving];
104 for(i = 0; i < cp->len; i++)
105 CSUM_ADD(csum, buf[i]);
106 CSUM_ADD(csum, c);
107 cp->status = ST_WAIT_MAGIC0;
108 if(csum == 0)
109 cmd = make_cmd(cp);
110 else
111 cmd = &CSUM_ERR_CMD;
112 break;
113
114 default:
115 cp->status = ST_WAIT_MAGIC0;
116 }
117
118 return cmd;
119 }
120
121 int cmd_proto_cmd_fill(char *buf, int seq, cp_ccode_t code, int data_sz) {
122 int i, last = data_sz + CP_CMD_HEAD_SZ;
123 int csum = 0;
124
125 buf[0] = CP_MAGIC[0];
126 buf[1] = CP_MAGIC[1];
127 buf[2] = seq;
128 buf[3] = data_sz + 1;
129 buf[4] = code;
130 for(i = CP_CMD_HEAD_SZ - 1; i < last; i++)
131 CSUM_ADD(csum, buf[i]);
132 CSUM_ADD(csum, 0);
133 buf[i] = csum;
134
135 return data_sz + CP_CMD_OVERHEAD;
136 }