00001
00025 #include "stdint.h"
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #if defined(_USE_WIN_API)
00030 #include <process.h>
00031 #include <winsock2.h>
00032 #pragma comment(lib, "wsock32.lib")
00033 #elif defined(_USE_LINUX_API)
00034 #include <arpa/inet.h>
00035 #include <errno.h>
00036 #include <pthread.h>
00037 #include <termios.h>
00038 #else
00039 #include "dn_additional.h"
00040 #endif
00041
00042 #include "dn_common.h"
00043 #include "dn_device.h"
00044 #include "dn_tcp.h"
00045 #include "dn_udp.h"
00046 #include "dn_com.h"
00047 #include "dn_thread.h"
00048 #include "bcap_common.h"
00049 #include "bcap_mapid.h"
00050 #include "bcap_server.h"
00051
00056 #define _BCAP_SERVER_MAX (BCAP_TCP_MAX + BCAP_UDP_MAX + BCAP_COM_MAX)
00057
00062 #define _FUNCTION_ID_MAX (137 + 1)
00063
00068 enum CHANGE_RELATION
00069 {
00070 ADD_CHILD,
00071 DELETE_CHILD,
00072 DESTROY_SELF,
00073 };
00074
00079 struct VEC_OBJECT
00080 {
00081 int32_t id;
00082 uint32_t hObj;
00083 struct VEC_OBJECT *prev;
00084 struct VEC_OBJECT *next;
00085 };
00086
00091 struct CONN_BCAP_SERVER
00092 {
00093 struct CONN_PARAM_COMMON device;
00094 struct BCAP_PACKET last_send;
00095 struct BCAP_PACKET last_recv;
00096 uint32_t exec_timeout;
00097 uint32_t wdt_interval;
00098 uint32_t last_modified;
00099 THREAD main_thread;
00100 THREAD sub_thread;
00101 EVENT term_main_evt;
00102 EVENT term_sub_evt;
00103 EVENT exec_evt;
00104 EVENT comp_evt;
00105 int num_object;
00106 struct VEC_OBJECT *stack;
00107 int num_child;
00108 MUTEX *relation_mutex;
00109 struct CONN_BCAP_SERVER *parent;
00110 struct CONN_BCAP_SERVER *node1;
00111 struct CONN_BCAP_SERVER *node2;
00112 };
00113
00114 static CALL_FUNC_BCAP m_list_func[_FUNCTION_ID_MAX];
00115 static struct CONN_BCAP_SERVER m_conn_param[_BCAP_SERVER_MAX];
00116
00117 static THRET THTYPE
00118 recv_thread(void *arg);
00119
00126 static int
00127 find_open_address(int type)
00128 {
00129 int i, start, end, index = -1;
00130
00131 switch(type) {
00132 case CONN_TCP:
00133 start = 0;
00134 end = BCAP_TCP_MAX;
00135 break;
00136 case CONN_UDP:
00137 start = BCAP_TCP_MAX;
00138 end = start + BCAP_UDP_MAX;
00139 break;
00140 case CONN_COM:
00141 start = BCAP_TCP_MAX + BCAP_UDP_MAX;
00142 end = start + BCAP_COM_MAX;
00143 break;
00144 default:
00145 return 0;
00146 }
00147
00148 for(i = start; i < end; i++) {
00149 if(m_conn_param[i].device.sock == 0) {
00150 index = i;
00151 break;
00152 }
00153 }
00154
00155 return (index + 1);
00156 }
00157
00164 static struct CONN_BCAP_SERVER*
00165 check_address(int index)
00166 {
00167 index--;
00168
00169 if(index < 0 || _BCAP_SERVER_MAX <= index) {
00170 return NULL;
00171 }
00172 else if(m_conn_param[index].device.sock == 0) {
00173 return NULL;
00174 }
00175
00176 return &m_conn_param[index];
00177 }
00178
00185 static HRESULT
00186 push_vector(struct CONN_BCAP_SERVER *bcap_param, struct VEC_OBJECT *pObj)
00187 {
00188 struct VEC_OBJECT *pPrev;
00189
00190 if(bcap_param->num_object >= BCAP_OBJECT_MAX) {
00191 return E_MAX_OBJECT;
00192 }
00193
00194
00195 pPrev = bcap_param->stack;
00196 bcap_param->stack = pObj;
00197
00198
00199 pObj->prev = pPrev;
00200 if(pPrev != NULL) {
00201 pPrev->next = pObj;
00202 }
00203
00204 bcap_param->num_object++;
00205
00206 return S_OK;
00207 }
00208
00216 static HRESULT
00217 pop_vector(struct CONN_BCAP_SERVER *bcap_param, struct VEC_OBJECT **pObj,
00218 int index)
00219 {
00220 int i;
00221 struct VEC_OBJECT *pPrev, *pNext, *pCur = bcap_param->stack;
00222 HRESULT hr = E_HANDLE;
00223
00224 for(i = 0; (i < bcap_param->num_object) && (pCur); i++) {
00225 if(i == index) {
00226 *pObj = pCur;
00227
00228
00229 pNext = pCur->next;
00230 pCur->next = NULL;
00231
00232
00233 pPrev = pCur->prev;
00234 pCur->prev = NULL;
00235
00236 if(pNext == NULL) {
00237 bcap_param->stack = pPrev;
00238 } else {
00239 pNext->prev = pPrev;
00240 }
00241
00242 if(pPrev != NULL) {
00243 pPrev->next = pNext;
00244 }
00245
00246 bcap_param->num_object--;
00247 hr = S_OK;
00248 break;
00249 }
00250
00251 pCur = pCur->prev;
00252 }
00253
00254 return hr;
00255 }
00256
00265 static int
00266 search_vector(struct CONN_BCAP_SERVER *bcap_param, int32_t id, uint32_t hObj)
00267 {
00268 int i, index = -1;
00269 struct VEC_OBJECT *pCur = bcap_param->stack;
00270
00271 for(i = 0; (i < bcap_param->num_object) && (pCur); i++) {
00272 if((pCur->id == id) && (pCur->hObj == hObj)) {
00273 index = i;
00274 break;
00275 }
00276
00277 pCur = pCur->prev;
00278 }
00279
00280 return index;
00281 }
00282
00290 static struct CONN_BCAP_SERVER *
00291 search_node(struct CONN_BCAP_SERVER *parent, const void *arg, int size)
00292 {
00293 struct CONN_BCAP_SERVER *node = NULL, *tmp;
00294
00295 tmp = parent->node1;
00296 while(tmp != NULL) {
00297 if(memcmp(tmp->device.arg, arg, size) == 0) {
00298 node = tmp;
00299 break;
00300 }
00301 tmp = tmp->node2;
00302 }
00303
00304 return node;
00305 }
00306
00314 static HRESULT
00315 change_relation(struct CONN_BCAP_SERVER *own, int mode, int *sock)
00316 {
00317 HRESULT hr = S_OK;
00318 struct CONN_BCAP_SERVER *node, *tmp;
00319 int flag_mutex;
00320 MUTEX *mutex;
00321
00322
00323 mutex = own->relation_mutex;
00324 flag_mutex = ((mutex != NULL) ? 1 : 0);
00325
00326
00327 if(flag_mutex) {
00328 hr = lock_mutex(mutex, INFINITE);
00329 if(FAILED(hr)) return hr;
00330 }
00331
00332 switch(mode) {
00333 case ADD_CHILD:
00334
00335 if(own->parent == NULL) {
00336
00337 node = (struct CONN_BCAP_SERVER *) malloc(
00338 sizeof(struct CONN_BCAP_SERVER));
00339 if(node == NULL) {
00340 hr = E_OUTOFMEMORY;
00341 goto exit_proc;
00342 }
00343
00344
00345 memset(node, 0, sizeof(struct CONN_BCAP_SERVER));
00346
00347
00348 node->device = own->device;
00349
00350
00351 node->device.sock = *sock;
00352
00353
00354 node->exec_timeout = own->exec_timeout;
00355 node->wdt_interval = own->wdt_interval;
00356
00357
00358 node->last_modified = gettimeofday_msec();
00359
00360
00361 node->relation_mutex = own->relation_mutex;
00362
00363
00364 node->parent = own;
00365 own->num_child++;
00366
00367
00368 tmp = own->node1;
00369 own->node1 = node;
00370 node->node2 = tmp;
00371 if(tmp != NULL) tmp->node1 = node;
00372
00373 if(flag_mutex) {
00374 hr = node->device.dn_set_timeout(*sock, node->device.timeout);
00375 if(FAILED(hr)) {
00376 node->device.dn_close(sock);
00377 free(node);
00378 goto exit_proc;
00379 }
00380
00381
00382 hr = create_event(&node->term_main_evt, 1, 0);
00383 if(FAILED(hr)) {
00384 node->device.dn_close(sock);
00385 free(node);
00386 goto exit_proc;
00387 }
00388
00389
00390 begin_thread(&node->main_thread, &recv_thread, node);
00391 } else {
00392 switch(node->device.type) {
00393 case CONN_UDP:
00394 node->device.arg = malloc(sizeof(struct sockaddr_in));
00395 memcpy(node->device.arg, own->device.arg, sizeof(struct sockaddr_in));
00396 break;
00397 default:
00398 break;
00399 }
00400
00401 node->last_send.args =
00402 (VARIANT*) malloc(sizeof(VARIANT));
00403 VariantInit(node->last_send.args);
00404 }
00405 }
00406 break;
00407
00408 case DELETE_CHILD:
00409
00410 if(own->parent == NULL) {
00411 node = own->node2;
00412 while (node != NULL) {
00413 tmp = node->node2;
00414
00415 if(flag_mutex) {
00416
00417 set_event(&node->term_main_evt);
00418 exit_thread(node->main_thread);
00419
00420
00421 destroy_event(&node->term_main_evt);
00422
00423
00424 node->device.dn_close(&node->device.sock);
00425 } else {
00426 VariantClear(node->last_send.args);
00427 free(node->last_send.args);
00428
00429 if(node->device.arg != NULL) {
00430 free(node->device.arg);
00431 }
00432 }
00433
00434 free(node);
00435 node = tmp;
00436
00437 own->num_child--;
00438 }
00439 own->node2 = NULL;
00440 }
00441 break;
00442
00443 case DESTROY_SELF:
00444 if(own->parent != NULL) {
00445
00446 tmp = own->node1;
00447
00448 if(tmp == NULL) {
00449 own->parent->node1 = own->node2;
00450 } else {
00451 tmp->node2 = own->node2;
00452 }
00453
00454 if(own->node2 != NULL) {
00455 own->node2->node1 = tmp;
00456 }
00457
00458
00459 tmp = own->parent->node2;
00460 own->parent->node2 = own;
00461 own->node2 = tmp;
00462 if(tmp != NULL) tmp->node1 = own;
00463 } else {
00464 if(!flag_mutex) {
00465 node = own->node1;
00466 while(node != NULL) {
00467 tmp = node->node2;
00468 change_relation(node, DESTROY_SELF, NULL);
00469 node = tmp;
00470 }
00471 change_relation(own, DELETE_CHILD, NULL);
00472 }
00473 }
00474 break;
00475
00476 default:
00477 hr = E_INVALIDARG;
00478 break;
00479 }
00480
00481 exit_proc:
00482 if(flag_mutex) {
00483 unlock_mutex(mutex);
00484 }
00485
00486 return hr;
00487 }
00488
00494 static int
00495 check_lifelimit(struct CONN_BCAP_SERVER *parent)
00496 {
00497 uint32_t cur, diff;
00498 struct CONN_BCAP_SERVER *child, *tmp;
00499
00500 child = parent->node1;
00501 while(child != NULL) {
00502 tmp = child->node2;
00503
00504 cur = gettimeofday_msec();
00505 diff = calc_time_diff(child->last_modified, cur);
00506 if(diff > UDP_LIFELIMIT) {
00507 change_relation(child, DESTROY_SELF, NULL);
00508 }
00509
00510 child = tmp;
00511 }
00512
00513 change_relation(parent, DELETE_CHILD, NULL);
00514
00515 return parent->num_child;
00516 }
00517
00524 static HRESULT
00525 bcap_callfunc(struct BCAP_PACKET *recv_packet, struct BCAP_PACKET *send_packet)
00526 {
00527 int32_t id;
00528 CALL_FUNC_BCAP func;
00529
00530
00531 send_packet->serial = recv_packet->serial;
00532 send_packet->reserv = 0;
00533 send_packet->id = E_INVALIDARG;
00534 send_packet->argc = 0;
00535
00536 id = recv_packet->id;
00537 if((0 < id) && (id < _FUNCTION_ID_MAX)) {
00538 func = m_list_func[id];
00539 if(func == NULL) {
00540
00541 send_packet->id = E_NOTIMPL;
00542 } else {
00543
00544 VariantClear(send_packet->args);
00545 send_packet->id = func(recv_packet->args, recv_packet->argc,
00546 send_packet->args);
00547 send_packet->argc = m_map_id[id].return_flag ? 1 : 0;
00548 }
00549 }
00550
00551 return S_OK;
00552 }
00553
00559 static HRESULT
00560 receive_execute(struct CONN_BCAP_SERVER *bcap_param)
00561 {
00562 int index;
00563 int32_t relation_id;
00564 uint16_t i, clear_flag = 1;
00565 uint32_t cur, start, diff;
00566 HRESULT hr;
00567 struct CONN_BCAP_SERVER *tmp_param = bcap_param;
00568 struct CONN_PARAM_COMMON *device = &bcap_param->device;
00569 struct BCAP_PACKET tmp_send_packet, tmp_recv_packet, *send_packet =
00570 &bcap_param->last_send, *recv_packet = &bcap_param->last_recv;
00571 struct VEC_OBJECT *pObj = NULL;
00572 BSTR bstrOpt = NULL;
00573 VARIANT vntTmp, vntOpt;
00574
00575 VariantInit(&vntTmp);
00576 VariantInit(&vntOpt);
00577
00578
00579 tmp_recv_packet.argc = (uint16_t) -1;
00580 tmp_recv_packet.args = NULL;
00581
00582
00583 hr = bcap_recv(device, &tmp_recv_packet, 0);
00584
00585 if(SUCCEEDED(hr)) {
00586
00587 memset(&tmp_send_packet, 0, sizeof(struct BCAP_PACKET));
00588 tmp_send_packet.serial = tmp_recv_packet.serial;
00589 tmp_send_packet.id = S_EXECUTING;
00590
00591
00592 switch(device->type) {
00593 case CONN_UDP:
00594 tmp_param = search_node(bcap_param, device->arg,
00595 sizeof(struct sockaddr_in));
00596 if(tmp_param == NULL) {
00597
00598 if((bcap_param->num_child >= BCAP_CLIENT_MAX)
00599 && (check_lifelimit(bcap_param) >= BCAP_CLIENT_MAX))
00600 {
00601 tmp_send_packet.id = E_MAX_CONNECT;
00602 bcap_send(device, &tmp_send_packet);
00603 hr = S_FALSE;
00604 goto exit_proc;
00605 }
00606
00607
00608 change_relation(bcap_param, ADD_CHILD, &device->sock);
00609 tmp_param = bcap_param->node1;
00610 }
00611
00612 send_packet = &tmp_param->last_send;
00613
00614
00615
00616 case CONN_COM:
00617
00618 tmp_recv_packet.reserv =
00619 (tmp_recv_packet.reserv == 0) ?
00620 tmp_recv_packet.serial : tmp_recv_packet.reserv;
00621
00622
00623 if(send_packet->serial == tmp_recv_packet.reserv) {
00624
00625 tmp_send_packet = *send_packet;
00626
00627
00628 tmp_send_packet.serial = tmp_recv_packet.serial;
00629
00630
00631 bcap_send(device, &tmp_send_packet);
00632 hr = S_FALSE;
00633 goto exit_proc;
00634 }
00635
00636 break;
00637
00638 default:
00639 break;
00640 }
00641
00642
00643 hr = wait_event(&bcap_param->comp_evt, 0);
00644 if(hr == E_TIMEOUT) {
00645
00646 tmp_send_packet.id = E_BUSY_PROC;
00647 bcap_send(device, &tmp_send_packet);
00648 goto exit_proc;
00649 }
00650
00651 switch(tmp_recv_packet.id) {
00652 case ID_SERVICE_START:
00653 case ID_CONTROLLER_CONNECT:
00654 case ID_CONTROLLER_GETEXTENSION:
00655 case ID_CONTROLLER_GETFILE:
00656 case ID_FILE_GETFILE:
00657 case ID_CONTROLLER_GETROBOT:
00658 case ID_CONTROLLER_GETTASK:
00659 case ID_CONTROLLER_GETVARIABLE:
00660 case ID_EXTENSION_GETVARIABLE:
00661 case ID_FILE_GETVARIABLE:
00662 case ID_ROBOT_GETVARIABLE:
00663 case ID_TASK_GETVARIABLE:
00664 case ID_CONTROLLER_GETCOMMAND:
00665 case ID_CONTROLLER_GETMESSAGE:
00666 if(bcap_param->num_object >= BCAP_OBJECT_MAX) {
00667 tmp_send_packet.id = E_MAX_OBJECT;
00668 bcap_send(device, &tmp_send_packet);
00669 hr = S_FALSE;
00670 goto exit_proc;
00671 }
00672
00673 if(tmp_recv_packet.id == ID_SERVICE_START) {
00674 if((tmp_recv_packet.argc >= 1) && (tmp_recv_packet.args != NULL)) {
00675 VariantCopy(&vntTmp, &tmp_recv_packet.args[0]);
00676 hr = VariantChangeType(&vntTmp, &vntTmp, 0, VT_BSTR);
00677 if(FAILED(hr)) {
00678 tmp_send_packet.id = hr;
00679 bcap_send(device, &tmp_send_packet);
00680 hr = S_FALSE;
00681 goto exit_proc;
00682 }
00683 } else {
00684 vntTmp.vt = VT_BSTR;
00685 vntTmp.bstrVal = SysAllocString(L"");
00686 }
00687
00688 bstrOpt = SysAllocString(L"WDT");
00689 hr = GetOptionValue(vntTmp.bstrVal, bstrOpt, VT_UI4, &vntOpt);
00690 vntOpt.ulVal =
00691 (vntOpt.vt == VT_UI4) ? vntOpt.ulVal : INIT_WDT_INTERVAL;
00692 if(vntOpt.ulVal < MIN_WDT_INTERVAL) {
00693 tmp_send_packet.id = E_INVALIDARG;
00694 bcap_send(device, &tmp_send_packet);
00695 hr = S_FALSE;
00696 goto exit_proc;
00697 } else {
00698 tmp_param->wdt_interval = vntOpt.ulVal;
00699 }
00700 SysFreeString(bstrOpt);
00701 VariantClear(&vntOpt);
00702
00703 bstrOpt = SysAllocString(L"InvokeTimeout");
00704 hr = GetOptionValue(vntTmp.bstrVal, bstrOpt, VT_UI4, &vntOpt);
00705 vntOpt.ulVal =
00706 (vntOpt.vt == VT_UI4) ? vntOpt.ulVal : INIT_EXEC_TIMEOUT;
00707 if(vntOpt.ulVal < MIN_WDT_INTERVAL) {
00708 tmp_send_packet.id = E_INVALIDARG;
00709 bcap_send(device, &tmp_send_packet);
00710 hr = S_FALSE;
00711 goto exit_proc;
00712 } else {
00713 tmp_param->exec_timeout = vntOpt.ulVal;
00714 }
00715 SysFreeString(bstrOpt);
00716 VariantClear(&vntOpt);
00717
00718 VariantClear(&vntTmp);
00719 bstrOpt = NULL;
00720 }
00721
00722 break;
00723
00724 default:
00725 break;
00726 }
00727
00728
00729 if(recv_packet->args != NULL) {
00730 for(i = 0; i < recv_packet->argc; i++) {
00731 VariantClear(&recv_packet->args[i]);
00732 }
00733 free(recv_packet->args);
00734 }
00735
00736
00737 clear_flag = 0;
00738 *recv_packet = tmp_recv_packet;
00739
00740
00741 reset_event(&bcap_param->comp_evt);
00742 set_event(&bcap_param->exec_evt);
00743
00744 if(SUCCEEDED(hr)) {
00745 start = gettimeofday_msec();
00746 while(1) {
00747 hr = wait_event(&bcap_param->comp_evt, tmp_param->wdt_interval);
00748 if(SUCCEEDED(hr)) {
00749 break;
00750 } else {
00751
00752 hr = bcap_send(device, &tmp_send_packet);
00753 if(FAILED(hr)) {
00754 break;
00755 }
00756 }
00757
00758
00759 cur = gettimeofday_msec();
00760 diff = calc_time_diff(start, cur);
00761 if(diff > tmp_param->exec_timeout) {
00762 hr = E_TIMEOUT;
00763 break;
00764 }
00765 }
00766 }
00767 }
00768
00769 exit_proc:
00770 if(hr == S_OK) {
00771 if(bcap_param->last_send.id == S_OK) {
00772
00773 relation_id = m_map_id[recv_packet->id].relation_id;
00774 if(relation_id > 0) {
00775 pObj = (struct VEC_OBJECT *) malloc(sizeof(struct VEC_OBJECT));
00776 if(pObj != NULL) {
00777 memset(pObj, 0, sizeof(struct VEC_OBJECT));
00778 pObj->id = relation_id;
00779 pObj->hObj =
00780 (recv_packet->id == ID_SERVICE_START) ?
00781 0 : bcap_param->last_send.args[0].lVal;
00782 push_vector(bcap_param, pObj);
00783 }
00784 }
00785 else if(relation_id < 0) {
00786 index = search_vector(bcap_param, recv_packet->id,
00787 (recv_packet->id == ID_SERVICE_STOP) ?
00788 0 : recv_packet->args[0].lVal);
00789 if(index >= 0) {
00790 pop_vector(bcap_param, &pObj, index);
00791 free(pObj);
00792 }
00793 if((device->type == CONN_UDP)
00794 && (recv_packet->id == ID_SERVICE_STOP))
00795 {
00796 change_relation(tmp_param, DESTROY_SELF, NULL);
00797 change_relation(bcap_param, DELETE_CHILD, NULL);
00798 tmp_param = NULL;
00799 }
00800 }
00801 }
00802
00803
00804 hr = bcap_send(device, &bcap_param->last_send);
00805 if(SUCCEEDED(hr) && (tmp_param != NULL)) {
00806 tmp_param->last_send.serial = bcap_param->last_send.serial;
00807 tmp_param->last_send.reserv = bcap_param->last_send.reserv;
00808 tmp_param->last_send.id = bcap_param->last_send.id;
00809 tmp_param->last_send.argc = bcap_param->last_send.argc;
00810 VariantCopy(tmp_param->last_send.args, bcap_param->last_send.args);
00811
00812 tmp_param->last_modified = gettimeofday_msec();
00813 }
00814 }
00815
00816
00817 if(clear_flag) {
00818 if(tmp_recv_packet.args != NULL) {
00819 for(i = 0; i < tmp_recv_packet.argc; i++) {
00820 VariantClear(&tmp_recv_packet.args[i]);
00821 }
00822 free(tmp_recv_packet.args);
00823 }
00824 }
00825
00826 VariantClear(&vntTmp);
00827 VariantClear(&vntOpt);
00828 if(bstrOpt) {
00829 SysFreeString(bstrOpt);
00830 }
00831
00832 return hr;
00833 }
00834
00840 static THRET THTYPE
00841 exec_thread(void *arg)
00842 {
00843 #if !defined(THRET)
00844 THRET ret = (THRET)NULL;
00845 #endif
00846
00847 HRESULT hr;
00848 struct CONN_BCAP_SERVER *bcap_param = (struct CONN_BCAP_SERVER *) arg;
00849 EVENT *evt[2] =
00850 { &bcap_param->exec_evt, &bcap_param->term_sub_evt };
00851
00852 while(1) {
00853 hr = wait_event_multi(evt, 2, INFINITE, 0);
00854 if(hr == WAIT_OBJECT_0 + 1) {
00855 break;
00856 }
00857 else if(hr == WAIT_OBJECT_0) {
00858 bcap_callfunc(&bcap_param->last_recv, &bcap_param->last_send);
00859 }
00860 else {
00861 bcap_param->last_send.serial = bcap_param->last_recv.serial;
00862 bcap_param->last_send.reserv = 0;
00863 bcap_param->last_send.id = hr;
00864 bcap_param->last_send.argc = 0;
00865 }
00866 set_event(&bcap_param->comp_evt);
00867 }
00868
00869 #if !defined(THRET)
00870 return ret;
00871 #endif
00872 }
00873
00879 static THRET THTYPE
00880 recv_thread(void *arg)
00881 {
00882 #if !defined(THRET)
00883 THRET ret = (THRET)NULL;
00884 #endif
00885
00886 uint16_t i;
00887 HRESULT hr;
00888 struct CONN_BCAP_SERVER *bcap_param = (struct CONN_BCAP_SERVER *) arg;
00889 struct BCAP_PACKET *send_packet = &bcap_param->last_send, *recv_packet =
00890 &bcap_param->last_recv;
00891 struct VEC_OBJECT *pObj = NULL;
00892 VARIANT vnt_send, vntTmp;
00893 CALL_FUNC_BCAP func;
00894
00895
00896 send_packet->args = &vnt_send;
00897 VariantInit(&vnt_send);
00898
00899
00900 hr = create_event(&bcap_param->term_sub_evt, 1, 0);
00901 if(FAILED(hr)) goto exit_proc;
00902
00903
00904 hr = create_event(&bcap_param->exec_evt, 0, 0);
00905 if(FAILED(hr)) goto exit_proc;
00906
00907 hr = create_event(&bcap_param->comp_evt, 1, 1);
00908 if(FAILED(hr)) goto exit_proc;
00909
00910
00911 begin_thread(&bcap_param->sub_thread, &exec_thread, arg);
00912
00913 while(1) {
00914 hr = wait_event(&bcap_param->term_main_evt, 0);
00915 if(SUCCEEDED(hr)) {
00916 break;
00917 }
00918
00919 hr = receive_execute(bcap_param);
00920 if(FAILED(hr) && hr != E_TIMEOUT) {
00921 break;
00922 }
00923 }
00924
00925 exit_proc:
00926
00927 set_event(&bcap_param->term_sub_evt);
00928 exit_thread(bcap_param->sub_thread);
00929
00930
00931 destroy_event(&bcap_param->term_sub_evt);
00932 destroy_event(&bcap_param->exec_evt);
00933 destroy_event(&bcap_param->comp_evt);
00934
00935
00936 VariantClear(&vnt_send);
00937
00938
00939 if(recv_packet->args != NULL) {
00940 for(i = 0; i < recv_packet->argc; i++) {
00941 VariantClear(&recv_packet->args[i]);
00942 }
00943 free(recv_packet->args);
00944 }
00945
00946
00947 VariantInit(&vntTmp);
00948 vntTmp.vt = VT_I4;
00949
00950 while(1) {
00951 hr = pop_vector(bcap_param, &pObj, 0);
00952 if(FAILED(hr)) break;
00953
00954 func = m_list_func[pObj->id];
00955 if(func != NULL) {
00956 vntTmp.lVal = pObj->hObj;
00957 func(&vntTmp, ((pObj->id == ID_SERVICE_STOP) ? 0 : 1), &vnt_send);
00958 VariantClear(&vnt_send);
00959 }
00960
00961 free(pObj);
00962 }
00963
00964 VariantClear(&vntTmp);
00965
00966
00967 change_relation(bcap_param, DESTROY_SELF, NULL);
00968
00969 #if !defined(THRET)
00970 return ret;
00971 #endif
00972 }
00973
00979 static THRET THTYPE
00980 accept_thread(void *arg)
00981 {
00982 #if !defined(THRET)
00983 THRET ret = (THRET)NULL;
00984 #endif
00985
00986 int client;
00987 HRESULT hr;
00988 volatile struct CONN_BCAP_SERVER *child;
00989 struct CONN_BCAP_SERVER *bcap_param = (struct CONN_BCAP_SERVER *) arg;
00990 MUTEX mutex;
00991
00992
00993 bcap_param->relation_mutex = &mutex;
00994 hr = initialize_mutex(&mutex);
00995 if(FAILED(hr)) goto exit_proc;
00996
00997 while(1) {
00998 hr = wait_event(&bcap_param->term_main_evt, 300);
00999 if(SUCCEEDED(hr)) {
01000 break;
01001 }
01002
01003 if(bcap_param->num_child < BCAP_CLIENT_MAX) {
01004 hr = tcp_accept(bcap_param->device.sock, &client);
01005 if(SUCCEEDED(hr)) {
01006
01007 tcp_set_nodelay(client, 1);
01008
01009
01010 tcp_set_keepalive(client, KEEPALIVE_ENABLE, KEEPALIVE_IDLE,
01011 KEEPALIVE_INTERVAL, KEEPALIVE_COUNT);
01012
01013
01014 change_relation(bcap_param, ADD_CHILD, &client);
01015 }
01016 }
01017
01018
01019 change_relation(bcap_param, DELETE_CHILD, NULL);
01020 }
01021
01022 exit_proc:
01023
01024 child = bcap_param->node1;
01025 while(child != NULL) {
01026 set_event((EVENT *) &child->term_main_evt);
01027 exit_thread(child->main_thread);
01028
01029 child = bcap_param->node1;
01030 }
01031
01032
01033 change_relation(bcap_param, DELETE_CHILD, NULL);
01034
01035
01036 release_mutex(&mutex);
01037
01038 #if !defined(THRET)
01039 return ret;
01040 #endif
01041 }
01042
01043 HRESULT
01044 bCap_SetCallFunc(int32_t id, CALL_FUNC_BCAP func)
01045 {
01046 if((id <= 0) || (_FUNCTION_ID_MAX <= id)) {
01047 return E_INVALIDARG;
01048 }
01049
01050 m_list_func[id] = func;
01051
01052 return S_OK;
01053 }
01054
01055 HRESULT
01056 bCap_Open_Server(const char *connect, uint32_t timeout, int *pfd)
01057 {
01058 int type, index, *sock;
01059 HRESULT hr;
01060 void *conn_param;
01061 struct CONN_PARAM_ETH eth_param =
01062 { 0, 0, htonl(INADDR_ANY), htons(5007) };
01063 struct CONN_PARAM_COM com_param =
01064 { 1, 38400, NOPARITY, 8, ONESTOPBIT, 0 };
01065 struct CONN_BCAP_SERVER *bcap_param;
01066 struct CONN_PARAM_COMMON *device;
01067 struct sockaddr_in *paddr;
01068
01069 if(connect == NULL || pfd == NULL)
01070 return E_INVALIDARG;
01071
01072 type = parse_conn_type(connect);
01073
01074 index = find_open_address(type);
01075 if(index == 0)
01076 return E_MAX_OBJECT;
01077
01078 bcap_param = &m_conn_param[index - 1];
01079 device = &bcap_param->device;
01080
01081
01082 device->type = type;
01083 switch(device->type) {
01084 case CONN_TCP:
01085 hr = parse_conn_param_ether(connect, ð_param);
01086 conn_param = ð_param;
01087 device->arg = NULL;
01088 device->dn_open = &tcp_open_server;
01089 device->dn_close = &tcp_close;
01090 device->dn_send = &tcp_send;
01091 device->dn_recv = &tcp_recv;
01092 device->dn_set_timeout = &tcp_set_timeout;
01093 break;
01094 case CONN_UDP:
01095 hr = parse_conn_param_ether(connect, ð_param);
01096 conn_param = ð_param;
01097 paddr = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
01098 if(paddr == NULL) {
01099 hr = E_OUTOFMEMORY;
01100 break;
01101 }
01102 paddr->sin_addr.s_addr = eth_param.dst_addr;
01103 paddr->sin_port = eth_param.dst_port;
01104 paddr->sin_family = AF_INET;
01105 device->arg = (void *) paddr;
01106 device->dn_open = &udp_open;
01107 device->dn_close = &udp_close;
01108 device->dn_send = &udp_send;
01109 device->dn_recv = &udp_recv;
01110 device->dn_set_timeout = &udp_set_timeout;
01111 break;
01112 case CONN_COM:
01113 hr = parse_conn_param_serial(connect, &com_param);
01114 conn_param = &com_param;
01115 device->arg = NULL;
01116 device->dn_open = &com_open;
01117 device->dn_close = &com_close;
01118 device->dn_send = &com_send;
01119 device->dn_recv = &com_recv;
01120 device->dn_set_timeout = &com_set_timeout;
01121 break;
01122 default:
01123 hr = E_INVALIDARG;
01124 break;
01125 }
01126
01127 if(FAILED(hr)) {
01128 if(device->arg != NULL) {
01129 free(device->arg);
01130 device->arg = NULL;
01131 }
01132 memset(bcap_param, 0, sizeof(struct CONN_BCAP_SERVER));
01133 return hr;
01134 }
01135
01136
01137 hr = create_event(&bcap_param->term_main_evt, 1, 0);
01138 if(FAILED(hr)) {
01139 if(device->arg != NULL) {
01140 free(device->arg);
01141 device->arg = NULL;
01142 }
01143 memset(bcap_param, 0, sizeof(struct CONN_BCAP_SERVER));
01144 return hr;
01145 }
01146
01147
01148 sock = &device->sock;
01149 hr = device->dn_open(conn_param, sock);
01150 if(FAILED(hr)) {
01151 destroy_event(&bcap_param->term_main_evt);
01152 if(device->arg != NULL) {
01153 free(device->arg);
01154 device->arg = NULL;
01155 }
01156 memset(bcap_param, 0, sizeof(struct CONN_BCAP_SERVER));
01157 return hr;
01158 }
01159
01160 hr = device->dn_set_timeout(*sock, timeout);
01161 if(FAILED(hr)) {
01162 bCap_Close_Server(&index);
01163 return hr;
01164 }
01165
01166
01167 device->timeout = timeout;
01168 bcap_param->exec_timeout = INIT_EXEC_TIMEOUT;
01169 bcap_param->wdt_interval = INIT_WDT_INTERVAL;
01170
01171
01172 if(device->type == CONN_TCP) {
01173 begin_thread(&bcap_param->main_thread, &accept_thread, bcap_param);
01174 } else {
01175 begin_thread(&bcap_param->main_thread, &recv_thread, bcap_param);
01176 }
01177
01178 *pfd = index;
01179
01180 return S_OK;
01181 }
01182
01183 HRESULT
01184 bCap_Close_Server(int *pfd)
01185 {
01186 int index, *sock;
01187 struct CONN_BCAP_SERVER *bcap_param;
01188 struct CONN_PARAM_COMMON *device;
01189
01190 if(pfd == NULL)
01191 return E_HANDLE;
01192
01193 index = *pfd;
01194
01195 bcap_param = check_address(index);
01196 if(bcap_param == NULL)
01197 return E_HANDLE;
01198
01199 device = &bcap_param->device;
01200 sock = &device->sock;
01201
01202
01203 set_event(&bcap_param->term_main_evt);
01204 exit_thread(bcap_param->main_thread);
01205
01206
01207 destroy_event(&bcap_param->term_main_evt);
01208
01209
01210 device->dn_close(sock);
01211
01212
01213 if(device->arg != NULL) {
01214 free(device->arg);
01215 device->arg = NULL;
01216 }
01217
01218
01219 memset(bcap_param, 0, sizeof(struct CONN_BCAP_SERVER));
01220
01221 *pfd = 0;
01222
01223 return S_OK;
01224 }