00001 00025 #include "stdint.h" 00026 #include <stdlib.h> 00027 #include <string.h> 00028 00029 #if defined(_USE_WIN_API) 00030 #include <winsock2.h> 00031 #else 00032 #if defined(_USE_LINUX_API) 00033 #include <arpa/inet.h> 00034 #else 00035 #include "dn_additional.h" 00036 #endif 00037 00042 #define _TIME_DIFFERENCE (25569.0) 00043 00048 #define _SEC_ONEDAY (24 * 60 * 60) 00049 00050 #endif 00051 00052 #include "dn_common.h" 00053 #include "dn_device.h" 00054 #include "dn_udp.h" 00055 #include "bcap_common.h" 00056 00057 static HRESULT 00058 bcap_vntary2bytary(const VARIANT *src, uint32_t argc, char *dst, 00059 uint32_t len_dst, uint32_t *offset, int flag); 00060 static HRESULT 00061 bcap_bytary2vntary(const char *src, uint32_t len_src, VARIANT *dst, 00062 uint32_t argc, uint32_t *offset, int flag); 00063 00069 static uint32_t 00070 bcap_calc_size_variant(const VARIANT *vnt) 00071 { 00072 int32_t i, lbnd, ubnd, cnt; 00073 uint16_t vt; 00074 void *pdata; 00075 uint32_t ret = 0; 00076 00077 if (vnt != NULL) { 00078 vt = vnt->vt; 00079 if ((vt & VT_ARRAY) != 0) { 00080 if (vnt->parray != NULL) { 00081 SafeArrayGetLBound(vnt->parray, 1, &lbnd); 00082 SafeArrayGetUBound(vnt->parray, 1, &ubnd); 00083 cnt = ubnd - lbnd + 1; 00084 00085 switch (vt ^ VT_ARRAY) { 00086 case VT_UI1: 00087 ret = cnt; 00088 break; 00089 case VT_I2: 00090 case VT_UI2: 00091 case VT_BOOL: 00092 ret = cnt * 2; 00093 break; 00094 case VT_I4: 00095 case VT_UI4: 00096 case VT_R4: 00097 ret = cnt * 4; 00098 break; 00099 case VT_I8: 00100 case VT_UI8: 00101 case VT_R8: 00102 case VT_CY: 00103 case VT_DATE: 00104 ret = cnt * 8; 00105 break; 00106 case VT_BSTR: 00107 SafeArrayAccessData(vnt->parray, &pdata); 00108 for (i = 0; i < cnt; i++) { 00109 ret += BCAP_SIZE_BSTR_LEN; 00110 if (((BSTR*) pdata + i) != NULL) { 00111 ret += BCAP_SIZE_BSTR_BUFFER 00112 * SysStringLen(*((BSTR*) pdata + i)); 00113 } 00114 } 00115 SafeArrayUnaccessData(vnt->parray); 00116 break; 00117 case VT_VARIANT: 00118 SafeArrayAccessData(vnt->parray, &pdata); 00119 for (i = 0; i < cnt; i++) { 00120 ret += BCAP_SIZE_VARIANT_TYPE + BCAP_SIZE_VARIANT_NUM; 00121 if (((VARIANT*) pdata + i) != NULL) { 00122 ret += bcap_calc_size_variant(((VARIANT*) pdata + i)); 00123 } 00124 } 00125 SafeArrayUnaccessData(vnt->parray); 00126 break; 00127 default: 00128 break; 00129 } 00130 } 00131 } else { 00132 switch (vt) { 00133 case VT_UI1: 00134 ret = 1; 00135 break; 00136 case VT_I2: 00137 case VT_UI2: 00138 case VT_BOOL: 00139 ret = 2; 00140 break; 00141 case VT_I4: 00142 case VT_UI4: 00143 case VT_R4: 00144 case VT_ERROR: 00145 ret = 4; 00146 break; 00147 case VT_I8: 00148 case VT_UI8: 00149 case VT_R8: 00150 case VT_CY: 00151 case VT_DATE: 00152 ret = 8; 00153 break; 00154 case VT_BSTR: 00155 ret = BCAP_SIZE_BSTR_LEN; 00156 if (vnt->bstrVal != NULL) { 00157 ret += BCAP_SIZE_BSTR_BUFFER * SysStringLen(vnt->bstrVal); 00158 } 00159 break; 00160 default: 00161 break; 00162 } 00163 } 00164 } 00165 00166 return ret; 00167 } 00168 00175 static void 00176 bcap_vntdate2bytary(const DATE *src, char *dst) 00177 { 00178 #if defined(_USE_WIN_API) 00179 memcpy_le(dst, src, 8); 00180 #else 00181 double dbl = 0; 00182 if (*src > 0) { 00183 dbl = (double) (*src) / _SEC_ONEDAY + _TIME_DIFFERENCE; 00184 } 00185 memcpy_le(dst, &dbl, 8); 00186 #endif 00187 } 00188 00195 static void 00196 bcap_bytary2vntdate(const char *src, DATE *dst) 00197 { 00198 #if defined(_USE_WIN_API) 00199 memcpy_le(dst, src, 8); 00200 #else 00201 double dbl = 0; 00202 memcpy_le(&dbl, src, 8); 00203 if (dbl > 0) { 00204 *dst = (DATE) ((dbl - _TIME_DIFFERENCE) * _SEC_ONEDAY); 00205 } 00206 #endif 00207 } 00208 00218 static HRESULT 00219 bcap_vnt2bytary(const VARIANT *src, uint32_t argc, char *dst, uint32_t len_dst, 00220 uint32_t *offset) 00221 { 00222 uint16_t vt; 00223 uint32_t i, j, len_bstr, size = 0; 00224 void const *pdata; 00225 void *parray; 00226 HRESULT hr; 00227 00228 vt = src->vt; 00229 if ((vt & VT_ARRAY) != 0) { 00230 if (src->parray != NULL) { 00231 SafeArrayAccessData(src->parray, &parray); 00232 switch (vt ^ VT_ARRAY) { 00233 case VT_UI1: 00234 if (*offset + argc > len_dst) 00235 return E_INVALIDARG; 00236 memcpy(&dst[*offset], parray, argc); 00237 *offset += argc; 00238 00239 size = 0; 00240 break; 00241 case VT_I2: 00242 case VT_UI2: 00243 case VT_BOOL: 00244 size = 2; 00245 break; 00246 case VT_I4: 00247 case VT_UI4: 00248 case VT_R4: 00249 size = 4; 00250 break; 00251 case VT_I8: 00252 case VT_UI8: 00253 case VT_R8: 00254 case VT_CY: 00255 size = 8; 00256 break; 00257 case VT_DATE: 00258 size = 8; 00259 for (i = 0; i < argc; i++) { 00260 if (*offset + size > len_dst) 00261 return E_INVALIDARG; 00262 bcap_vntdate2bytary((DATE *) parray + i, &dst[*offset]); 00263 *offset += size; 00264 } 00265 00266 size = 0; 00267 break; 00268 case VT_BSTR: 00269 for (i = 0; i < argc; i++) { 00270 size = BCAP_SIZE_BSTR_LEN; 00271 if (*offset + size > len_dst) 00272 return E_INVALIDARG; 00273 len_bstr = BCAP_SIZE_BSTR_BUFFER 00274 * SysStringLen(*((BSTR *) parray + i)); 00275 memcpy_le(&dst[*offset], &len_bstr, size); 00276 *offset += size; 00277 00278 size = BCAP_SIZE_BSTR_BUFFER; 00279 for (j = 0; j < len_bstr / size; j++) { 00280 if (*offset + size > len_dst) 00281 return E_INVALIDARG; 00282 memcpy_le(&dst[*offset], *((BSTR *) parray + i) + j, size); 00283 *offset += size; 00284 } 00285 } 00286 00287 size = 0; 00288 break; 00289 case VT_VARIANT: 00290 hr = bcap_vntary2bytary((VARIANT *) parray, argc, dst, len_dst, 00291 offset, 0); 00292 if (FAILED(hr)) 00293 return hr; 00294 00295 size = 0; 00296 break; 00297 default: 00298 break; 00299 } 00300 00301 if (size > 0) { 00302 for (i = 0; i < argc; i++) { 00303 if (*offset + size > len_dst) 00304 return E_INVALIDARG; 00305 memcpy_le(&dst[*offset], (char *) parray + i * size, size); 00306 *offset += size; 00307 } 00308 } 00309 00310 SafeArrayUnaccessData(src->parray); 00311 } 00312 } else { 00313 switch (vt) { 00314 case VT_UI1: 00315 size = 1; 00316 pdata = &src->bVal; 00317 break; 00318 case VT_I2: 00319 size = 2; 00320 pdata = &src->iVal; 00321 break; 00322 case VT_UI2: 00323 size = 2; 00324 pdata = &src->uiVal; 00325 break; 00326 case VT_BOOL: 00327 size = 2; 00328 pdata = &src->boolVal; 00329 break; 00330 case VT_I4: 00331 size = 4; 00332 pdata = &src->lVal; 00333 break; 00334 case VT_UI4: 00335 size = 4; 00336 pdata = &src->ulVal; 00337 break; 00338 case VT_R4: 00339 size = 4; 00340 pdata = &src->fltVal; 00341 break; 00342 case VT_ERROR: 00343 size = 4; 00344 pdata = &src->scode; 00345 break; 00346 case VT_I8: 00347 size = 8; 00348 pdata = &src->llVal; 00349 break; 00350 case VT_UI8: 00351 size = 8; 00352 pdata = &src->ullVal; 00353 break; 00354 case VT_R8: 00355 size = 8; 00356 pdata = &src->dblVal; 00357 break; 00358 case VT_CY: 00359 size = 8; 00360 pdata = &src->cyVal; 00361 break; 00362 case VT_DATE: 00363 size = 8; 00364 if (*offset + size > len_dst) 00365 return E_INVALIDARG; 00366 bcap_vntdate2bytary(&src->date, &dst[*offset]); 00367 *offset += size; 00368 00369 size = 0; 00370 break; 00371 case VT_BSTR: 00372 size = BCAP_SIZE_BSTR_LEN; 00373 if (*offset + size > len_dst) 00374 return E_INVALIDARG; 00375 len_bstr = BCAP_SIZE_BSTR_BUFFER * SysStringLen(src->bstrVal); 00376 memcpy_le(&dst[*offset], &len_bstr, size); 00377 *offset += size; 00378 00379 size = BCAP_SIZE_BSTR_BUFFER; 00380 for (i = 0; i < len_bstr / size; i++) { 00381 if (*offset + size > len_dst) 00382 return E_INVALIDARG; 00383 memcpy_le(&dst[*offset], src->bstrVal + i, size); 00384 *offset += size; 00385 } 00386 00387 size = 0; 00388 break; 00389 default: 00390 break; 00391 } 00392 00393 if (size > 0) { 00394 if (*offset + size > len_dst) 00395 return E_INVALIDARG; 00396 memcpy_le(&dst[*offset], pdata, size); 00397 *offset += size; 00398 } 00399 } 00400 00401 return S_OK; 00402 } 00403 00414 static HRESULT 00415 bcap_vntary2bytary(const VARIANT *src, uint32_t argc, char *dst, 00416 uint32_t len_dst, uint32_t *offset, int flag) 00417 { 00418 int32_t lbnd, ubnd; 00419 uint32_t i, cnt, size, len_vnt, offset_tmp; 00420 const VARIANT *vnt; 00421 HRESULT hr = S_OK; 00422 00423 for (i = 0; i < argc; i++) { 00424 vnt = &src[i]; 00425 offset_tmp = *offset; 00426 00427 if (flag != 0) { 00428 *offset += BCAP_SIZE_DATA_LEN; 00429 } 00430 00431 size = BCAP_SIZE_VARIANT_TYPE; 00432 if (*offset + size > len_dst) 00433 return E_INVALIDARG; 00434 memcpy_le(&dst[*offset], &vnt->vt, size); 00435 *offset += size; 00436 00437 if ((vnt->vt & VT_ARRAY) != 0) { 00438 if (vnt->parray != NULL) { 00439 SafeArrayGetLBound(vnt->parray, 1, &lbnd); 00440 SafeArrayGetUBound(vnt->parray, 1, &ubnd); 00441 cnt = ubnd - lbnd + 1; 00442 } else { 00443 return E_INVALIDARG; 00444 } 00445 } else { 00446 cnt = 1; 00447 } 00448 00449 size = BCAP_SIZE_VARIANT_NUM; 00450 if (*offset + size > len_dst) 00451 return E_INVALIDARG; 00452 memcpy_le(&dst[*offset], &cnt, size); 00453 *offset += size; 00454 00455 hr = bcap_vnt2bytary(vnt, cnt, dst, len_dst, offset); 00456 if (FAILED(hr)) 00457 return hr; 00458 00459 if (flag != 0) { 00460 len_vnt = *offset - offset_tmp - BCAP_SIZE_DATA_LEN; 00461 memcpy_le(&dst[offset_tmp], &len_vnt, BCAP_SIZE_DATA_LEN); 00462 } 00463 } 00464 00465 return hr; 00466 } 00467 00475 HRESULT 00476 bcap_packet2bytary(const struct BCAP_PACKET *src, char *dst, uint32_t len_dst) 00477 { 00478 uint32_t size, offset = 1; 00479 HRESULT hr; 00480 00481 if (src == NULL || dst == NULL) 00482 return E_INVALIDARG; 00483 00484 if (len_dst < BCAP_SIZE_MIN) 00485 return E_INVALIDARG; 00486 00487 memset(dst, 0, len_dst); 00488 00489 dst[BCAP_POS_HEADER] = BCAP_HEADER; 00490 00491 size = BCAP_SIZE_LEN; 00492 memcpy_le(&dst[offset], &len_dst, size); 00493 offset += size; 00494 00495 size = BCAP_SIZE_SERIAL; 00496 memcpy_le(&dst[offset], &src->serial, size); 00497 offset += size; 00498 00499 size = BCAP_SIZE_RESERVE; 00500 memcpy_le(&dst[offset], &src->reserv, size); 00501 offset += size; 00502 00503 size = BCAP_SIZE_ID; 00504 memcpy_le(&dst[offset], &src->id, size); 00505 offset += size; 00506 00507 size = BCAP_SIZE_ARGC; 00508 memcpy_le(&dst[offset], &src->argc, size); 00509 offset += size; 00510 00511 hr = bcap_vntary2bytary(src->args, src->argc, dst, len_dst - 1, &offset, 1); 00512 00513 dst[len_dst - 1] = BCAP_TERMINATOR; 00514 00515 return hr; 00516 } 00517 00527 static HRESULT 00528 bcap_bytary2vnt(const char *src, uint32_t len_src, VARIANT *dst, uint32_t argc, 00529 uint32_t *offset) 00530 { 00531 uint16_t vt; 00532 uint32_t i, j, len_bstr, size = 0; 00533 void *pdata, *parray; 00534 HRESULT hr; 00535 00536 vt = dst->vt; 00537 if ((vt & VT_ARRAY) != 0) { 00538 dst->parray = SafeArrayCreateVector(vt ^ VT_ARRAY, 1, argc); 00539 if (dst->parray == NULL) 00540 return E_OUTOFMEMORY; 00541 00542 SafeArrayAccessData(dst->parray, &parray); 00543 switch (vt ^ VT_ARRAY) { 00544 case VT_UI1: 00545 if (*offset + argc > len_src) 00546 return E_INVALIDARG; 00547 memcpy(parray, &src[*offset], argc); 00548 *offset += argc; 00549 00550 size = 0; 00551 break; 00552 case VT_I2: 00553 case VT_UI2: 00554 case VT_BOOL: 00555 size = 2; 00556 break; 00557 case VT_I4: 00558 case VT_UI4: 00559 case VT_R4: 00560 size = 4; 00561 break; 00562 case VT_I8: 00563 case VT_UI8: 00564 case VT_R8: 00565 case VT_CY: 00566 size = 8; 00567 break; 00568 case VT_DATE: 00569 size = 8; 00570 for (i = 0; i < argc; i++) { 00571 if (*offset + size > len_src) 00572 return E_INVALIDPACKET; 00573 bcap_bytary2vntdate(&src[*offset], (DATE *) parray + i); 00574 *offset += size; 00575 } 00576 00577 size = 0; 00578 break; 00579 case VT_BSTR: 00580 for (i = 0; i < argc; i++) { 00581 size = BCAP_SIZE_BSTR_LEN; 00582 if (*offset + size > len_src) 00583 return E_INVALIDPACKET; 00584 memcpy_le(&len_bstr, &src[*offset], size); 00585 len_bstr /= BCAP_SIZE_BSTR_BUFFER; 00586 *offset += size; 00587 00588 *((BSTR*) parray + i) = SysAllocStringLen(L"", len_bstr); 00589 if (*((BSTR*) parray + i) == NULL) 00590 return E_OUTOFMEMORY; 00591 00592 size = BCAP_SIZE_BSTR_BUFFER; 00593 for (j = 0; j < len_bstr; j++) { 00594 if (*offset + size > len_src) 00595 return E_INVALIDPACKET; 00596 memcpy_le(*((BSTR*) parray + i) + j, &src[*offset], size); 00597 *offset += size; 00598 } 00599 } 00600 00601 size = 0; 00602 break; 00603 case VT_VARIANT: 00604 hr = bcap_bytary2vntary(src, len_src, (VARIANT *) parray, argc, offset, 00605 0); 00606 if (FAILED(hr)) 00607 return hr; 00608 00609 size = 0; 00610 break; 00611 default: 00612 break; 00613 } 00614 00615 if (size > 0) { 00616 for (i = 0; i < argc; i++) { 00617 if (*offset + size > len_src) 00618 return E_INVALIDPACKET; 00619 memcpy_le((char *) parray + i * size, &src[*offset], size); 00620 *offset += size; 00621 } 00622 } 00623 00624 SafeArrayUnaccessData(dst->parray); 00625 } else { 00626 switch (vt) { 00627 case VT_UI1: 00628 size = 1; 00629 pdata = &dst->bVal; 00630 break; 00631 case VT_I2: 00632 size = 2; 00633 pdata = &dst->iVal; 00634 break; 00635 case VT_UI2: 00636 size = 2; 00637 pdata = &dst->uiVal; 00638 break; 00639 case VT_BOOL: 00640 size = 2; 00641 pdata = &dst->boolVal; 00642 break; 00643 case VT_I4: 00644 size = 4; 00645 pdata = &dst->lVal; 00646 break; 00647 case VT_UI4: 00648 size = 4; 00649 pdata = &dst->ulVal; 00650 break; 00651 case VT_R4: 00652 size = 4; 00653 pdata = &dst->fltVal; 00654 break; 00655 case VT_ERROR: 00656 size = 4; 00657 pdata = &dst->scode; 00658 break; 00659 case VT_I8: 00660 size = 8; 00661 pdata = &dst->llVal; 00662 break; 00663 case VT_UI8: 00664 size = 8; 00665 pdata = &dst->ullVal; 00666 break; 00667 case VT_R8: 00668 size = 8; 00669 pdata = &dst->dblVal; 00670 break; 00671 case VT_CY: 00672 size = 8; 00673 pdata = &dst->cyVal; 00674 break; 00675 case VT_DATE: 00676 size = 8; 00677 if (*offset + size > len_src) 00678 return E_INVALIDPACKET; 00679 bcap_bytary2vntdate(&src[*offset], &dst->date); 00680 *offset += size; 00681 00682 size = 0; 00683 break; 00684 case VT_BSTR: 00685 size = BCAP_SIZE_BSTR_LEN; 00686 if (*offset + size > len_src) 00687 return E_INVALIDPACKET; 00688 memcpy_le(&len_bstr, &src[*offset], size); 00689 len_bstr /= BCAP_SIZE_BSTR_BUFFER; 00690 *offset += size; 00691 00692 dst->bstrVal = SysAllocStringLen(L"", len_bstr); 00693 if (dst->bstrVal == NULL) 00694 return E_OUTOFMEMORY; 00695 00696 size = BCAP_SIZE_BSTR_BUFFER; 00697 for (i = 0; i < len_bstr; i++) { 00698 if (*offset + size > len_src) 00699 return E_INVALIDPACKET; 00700 memcpy_le(dst->bstrVal + i, &src[*offset], size); 00701 *offset += size; 00702 } 00703 00704 size = 0; 00705 break; 00706 default: 00707 break; 00708 } 00709 00710 if (size > 0) { 00711 if (*offset + size > len_src) 00712 return E_INVALIDPACKET; 00713 memcpy_le(pdata, &src[*offset], size); 00714 *offset += size; 00715 } 00716 } 00717 00718 return S_OK; 00719 } 00720 00731 static HRESULT 00732 bcap_bytary2vntary(const char *src, uint32_t len_src, VARIANT *dst, 00733 uint32_t argc, uint32_t *offset, int flag) 00734 { 00735 uint32_t i, cnt, size; 00736 VARIANT *vnt; 00737 HRESULT hr = S_OK; 00738 00739 for (i = 0; i < argc; i++) { 00740 vnt = &dst[i]; 00741 VariantInit(vnt); 00742 00743 if (flag != 0) { 00744 *offset += BCAP_SIZE_DATA_LEN; 00745 } 00746 00747 size = BCAP_SIZE_VARIANT_TYPE; 00748 if (*offset + size > len_src) 00749 return E_INVALIDPACKET; 00750 memcpy_le(&vnt->vt, &src[*offset], size); 00751 *offset += size; 00752 00753 size = BCAP_SIZE_VARIANT_NUM; 00754 if (*offset + size > len_src) 00755 return E_INVALIDPACKET; 00756 memcpy_le(&cnt, &src[*offset], size); 00757 *offset += size; 00758 00759 hr = bcap_bytary2vnt(src, len_src, vnt, cnt, offset); 00760 if (FAILED(hr)) 00761 return hr; 00762 } 00763 00764 return hr; 00765 } 00766 00775 HRESULT 00776 bcap_bytary2packet(const char *src, uint32_t len_src, struct BCAP_PACKET *dst) 00777 { 00778 uint16_t tmp_argc; 00779 uint32_t len_tmp, size, offset = 1; 00780 HRESULT hr = S_OK; 00781 00782 if (src == NULL || dst == NULL) 00783 return E_INVALIDARG; 00784 00785 if (len_src < BCAP_SIZE_MIN) 00786 return E_INVALIDPACKET; 00787 00788 size = BCAP_SIZE_LEN; 00789 memcpy_le(&len_tmp, &src[offset], size); 00790 offset += size; 00791 00792 if (len_tmp != len_src) 00793 return E_INVALIDPACKET; 00794 00795 if ((src[BCAP_POS_HEADER] != BCAP_HEADER) 00796 || (src[len_src - 1] != BCAP_TERMINATOR)) 00797 return E_INVALIDPACKET; 00798 00799 size = BCAP_SIZE_SERIAL; 00800 memcpy_le(&dst->serial, &src[offset], size); 00801 offset += size; 00802 00803 size = BCAP_SIZE_RESERVE; 00804 memcpy_le(&dst->reserv, &src[offset], size); 00805 offset += size; 00806 00807 size = BCAP_SIZE_ID; 00808 memcpy_le(&dst->id, &src[offset], size); 00809 offset += size; 00810 00811 size = BCAP_SIZE_ARGC; 00812 memcpy_le(&tmp_argc, &src[offset], size); 00813 offset += size; 00814 00815 if (dst->argc == (uint16_t) -1) { 00816 if (dst->args != NULL) 00817 return E_INVALIDARG; 00818 dst->argc = tmp_argc; 00819 } else { 00820 if ((dst->argc > 0) && (dst->args == NULL)) 00821 return E_INVALIDARG; 00822 if (tmp_argc > dst->argc) 00823 return E_INVALIDPACKET; 00824 dst->argc = tmp_argc; 00825 } 00826 00827 if (dst->argc > 0) { 00828 if (dst->args == NULL) { 00829 dst->args = (VARIANT *) malloc(sizeof(VARIANT) * dst->argc); 00830 if (dst->args == NULL) 00831 return E_OUTOFMEMORY; 00832 } 00833 00834 hr = bcap_bytary2vntary(src, len_src - 1, dst->args, dst->argc, &offset, 00835 1); 00836 } 00837 00838 return hr; 00839 } 00840 00846 uint32_t 00847 bcap_calc_size_packet(const struct BCAP_PACKET *packet) 00848 { 00849 int i; 00850 uint32_t ret = 0; 00851 00852 if (packet != NULL) { 00853 ret = BCAP_SIZE_MIN; 00854 for (i = 0; i < packet->argc; i++) { 00855 ret += BCAP_SIZE_DATA_LEN + BCAP_SIZE_VARIANT_TYPE 00856 + BCAP_SIZE_VARIANT_NUM 00857 + bcap_calc_size_variant(&packet->args[i]); 00858 } 00859 } 00860 00861 return ret; 00862 } 00863 00869 uint16_t 00870 bcap_calc_crc(uint8_t *buf, uint32_t len_buf) 00871 { 00872 int cnt; 00873 uint32_t pos; 00874 uint16_t crc = 0xFFFF; 00875 00876 if (buf != NULL) { 00877 for (pos = 0; pos < len_buf; pos++) { 00878 crc ^= (buf[pos] << 8); 00879 for (cnt = 0; cnt < 8; cnt++) { 00880 if (crc & 0x8000) { 00881 crc = (crc << 1) ^ 0x1021; 00882 } else { 00883 crc <<= 1; 00884 } 00885 } 00886 } 00887 } 00888 00889 return crc; 00890 } 00891 00898 HRESULT 00899 bcap_send(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_send) 00900 { 00901 int opt_tcp; 00902 uint16_t crc; 00903 uint32_t len_send, len_max; 00904 char *buf_send = NULL; 00905 void *parg = NULL; 00906 struct udpaddr opt_udp; 00907 HRESULT hr; 00908 00909 hr = check_conn_param(device, BCAP_CHECK_SEND); 00910 if (FAILED(hr)) 00911 return hr; 00912 00913 if (packet_send == NULL) 00914 return E_INVALIDARG; 00915 00916 switch (device->type) { 00917 case CONN_TCP: 00918 len_max = (uint32_t) -1; 00919 opt_tcp = 0; 00920 parg = &opt_tcp; 00921 break; 00922 case CONN_UDP: 00923 if (device->arg == NULL) 00924 return E_INVALIDARG; 00925 len_max = UDP_MAX_PACKET; 00926 opt_udp.flag = 0; 00927 opt_udp.addr = *(struct sockaddr_in *) device->arg; 00928 parg = &opt_udp; 00929 break; 00930 case CONN_COM: 00931 len_max = UDP_MAX_PACKET; 00932 break; 00933 default: 00934 return E_INVALIDARG; 00935 } 00936 00937 len_send = bcap_calc_size_packet(packet_send); 00938 if (device->type == CONN_COM) { 00939 len_send += BCAP_SIZE_CRC; 00940 } 00941 00942 if (len_send > len_max) { 00943 hr = E_TOO_MUCH_DATA; 00944 goto send_end; 00945 } 00946 00947 buf_send = (char *) malloc(len_send); 00948 if (buf_send == NULL) { 00949 hr = E_OUTOFMEMORY; 00950 goto send_end; 00951 } 00952 00953 hr = bcap_packet2bytary(packet_send, buf_send, len_send); 00954 if (FAILED(hr)) 00955 goto send_end; 00956 00957 if (device->type == CONN_COM) { 00958 crc = bcap_calc_crc((uint8_t *) &buf_send[BCAP_POS_LEN], 00959 BCAP_SIZE_CALC_CRC(len_send)); 00960 memcpy_le(&buf_send[BCAP_POS_CRC(len_send)], &crc, BCAP_SIZE_CRC); 00961 } 00962 00963 hr = device->dn_send(device->sock, buf_send, len_send, parg); 00964 if (FAILED(hr)) 00965 goto send_end; 00966 00967 send_end: 00968 if (buf_send != NULL) { 00969 free(buf_send); 00970 buf_send = NULL; 00971 } 00972 00973 return hr; 00974 } 00975 00983 HRESULT 00984 bcap_recv(struct CONN_PARAM_COMMON *device, struct BCAP_PACKET *packet_recv, 00985 int client) 00986 { 00987 int opt_tcp, flag_init = 0, flag_crc = 1; 00988 uint16_t crc, crc_recv; 00989 uint32_t len_recv, len_recved, len_tmp, len_min, len_max; 00990 char *buf_recv = NULL, *pos, buf_tmp[UDP_MAX_PACKET + 1] = 00991 { 0, }; 00992 void *parg = NULL; 00993 struct udpaddr opt_udp; 00994 HRESULT hr; 00995 00996 hr = check_conn_param(device, BCAP_CHECK_RECV); 00997 if (FAILED(hr)) 00998 return hr; 00999 01000 if (packet_recv == NULL) 01001 return E_INVALIDARG; 01002 01003 switch (device->type) { 01004 case CONN_TCP: 01005 len_min = BCAP_SIZE_MIN; 01006 len_max = (uint32_t) -1; 01007 opt_tcp = MSG_PEEK; 01008 parg = &opt_tcp; 01009 break; 01010 case CONN_UDP: 01011 if (device->arg == NULL) 01012 return E_INVALIDARG; 01013 len_min = BCAP_SIZE_MIN; 01014 len_max = UDP_MAX_PACKET; 01015 opt_udp.flag = 0; 01016 parg = &opt_udp; 01017 break; 01018 case CONN_COM: 01019 len_min = BCAP_SIZE_MIN + BCAP_SIZE_CRC; 01020 len_max = UDP_MAX_PACKET; 01021 break; 01022 default: 01023 return E_INVALIDARG; 01024 } 01025 01026 while (1) { 01027 len_recved = 0; 01028 while (1) { 01029 pos = (char *) memchr(buf_tmp, BCAP_HEADER, len_recved); 01030 if (pos != NULL) { 01031 if (pos != buf_tmp) { 01032 if (device->type == CONN_TCP) { 01033 len_tmp = ((long) pos - (long) buf_tmp); 01034 device->dn_recv(device->sock, buf_tmp, len_tmp, &len_recv, 01035 device->timeout, NULL); 01036 } 01037 len_recved -= ((long) pos - (long) buf_tmp); 01038 memcpy(buf_tmp, pos, len_recved); 01039 } 01040 } else { 01041 if (device->type == CONN_TCP) { 01042 device->dn_recv(device->sock, buf_tmp, len_recved, &len_recv, 01043 device->timeout, NULL); 01044 } 01045 len_recved = 0; 01046 } 01047 01048 if (len_recved >= BCAP_SIZE_HEADER + BCAP_SIZE_LEN) { 01049 break; 01050 } 01051 01052 if (device->type == CONN_TCP) { 01053 len_recved = 0; 01054 } 01055 01056 hr = device->dn_recv(device->sock, &buf_tmp[len_recved], 01057 UDP_MAX_PACKET - len_recved, &len_tmp, device->timeout, parg); 01058 01059 if (device->type == CONN_UDP) { 01060 if (client || flag_init) { 01061 hr = SUCCEEDED(hr) ? 01062 udp_check_sockaddr((struct sockaddr_in *) device->arg, 01063 &opt_udp.addr) : hr; 01064 } else { 01065 flag_init = 1; 01066 *(struct sockaddr_in *) device->arg = opt_udp.addr; 01067 } 01068 } 01069 01070 if (FAILED(hr)) 01071 goto recv_end; 01072 01073 len_recved += len_tmp; 01074 } 01075 01076 memcpy_le(&len_recv, &buf_tmp[BCAP_POS_LEN], BCAP_SIZE_LEN); 01077 if ((len_recv < len_min) || (len_max < len_recv)) { 01078 if (device->type == CONN_TCP) { 01079 device->dn_recv(device->sock, buf_tmp, BCAP_SIZE_HEADER, &len_tmp, 01080 device->timeout, NULL); 01081 } 01082 len_recved -= BCAP_SIZE_HEADER; 01083 memcpy(buf_tmp, &buf_tmp[BCAP_POS_LEN], len_recved); 01084 continue; 01085 } 01086 01087 buf_recv = (char *) malloc(len_recv); 01088 if (buf_recv == NULL) { 01089 hr = E_OUTOFMEMORY; 01090 goto recv_end; 01091 } 01092 01093 if (device->type == CONN_TCP) { 01094 opt_tcp = 0; 01095 device->dn_recv(device->sock, buf_recv, len_recv, &len_recved, 01096 device->timeout, parg); 01097 } else { 01098 memcpy(buf_recv, buf_tmp, 01099 (len_recv < len_recved) ? len_recv : len_recved); 01100 } 01101 01102 while (len_recv > len_recved) { 01103 hr = device->dn_recv(device->sock, &buf_recv[len_recved], 01104 len_recv - len_recved, &len_tmp, device->timeout, parg); 01105 01106 if (device->type == CONN_UDP) { 01107 hr = SUCCEEDED(hr) ? 01108 udp_check_sockaddr((struct sockaddr_in *) device->arg, 01109 &opt_udp.addr) : hr; 01110 } 01111 01112 if (FAILED(hr)) 01113 goto recv_end; 01114 01115 len_recved += len_tmp; 01116 } 01117 01118 hr = bcap_bytary2packet(buf_recv, len_recv, packet_recv); 01119 if (FAILED(hr)) 01120 goto recv_end; 01121 01122 if (device->type == CONN_COM) { 01123 crc = bcap_calc_crc((uint8_t *) &buf_recv[BCAP_POS_LEN], 01124 BCAP_SIZE_CALC_CRC(len_recv)); 01125 memcpy_le(&crc_recv, &buf_recv[BCAP_POS_CRC(len_recv)], 01126 BCAP_SIZE_CRC); 01127 flag_crc = (crc == crc_recv); 01128 } 01129 01130 if (flag_crc) { 01131 break; 01132 } 01133 } 01134 01135 recv_end: 01136 if (buf_recv != NULL) { 01137 free(buf_recv); 01138 buf_recv = NULL; 01139 } 01140 01141 return hr; 01142 }