bcap_common.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 <winsock2.h>
31 #else
32 #if defined(_USE_LINUX_API)
33 #include <arpa/inet.h>
34 #else
35 #include "dn_additional.h"
36 #endif
37 
42 #define _TIME_DIFFERENCE (25569.0)
43 
48 #define _SEC_ONEDAY (24 * 60 * 60)
49 
50 #endif
51 
52 #include "dn_common.h"
53 #include "dn_device.h"
54 #include "dn_udp.h"
55 #include "bcap_common.h"
56 
57 static HRESULT
58 bcap_vntary2bytary(const VARIANT *src, uint32_t argc, char *dst,
59  uint32_t len_dst, uint32_t *offset, int flag);
60 static HRESULT
61 bcap_bytary2vntary(const char *src, uint32_t len_src, VARIANT *dst,
62  uint32_t argc, uint32_t *offset, int flag);
63 
69 static uint32_t
71 {
72  int32_t i, lbnd, ubnd, cnt;
73  uint16_t vt;
74  void *pdata;
75  uint32_t ret = 0;
76 
77  if (vnt != NULL) {
78  vt = vnt->vt;
79  if ((vt & VT_ARRAY) != 0) {
80  if (vnt->parray != NULL) {
81  SafeArrayGetLBound(vnt->parray, 1, &lbnd);
82  SafeArrayGetUBound(vnt->parray, 1, &ubnd);
83  cnt = ubnd - lbnd + 1;
84 
85  switch (vt ^ VT_ARRAY) {
86  case VT_UI1:
87  ret = cnt;
88  break;
89  case VT_I2:
90  case VT_UI2:
91  case VT_BOOL:
92  ret = cnt * 2;
93  break;
94  case VT_I4:
95  case VT_UI4:
96  case VT_R4:
97  ret = cnt * 4;
98  break;
99  case VT_I8:
100  case VT_UI8:
101  case VT_R8:
102  case VT_CY:
103  case VT_DATE:
104  ret = cnt * 8;
105  break;
106  case VT_BSTR:
107  SafeArrayAccessData(vnt->parray, &pdata);
108  for (i = 0; i < cnt; i++) {
109  ret += BCAP_SIZE_BSTR_LEN;
110  if (((BSTR*) pdata + i) != NULL) {
111  ret += BCAP_SIZE_BSTR_BUFFER
112  * SysStringLen(*((BSTR*) pdata + i));
113  }
114  }
116  break;
117  case VT_VARIANT:
118  SafeArrayAccessData(vnt->parray, &pdata);
119  for (i = 0; i < cnt; i++) {
121  if (((VARIANT*) pdata + i) != NULL) {
122  ret += bcap_calc_size_variant(((VARIANT*) pdata + i));
123  }
124  }
126  break;
127  default:
128  break;
129  }
130  }
131  } else {
132  switch (vt) {
133  case VT_UI1:
134  ret = 1;
135  break;
136  case VT_I2:
137  case VT_UI2:
138  case VT_BOOL:
139  ret = 2;
140  break;
141  case VT_I4:
142  case VT_UI4:
143  case VT_R4:
144  case VT_ERROR:
145  ret = 4;
146  break;
147  case VT_I8:
148  case VT_UI8:
149  case VT_R8:
150  case VT_CY:
151  case VT_DATE:
152  ret = 8;
153  break;
154  case VT_BSTR:
155  ret = BCAP_SIZE_BSTR_LEN;
156  if (vnt->bstrVal != NULL) {
158  }
159  break;
160  default:
161  break;
162  }
163  }
164  }
165 
166  return ret;
167 }
168 
175 static void
176 bcap_vntdate2bytary(const DATE *src, char *dst)
177 {
178 #if defined(_USE_WIN_API)
179  memcpy_le(dst, src, 8);
180 #else
181  double dbl = 0;
182  if (*src > 0) {
183  dbl = (double) (*src) / _SEC_ONEDAY + _TIME_DIFFERENCE;
184  }
185  memcpy_le(dst, &dbl, 8);
186 #endif
187 }
188 
195 static void
196 bcap_bytary2vntdate(const char *src, DATE *dst)
197 {
198 #if defined(_USE_WIN_API)
199  memcpy_le(dst, src, 8);
200 #else
201  double dbl = 0;
202  memcpy_le(&dbl, src, 8);
203  if (dbl > 0) {
204  *dst = (DATE) ((dbl - _TIME_DIFFERENCE) * _SEC_ONEDAY);
205  }
206 #endif
207 }
208 
218 static HRESULT
219 bcap_vnt2bytary(const VARIANT *src, uint32_t argc, char *dst, uint32_t len_dst,
220  uint32_t *offset)
221 {
222  uint16_t vt;
223  uint32_t i, j, len_bstr, size = 0;
224  void const *pdata;
225  void *parray;
226  HRESULT hr;
227 
228  vt = src->vt;
229  if ((vt & VT_ARRAY) != 0) {
230  if (src->parray != NULL) {
231  SafeArrayAccessData(src->parray, &parray);
232  switch (vt ^ VT_ARRAY) {
233  case VT_UI1:
234  if (*offset + argc > len_dst)
235  return E_INVALIDARG;
236  memcpy(&dst[*offset], parray, argc);
237  *offset += argc;
238 
239  size = 0;
240  break;
241  case VT_I2:
242  case VT_UI2:
243  case VT_BOOL:
244  size = 2;
245  break;
246  case VT_I4:
247  case VT_UI4:
248  case VT_R4:
249  size = 4;
250  break;
251  case VT_I8:
252  case VT_UI8:
253  case VT_R8:
254  case VT_CY:
255  size = 8;
256  break;
257  case VT_DATE:
258  size = 8;
259  for (i = 0; i < argc; i++) {
260  if (*offset + size > len_dst)
261  return E_INVALIDARG;
262  bcap_vntdate2bytary((DATE *) parray + i, &dst[*offset]);
263  *offset += size;
264  }
265 
266  size = 0;
267  break;
268  case VT_BSTR:
269  for (i = 0; i < argc; i++) {
270  size = BCAP_SIZE_BSTR_LEN;
271  if (*offset + size > len_dst)
272  return E_INVALIDARG;
273  len_bstr = BCAP_SIZE_BSTR_BUFFER
274  * SysStringLen(*((BSTR *) parray + i));
275  memcpy_le(&dst[*offset], &len_bstr, size);
276  *offset += size;
277 
278  size = BCAP_SIZE_BSTR_BUFFER;
279  for (j = 0; j < len_bstr / size; j++) {
280  if (*offset + size > len_dst)
281  return E_INVALIDARG;
282  memcpy_le(&dst[*offset], *((BSTR *) parray + i) + j, size);
283  *offset += size;
284  }
285  }
286 
287  size = 0;
288  break;
289  case VT_VARIANT:
290  hr = bcap_vntary2bytary((VARIANT *) parray, argc, dst, len_dst,
291  offset, 0);
292  if (FAILED(hr))
293  return hr;
294 
295  size = 0;
296  break;
297  default:
298  break;
299  }
300 
301  if (size > 0) {
302  for (i = 0; i < argc; i++) {
303  if (*offset + size > len_dst)
304  return E_INVALIDARG;
305  memcpy_le(&dst[*offset], (char *) parray + i * size, size);
306  *offset += size;
307  }
308  }
309 
311  }
312  } else {
313  switch (vt) {
314  case VT_UI1:
315  size = 1;
316  pdata = &src->bVal;
317  break;
318  case VT_I2:
319  size = 2;
320  pdata = &src->iVal;
321  break;
322  case VT_UI2:
323  size = 2;
324  pdata = &src->uiVal;
325  break;
326  case VT_BOOL:
327  size = 2;
328  pdata = &src->boolVal;
329  break;
330  case VT_I4:
331  size = 4;
332  pdata = &src->lVal;
333  break;
334  case VT_UI4:
335  size = 4;
336  pdata = &src->ulVal;
337  break;
338  case VT_R4:
339  size = 4;
340  pdata = &src->fltVal;
341  break;
342  case VT_ERROR:
343  size = 4;
344  pdata = &src->scode;
345  break;
346  case VT_I8:
347  size = 8;
348  pdata = &src->llVal;
349  break;
350  case VT_UI8:
351  size = 8;
352  pdata = &src->ullVal;
353  break;
354  case VT_R8:
355  size = 8;
356  pdata = &src->dblVal;
357  break;
358  case VT_CY:
359  size = 8;
360  pdata = &src->cyVal;
361  break;
362  case VT_DATE:
363  size = 8;
364  if (*offset + size > len_dst)
365  return E_INVALIDARG;
366  bcap_vntdate2bytary(&src->date, &dst[*offset]);
367  *offset += size;
368 
369  size = 0;
370  break;
371  case VT_BSTR:
372  size = BCAP_SIZE_BSTR_LEN;
373  if (*offset + size > len_dst)
374  return E_INVALIDARG;
375  len_bstr = BCAP_SIZE_BSTR_BUFFER * SysStringLen(src->bstrVal);
376  memcpy_le(&dst[*offset], &len_bstr, size);
377  *offset += size;
378 
379  size = BCAP_SIZE_BSTR_BUFFER;
380  for (i = 0; i < len_bstr / size; i++) {
381  if (*offset + size > len_dst)
382  return E_INVALIDARG;
383  memcpy_le(&dst[*offset], src->bstrVal + i, size);
384  *offset += size;
385  }
386 
387  size = 0;
388  break;
389  default:
390  break;
391  }
392 
393  if (size > 0) {
394  if (*offset + size > len_dst)
395  return E_INVALIDARG;
396  memcpy_le(&dst[*offset], pdata, size);
397  *offset += size;
398  }
399  }
400 
401  return S_OK;
402 }
403 
414 static HRESULT
415 bcap_vntary2bytary(const VARIANT *src, uint32_t argc, char *dst,
416  uint32_t len_dst, uint32_t *offset, int flag)
417 {
418  int32_t lbnd, ubnd;
419  uint32_t i, cnt, size, len_vnt, offset_tmp;
420  const VARIANT *vnt;
421  HRESULT hr = S_OK;
422 
423  for (i = 0; i < argc; i++) {
424  vnt = &src[i];
425  offset_tmp = *offset;
426 
427  if (flag != 0) {
428  *offset += BCAP_SIZE_DATA_LEN;
429  }
430 
431  size = BCAP_SIZE_VARIANT_TYPE;
432  if (*offset + size > len_dst)
433  return E_INVALIDARG;
434  memcpy_le(&dst[*offset], &vnt->vt, size);
435  *offset += size;
436 
437  if ((vnt->vt & VT_ARRAY) != 0) {
438  if (vnt->parray != NULL) {
439  SafeArrayGetLBound(vnt->parray, 1, &lbnd);
440  SafeArrayGetUBound(vnt->parray, 1, &ubnd);
441  cnt = ubnd - lbnd + 1;
442  } else {
443  return E_INVALIDARG;
444  }
445  } else {
446  cnt = 1;
447  }
448 
449  size = BCAP_SIZE_VARIANT_NUM;
450  if (*offset + size > len_dst)
451  return E_INVALIDARG;
452  memcpy_le(&dst[*offset], &cnt, size);
453  *offset += size;
454 
455  hr = bcap_vnt2bytary(vnt, cnt, dst, len_dst, offset);
456  if (FAILED(hr))
457  return hr;
458 
459  if (flag != 0) {
460  len_vnt = *offset - offset_tmp - BCAP_SIZE_DATA_LEN;
461  memcpy_le(&dst[offset_tmp], &len_vnt, BCAP_SIZE_DATA_LEN);
462  }
463  }
464 
465  return hr;
466 }
467 
475 HRESULT
476 bcap_packet2bytary(const struct BCAP_PACKET *src, char *dst, uint32_t len_dst)
477 {
478  uint32_t size, offset = 1;
479  HRESULT hr;
480 
481  if (src == NULL || dst == NULL)
482  return E_INVALIDARG;
483 
484  if (len_dst < BCAP_SIZE_MIN)
485  return E_INVALIDARG;
486 
487  memset(dst, 0, len_dst);
488 
490 
491  size = BCAP_SIZE_LEN;
492  memcpy_le(&dst[offset], &len_dst, size);
493  offset += size;
494 
495  size = BCAP_SIZE_SERIAL;
496  memcpy_le(&dst[offset], &src->serial, size);
497  offset += size;
498 
499  size = BCAP_SIZE_RESERVE;
500  memcpy_le(&dst[offset], &src->reserv, size);
501  offset += size;
502 
503  size = BCAP_SIZE_ID;
504  memcpy_le(&dst[offset], &src->id, size);
505  offset += size;
506 
507  size = BCAP_SIZE_ARGC;
508  memcpy_le(&dst[offset], &src->argc, size);
509  offset += size;
510 
511  hr = bcap_vntary2bytary(src->args, src->argc, dst, len_dst - 1, &offset, 1);
512 
513  dst[len_dst - 1] = BCAP_TERMINATOR;
514 
515  return hr;
516 }
517 
527 static HRESULT
528 bcap_bytary2vnt(const char *src, uint32_t len_src, VARIANT *dst, uint32_t argc,
529  uint32_t *offset)
530 {
531  uint16_t vt;
532  uint32_t i, j, len_bstr, size = 0;
533  void *pdata, *parray;
534  HRESULT hr;
535 
536  vt = dst->vt;
537  if ((vt & VT_ARRAY) != 0) {
538  dst->parray = SafeArrayCreateVector(vt ^ VT_ARRAY, 1, argc);
539  if (dst->parray == NULL)
540  return E_OUTOFMEMORY;
541 
542  SafeArrayAccessData(dst->parray, &parray);
543  switch (vt ^ VT_ARRAY) {
544  case VT_UI1:
545  if (*offset + argc > len_src)
546  return E_INVALIDARG;
547  memcpy(parray, &src[*offset], argc);
548  *offset += argc;
549 
550  size = 0;
551  break;
552  case VT_I2:
553  case VT_UI2:
554  case VT_BOOL:
555  size = 2;
556  break;
557  case VT_I4:
558  case VT_UI4:
559  case VT_R4:
560  size = 4;
561  break;
562  case VT_I8:
563  case VT_UI8:
564  case VT_R8:
565  case VT_CY:
566  size = 8;
567  break;
568  case VT_DATE:
569  size = 8;
570  for (i = 0; i < argc; i++) {
571  if (*offset + size > len_src)
572  return E_INVALIDPACKET;
573  bcap_bytary2vntdate(&src[*offset], (DATE *) parray + i);
574  *offset += size;
575  }
576 
577  size = 0;
578  break;
579  case VT_BSTR:
580  for (i = 0; i < argc; i++) {
581  size = BCAP_SIZE_BSTR_LEN;
582  if (*offset + size > len_src)
583  return E_INVALIDPACKET;
584  memcpy_le(&len_bstr, &src[*offset], size);
585  len_bstr /= BCAP_SIZE_BSTR_BUFFER;
586  *offset += size;
587 
588  *((BSTR*) parray + i) = SysAllocStringLen(L"", len_bstr);
589  if (*((BSTR*) parray + i) == NULL)
590  return E_OUTOFMEMORY;
591 
592  size = BCAP_SIZE_BSTR_BUFFER;
593  for (j = 0; j < len_bstr; j++) {
594  if (*offset + size > len_src)
595  return E_INVALIDPACKET;
596  memcpy_le(*((BSTR*) parray + i) + j, &src[*offset], size);
597  *offset += size;
598  }
599  }
600 
601  size = 0;
602  break;
603  case VT_VARIANT:
604  hr = bcap_bytary2vntary(src, len_src, (VARIANT *) parray, argc, offset,
605  0);
606  if (FAILED(hr))
607  return hr;
608 
609  size = 0;
610  break;
611  default:
612  break;
613  }
614 
615  if (size > 0) {
616  for (i = 0; i < argc; i++) {
617  if (*offset + size > len_src)
618  return E_INVALIDPACKET;
619  memcpy_le((char *) parray + i * size, &src[*offset], size);
620  *offset += size;
621  }
622  }
623 
625  } else {
626  switch (vt) {
627  case VT_UI1:
628  size = 1;
629  pdata = &dst->bVal;
630  break;
631  case VT_I2:
632  size = 2;
633  pdata = &dst->iVal;
634  break;
635  case VT_UI2:
636  size = 2;
637  pdata = &dst->uiVal;
638  break;
639  case VT_BOOL:
640  size = 2;
641  pdata = &dst->boolVal;
642  break;
643  case VT_I4:
644  size = 4;
645  pdata = &dst->lVal;
646  break;
647  case VT_UI4:
648  size = 4;
649  pdata = &dst->ulVal;
650  break;
651  case VT_R4:
652  size = 4;
653  pdata = &dst->fltVal;
654  break;
655  case VT_ERROR:
656  size = 4;
657  pdata = &dst->scode;
658  break;
659  case VT_I8:
660  size = 8;
661  pdata = &dst->llVal;
662  break;
663  case VT_UI8:
664  size = 8;
665  pdata = &dst->ullVal;
666  break;
667  case VT_R8:
668  size = 8;
669  pdata = &dst->dblVal;
670  break;
671  case VT_CY:
672  size = 8;
673  pdata = &dst->cyVal;
674  break;
675  case VT_DATE:
676  size = 8;
677  if (*offset + size > len_src)
678  return E_INVALIDPACKET;
679  bcap_bytary2vntdate(&src[*offset], &dst->date);
680  *offset += size;
681 
682  size = 0;
683  break;
684  case VT_BSTR:
685  size = BCAP_SIZE_BSTR_LEN;
686  if (*offset + size > len_src)
687  return E_INVALIDPACKET;
688  memcpy_le(&len_bstr, &src[*offset], size);
689  len_bstr /= BCAP_SIZE_BSTR_BUFFER;
690  *offset += size;
691 
692  dst->bstrVal = SysAllocStringLen(L"", len_bstr);
693  if (dst->bstrVal == NULL)
694  return E_OUTOFMEMORY;
695 
696  size = BCAP_SIZE_BSTR_BUFFER;
697  for (i = 0; i < len_bstr; i++) {
698  if (*offset + size > len_src)
699  return E_INVALIDPACKET;
700  memcpy_le(dst->bstrVal + i, &src[*offset], size);
701  *offset += size;
702  }
703 
704  size = 0;
705  break;
706  default:
707  break;
708  }
709 
710  if (size > 0) {
711  if (*offset + size > len_src)
712  return E_INVALIDPACKET;
713  memcpy_le(pdata, &src[*offset], size);
714  *offset += size;
715  }
716  }
717 
718  return S_OK;
719 }
720 
731 static HRESULT
732 bcap_bytary2vntary(const char *src, uint32_t len_src, VARIANT *dst,
733  uint32_t argc, uint32_t *offset, int flag)
734 {
735  uint32_t i, cnt, size;
736  VARIANT *vnt;
737  HRESULT hr = S_OK;
738 
739  for (i = 0; i < argc; i++) {
740  vnt = &dst[i];
741  VariantInit(vnt);
742 
743  if (flag != 0) {
744  *offset += BCAP_SIZE_DATA_LEN;
745  }
746 
747  size = BCAP_SIZE_VARIANT_TYPE;
748  if (*offset + size > len_src)
749  return E_INVALIDPACKET;
750  memcpy_le(&vnt->vt, &src[*offset], size);
751  *offset += size;
752 
753  size = BCAP_SIZE_VARIANT_NUM;
754  if (*offset + size > len_src)
755  return E_INVALIDPACKET;
756  memcpy_le(&cnt, &src[*offset], size);
757  *offset += size;
758 
759  hr = bcap_bytary2vnt(src, len_src, vnt, cnt, offset);
760  if (FAILED(hr))
761  return hr;
762  }
763 
764  return hr;
765 }
766 
775 HRESULT
776 bcap_bytary2packet(const char *src, uint32_t len_src, struct BCAP_PACKET *dst)
777 {
778  uint16_t tmp_argc;
779  uint32_t len_tmp, size, offset = 1;
780  HRESULT hr = S_OK;
781 
782  if (src == NULL || dst == NULL)
783  return E_INVALIDARG;
784 
785  if (len_src < BCAP_SIZE_MIN)
786  return E_INVALIDPACKET;
787 
788  size = BCAP_SIZE_LEN;
789  memcpy_le(&len_tmp, &src[offset], size);
790  offset += size;
791 
792  if (len_tmp != len_src)
793  return E_INVALIDPACKET;
794 
795  if ((src[BCAP_POS_HEADER] != BCAP_HEADER)
796  || (src[len_src - 1] != BCAP_TERMINATOR))
797  return E_INVALIDPACKET;
798 
799  size = BCAP_SIZE_SERIAL;
800  memcpy_le(&dst->serial, &src[offset], size);
801  offset += size;
802 
803  size = BCAP_SIZE_RESERVE;
804  memcpy_le(&dst->reserv, &src[offset], size);
805  offset += size;
806 
807  size = BCAP_SIZE_ID;
808  memcpy_le(&dst->id, &src[offset], size);
809  offset += size;
810 
811  size = BCAP_SIZE_ARGC;
812  memcpy_le(&tmp_argc, &src[offset], size);
813  offset += size;
814 
815  if (dst->argc == (uint16_t) -1) {
816  if (dst->args != NULL)
817  return E_INVALIDARG;
818  dst->argc = tmp_argc;
819  } else {
820  if ((dst->argc > 0) && (dst->args == NULL))
821  return E_INVALIDARG;
822  if (tmp_argc > dst->argc)
823  return E_INVALIDPACKET;
824  dst->argc = tmp_argc;
825  }
826 
827  if (dst->argc > 0) {
828  if (dst->args == NULL) {
829  dst->args = (VARIANT *) malloc(sizeof(VARIANT) * dst->argc);
830  if (dst->args == NULL)
831  return E_OUTOFMEMORY;
832  }
833 
834  hr = bcap_bytary2vntary(src, len_src - 1, dst->args, dst->argc, &offset,
835  1);
836  }
837 
838  return hr;
839 }
840 
846 uint32_t
847 bcap_calc_size_packet(const struct BCAP_PACKET *packet)
848 {
849  int i;
850  uint32_t ret = 0;
851 
852  if (packet != NULL) {
853  ret = BCAP_SIZE_MIN;
854  for (i = 0; i < packet->argc; i++) {
857  + bcap_calc_size_variant(&packet->args[i]);
858  }
859  }
860 
861  return ret;
862 }
863 
869 uint16_t
871 {
872  int cnt;
873  uint32_t pos;
874  uint16_t crc = 0xFFFF;
875 
876  if (buf != NULL) {
877  for (pos = 0; pos < len_buf; pos++) {
878  crc ^= (buf[pos] << 8);
879  for (cnt = 0; cnt < 8; cnt++) {
880  if (crc & 0x8000) {
881  crc = (crc << 1) ^ 0x1021;
882  } else {
883  crc <<= 1;
884  }
885  }
886  }
887  }
888 
889  return crc;
890 }
891 
898 HRESULT
899 bcap_send(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_send)
900 {
901  int opt_tcp;
902  uint16_t crc;
903  uint32_t len_send, len_max;
904  char *buf_send = NULL;
905  void *parg = NULL;
906  struct udpaddr opt_udp;
907  HRESULT hr;
908 
909  hr = check_conn_param(device, BCAP_CHECK_SEND);
910  if (FAILED(hr))
911  return hr;
912 
913  if (packet_send == NULL)
914  return E_INVALIDARG;
915 
916  switch (device->type) {
917  case CONN_TCP:
918  len_max = (uint32_t) -1;
919  opt_tcp = 0;
920  parg = &opt_tcp;
921  break;
922  case CONN_UDP:
923  if (device->arg == NULL)
924  return E_INVALIDARG;
925  len_max = UDP_MAX_PACKET;
926  opt_udp.flag = 0;
927  opt_udp.addr = *(struct sockaddr_in *) device->arg;
928  parg = &opt_udp;
929  break;
930  case CONN_COM:
931  len_max = UDP_MAX_PACKET;
932  break;
933  default:
934  return E_INVALIDARG;
935  }
936 
937  len_send = bcap_calc_size_packet(packet_send);
938  if (device->type == CONN_COM) {
939  len_send += BCAP_SIZE_CRC;
940  }
941 
942  if (len_send > len_max) {
943  hr = E_TOO_MUCH_DATA;
944  goto send_end;
945  }
946 
947  buf_send = (char *) malloc(len_send);
948  if (buf_send == NULL) {
949  hr = E_OUTOFMEMORY;
950  goto send_end;
951  }
952 
953  hr = bcap_packet2bytary(packet_send, buf_send, len_send);
954  if (FAILED(hr))
955  goto send_end;
956 
957  if (device->type == CONN_COM) {
958  crc = bcap_calc_crc((uint8_t *) &buf_send[BCAP_POS_LEN],
959  BCAP_SIZE_CALC_CRC(len_send));
960  memcpy_le(&buf_send[BCAP_POS_CRC(len_send)], &crc, BCAP_SIZE_CRC);
961  }
962 
963  hr = device->dn_send(device->sock, buf_send, len_send, parg);
964  if (FAILED(hr))
965  goto send_end;
966 
967 send_end:
968  if (buf_send != NULL) {
969  free(buf_send);
970  buf_send = NULL;
971  }
972 
973  return hr;
974 }
975 
983 HRESULT
984 bcap_recv(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_recv,
985  int client)
986 {
987  int opt_tcp, flag_init = 0, flag_crc = 1;
988  uint16_t crc, crc_recv;
989  uint32_t len_recv, len_recved, len_tmp, len_min, len_max;
990  char *buf_recv = NULL, *pos, buf_tmp[UDP_MAX_PACKET + 1] =
991  { 0, };
992  void *parg = NULL;
993  struct udpaddr opt_udp;
994  HRESULT hr;
995 
996  hr = check_conn_param(device, BCAP_CHECK_RECV);
997  if (FAILED(hr))
998  return hr;
999 
1000  if (packet_recv == NULL)
1001  return E_INVALIDARG;
1002 
1003  switch (device->type) {
1004  case CONN_TCP:
1005  len_min = BCAP_SIZE_MIN;
1006  len_max = (uint32_t) -1;
1007  opt_tcp = MSG_PEEK;
1008  parg = &opt_tcp;
1009  break;
1010  case CONN_UDP:
1011  if (device->arg == NULL)
1012  return E_INVALIDARG;
1013  len_min = BCAP_SIZE_MIN;
1014  len_max = UDP_MAX_PACKET;
1015  opt_udp.flag = 0;
1016  parg = &opt_udp;
1017  break;
1018  case CONN_COM:
1019  len_min = BCAP_SIZE_MIN + BCAP_SIZE_CRC;
1020  len_max = UDP_MAX_PACKET;
1021  break;
1022  default:
1023  return E_INVALIDARG;
1024  }
1025 
1026  while (1) {
1027  len_recved = 0;
1028  while (1) {
1029  pos = (char *) memchr(buf_tmp, BCAP_HEADER, len_recved);
1030  if (pos != NULL) {
1031  if (pos != buf_tmp) {
1032  if (device->type == CONN_TCP) {
1033  len_tmp = ((long) pos - (long) buf_tmp);
1034  device->dn_recv(device->sock, buf_tmp, len_tmp, &len_recv,
1035  device->timeout, NULL);
1036  }
1037  len_recved -= ((long) pos - (long) buf_tmp);
1038  memcpy(buf_tmp, pos, len_recved);
1039  }
1040  } else {
1041  if (device->type == CONN_TCP) {
1042  device->dn_recv(device->sock, buf_tmp, len_recved, &len_recv,
1043  device->timeout, NULL);
1044  }
1045  len_recved = 0;
1046  }
1047 
1048  if (len_recved >= BCAP_SIZE_HEADER + BCAP_SIZE_LEN) {
1049  break;
1050  }
1051 
1052  if (device->type == CONN_TCP) {
1053  len_recved = 0;
1054  }
1055 
1056  hr = device->dn_recv(device->sock, &buf_tmp[len_recved],
1057  UDP_MAX_PACKET - len_recved, &len_tmp, device->timeout, parg);
1058 
1059  if (device->type == CONN_UDP) {
1060  if (client || flag_init) {
1061  hr = SUCCEEDED(hr) ?
1062  udp_check_sockaddr((struct sockaddr_in *) device->arg,
1063  &opt_udp.addr) : hr;
1064  } else {
1065  flag_init = 1;
1066  *(struct sockaddr_in *) device->arg = opt_udp.addr;
1067  }
1068  }
1069 
1070  if (FAILED(hr))
1071  goto recv_end;
1072 
1073  len_recved += len_tmp;
1074  }
1075 
1076  memcpy_le(&len_recv, &buf_tmp[BCAP_POS_LEN], BCAP_SIZE_LEN);
1077  if ((len_recv < len_min) || (len_max < len_recv)) {
1078  if (device->type == CONN_TCP) {
1079  device->dn_recv(device->sock, buf_tmp, BCAP_SIZE_HEADER, &len_tmp,
1080  device->timeout, NULL);
1081  }
1082  len_recved -= BCAP_SIZE_HEADER;
1083  memcpy(buf_tmp, &buf_tmp[BCAP_POS_LEN], len_recved);
1084  continue;
1085  }
1086 
1087  buf_recv = (char *) malloc(len_recv);
1088  if (buf_recv == NULL) {
1089  hr = E_OUTOFMEMORY;
1090  goto recv_end;
1091  }
1092 
1093  if (device->type == CONN_TCP) {
1094  opt_tcp = 0;
1095  device->dn_recv(device->sock, buf_recv, len_recv, &len_recved,
1096  device->timeout, parg);
1097  } else {
1098  memcpy(buf_recv, buf_tmp,
1099  (len_recv < len_recved) ? len_recv : len_recved);
1100  }
1101 
1102  while (len_recv > len_recved) {
1103  hr = device->dn_recv(device->sock, &buf_recv[len_recved],
1104  len_recv - len_recved, &len_tmp, device->timeout, parg);
1105 
1106  if (device->type == CONN_UDP) {
1107  hr = SUCCEEDED(hr) ?
1108  udp_check_sockaddr((struct sockaddr_in *) device->arg,
1109  &opt_udp.addr) : hr;
1110  }
1111 
1112  if (FAILED(hr))
1113  goto recv_end;
1114 
1115  len_recved += len_tmp;
1116  }
1117 
1118  hr = bcap_bytary2packet(buf_recv, len_recv, packet_recv);
1119  if (FAILED(hr))
1120  goto recv_end;
1121 
1122  if (device->type == CONN_COM) {
1123  crc = bcap_calc_crc((uint8_t *) &buf_recv[BCAP_POS_LEN],
1124  BCAP_SIZE_CALC_CRC(len_recv));
1125  memcpy_le(&crc_recv, &buf_recv[BCAP_POS_CRC(len_recv)],
1126  BCAP_SIZE_CRC);
1127  flag_crc = (crc == crc_recv);
1128  }
1129 
1130  if (flag_crc) {
1131  break;
1132  }
1133  }
1134 
1135 recv_end:
1136  if (buf_recv != NULL) {
1137  free(buf_recv);
1138  buf_recv = NULL;
1139  }
1140 
1141  return hr;
1142 }
uint64_t ullVal
Definition: dn_common.h:324
#define BCAP_HEADER
A definition for the b-CAP header.
Definition: bcap_common.h:69
VARIANT_BOOL boolVal
Definition: dn_common.h:320
unsigned uint32_t
Definition: stdint.h:43
static HRESULT bcap_bytary2vnt(const char *src, uint32_t len_src, VARIANT *dst, uint32_t argc, uint32_t *offset)
Converts the byte array to a VARIANT value.
Definition: bcap_common.c:528
struct CONN_PARAM_COMMON device
Definition: bcap_client.c:68
uint16_t argc
Definition: bcap_common.h:232
UDP API file.
int flag
Definition: dn_udp.h:58
uint32_t bcap_calc_size_packet(const struct BCAP_PACKET *packet)
Calculates the converted buffer size of the b-CAP packet.
Definition: bcap_common.c:847
#define BCAP_SIZE_HEADER
A definition for the size of b-CAP header.
Definition: bcap_common.h:81
HRESULT bcap_send(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_send)
Sends b-CAP packet.
Definition: bcap_common.c:899
_DN_EXP_COMMON HRESULT SafeArrayUnaccessData(SAFEARRAY *psa)
Unaccesses the SAFEARRAY.
Definition: dn_common.c:353
uint32_t timeout
Definition: dn_device.h:174
_DN_EXP_COMMON BSTR SysAllocStringLen(const wchar_t *pch, uint16_t cch)
Allocates and returns BSTR.
Definition: dn_common.c:77
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
uint8_t bVal
Definition: dn_common.h:321
#define S_OK
Succeeded.
Definition: dn_common.h:89
_DN_EXP_COMMON HRESULT SafeArrayGetLBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plLbound)
Gets the lower bound of SAFEARRAY.
Definition: dn_common.c:278
#define BCAP_SIZE_RESERVE
A definition for the size of b-CAP version or retry count.
Definition: bcap_common.h:105
#define UDP_MAX_PACKET
The maximum buffer size of a UDP packet.
Definition: dn_udp.h:44
wchar_t * BSTR
Definition: dn_common.h:239
#define BCAP_POS_HEADER
A definition for the buffer position of b-CAP header.
Definition: bcap_common.h:129
unsigned short uint16_t
Definition: stdint.h:41
A type definition for parameters of udp_send and udp_recv.
Definition: dn_udp.h:56
static HRESULT bcap_bytary2vntary(const char *src, uint32_t len_src, VARIANT *dst, uint32_t argc, uint32_t *offset, int flag)
Converts the byte array to a VARIANT array.
Definition: bcap_common.c:732
int32_t lVal
Definition: dn_common.h:312
VARIANT * args
Definition: bcap_common.h:233
time_t DATE
Definition: dn_common.h:259
unsigned char uint8_t
Definition: stdint.h:39
static void bcap_bytary2vntdate(const char *src, DATE *dst)
Converts the byte array to a DATE value.
Definition: bcap_common.c:196
BSTR bstrVal
Definition: dn_common.h:318
#define BCAP_SIZE_BSTR_BUFFER
A definition for the size of a BSTR character.
Definition: bcap_common.h:190
#define BCAP_SIZE_VARIANT_NUM
A definition for the size of VARIANT number of elements.
Definition: bcap_common.h:202
#define BCAP_SIZE_ARGC
A definition for the size of b-CAP number of args.
Definition: bcap_common.h:117
#define BCAP_SIZE_VARIANT_TYPE
A definition for the size of VARIANT data type.
Definition: bcap_common.h:196
#define FAILED(hr)
A macro that returns TRUE/FALSE. If hr is less than zero, then returns TRUE.
Definition: dn_common.h:77
int64_t llVal
Definition: dn_common.h:313
#define E_INVALIDARG
Failed because some arguments are invalid.
Definition: dn_common.h:131
#define MSG_PEEK
Definition: dn_additional.h:79
_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
#define BCAP_SIZE_ID
A definition for the size of b-CAP function ID or return code.
Definition: bcap_common.h:111
CY cyVal
Definition: dn_common.h:316
_DN_EXP_COMMON HRESULT SafeArrayGetUBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plUbound)
Gets the upper bound of SAFEARRAY.
Definition: dn_common.c:298
int32_t HRESULT
Definition: dn_common.h:61
#define E_TOO_MUCH_DATA
Failed because the packet is too much.
Definition: dn_common.h:193
HRESULT bcap_recv(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_recv, int client)
Receives b-CAP packet.
Definition: bcap_common.c:984
#define BCAP_SIZE_MIN
A definition for the minimum buffer size of a b-CAP packet.
Definition: bcap_common.h:178
static HRESULT bcap_vntary2bytary(const VARIANT *src, uint32_t argc, char *dst, uint32_t len_dst, uint32_t *offset, int flag)
Definition: bcap_common.c:415
#define E_INVALIDPACKET
Failed because the packet is invalid.
Definition: dn_device.h:107
int32_t id
Definition: bcap_common.h:231
static HRESULT bcap_vnt2bytary(const VARIANT *src, uint32_t argc, char *dst, uint32_t len_dst, uint32_t *offset)
Definition: bcap_common.c:219
#define _SEC_ONEDAY
A definition for the second of one day.
Definition: bcap_common.c:48
#define E_OUTOFMEMORY
Failed because there is no enough memory space.
Definition: dn_common.h:125
_DN_EXP_COMMON uint16_t SysStringLen(BSTR bstr)
Gets and returns the number of characters of BSTR.
Definition: dn_common.c:118
#define BCAP_SIZE_BSTR_LEN
A definition for the size of BSTR string length.
Definition: bcap_common.h:184
uint16_t reserv
Definition: bcap_common.h:230
HRESULT bcap_bytary2packet(const char *src, uint32_t len_src, struct BCAP_PACKET *dst)
Converts the byte array to a b-CAP packet.
Definition: bcap_common.c:776
SAFEARRAY * parray
Definition: dn_common.h:325
uint16_t bcap_calc_crc(uint8_t *buf, uint32_t len_buf)
Calculates CRC of the b-CAP packet.
Definition: bcap_common.c:870
uint16_t uiVal
Definition: dn_common.h:322
#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.
uint16_t vt
Definition: dn_common.h:308
Common API file.
_DN_EXP_COMMON void VariantInit(VARIANT *pvarg)
Initializes the VARIANT.
Definition: dn_common.c:368
A type definition for common communication parameters.
Definition: dn_device.h:170
#define BCAP_SIZE_DATA_LEN
A definition for the size of b-CAP argument data length.
Definition: bcap_common.h:123
User own API file.
#define _TIME_DIFFERENCE
A definition for the time difference between time_t(0) and DATE(0).
Definition: bcap_common.c:42
_DN_EXP_DEVICE void memcpy_le(void *dst, const void *src, uint32_t len)
Orders to little endian.
Definition: dn_device.c:469
A type definition for the multi type variable.
Definition: dn_common.h:306
static void bcap_vntdate2bytary(const DATE *src, char *dst)
Converts the DATE value to a byte array.
Definition: bcap_common.c:176
static uint32_t bcap_calc_size_variant(const VARIANT *vnt)
Calculates the buffer length of the VARIANT.
Definition: bcap_common.c:70
#define BCAP_TERMINATOR
A definition for the b-CAP terminator.
Definition: bcap_common.h:75
int int32_t
Definition: stdint.h:42
#define BCAP_SIZE_LEN
A definition for the size of b-CAP message length.
Definition: bcap_common.h:93
A type definition for the b-CAP packet.
Definition: bcap_common.h:227
uint32_t ulVal
Definition: dn_common.h:323
#define BCAP_POS_LEN
A definition for the buffer position of b-CAP message length.
Definition: bcap_common.h:135
int32_t scode
Definition: dn_common.h:319
HRESULT bcap_packet2bytary(const struct BCAP_PACKET *src, char *dst, uint32_t len_dst)
Converts the b-CAP packet to a byte array.
Definition: bcap_common.c:476
#define BCAP_SIZE_CRC
A definition for the size of b-CAP CRC.
Definition: bcap_common.h:208
float fltVal
Definition: dn_common.h:314
int16_t iVal
Definition: dn_common.h:311
DATE date
Definition: dn_common.h:317
#define BCAP_SIZE_CALC_CRC(total_size)
A macro for calculating a b-CAP CRC.
Definition: bcap_common.h:220
#define BCAP_POS_CRC(total_size)
A macro for calculating the buffer position of b-CAP CRC.
Definition: bcap_common.h:214
_DN_EXP_DEVICE HRESULT check_conn_param(const struct CONN_PARAM_COMMON *device, int flag)
Checks the communication parameters.
Definition: dn_device.c:419
#define BCAP_CHECK_SEND
A definition for the check_conn_param function.
Definition: bcap_common.h:51
b-CAP Common API file.
#define BCAP_SIZE_SERIAL
A definition for the size of b-CAP serial number.
Definition: bcap_common.h:99
HRESULT(* dn_send)(int sock, const char *buf, uint32_t len_buf, void *arg)
Definition: dn_device.h:178
#define BCAP_CHECK_RECV
A definition for the check_conn_param function.
Definition: bcap_common.h:57
double dblVal
Definition: dn_common.h:315
uint16_t serial
Definition: bcap_common.h:229
_DN_EXP_COMMON SAFEARRAY * SafeArrayCreateVector(uint16_t vt, int32_t lLbound, uint32_t cElements)
Allocates and returns SAFEARRAY.
Definition: dn_common.c:138
_DN_EXP_COMMON HRESULT SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Accesses the SAFEARRAY and gets the pointer of array data.
Definition: dn_common.c:336


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