Develop and Download Open Source Software

Browse Subversion Repository

Contents of /runCtrl/TransmitCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 379 - (show annotations) (download) (as text)
Mon Apr 19 19:53:12 2010 UTC (14 years, 1 month ago) by satofumi
File MIME type: text/x-c++src
File size: 6005 byte(s)
コンパイルエラーを修正
1 /*!
2 \file
3 \brief 走行制御パケットの送受信
4
5 \author Satofumi KAMIMURA
6
7 $Id$
8 */
9
10 #include "TransmitCtrl.h"
11 #include "ConnectionInterface.h"
12 #include <cstring>
13 #include <cstdio>
14
15 using namespace beego;
16
17
18 struct TransmitCtrl::pImpl {
19 ConnectionInterface* con;
20 unsigned char* top;
21 char type;
22 std::vector<unsigned char> packet_data;
23 size_t unique_id;
24 int packet_size;
25 size_t items;
26
27 pImpl(ConnectionInterface* con_obj, unsigned char* struct_ptr)
28 : con(con_obj), top(struct_ptr), type(UNKNOWN_PACKET), unique_id(0),
29 packet_size(0), items(0) {
30 }
31
32 // パケットへの書き込み用
33 void setData(unsigned char* dst, int value, char byte) {
34 for (int i = 0; i < byte; ++i) {
35 dst[(byte -1) - i] = value & 0xff;
36 value >>= 8;
37 }
38 }
39
40 // パケットからの読み出し用
41 int getValue(unsigned char* data, int size) {
42 int value = 0;
43 for (int i = 0; i < size; ++i) {
44 value <<= 8;
45 value |= data[i];
46 }
47 return value;
48 }
49
50 void initPacket(char packet_type) {
51 type = packet_type;
52
53 // length 情報(4-6), checksum(15) は、terminatePacket() にて格納する
54 packet_data.resize(HEADER_SIZE + 2);
55 memmove(&packet_data[0], FirstTag, 3);
56 packet_data[3] = type;
57 packet_data[7] = REPLY_REQUEST;
58 setData(&packet_data[8], 0, 4);
59 setData(&packet_data[12], unique_id, 3);
60
61 items = 0;
62 packet_size = 0;
63 }
64
65 void setChecksum(unsigned char* data, int size) {
66 char sum = 0;
67 for (int i = 0; i < size -1; ++i) {
68 sum ^= data[i];
69 }
70 data[size -1] = sum;
71 }
72
73 void terminatePacket(void) {
74
75 // パケット長の格納
76 int packet_size = packet_data.size() + 1;
77 setData(&packet_data[4], packet_size, 3);
78
79 // ヘッダ checksum の作成
80 setChecksum(&packet_data[0], HEADER_SIZE);
81
82 // データ組数の格納
83 setData(&packet_data[HEADER_SIZE], items, 2);
84
85 // 全体 checsum の作成
86 packet_data.push_back(0x0);
87 setChecksum(&packet_data[0], packet_size);
88 }
89 };
90
91
92 TransmitCtrl::TransmitCtrl(ConnectionInterface* con, unsigned char* struct_ptr)
93 : pimpl(new pImpl(con, struct_ptr)) {
94 }
95
96
97 TransmitCtrl::~TransmitCtrl(void) {
98 }
99
100
101 void TransmitCtrl::initPacket(char type) {
102 pimpl->initPacket(type);
103 }
104
105
106 void TransmitCtrl::addVariable(unsigned char* ptr, int byte) {
107
108 int offset = ptr - pimpl->top;
109
110 unsigned char buffer[3 + 1 + 4];
111 pimpl->setData(&buffer[0], offset, 3);
112 pimpl->setData(&buffer[3], byte, 1);
113
114 if (byte == sizeof(char)) {
115 pimpl->setData(&buffer[4], *ptr, byte);
116
117 } else if (byte == sizeof(short)) {
118 short* short_value = reinterpret_cast<short*>(ptr);
119 pimpl->setData(&buffer[4], *short_value, byte);
120
121 } else if (byte == sizeof(long)) {
122 long* long_value = reinterpret_cast<long*>(ptr);
123 pimpl->setData(&buffer[4], *long_value, byte);
124 }
125
126 int add_size = 3 + 1 + byte;
127 for (int i = 0; i < add_size; ++i) {
128 pimpl->packet_data.push_back(buffer[i]);
129 }
130 ++pimpl->items;
131 }
132
133
134 bool TransmitCtrl::send(std::vector<unsigned char>* copy_message) {
135 pimpl->terminatePacket();
136
137 int packet_size = pimpl->packet_data.size();
138 int n = pimpl->con->send(reinterpret_cast<char*>(&pimpl->packet_data[0]),
139 packet_size);
140 #if 0
141 fprintf(stderr, "send: n = %d\n", packet_size);
142 for (int i = 0; i < packet_size; ++i) {
143 fprintf(stderr, "%02x ", (unsigned char)pimpl->packet_data[i]);
144 }
145 fprintf(stderr, "\n\n");
146 #endif
147 if (n < packet_size) {
148 // 受信タイムアウト
149 fprintf(stderr, " packet recv timeout! : %d\n", n);
150 //fprintf(stderr, "con: %s\n", pimpl->con->what());
151 return false;
152 }
153 if (copy_message) {
154 *copy_message = pimpl->packet_data;
155 }
156 ++pimpl->unique_id;
157 pimpl->packet_size = packet_size;
158 return true;
159 }
160
161
162 bool TransmitCtrl::recv(int timeout) {
163
164 std::vector<unsigned char> recv_buffer;
165 int recv_size = (pimpl->type == WRITE_PACKET)
166 ? HEADER_SIZE +1 : pimpl->packet_size;
167 recv_buffer.resize(recv_size);
168 int n = pimpl->con->recv(reinterpret_cast<char*>(&recv_buffer[0]),
169 recv_size, timeout);
170 #if 0
171 fprintf(stderr, "recv: n = %d\n", n);
172 for (int i = 0; i < n; ++i) {
173 fprintf(stderr, "%02x ", (unsigned char)recv_buffer[i]);
174 }
175 fprintf(stderr, "\n\n");
176 fprintf(stderr, "recv_buffer.size(): %d, recv_size: %d, n:%d\n",
177 recv_buffer.size(), recv_size, n);
178 #endif
179 if ((n <= 0) || (n < recv_size)) {
180 return false;
181 }
182
183 // 受信情報の処理
184 bool ret = false;
185 // !!! パース
186 char recv_type = recv_buffer[3];
187 int items_num = 0;
188 unsigned char* p = NULL;
189
190 switch (recv_type) {
191 case READ_REPLY_PACKET:
192 // 読み込みへの応答
193 items_num = pimpl->getValue(&recv_buffer[HEADER_SIZE], 2);
194 // !!! このあたりの関数は、ターゲット側のと共通にすべきかと
195 p = &recv_buffer[HEADER_SIZE +2];
196 for (int i = 0; i < items_num; ++i) {
197 int offset = pimpl->getValue(p, 3);
198 p += 3;
199 int byte = pimpl->getValue(p, 1);
200 ++p;
201 int value = pimpl->getValue(p, byte);
202 p += byte;
203
204 char* address = reinterpret_cast<char*>(&pimpl->top[offset]);
205 if (byte == sizeof(char)) {
206 *address = value;
207
208 } else if (byte == sizeof(short)) {
209 short* short_address = reinterpret_cast<short*>(address);
210 *short_address = value;
211
212 } else if (byte == sizeof(long)) {
213 long* long_address = reinterpret_cast<long*>(address);
214 *long_address = value;
215 }
216 }
217 ret = true;
218 break;
219
220 case WRITE_REPLY_PACKET:
221 // 書き込みへの応答
222 // !!!
223 // !!! とりあえず
224 ret = true;
225 break;
226
227 default:
228 break;
229 }
230 return ret;
231 }
232
233
234
235 bool TransmitCtrl::sendWithRetry(std::vector<unsigned char>& last_command,
236 size_t max_retry, int timeout) {
237
238 bool ret = send(&last_command);
239 if (! ret) {
240 //fprintf(stderr, "send return: %d\n", ret);
241 return false;
242 }
243
244 ret = recv(timeout);
245 if (! ret) {
246 //fprintf(stderr, "recv return: %d\n", ret);
247 return false;
248 }
249
250 //fprintf(stderr, "true\n");
251 return true;
252 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26