dn_tpcomm.c
Go to the documentation of this file.
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   /* If the function is not implemented, then returns E_NOTIMPL.  */
00200   HRESULT hr = E_NOTIMPL;
00201 
00202   /* Copies call back functions */
00203   struct CALL_FUNC_TP func = m_call_func;
00204 
00205   switch (command) {
00206     case _TP_CMD_SPECIAL: /* Changes TP state */
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: /* Received request ID command */
00216       hr = S_OK;
00217       break;
00218 
00219     case TP_CMD_KEYINFO: /* Received key information command */
00220       if (len_data == 8) {
00221         param = malloc(sizeof(struct TP_KEY_INFO));
00222         if (param != NULL) {
00223           /* Maps the received data to TP_KEY_INFO */
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: /* Received touch information command */
00236       if (len_data == 5) {
00237         param = malloc(sizeof(struct TP_TOUCH_INFO));
00238         if (param != NULL) {
00239           /* Maps the received data to TP_TOUCH_INFO */
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       /* Keeps the last sent packet and updates the last send time. */
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       /* If the CTS bit is off then changes TP state to TP_LESS */
00336       if (com_state & COM_BITS_CTS) { /* CTS bit is on  */
00337         /* If the previous CTS bit is off then clears temporary buffers. */
00338         if (!tp_param->flags.cts) {
00339           device->dn_clear(device->sock, device->timeout);
00340         }
00341         tp_param->flags.cts = 1;
00342       } else { /* CTS bit is off */
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     /* If received NAK packet then sends the last sent packet. */
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       /* Updates the receiver ID. */
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   /* Locks mutex and must not returns this function without end of one. */
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     /* If the timeout retry count is more than 0, then sets retry flag and counts. */
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   /* Unlocks mutex */
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   /* Locks mutex and must not returns this function without end of one. */
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     /* Updates temporary TP state. */
00468     if (hr == E_ACCESSDENIED) {
00469       tmp_state = TP_TPLESS;
00470     } else {
00471       tmp_state = TP_TPERROR;
00472     }
00473   } else {
00474     /* Executes callback functions. */
00475     switch (NativeCommand(packet_recv.command)) {
00476       /* If the received ROBOTalk command is not executable then do nothing. */
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     /* Responds the result of callback functions */
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       /* If received the request ID command, then responds another command. */
00501       if (NativeCommand(packet_recv.command) == TP_CMD_REQ_ID) {
00502         hr = tp_send(tp_param, TP_CMD_PING, NULL, 0);
00503       } else {
00504         /* If received the another command, then changes temporary TP state. */
00505         tmp_state = TP_CONNECT;
00506       }
00507     }
00508   }
00509 
00510   /* Updates TP state */
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   /* Unlocks mutex */
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   /* Locks mutex and must not returns this function without end of one. */
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     /* Sends request ID command until receiving ACK packet */
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; /* Waits receiving thread */
00606 
00607       tp_param->init_clock = cur;
00608     }
00609   } else {
00610     if (!tp_param->flags.init) {
00611       /* Waits until connecting */
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       /* Sends ping packet */
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; /* Waits receiving thread */
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; /* Waits receiving thread */
00641           }
00642           break;
00643         case TP_TPLESS:
00644           break;
00645         default:
00646           break;
00647       }
00648     }
00649   }
00650 
00651   /* Unlocks mutex */
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     /* Calculates time difference */
00711     cur = gettimeofday_msec();
00712     diff = calc_time_diff(tp_param->timer_clock, cur);
00713 
00714     /* Makes timer interval */
00715     if (_TIMER_INTERVAL > diff) {
00716       dn_sleep(_TIMER_INTERVAL - diff);
00717     }
00718 
00719     /* Sets last event time */
00720     tp_param->timer_clock = gettimeofday_msec();
00721 
00722     hr = timer_event(tp_param);
00723 
00724     /* Waits receiving thread */
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   /* Initializes connection parameters */
00772   device->type = parse_conn_type(connect);
00773   switch (device->type) {
00774     case CONN_UDP:
00775       hr = parse_conn_param_ether(connect, &eth_param);
00776       conn_param = &eth_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   /* Initializes mutex */
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   /* Initializes event */
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   /* Opens connection */
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   /* Sets timeout */
00855   hr = TPComm_SetTimeout(index, timeout);
00856   if (FAILED(hr)) {
00857     TPComm_Close(&index);
00858     return hr;
00859   }
00860 
00861   /* Sets parameters */
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   /* Sets initialize time */
00870   tp_param->timer_clock = tp_param->ping_clock = tp_param->init_clock =
00871       tp_param->check_clock = gettimeofday_msec();
00872 
00873   /* Begins thread */
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   /* Ends timer thread first */
00904   tp_param->flags.timer_flag = 0;
00905   exit_thread(tp_param->timer_thread);
00906 
00907   /* Ends receive thread second */
00908   tp_param->flags.recv_flag = 0;
00909   exit_thread(tp_param->recv_thread);
00910 
00911   /* Destroys event */
00912   destroy_event(&tp_param->evt);
00913 
00914   /* Releases mutex */
00915   release_mutex(&tp_param->mutex);
00916 
00917   /* Closes connection */
00918   device->dn_close(sock);
00919 
00920   /* Releases argument */
00921   if (device->arg != NULL) {
00922     free(device->arg);
00923     device->arg = NULL;
00924   }
00925 
00926   /* Resets connection parameters */
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   /* Locks mutex and must not returns this function without end of one. */
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   /* Unlocks mutex */
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   // Sets COLOR_FG
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   // Sets COLOR_BG
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   // Sets DRAW_STRING
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   // Sets COLOR_FG
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   // Sets DRAW_LINE
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   // Sets COLOR_FG
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   // Sets COLOR_BG
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   // Sets DRAW_RECT
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 }


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