00001
00023 #include "stdint.h"
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #if defined(_USE_WIN_API)
00028 #include <process.h>
00029 #include <winsock2.h>
00030 #pragma comment(lib, "wsock32.lib")
00031 #elif defined(_USE_LINUX_API)
00032 #include <arpa/inet.h>
00033 #include <pthread.h>
00034 #include <sys/ioctl.h>
00035 #include <termios.h>
00036 #include <unistd.h>
00037 #else
00038 #include "dn_additional.h"
00039 #endif
00040
00041 #include "dn_common.h"
00042 #include "dn_device.h"
00043 #include "dn_udp.h"
00044 #include "dn_com.h"
00045 #include "dn_thread.h"
00046 #include "dn_robotalk.h"
00047 #include "dn_tpcomm.h"
00048
00049 #ifndef _DEBUG
00050 #define _DEBUG (0)
00051 #endif
00052
00057 #define _TP_CMD_SPECIAL (0x0FFF)
00058
00064 #define _TIMER_INTERVAL (10)
00065
00071 #define _TPERROR_TIMEOUT (10000)
00072
00078 #define _TPLESS_INTERVAL (10000)
00079
00085 #define _PING_INTERVAL_CONNECT (300)
00086
00092 #define _PING_INTERVAL_TPERROR (1000)
00093
00099 #define _TP_INIT_WAIT_CLIENT (100)
00100
00106 #define _TP_INIT_WAIT_SERVER (3000)
00107
00112 struct TP_FLAGS
00113 {
00114 uint8_t client :1;
00115 uint8_t init :1;
00116 uint8_t state :3;
00117 uint8_t cts :1;
00118 volatile uint8_t timer_flag :1;
00119 volatile uint8_t recv_flag :1;
00120 };
00121
00126 struct CONN_PARAM_TP
00127 {
00128 struct CONN_PARAM_COMMON device;
00129 struct TP_FLAGS flags;
00130 uint8_t from_id;
00131 uint8_t to_id;
00132 uint32_t timer_clock;
00133 uint32_t ping_clock;
00134 uint32_t init_clock;
00135 uint32_t check_clock;
00136 MUTEX mutex;
00137 EVENT evt;
00138 THREAD timer_thread;
00139 THREAD recv_thread;
00140 union RTK_PACKET last_packet;
00141 };
00142
00143 static struct CONN_PARAM_TP m_conn_param[TP_CONN_MAX];
00144 static struct CALL_FUNC_TP m_call_func;
00145
00151 static int
00152 find_open_address()
00153 {
00154 int i, index = -1;
00155
00156 for (i = 0; i < TP_CONN_MAX; i++) {
00157 if (m_conn_param[i].device.sock == 0) {
00158 index = i;
00159 break;
00160 }
00161 }
00162
00163 return (index + 1);
00164 }
00165
00172 static struct CONN_PARAM_TP*
00173 check_address(int index)
00174 {
00175 index--;
00176
00177 if (index < 0 || TP_CONN_MAX <= index) {
00178 return NULL;
00179 }
00180 else if (m_conn_param[index].device.sock == 0) {
00181 return NULL;
00182 }
00183
00184 return &m_conn_param[index];
00185 }
00186
00194 static HRESULT
00195 tp_callfunc(uint16_t command, const uint8_t *data, uint8_t len_data)
00196 {
00197 void *param = NULL;
00198
00199
00200 HRESULT hr = E_NOTIMPL;
00201
00202
00203 struct CALL_FUNC_TP func = m_call_func;
00204
00205 switch (command) {
00206 case _TP_CMD_SPECIAL:
00207 if (len_data == sizeof(int)) {
00208 if (func.Call_TPState != NULL)
00209 hr = func.Call_TPState(*(int *) data);
00210 } else {
00211 hr = E_INVALIDARG;
00212 }
00213 break;
00214
00215 case TP_CMD_REQ_ID:
00216 hr = S_OK;
00217 break;
00218
00219 case TP_CMD_KEYINFO:
00220 if (len_data == 8) {
00221 param = malloc(sizeof(struct TP_KEY_INFO));
00222 if (param != NULL) {
00223
00224 memcpy_be(param, data, len_data);
00225 if (func.Call_TPKeyInfo != NULL)
00226 hr = func.Call_TPKeyInfo(*(struct TP_KEY_INFO *) param);
00227 } else {
00228 hr = E_OUTOFMEMORY;
00229 }
00230 } else {
00231 hr = E_INVALIDARG;
00232 }
00233 break;
00234
00235 case TP_CMD_TOUTCHINFO:
00236 if (len_data == 5) {
00237 param = malloc(sizeof(struct TP_TOUCH_INFO));
00238 if (param != NULL) {
00239
00240 ((struct TP_TOUCH_INFO *) param)->mode = data[0];
00241 memcpy_be(&((struct TP_TOUCH_INFO *) param)->pos_x, &data[1], 2);
00242 ((struct TP_TOUCH_INFO *) param)->pos_x =
00243 ((struct TP_TOUCH_INFO *) param)->pos_x * 8 + 4;
00244 memcpy_be(&((struct TP_TOUCH_INFO *) param)->pos_y, &data[3], 2);
00245 ((struct TP_TOUCH_INFO *) param)->pos_y =
00246 ((struct TP_TOUCH_INFO *) param)->pos_y * 8 + 4;
00247 if (func.Call_TPTouchInfo != NULL)
00248 hr = func.Call_TPTouchInfo(*(struct TP_TOUCH_INFO *) param);
00249 } else {
00250 hr = E_OUTOFMEMORY;
00251 }
00252 } else {
00253 hr = E_INVALIDARG;
00254 }
00255 break;
00256
00257 #if (_DEBUG)
00258 default:
00259 if(func.Call_TPDefault != NULL) {
00260 hr = func.Call_TPDefault(command, data, len_data);
00261 }
00262 break;
00263 #else
00264 default:
00265 break;
00266 #endif
00267 }
00268
00269 if (param != NULL) {
00270 free(param);
00271 param = NULL;
00272 }
00273
00274 return hr;
00275 }
00276
00286 static HRESULT
00287 tp_send(struct CONN_PARAM_TP *tp_param, uint16_t command, uint8_t *data,
00288 uint8_t len_data)
00289 {
00290 struct CONN_PARAM_COMMON *device;
00291 union RTK_PACKET packet;
00292 HRESULT hr;
00293
00294 device = &tp_param->device;
00295
00296 hr = rtk_param2packet(command, data, len_data, tp_param->from_id,
00297 tp_param->to_id, &packet);
00298 if (SUCCEEDED(hr)) {
00299 hr = rtk_send(device, &packet);
00300 if (SUCCEEDED(hr)) {
00301
00302 tp_param->last_packet = packet;
00303 tp_param->ping_clock = gettimeofday_msec();
00304 }
00305 }
00306
00307 return hr;
00308 }
00309
00320 static HRESULT
00321 tp_recv(struct CONN_PARAM_TP *tp_param, unsigned int retry_nak,
00322 uint16_t *command, uint8_t *data, uint8_t *len_data)
00323 {
00324 unsigned int retry_cnt;
00325 uint32_t com_state;
00326 struct CONN_PARAM_COMMON *device;
00327 union RTK_PACKET packet;
00328 HRESULT hr = S_OK;
00329
00330 device = &tp_param->device;
00331
00332 for (retry_cnt = 0; retry_cnt <= retry_nak; retry_cnt++) {
00333 if (device->type == CONN_COM) {
00334 com_get_modem_state(device->sock, &com_state);
00335
00336 if (com_state & COM_BITS_CTS) {
00337
00338 if (!tp_param->flags.cts) {
00339 device->dn_clear(device->sock, device->timeout);
00340 }
00341 tp_param->flags.cts = 1;
00342 } else {
00343 tp_param->flags.cts = 0;
00344 hr = E_ACCESSDENIED;
00345 break;
00346 }
00347 }
00348
00349 hr = rtk_recv(device, &packet, tp_param->flags.client, retry_nak);
00350 if (FAILED(hr))
00351 break;
00352
00353
00354 if (NativeCommand(packet.command) == RTK_CMD_NAK) {
00355 hr = rtk_send(device, &tp_param->last_packet);
00356 if (FAILED(hr)) {
00357 break;
00358 }
00359 if (retry_cnt == retry_nak) {
00360 hr = E_INVALIDPACKET;
00361 }
00362 } else {
00363 *command = packet.command;
00364 *len_data = packet.len;
00365 if (packet.len > 0) {
00366 memcpy(data, packet.data, packet.len);
00367 }
00368
00369
00370 tp_param->to_id = packet.from_id;
00371
00372 break;
00373 }
00374 }
00375
00376 return hr;
00377 }
00378
00393 static HRESULT
00394 send_receive(int index, unsigned int retry_timeout, uint16_t command_send,
00395 uint8_t *data_send, uint8_t len_send, uint16_t *command_recv,
00396 uint8_t *data_recv, uint8_t *len_recv)
00397 {
00398 unsigned int retry_cnt;
00399 HRESULT hr;
00400 struct CONN_PARAM_TP *tp_param;
00401
00402 tp_param = check_address(index);
00403 if (tp_param == NULL)
00404 return E_HANDLE;
00405
00406 if (tp_param->flags.state == TP_TPLESS)
00407 return E_ACCESSDENIED;
00408
00409
00410 hr = lock_mutex(&tp_param->mutex, INFINITE);
00411 if (FAILED(hr))
00412 return hr;
00413
00414 for (retry_cnt = 0; retry_cnt <= retry_timeout; retry_cnt++) {
00415
00416 if (retry_cnt > 0) {
00417 command_send |= RTK_RETRY_FLAG;
00418 command_send += RTK_RETRY_COUNT;
00419 }
00420
00421 hr = tp_send(tp_param, command_send, data_send, len_send);
00422 if (FAILED(hr))
00423 break;
00424
00425 hr = tp_recv(tp_param, TP_RETRY_NAK, command_recv, data_recv, len_recv);
00426 if (SUCCEEDED(hr) || hr != E_TIMEOUT) {
00427 if (SUCCEEDED(hr)) {
00428 switch (NativeCommand(*command_recv)) {
00429 case RTK_CMD_REJ:
00430 hr = E_FAIL;
00431 break;
00432 default:
00433 break;
00434 }
00435 }
00436 break;
00437 }
00438 }
00439
00440
00441 unlock_mutex(&tp_param->mutex);
00442
00443 return hr;
00444 }
00445
00451 static HRESULT
00452 receive_execute(struct CONN_PARAM_TP *tp_param)
00453 {
00454 int resp = 1, tmp_state = tp_param->flags.state;
00455 uint32_t cur, diff;
00456 union RTK_PACKET packet_send, packet_recv;
00457 HRESULT hr;
00458
00459
00460 hr = lock_mutex(&tp_param->mutex, INFINITE);
00461 if (FAILED(hr))
00462 return hr;
00463
00464 hr = tp_recv(tp_param, TP_RETRY_NAK, &packet_recv.command, packet_recv.data,
00465 &packet_recv.len);
00466 if (FAILED(hr)) {
00467
00468 if (hr == E_ACCESSDENIED) {
00469 tmp_state = TP_TPLESS;
00470 } else {
00471 tmp_state = TP_TPERROR;
00472 }
00473 } else {
00474
00475 switch (NativeCommand(packet_recv.command)) {
00476
00477 case RTK_CMD_REJ:
00478 case RTK_CMD_ACK:
00479 case RTK_CMD_NAK:
00480 resp = 0;
00481 break;
00482 default:
00483 hr = tp_callfunc(NativeCommand(packet_recv.command), packet_recv.data,
00484 packet_recv.len);
00485 resp = 1;
00486 packet_send.command = (SUCCEEDED(hr) ? RTK_CMD_ACK : RTK_CMD_REJ);
00487 packet_send.len = 0;
00488 break;
00489 }
00490
00491
00492 if (resp) {
00493 hr = tp_send(tp_param, packet_send.command, packet_send.data,
00494 packet_send.len);
00495 if (FAILED(hr))
00496 goto exit_proc;
00497 }
00498
00499 if (tmp_state != TP_CONNECT) {
00500
00501 if (NativeCommand(packet_recv.command) == TP_CMD_REQ_ID) {
00502 hr = tp_send(tp_param, TP_CMD_PING, NULL, 0);
00503 } else {
00504
00505 tmp_state = TP_CONNECT;
00506 }
00507 }
00508 }
00509
00510
00511 cur = gettimeofday_msec();
00512 diff = calc_time_diff(tp_param->check_clock, cur);
00513
00514 packet_send.command = _TP_CMD_SPECIAL;
00515 packet_send.len = sizeof(int);
00516
00517 switch (tp_param->flags.state) {
00518 case TP_CONNECT:
00519 switch (tmp_state) {
00520 case TP_CONNECT:
00521 tp_param->flags.state = tmp_state;
00522 tp_param->check_clock = cur;
00523 break;
00524 case TP_TPLESS:
00525 *(int *) packet_send.data = (int) TP_DISCONNECT;
00526 hr = tp_callfunc(packet_send.command, packet_send.data, packet_send.len);
00527 tp_param->flags.state = tmp_state;
00528 tp_param->check_clock = cur;
00529 break;
00530 case TP_TPERROR:
00531 if (diff > _TPERROR_TIMEOUT) {
00532 *(int *) packet_send.data = (int) TP_DISCONNECT;
00533 hr = tp_callfunc(packet_send.command, packet_send.data,
00534 packet_send.len);
00535 tp_param->flags.state = tmp_state;
00536 tp_param->check_clock = cur;
00537 }
00538 break;
00539 default:
00540 break;
00541 }
00542 break;
00543 case TP_TPLESS:
00544 case TP_TPERROR:
00545 switch (tmp_state) {
00546 case TP_CONNECT:
00547 *(int *) packet_send.data = (int) TP_CONNECT;
00548 hr = tp_callfunc(packet_send.command, packet_send.data, packet_send.len);
00549 tp_param->flags.state = tmp_state;
00550 tp_param->check_clock = cur;
00551 break;
00552 case TP_TPLESS:
00553 case TP_TPERROR:
00554 if (diff > _TPLESS_INTERVAL) {
00555 *(int *) packet_send.data = tmp_state;
00556 hr = tp_callfunc(packet_send.command, packet_send.data,
00557 packet_send.len);
00558 tp_param->flags.state = tmp_state;
00559 tp_param->check_clock = cur;
00560 }
00561 break;
00562 default:
00563 break;
00564 }
00565 break;
00566 default:
00567 break;
00568 }
00569
00570 exit_proc:
00571
00572 unlock_mutex(&tp_param->mutex);
00573
00574 return hr;
00575 }
00576
00582 static HRESULT
00583 timer_event(struct CONN_PARAM_TP *tp_param)
00584 {
00585 uint32_t cur, diff;
00586 HRESULT hr;
00587
00588
00589 hr = lock_mutex(&tp_param->mutex, INFINITE);
00590 if (FAILED(hr))
00591 return hr;
00592
00593 if (tp_param->flags.client) {
00594 tp_param->flags.init = 1;
00595
00596
00597 cur = gettimeofday_msec();
00598 diff = calc_time_diff(tp_param->init_clock, cur);
00599 if ((diff > _TP_INIT_WAIT_CLIENT)
00600 && (tp_param->flags.state != TP_CONNECT))
00601 {
00602
00603 hr = tp_send(tp_param, TP_CMD_REQ_ID, NULL, 0);
00604 if (SUCCEEDED(hr))
00605 hr = S_FALSE;
00606
00607 tp_param->init_clock = cur;
00608 }
00609 } else {
00610 if (!tp_param->flags.init) {
00611
00612 cur = gettimeofday_msec();
00613 diff = calc_time_diff(tp_param->init_clock, cur);
00614 if ((diff > _TP_INIT_WAIT_SERVER)
00615 || (tp_param->flags.state == TP_CONNECT))
00616 {
00617
00618 if (tp_param->flags.state != TP_CONNECT) {
00619 hr = tp_send(tp_param, TP_CMD_GET_KEYSTATE, NULL, 0);
00620 }
00621
00622 tp_param->flags.init = 1;
00623 }
00624 } else {
00625
00626 cur = gettimeofday_msec();
00627 diff = calc_time_diff(tp_param->ping_clock, cur);
00628 switch (tp_param->flags.state) {
00629 case TP_CONNECT:
00630 if (diff > _PING_INTERVAL_CONNECT) {
00631 hr = tp_send(tp_param, TP_CMD_PING, NULL, 0);
00632 if (SUCCEEDED(hr))
00633 hr = S_FALSE;
00634 }
00635 break;
00636 case TP_TPERROR:
00637 if (diff > _PING_INTERVAL_TPERROR) {
00638 hr = tp_send(tp_param, TP_CMD_PING, NULL, 0);
00639 if (SUCCEEDED(hr))
00640 hr = S_FALSE;
00641 }
00642 break;
00643 case TP_TPLESS:
00644 break;
00645 default:
00646 break;
00647 }
00648 }
00649 }
00650
00651
00652 unlock_mutex(&tp_param->mutex);
00653
00654 return hr;
00655 }
00656
00662 static THRET THTYPE
00663 recv_thread(void *arg)
00664 {
00665 #if !defined(THRET)
00666 THRET ret = (THRET)NULL;
00667 #endif
00668
00669 uint32_t time_sleep;
00670 struct CONN_PARAM_TP *tp_param = (struct CONN_PARAM_TP *) arg;
00671
00672 tp_param->check_clock = gettimeofday_msec();
00673
00674 while (tp_param->flags.recv_flag) {
00675 time_sleep = (tp_param->flags.state == TP_CONNECT ? 0 : 300);
00676 dn_sleep(time_sleep);
00677
00678 receive_execute(tp_param);
00679
00680 set_event(&tp_param->evt);
00681 dn_sleep(0);
00682 }
00683
00684 set_event(&tp_param->evt);
00685
00686 #if !defined(THRET)
00687 return ret;
00688 #endif
00689 }
00690
00696 static THRET THTYPE
00697 timer_thread(void *arg)
00698 {
00699 #if !defined(THRET)
00700 THRET ret = (THRET)NULL;
00701 #endif
00702
00703 uint32_t cur, diff;
00704 HRESULT hr;
00705 struct CONN_PARAM_TP *tp_param = (struct CONN_PARAM_TP *) arg;
00706
00707 tp_param->init_clock = gettimeofday_msec();
00708
00709 while (tp_param->flags.timer_flag) {
00710
00711 cur = gettimeofday_msec();
00712 diff = calc_time_diff(tp_param->timer_clock, cur);
00713
00714
00715 if (_TIMER_INTERVAL > diff) {
00716 dn_sleep(_TIMER_INTERVAL - diff);
00717 }
00718
00719
00720 tp_param->timer_clock = gettimeofday_msec();
00721
00722 hr = timer_event(tp_param);
00723
00724
00725 if (hr == S_FALSE) {
00726 reset_event(&tp_param->evt);
00727 wait_event(&tp_param->evt, INFINITE);
00728 }
00729 }
00730
00731 #if !defined(THRET)
00732 return ret;
00733 #endif
00734 }
00735
00736 HRESULT
00737 TPComm_SetCallFunc(const struct CALL_FUNC_TP *func)
00738 {
00739 if (func == NULL)
00740 return E_INVALIDARG;
00741
00742 m_call_func = *func;
00743
00744 return S_OK;
00745 }
00746
00747 HRESULT
00748 TPComm_Open(const char *connect, uint32_t timeout, int client, int *pfd)
00749 {
00750 int index, *sock;
00751 HRESULT hr;
00752 void *conn_param;
00753 struct CONN_PARAM_ETH eth_param =
00754 { inet_addr("127.0.0.1"), htons(5007), htonl(INADDR_ANY), 0 };
00755 struct CONN_PARAM_COM com_param =
00756 { 1, 38400, NOPARITY, 8, ONESTOPBIT, 0 };
00757 struct CONN_PARAM_TP *tp_param;
00758 struct CONN_PARAM_COMMON *device;
00759 struct sockaddr_in *paddr;
00760
00761 if (connect == NULL || pfd == NULL)
00762 return E_INVALIDARG;
00763
00764 index = find_open_address();
00765 if (index == 0)
00766 return E_MAX_OBJECT;
00767
00768 tp_param = &m_conn_param[index - 1];
00769 device = &tp_param->device;
00770
00771
00772 device->type = parse_conn_type(connect);
00773 switch (device->type) {
00774 case CONN_UDP:
00775 hr = parse_conn_param_ether(connect, ð_param);
00776 conn_param = ð_param;
00777 paddr = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
00778 if (paddr == NULL) {
00779 hr = E_OUTOFMEMORY;
00780 break;
00781 }
00782 paddr->sin_addr.s_addr = eth_param.dst_addr;
00783 paddr->sin_port = eth_param.dst_port;
00784 paddr->sin_family = AF_INET;
00785 device->arg = (void *) paddr;
00786 device->dn_open = &udp_open;
00787 device->dn_close = &udp_close;
00788 device->dn_send = &udp_send;
00789 device->dn_recv = &udp_recv;
00790 device->dn_set_timeout = &udp_set_timeout;
00791 device->dn_clear = &udp_clear;
00792 break;
00793 case CONN_COM:
00794 hr = parse_conn_param_serial(connect, &com_param);
00795 conn_param = &com_param;
00796 device->arg = NULL;
00797 device->dn_open = &com_open;
00798 device->dn_close = &com_close;
00799 device->dn_send = &com_send;
00800 device->dn_recv = &com_recv;
00801 device->dn_set_timeout = &com_set_timeout;
00802 device->dn_clear = &com_clear;
00803 break;
00804 default:
00805 hr = E_INVALIDARG;
00806 break;
00807 }
00808
00809 if (FAILED(hr)) {
00810 if (device->arg != NULL) {
00811 free(device->arg);
00812 device->arg = NULL;
00813 }
00814 memset(tp_param, 0, sizeof(struct CONN_PARAM_TP));
00815 return hr;
00816 }
00817
00818
00819 hr = initialize_mutex(&tp_param->mutex);
00820 if (FAILED(hr)) {
00821 if (device->arg != NULL) {
00822 free(device->arg);
00823 device->arg = NULL;
00824 }
00825 return hr;
00826 }
00827
00828
00829 hr = create_event(&tp_param->evt, 0, 0);
00830 if (FAILED(hr)) {
00831 release_mutex(&tp_param->mutex);
00832 if (device->arg != NULL) {
00833 free(device->arg);
00834 device->arg = NULL;
00835 }
00836 memset(tp_param, 0, sizeof(struct CONN_PARAM_TP));
00837 return hr;
00838 }
00839
00840
00841 sock = &device->sock;
00842 hr = device->dn_open(conn_param, sock);
00843 if (FAILED(hr)) {
00844 release_mutex(&tp_param->mutex);
00845 destroy_event(&tp_param->evt);
00846 if (device->arg != NULL) {
00847 free(device->arg);
00848 device->arg = NULL;
00849 }
00850 memset(tp_param, 0, sizeof(struct CONN_PARAM_TP));
00851 return hr;
00852 }
00853
00854
00855 hr = TPComm_SetTimeout(index, timeout);
00856 if (FAILED(hr)) {
00857 TPComm_Close(&index);
00858 return hr;
00859 }
00860
00861
00862 tp_param->flags.client = (client ? 1 : 0);
00863 tp_param->flags.init = 0;
00864 tp_param->flags.state = TP_TPLESS;
00865 tp_param->flags.cts = 0;
00866 tp_param->from_id = (client ? TP_ID_CLIENT : TP_ID_SERVER);
00867 tp_param->to_id = TP_ID_CLIENT;
00868
00869
00870 tp_param->timer_clock = tp_param->ping_clock = tp_param->init_clock =
00871 tp_param->check_clock = gettimeofday_msec();
00872
00873
00874 tp_param->flags.timer_flag = 1;
00875 begin_thread(&tp_param->timer_thread, &timer_thread, tp_param);
00876 tp_param->flags.recv_flag = 1;
00877 begin_thread(&tp_param->recv_thread, &recv_thread, tp_param);
00878
00879 *pfd = index;
00880
00881 return S_OK;
00882 }
00883
00884 HRESULT
00885 TPComm_Close(int *pfd)
00886 {
00887 int index, *sock;
00888 struct CONN_PARAM_TP *tp_param;
00889 struct CONN_PARAM_COMMON *device;
00890
00891 if (pfd == NULL)
00892 return E_HANDLE;
00893
00894 index = *pfd;
00895
00896 tp_param = check_address(index);
00897 if (tp_param == NULL)
00898 return E_HANDLE;
00899
00900 device = &tp_param->device;
00901 sock = &device->sock;
00902
00903
00904 tp_param->flags.timer_flag = 0;
00905 exit_thread(tp_param->timer_thread);
00906
00907
00908 tp_param->flags.recv_flag = 0;
00909 exit_thread(tp_param->recv_thread);
00910
00911
00912 destroy_event(&tp_param->evt);
00913
00914
00915 release_mutex(&tp_param->mutex);
00916
00917
00918 device->dn_close(sock);
00919
00920
00921 if (device->arg != NULL) {
00922 free(device->arg);
00923 device->arg = NULL;
00924 }
00925
00926
00927 memset(tp_param, 0, sizeof(struct CONN_PARAM_TP));
00928
00929 *pfd = 0;
00930
00931 return S_OK;
00932 }
00933
00934 HRESULT
00935 TPComm_SetTimeout(int fd, uint32_t timeout)
00936 {
00937 int *sock;
00938 HRESULT hr;
00939 struct CONN_PARAM_TP *tp_param;
00940 struct CONN_PARAM_COMMON *device;
00941
00942 tp_param = check_address(fd);
00943 if (tp_param == NULL)
00944 return E_HANDLE;
00945
00946 device = &tp_param->device;
00947 sock = &device->sock;
00948
00949
00950 hr = lock_mutex(&tp_param->mutex, INFINITE);
00951 if (FAILED(hr))
00952 return hr;
00953
00954 hr = device->dn_set_timeout(*sock, timeout);
00955 if (SUCCEEDED(hr)) {
00956 device->timeout = timeout;
00957 }
00958
00959
00960 unlock_mutex(&tp_param->mutex);
00961
00962 return hr;
00963 }
00964
00965 HRESULT
00966 TPComm_GetTimeout(int fd, uint32_t *timeout)
00967 {
00968 struct CONN_PARAM_TP *tp_param;
00969 struct CONN_PARAM_COMMON *device;
00970
00971 tp_param = check_address(fd);
00972 if (tp_param == NULL)
00973 return E_HANDLE;
00974
00975 if (timeout == NULL)
00976 return E_INVALIDARG;
00977
00978 device = &tp_param->device;
00979 *timeout = device->timeout;
00980
00981 return S_OK;
00982 }
00983
00984 HRESULT
00985 TPComm_GetTPState(int fd, int *state)
00986 {
00987 struct CONN_PARAM_TP *tp_param;
00988
00989 tp_param = check_address(fd);
00990 if (tp_param == NULL)
00991 return E_HANDLE;
00992
00993 if (state == NULL)
00994 return E_INVALIDARG;
00995
00996 *state = tp_param->flags.state;
00997
00998 return S_OK;
00999 }
01000
01001 HRESULT
01002 TPComm_BEEP(int fd, int16_t time)
01003 {
01004 uint8_t data[2];
01005 HRESULT hr;
01006 union RTK_PACKET packet;
01007
01008 memcpy_be(data, &time, 2);
01009
01010 hr = send_receive(fd, TP_RETRY_TIMEOUT, TP_CMD_BEEP, data, 2, &packet.command,
01011 packet.data, &packet.len);
01012
01013 return hr;
01014 }
01015
01016 HRESULT
01017 TPComm_LED(int fd, int16_t number, int16_t state)
01018 {
01019 uint8_t data[2];
01020 uint16_t command;
01021 HRESULT hr;
01022 union RTK_PACKET packet;
01023
01024 switch (state) {
01025 case LED_OFF:
01026 command = TP_CMD_LED_OFF;
01027 break;
01028 case LED_ON:
01029 command = TP_CMD_LED_ON;
01030 break;
01031 case LED_FLASH:
01032 command = TP_CMD_LED_FLASH;
01033 break;
01034 default:
01035 return E_INVALIDARG;
01036 }
01037
01038 memcpy_be(data, &number, 2);
01039
01040 hr = send_receive(fd, TP_RETRY_TIMEOUT, command, data, 2, &packet.command,
01041 packet.data, &packet.len);
01042
01043 return hr;
01044 }
01045
01046 HRESULT
01047 TPComm_LCD(int fd, int16_t contrast)
01048 {
01049 uint8_t data[2];
01050 HRESULT hr;
01051 union RTK_PACKET packet;
01052
01053 memcpy_be(data, &contrast, 2);
01054
01055 hr = send_receive(fd, TP_RETRY_TIMEOUT, TP_CMD_LCD, data, 2, &packet.command,
01056 packet.data, &packet.len);
01057
01058 return hr;
01059 }
01060
01061 HRESULT
01062 TPComm_DrawMiniTP(int fd, VARIANT commands)
01063 {
01064 HRESULT hr;
01065 uint32_t ulPosCmd, ulNumCmd, ulNumPar, ulPosPar, ulPosSub, ulNumSub, ulLenStr,
01066 ulLenCmd;
01067 uint8_t chSub[4], data[248], len_data = 0;
01068 VARIANT *vntCmd, vntPar[2], vntSub[5];
01069 union RTK_PACKET packet;
01070
01071 memset(vntPar, 0, sizeof(vntPar));
01072 memset(vntSub, 0, sizeof(vntSub));
01073
01074 if (commands.vt != (VT_VARIANT | VT_ARRAY)) {
01075 return E_INVALIDARG;
01076 }
01077
01078 ulNumCmd = (int32_t) commands.parray->rgsabound[0].cElements;
01079
01080 SafeArrayAccessData(commands.parray, (void**) &vntCmd);
01081 for (ulPosCmd = 0; ulPosCmd < ulNumCmd; ulPosCmd++) {
01082 if (!(vntCmd[ulPosCmd].vt & VT_ARRAY)) {
01083 hr = E_INVALIDARG;
01084 goto exit_proc;
01085 }
01086
01087 for (ulPosPar = 0; ulPosPar < 2; ulPosPar++) {
01088 VariantClear(&vntPar[ulPosPar]);
01089 }
01090
01091 for (ulPosSub = 0; ulPosSub < 5; ulPosSub++) {
01092 VariantClear(&vntSub[ulPosSub]);
01093 }
01094
01095 ulNumPar = ChangeVarType(vntCmd[ulPosCmd], VT_VARIANT, vntPar, 2);
01096 if (ulNumPar < 2) {
01097 hr = E_INVALIDARG;
01098 goto exit_proc;
01099 }
01100
01101 hr = VariantChangeType(&vntPar[0], &vntPar[0], 0, VT_UI1);
01102 if (FAILED(hr))
01103 goto exit_proc;
01104
01105 switch (vntPar[0].bVal) {
01106 case COLOR_FG:
01107 case COLOR_BG:
01108 case COLOR_FILL:
01109 if (248 < len_data + 3) {
01110 hr = E_OUTOFMEMORY;
01111 goto exit_proc;
01112 }
01113
01114 hr = VariantChangeType(&vntPar[1], &vntPar[1], 0, VT_UI1);
01115 if (FAILED(hr))
01116 goto exit_proc;
01117
01118 data[len_data] = vntPar[0].bVal;
01119 data[len_data + 1] = 0x1;
01120 data[len_data + 2] = vntPar[1].bVal;
01121 len_data += 3;
01122
01123 break;
01124 case DRAW_STRING:
01125 ulNumSub = ChangeVarType(vntPar[1], VT_VARIANT, vntSub, 5);
01126 if (ulNumSub < 5) {
01127 hr = E_INVALIDARG;
01128 goto exit_proc;
01129 }
01130
01131 for (ulPosSub = 0; ulPosSub < 5; ulPosSub++) {
01132 hr = VariantChangeType(&vntSub[ulPosSub], &vntSub[ulPosSub], 0,
01133 (ulPosSub == 0 ? VT_BSTR : VT_UI1));
01134 if (FAILED(hr))
01135 goto exit_proc;
01136 }
01137
01138 ulLenStr = SysStringLen(vntSub[0].bstrVal);
01139 ulLenCmd = ulLenStr * 2 + 5;
01140
01141 if (248 < (len_data + ulLenCmd + 2)) {
01142 hr = E_OUTOFMEMORY;
01143 goto exit_proc;
01144 }
01145
01146 data[len_data] = vntPar[0].bVal;
01147 data[len_data + 1] = (uint8_t) ulLenCmd;
01148 data[len_data + 2] = vntSub[1].bVal;
01149 data[len_data + 3] = vntSub[2].bVal;
01150 data[len_data + 4] = vntSub[3].bVal;
01151 data[len_data + 5] = (uint8_t) ulLenStr;
01152 wcstombs((char*) &data[len_data + 6], vntSub[0].bstrVal, ulLenStr);
01153 data[len_data + ulLenStr + 6] = '\0';
01154 memset(&data[len_data + ulLenStr + 7], vntSub[4].bVal, ulLenStr);
01155 len_data += (uint8_t) (ulLenCmd + 2);
01156
01157 break;
01158 case DRAW_LINE:
01159 case DRAW_RECT:
01160 ulNumSub = ChangeVarType(vntPar[1], VT_UI1, chSub, 4);
01161 if (ulNumSub < 4) {
01162 hr = E_INVALIDARG;
01163 goto exit_proc;
01164 }
01165
01166 if (248 < len_data + 6) {
01167 hr = E_OUTOFMEMORY;
01168 goto exit_proc;
01169 }
01170
01171 data[len_data] = vntPar[0].bVal;
01172 data[len_data + 1] = 0x04;
01173 memcpy(&data[len_data + 2], chSub, 4);
01174 len_data += 6;
01175
01176 break;
01177 default:
01178 hr = E_INVALIDARG;
01179 goto exit_proc;
01180 }
01181 }
01182
01183 if (SUCCEEDED(hr)) {
01184 hr = send_receive(fd, TP_RETRY_TIMEOUT, TP_CMD_MTP_DRAW, data, len_data,
01185 &packet.command, packet.data, &packet.len);
01186 }
01187
01188 exit_proc:
01189 SafeArrayUnaccessData(commands.parray);
01190
01191 for (ulPosPar = 0; ulPosPar < 2; ulPosPar++) {
01192 VariantClear(&vntPar[ulPosPar]);
01193 }
01194
01195 for (ulPosSub = 0; ulPosSub < 5; ulPosSub++) {
01196 VariantClear(&vntSub[ulPosSub]);
01197 }
01198
01199 return hr;
01200 }
01201
01202 HRESULT
01203 TPComm_DrawString(int fd, BSTR bstr, uint8_t pos_x, uint8_t pos_y, uint8_t size,
01204 uint8_t attr, uint8_t color_fg, uint8_t color_bg)
01205 {
01206 HRESULT hr;
01207 uint8_t *bData;
01208 VARIANT vntCmd, *vntPar, *vntSub1, *vntSub2;
01209
01210 VariantInit(&vntCmd);
01211
01212 vntCmd.vt = VT_VARIANT | VT_ARRAY;
01213 vntCmd.parray = SafeArrayCreateVector(VT_VARIANT, 0, 3);
01214 SafeArrayAccessData(vntCmd.parray, (void **) &vntPar);
01215
01216
01217 vntPar[0].vt = VT_UI1 | VT_ARRAY;
01218 vntPar[0].parray = SafeArrayCreateVector(VT_UI1, 0, 2);
01219 SafeArrayAccessData(vntPar[0].parray, (void **) &bData);
01220 bData[0] = COLOR_FG;
01221 bData[1] = color_fg;
01222 SafeArrayUnaccessData(vntPar[0].parray);
01223
01224
01225 vntPar[1].vt = VT_UI1 | VT_ARRAY;
01226 vntPar[1].parray = SafeArrayCreateVector(VT_UI1, 0, 2);
01227 SafeArrayAccessData(vntPar[1].parray, (void **) &bData);
01228 bData[0] = COLOR_BG;
01229 bData[1] = color_bg;
01230 SafeArrayUnaccessData(vntPar[1].parray);
01231
01232
01233 vntPar[2].vt = VT_VARIANT | VT_ARRAY;
01234 vntPar[2].parray = SafeArrayCreateVector(VT_VARIANT, 0, 2);
01235 SafeArrayAccessData(vntPar[2].parray, (void **) &vntSub1);
01236 vntSub1[0].vt = VT_UI1;
01237 vntSub1[0].bVal = DRAW_STRING;
01238 vntSub1[1].vt = VT_VARIANT | VT_ARRAY;
01239 vntSub1[1].parray = SafeArrayCreateVector(VT_VARIANT, 0, 5);
01240 SafeArrayAccessData(vntSub1[1].parray, (void **) &vntSub2);
01241 vntSub2[0].vt = VT_BSTR;
01242 vntSub2[0].bstrVal = SysAllocString(bstr);
01243 vntSub2[1].vt = VT_UI1;
01244 vntSub2[1].bVal = pos_x;
01245 vntSub2[2].vt = VT_UI1;
01246 vntSub2[2].bVal = pos_y;
01247 vntSub2[3].vt = VT_UI1;
01248 vntSub2[3].bVal = size;
01249 vntSub2[4].vt = VT_UI1;
01250 vntSub2[4].bVal = attr;
01251 SafeArrayUnaccessData(vntSub1[1].parray);
01252 SafeArrayUnaccessData(vntPar[2].parray);
01253
01254 SafeArrayUnaccessData(vntCmd.parray);
01255
01256 hr = TPComm_DrawMiniTP(fd, vntCmd);
01257
01258 VariantClear(&vntCmd);
01259
01260 return hr;
01261 }
01262
01263 HRESULT
01264 TPComm_DrawLine(int fd, uint8_t start_x, uint8_t start_y, uint8_t end_x,
01265 uint8_t end_y, uint8_t color_fg)
01266 {
01267 HRESULT hr;
01268 uint8_t *bData;
01269 VARIANT vntCmd, *vntPar, *vntSub1;
01270
01271 VariantInit(&vntCmd);
01272
01273 vntCmd.vt = VT_VARIANT | VT_ARRAY;
01274 vntCmd.parray = SafeArrayCreateVector(VT_VARIANT, 0, 2);
01275 SafeArrayAccessData(vntCmd.parray, (void **) &vntPar);
01276
01277
01278 vntPar[0].vt = VT_UI1 | VT_ARRAY;
01279 vntPar[0].parray = SafeArrayCreateVector(VT_UI1, 0, 2);
01280 SafeArrayAccessData(vntPar[0].parray, (void **) &bData);
01281 bData[0] = COLOR_FG;
01282 bData[1] = color_fg;
01283 SafeArrayUnaccessData(vntPar[0].parray);
01284
01285
01286 vntPar[1].vt = VT_VARIANT | VT_ARRAY;
01287 vntPar[1].parray = SafeArrayCreateVector(VT_VARIANT, 0, 2);
01288 SafeArrayAccessData(vntPar[1].parray, (void **) &vntSub1);
01289 vntSub1[0].vt = VT_UI1;
01290 vntSub1[0].bVal = DRAW_LINE;
01291 vntSub1[1].vt = VT_UI1 | VT_ARRAY;
01292 vntSub1[1].parray = SafeArrayCreateVector(VT_UI1, 0, 4);
01293 SafeArrayAccessData(vntSub1[1].parray, (void **) &bData);
01294 bData[0] = start_x;
01295 bData[1] = start_y;
01296 bData[2] = end_x;
01297 bData[3] = end_y;
01298 SafeArrayUnaccessData(vntSub1[1].parray);
01299 SafeArrayUnaccessData(vntPar[1].parray);
01300
01301 SafeArrayUnaccessData(vntCmd.parray);
01302
01303 hr = TPComm_DrawMiniTP(fd, vntCmd);
01304
01305 VariantClear(&vntCmd);
01306
01307 return hr;
01308 }
01309
01310 HRESULT
01311 TPComm_DrawRectangle(int fd, uint8_t start_x, uint8_t start_y, uint8_t end_x,
01312 uint8_t end_y, uint8_t color_fg, uint8_t color_bg)
01313 {
01314 HRESULT hr;
01315 uint8_t *bData;
01316 VARIANT vntCmd, *vntPar, *vntSub1;
01317
01318 VariantInit(&vntCmd);
01319
01320 vntCmd.vt = VT_VARIANT | VT_ARRAY;
01321 vntCmd.parray = SafeArrayCreateVector(VT_VARIANT, 0, 3);
01322 SafeArrayAccessData(vntCmd.parray, (void **) &vntPar);
01323
01324
01325 vntPar[0].vt = VT_UI1 | VT_ARRAY;
01326 vntPar[0].parray = SafeArrayCreateVector(VT_UI1, 0, 2);
01327 SafeArrayAccessData(vntPar[0].parray, (void **) &bData);
01328 bData[0] = COLOR_FG;
01329 bData[1] = color_fg;
01330 SafeArrayUnaccessData(vntPar[0].parray);
01331
01332
01333 vntPar[1].vt = VT_UI1 | VT_ARRAY;
01334 vntPar[1].parray = SafeArrayCreateVector(VT_UI1, 0, 2);
01335 SafeArrayAccessData(vntPar[1].parray, (void **) &bData);
01336 bData[0] = COLOR_BG;
01337 bData[1] = color_bg;
01338 SafeArrayUnaccessData(vntPar[1].parray);
01339
01340
01341 vntPar[2].vt = VT_VARIANT | VT_ARRAY;
01342 vntPar[2].parray = SafeArrayCreateVector(VT_VARIANT, 0, 2);
01343 SafeArrayAccessData(vntPar[2].parray, (void **) &vntSub1);
01344 vntSub1[0].vt = VT_UI1;
01345 vntSub1[0].bVal = DRAW_RECT;
01346 vntSub1[1].vt = VT_UI1 | VT_ARRAY;
01347 vntSub1[1].parray = SafeArrayCreateVector(VT_UI1, 0, 4);
01348 SafeArrayAccessData(vntSub1[1].parray, (void **) &bData);
01349 bData[0] = start_x;
01350 bData[1] = start_y;
01351 bData[2] = end_x;
01352 bData[3] = end_y;
01353 SafeArrayUnaccessData(vntSub1[1].parray);
01354 SafeArrayUnaccessData(vntPar[2].parray);
01355
01356 SafeArrayUnaccessData(vntCmd.parray);
01357
01358 hr = TPComm_DrawMiniTP(fd, vntCmd);
01359
01360 VariantClear(&vntCmd);
01361
01362 return hr;
01363 }