dn_robotalk.c
Go to the documentation of this file.
1 
25 #include "stdint.h"
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #if defined(_USE_WIN_API)
30 #include <windows.h>
31 #elif defined(_USE_LINUX_API)
32 #include <arpa/inet.h>
33 #else
34 #include "dn_additional.h"
35 #endif
36 
37 #include "dn_common.h"
38 #include "dn_device.h"
39 #include "dn_udp.h"
40 #include "dn_robotalk.h"
41 
49 static HRESULT
50 rtk_send_nak(const struct CONN_PARAM_COMMON *device, uint8_t from_id,
51  uint8_t to_id)
52 {
53  union RTK_PACKET *packet = NULL;
54  HRESULT hr;
55 
56  packet = (union RTK_PACKET *) malloc(RTK_SIZE_HEADER + RTK_SIZE_CRC);
57  if (packet == NULL)
58  return E_OUTOFMEMORY;
59 
60  hr = rtk_param2packet(RTK_CMD_NAK, NULL, 0, from_id, to_id, packet);
61  if (FAILED(hr))
62  goto exit_proc;
63 
64  hr = rtk_send(device, packet);
65 
66 exit_proc:
67  if (packet != NULL) {
68  free(packet);
69  packet = NULL;
70  }
71 
72  return hr;
73 }
74 
85 HRESULT
87  uint8_t from_id, uint8_t to_id, union RTK_PACKET *packet)
88 {
89  if (packet == NULL)
90  return E_INVALIDARG;
91  if (len_data > 0 && data == NULL)
92  return E_INVALIDARG;
93  if (len_data > RTK_SIZE_DATA - RTK_SIZE_CRC)
94  return E_INVALIDARG;
95 
96  packet->enq = RTK_ENQ;
97  packet->len = len_data;
98 
99  /* Orders to ROBOTalk endian */
100  memcpy_be(&packet->command, &command, RTK_SIZE_COMMAND);
101 
102  packet->from_id = from_id;
103  packet->to_id = to_id;
104 
105  if (len_data > 0) {
106  memcpy(packet->data, data, len_data);
107  }
108 
109  return S_OK;
110 }
111 
117 uint16_t
118 rtk_calc_crc(const union RTK_PACKET *packet)
119 {
120  uint8_t pos, len_data;
121  uint16_t crc = 0;
122 
123  if (packet != NULL) {
124  len_data =
125  (packet->len > (RTK_SIZE_DATA - RTK_SIZE_CRC)) ?
126  (RTK_SIZE_DATA - RTK_SIZE_CRC) : packet->len;
127 
128  for (pos = 0; pos < RTK_SIZE_HEADER + len_data; pos++) {
129  crc += (uint16_t) packet->buf[pos];
130  }
131  }
132 
133  return crc;
134 }
135 
142 HRESULT
143 rtk_send(const struct CONN_PARAM_COMMON *device, union RTK_PACKET *packet_send)
144 {
145  uint16_t crc;
146  uint32_t len_send;
147  void *parg = NULL;
148  struct udpaddr opt_udp;
149  HRESULT hr;
150 
151  hr = check_conn_param(device, RTK_CHECK_SEND);
152  if (FAILED(hr))
153  return hr;
154 
155  if (packet_send == NULL)
156  return E_INVALIDARG;
157 
158  if (device->type == CONN_UDP) {
159  if (device->arg == NULL)
160  return E_INVALIDARG;
161  opt_udp.flag = 0;
162  opt_udp.addr = *(struct sockaddr_in *) device->arg;
163  parg = &opt_udp;
164  }
165 
166  len_send = RTK_SIZE_HEADER + RTK_SIZE_CRC + packet_send->len;
167  if (len_send > RTK_SIZE_PACKET) {
168  hr = E_TOO_MUCH_DATA;
169  goto send_end;
170  }
171 
172  /* Sets CRC */
173  crc = rtk_calc_crc(packet_send);
174  memcpy_be(&packet_send->data[packet_send->len], &crc, RTK_SIZE_CRC);
175 
176  hr = device->dn_send(device->sock, (const char *) packet_send->buf, len_send,
177  parg);
178  if (FAILED(hr))
179  goto send_end;
180 
181  send_end: return hr;
182 }
183 
192 HRESULT
193 rtk_recv(const struct CONN_PARAM_COMMON *device, union RTK_PACKET *packet_recv,
194  int client, unsigned int retry_nak)
195 {
196  int flag_init = 0;
197  unsigned int retry_cnt;
198  uint16_t crc, crc_recv, command;
199  uint32_t len_recv, len_recved, len_tmp;
200  char *pos, buf_tmp[UDP_MAX_PACKET + 1] =
201  { 0, };
202  void *parg = NULL;
203  struct udpaddr opt_udp;
204  HRESULT hr;
205 
206  hr = check_conn_param(device, RTK_CHECK_RECV);
207  if (FAILED(hr))
208  return hr;
209 
210  if (packet_recv == NULL)
211  return E_INVALIDARG;
212 
213  if (device->type == CONN_UDP) {
214  if (device->arg == NULL)
215  return E_INVALIDARG;
216  opt_udp.flag = 0;
217  parg = &opt_udp;
218  }
219 
220  for (retry_cnt = 0; retry_cnt <= retry_nak; retry_cnt++) {
221  len_recved = 0;
222  while (1) {
223  pos = (char *) memchr(buf_tmp, RTK_ENQ, len_recved);
224  if (pos != NULL) {
225  if (pos != buf_tmp) {
226  len_recved -= ((long) pos - (long) buf_tmp);
227  memcpy(buf_tmp, pos, len_recved);
228  }
229  } else {
230  len_recved = 0;
231  }
232 
233  if (len_recved >= RTK_SIZE_HEADER + RTK_SIZE_CRC)
234  break;
235 
236  hr = device->dn_recv(device->sock, &buf_tmp[len_recved],
237  UDP_MAX_PACKET - len_recved, &len_tmp, device->timeout, parg);
238 
239  if (device->type == CONN_UDP) {
240  if (client || flag_init) {
241  hr = SUCCEEDED(hr) ?
242  udp_check_sockaddr((struct sockaddr_in *) device->arg,
243  &opt_udp.addr) : hr;
244  } else {
245  flag_init = 1;
246  *(struct sockaddr_in *) device->arg = opt_udp.addr;
247  }
248  }
249 
250  if (FAILED(hr))
251  goto recv_end;
252 
253  len_recved += len_tmp;
254  }
255 
256  len_recv = RTK_SIZE_HEADER + RTK_SIZE_CRC
257  + ((union RTK_PACKET *) buf_tmp)->len;
258  if (len_recv > RTK_SIZE_PACKET) {
259  len_recved--;
260  memcpy(buf_tmp, &buf_tmp[1], len_recved);
261  continue;
262  }
263 
264  memcpy(packet_recv->buf, buf_tmp,
265  (len_recv < len_recved) ? len_recv : len_recved);
266 
267  while (len_recv > len_recved) {
268  hr = device->dn_recv(device->sock,
269  (char *) &packet_recv->buf[len_recved], len_recv - len_recved,
270  &len_tmp, device->timeout, parg);
271 
272  if (device->type == CONN_UDP) {
273  hr = SUCCEEDED(hr) ?
274  udp_check_sockaddr((struct sockaddr_in *) device->arg,
275  &opt_udp.addr) : hr;
276  }
277 
278  if (FAILED(hr))
279  goto recv_end;
280 
281  len_recved += len_tmp;
282  }
283 
284  /* Calculates CRC of the received packet */
285  crc = rtk_calc_crc(packet_recv);
286  memcpy_be(&crc_recv, &packet_recv->data[packet_recv->len], RTK_SIZE_CRC);
287 
288  /* Checks CRC */
289  if (crc != crc_recv) {
290  /* If CRC error occurs, then send NAK packet and retry */
291  hr = rtk_send_nak(device, packet_recv->from_id, packet_recv->to_id);
292  if (SUCCEEDED(hr)) {
293  if (retry_cnt == retry_nak)
294  hr = E_INVALIDPACKET;
295  continue;
296  }
297  }
298 
299  /* Orders to host's endian */
300  command = packet_recv->command;
301  memcpy_be(&packet_recv->command, &command, RTK_SIZE_COMMAND);
302 
303  break;
304  }
305 
306 recv_end:
307  return hr;
308 }
A type definition for the ROBOTalk packet.
Definition: dn_robotalk.h:143
unsigned uint32_t
Definition: stdint.h:43
#define RTK_CHECK_SEND
A definition for the check_conn_param function.
Definition: dn_robotalk.h:51
uint8_t len
Definition: dn_robotalk.h:148
UDP API file.
int flag
Definition: dn_udp.h:58
HRESULT rtk_param2packet(uint16_t command, const uint8_t *data, uint8_t len_data, uint8_t from_id, uint8_t to_id, union RTK_PACKET *packet)
Creates a ROBOTalk packet.
Definition: dn_robotalk.c:86
uint32_t timeout
Definition: dn_device.h:174
HRESULT(* dn_recv)(int sock, char *buf, uint32_t len_buf, uint32_t *len_recved, uint32_t timeout, void *arg)
Definition: dn_device.h:179
#define S_OK
Succeeded.
Definition: dn_common.h:89
#define UDP_MAX_PACKET
The maximum buffer size of a UDP packet.
Definition: dn_udp.h:44
#define RTK_SIZE_DATA
The data buffer size of a ROBOTalk packet.
Definition: dn_robotalk.h:99
unsigned short uint16_t
Definition: stdint.h:41
A type definition for parameters of udp_send and udp_recv.
Definition: dn_udp.h:56
#define RTK_SIZE_CRC
The CRC buffer size of a ROBOTalk packet.
Definition: dn_robotalk.h:111
unsigned char uint8_t
Definition: stdint.h:39
#define FAILED(hr)
A macro that returns TRUE/FALSE. If hr is less than zero, then returns TRUE.
Definition: dn_common.h:77
#define RTK_CMD_NAK
A definition for the ROBOTalk command which means negative acknowledge.
Definition: dn_robotalk.h:81
#define RTK_CHECK_RECV
A definition for the check_conn_param function.
Definition: dn_robotalk.h:57
uint16_t rtk_calc_crc(const union RTK_PACKET *packet)
Calculates CRC of the ROBOTalk packet.
Definition: dn_robotalk.c:118
#define E_INVALIDARG
Failed because some arguments are invalid.
Definition: dn_common.h:131
ROBOTalk API file.
#define RTK_SIZE_PACKET
The maximum buffer size of a ROBOTalk packet.
Definition: dn_robotalk.h:87
_DN_EXP_UDP HRESULT udp_check_sockaddr(const struct sockaddr_in *sock_to, const struct sockaddr_in *sock_from)
Checks the socket address. If sock_to and sock_from are equivalent, then returns S_OK.
Definition: dn_udp.c:216
int32_t HRESULT
Definition: dn_common.h:61
uint8_t enq
Definition: dn_robotalk.h:147
#define RTK_SIZE_COMMAND
The command buffer size of a ROBOTalk packet.
Definition: dn_robotalk.h:105
#define E_TOO_MUCH_DATA
Failed because the packet is too much.
Definition: dn_common.h:193
#define E_INVALIDPACKET
Failed because the packet is invalid.
Definition: dn_device.h:107
uint16_t command
Definition: dn_robotalk.h:149
#define E_OUTOFMEMORY
Failed because there is no enough memory space.
Definition: dn_common.h:125
#define RTK_ENQ
A definition for the ROBOTalk enquiry.
Definition: dn_robotalk.h:63
static HRESULT rtk_send_nak(const struct CONN_PARAM_COMMON *device, uint8_t from_id, uint8_t to_id)
Sends a NAK packet.
Definition: dn_robotalk.c:50
HRESULT rtk_send(const struct CONN_PARAM_COMMON *device, union RTK_PACKET *packet_send)
Sends ROBOTalk packet.
Definition: dn_robotalk.c:143
#define SUCCEEDED(hr)
A macro that returns TRUE/FALSE. If hr is zero or more, then returns TRUE.
Definition: dn_common.h:71
struct sockaddr_in addr
Definition: dn_udp.h:59
Common device API file.
Common API file.
_DN_EXP_DEVICE void memcpy_be(void *dst, const void *src, uint32_t len)
Orders to big endian.
Definition: dn_device.c:495
A type definition for common communication parameters.
Definition: dn_device.h:170
User own API file.
uint8_t buf[RTK_SIZE_PACKET]
Definition: dn_robotalk.h:154
#define RTK_SIZE_HEADER
The header buffer size of a ROBOTalk packet.
Definition: dn_robotalk.h:93
uint8_t from_id
Definition: dn_robotalk.h:150
HRESULT rtk_recv(const struct CONN_PARAM_COMMON *device, union RTK_PACKET *packet_recv, int client, unsigned int retry_nak)
Receives ROBOTalk packet.
Definition: dn_robotalk.c:193
_DN_EXP_DEVICE HRESULT check_conn_param(const struct CONN_PARAM_COMMON *device, int flag)
Checks the communication parameters.
Definition: dn_device.c:419
HRESULT(* dn_send)(int sock, const char *buf, uint32_t len_buf, void *arg)
Definition: dn_device.h:178
uint8_t to_id
Definition: dn_robotalk.h:151
uint8_t data[RTK_SIZE_DATA]
Definition: dn_robotalk.h:152


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Mon Jun 10 2019 13:12:20