tsb_t * get_tsb_ptr_by_name(char *name) { tsb_vector_el_t *tsb_ptr = search_vector(&Tsb_vector, (vector_search_func_t)tsb_name_compare, name); if(!tsb_ptr) { return NULL; } return *tsb_ptr; }
/** * @fn HRESULT receive_execute(struct CONN_BCAP_SERVER *bcap_param) * @brief Receives the b-CAP packet and executes callback functions. * @param[in,out] bcap_param b-CAP communication object. */ static HRESULT receive_execute(struct CONN_BCAP_SERVER *bcap_param) { int index; int32_t relation_id; uint16_t i, clear_flag = 1; uint32_t cur, start, diff; HRESULT hr; struct CONN_BCAP_SERVER *tmp_param = bcap_param; struct CONN_PARAM_COMMON *device = &bcap_param->device; struct BCAP_PACKET tmp_send_packet, tmp_recv_packet, *send_packet = &bcap_param->last_send, *recv_packet = &bcap_param->last_recv; struct VEC_OBJECT *pObj = NULL; BSTR bstrOpt = NULL; VARIANT vntTmp, vntOpt; VariantInit(&vntTmp); VariantInit(&vntOpt); /* Initializes temporary packet */ tmp_recv_packet.argc = (uint16_t) -1; tmp_recv_packet.args = NULL; /* Receives b-CAP packet */ hr = bcap_recv(device, &tmp_recv_packet, 0); if(SUCCEEDED(hr)) { /* Sets S_EXECUTING packet */ memset(&tmp_send_packet, 0, sizeof(struct BCAP_PACKET)); tmp_send_packet.serial = tmp_recv_packet.serial; tmp_send_packet.id = S_EXECUTING; /* Checks retry packet */ switch(device->type) { case CONN_UDP: tmp_param = search_node(bcap_param, device->arg, sizeof(struct sockaddr_in)); if(tmp_param == NULL) { /* Checks life limit */ if((bcap_param->num_child >= BCAP_CLIENT_MAX) && (check_lifelimit(bcap_param) >= BCAP_CLIENT_MAX)) { tmp_send_packet.id = E_MAX_CONNECT; bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } /* Adds child */ change_relation(bcap_param, ADD_CHILD, &device->sock); tmp_param = bcap_param->node1; } send_packet = &tmp_param->last_send; //break; case CONN_COM: /* Sets retry count */ tmp_recv_packet.reserv = (tmp_recv_packet.reserv == 0) ? tmp_recv_packet.serial : tmp_recv_packet.reserv; /* If already responded, then does not execute */ if(send_packet->serial == tmp_recv_packet.reserv) { /* Copies last send packet */ tmp_send_packet = *send_packet; /* Sets new serial number */ tmp_send_packet.serial = tmp_recv_packet.serial; /* Sends temporary send packet */ bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } break; default: break; } /* Checks execute thread */ hr = wait_event(&bcap_param->comp_evt, 0); if(hr == E_TIMEOUT) { /* Sends result busy process */ tmp_send_packet.id = E_BUSY_PROC; bcap_send(device, &tmp_send_packet); goto exit_proc; } switch(tmp_recv_packet.id) { case ID_SERVICE_START: case ID_CONTROLLER_CONNECT: case ID_CONTROLLER_GETEXTENSION: case ID_CONTROLLER_GETFILE: case ID_FILE_GETFILE: case ID_CONTROLLER_GETROBOT: case ID_CONTROLLER_GETTASK: case ID_CONTROLLER_GETVARIABLE: case ID_EXTENSION_GETVARIABLE: case ID_FILE_GETVARIABLE: case ID_ROBOT_GETVARIABLE: case ID_TASK_GETVARIABLE: case ID_CONTROLLER_GETCOMMAND: case ID_CONTROLLER_GETMESSAGE: if(bcap_param->num_object >= BCAP_OBJECT_MAX) { tmp_send_packet.id = E_MAX_OBJECT; bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } if(tmp_recv_packet.id == ID_SERVICE_START) { if((tmp_recv_packet.argc >= 1) && (tmp_recv_packet.args != NULL)) { VariantCopy(&vntTmp, &tmp_recv_packet.args[0]); hr = VariantChangeType(&vntTmp, &vntTmp, 0, VT_BSTR); if(FAILED(hr)) { tmp_send_packet.id = hr; bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } } else { vntTmp.vt = VT_BSTR; vntTmp.bstrVal = SysAllocString(L""); } bstrOpt = SysAllocString(L"WDT"); hr = GetOptionValue(vntTmp.bstrVal, bstrOpt, VT_UI4, &vntOpt); vntOpt.ulVal = (vntOpt.vt == VT_UI4) ? vntOpt.ulVal : INIT_WDT_INTERVAL; if(vntOpt.ulVal < MIN_WDT_INTERVAL) { tmp_send_packet.id = E_INVALIDARG; bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } else { tmp_param->wdt_interval = vntOpt.ulVal; } SysFreeString(bstrOpt); VariantClear(&vntOpt); bstrOpt = SysAllocString(L"InvokeTimeout"); hr = GetOptionValue(vntTmp.bstrVal, bstrOpt, VT_UI4, &vntOpt); vntOpt.ulVal = (vntOpt.vt == VT_UI4) ? vntOpt.ulVal : INIT_EXEC_TIMEOUT; if(vntOpt.ulVal < MIN_WDT_INTERVAL) { tmp_send_packet.id = E_INVALIDARG; bcap_send(device, &tmp_send_packet); hr = S_FALSE; goto exit_proc; } else { tmp_param->exec_timeout = vntOpt.ulVal; } SysFreeString(bstrOpt); VariantClear(&vntOpt); VariantClear(&vntTmp); bstrOpt = NULL; } break; default: break; } /* Resets last received packet */ if(recv_packet->args != NULL) { for(i = 0; i < recv_packet->argc; i++) { VariantClear(&recv_packet->args[i]); } free(recv_packet->args); } /* Copies to last receive packet */ clear_flag = 0; *recv_packet = tmp_recv_packet; /* Runs execute thread */ reset_event(&bcap_param->comp_evt); set_event(&bcap_param->exec_evt); if(SUCCEEDED(hr)) { start = gettimeofday_msec(); while(1) { hr = wait_event(&bcap_param->comp_evt, tmp_param->wdt_interval); if(SUCCEEDED(hr)) { break; } else { /* Sends S_EXECUTING packet */ hr = bcap_send(device, &tmp_send_packet); if(FAILED(hr)) { break; } } /* Checks executing timeout */ cur = gettimeofday_msec(); diff = calc_time_diff(start, cur); if(diff > tmp_param->exec_timeout) { hr = E_TIMEOUT; break; } } } } exit_proc: if(hr == S_OK) { if(bcap_param->last_send.id == S_OK) { /* Changes the vector of created objects */ relation_id = m_map_id[recv_packet->id].relation_id; if(relation_id > 0) { // Push pObj = (struct VEC_OBJECT *) malloc(sizeof(struct VEC_OBJECT)); if(pObj != NULL) { memset(pObj, 0, sizeof(struct VEC_OBJECT)); pObj->id = relation_id; pObj->hObj = (recv_packet->id == ID_SERVICE_START) ? 0 : bcap_param->last_send.args[0].lVal; push_vector(bcap_param, pObj); } } else if(relation_id < 0) { // Pop index = search_vector(bcap_param, recv_packet->id, (recv_packet->id == ID_SERVICE_STOP) ? 0 : recv_packet->args[0].lVal); if(index >= 0) { pop_vector(bcap_param, &pObj, index); free(pObj); } if((device->type == CONN_UDP) && (recv_packet->id == ID_SERVICE_STOP)) { change_relation(tmp_param, DESTROY_SELF, NULL); change_relation(bcap_param, DELETE_CHILD, NULL); tmp_param = NULL; } } } /* Responds the result message */ hr = bcap_send(device, &bcap_param->last_send); if(SUCCEEDED(hr) && (tmp_param != NULL)) { tmp_param->last_send.serial = bcap_param->last_send.serial; tmp_param->last_send.reserv = bcap_param->last_send.reserv; tmp_param->last_send.id = bcap_param->last_send.id; tmp_param->last_send.argc = bcap_param->last_send.argc; VariantCopy(tmp_param->last_send.args, bcap_param->last_send.args); tmp_param->last_modified = gettimeofday_msec(); } } /* Clears temporary packet */ if(clear_flag) { if(tmp_recv_packet.args != NULL) { for(i = 0; i < tmp_recv_packet.argc; i++) { VariantClear(&tmp_recv_packet.args[i]); } free(tmp_recv_packet.args); } } VariantClear(&vntTmp); VariantClear(&vntOpt); if(bstrOpt) { SysFreeString(bstrOpt); } return hr; }