bcap_common.c
Go to the documentation of this file.
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 }


bcap_core
Author(s): DENSO WAVE INCORPORATED
autogenerated on Thu Jun 6 2019 21:00:02