dn_tcp.c
Go to the documentation of this file.
00001 
00025 #include "stdint.h"
00026 #include <string.h>
00027 
00028 #if defined(_USE_WIN_API)
00029 #include <winsock2.h>
00030 #include <mstcpip.h>
00031 #pragma comment(lib, "wsock32.lib")
00032 #elif defined(_USE_LINUX_API)
00033 #include <arpa/inet.h>
00034 #include <errno.h>
00035 #include <fcntl.h>
00036 #include <netinet/tcp.h>
00037 #include <sys/socket.h>
00038 #else
00039 #include "dn_additional.h"
00040 #endif
00041 
00042 #include "dn_common.h"
00043 #include "dn_device.h"
00044 #include "dn_socket.h"
00045 #include "dn_tcp.h"
00046 
00047 uint32_t tcp_conn_timeout;
00048 
00049 #if defined(_USE_WIN_API)
00050 static HRESULT _tcp_set_keepalive(int sock, int enable, uint32_t idle, uint32_t interval, uint32_t count)
00051 {
00052   int ret;
00053   DWORD dwBytes;
00054   struct tcp_keepalive stParameter =
00055     { 0}, stReturned =
00056     { 0};
00057 
00058   stParameter.onoff = (enable != 0) ? 1: 0;
00059   stParameter.keepalivetime = (idle == 0) ? 1 : (idle * 1000);
00060   stParameter.keepaliveinterval = interval * 1000;
00061   ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &stParameter, sizeof(stParameter), &stReturned, sizeof(stReturned), &dwBytes, NULL, NULL);
00062 
00063   return (ret == SOCKET_ERROR) ? OSERR2HRESULT(ret) : S_OK;
00064 }
00065 #elif defined(_USE_LINUX_API)
00066 static HRESULT _tcp_set_keepalive(int sock, int enable, uint32_t idle, uint32_t interval, uint32_t count)
00067 {
00068   int ret;
00069 
00070   enable = (enable != 0) ? 1: 0;
00071   ret = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&enable, sizeof(enable));
00072   if(ret < 0) {
00073     ret = DNGetLastError();
00074     return OSERR2HRESULT(ret);
00075   }
00076 
00077   idle = (idle == 0) ? 1 : idle;
00078   ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&idle, sizeof(idle));
00079   if(ret < 0) {
00080     ret = DNGetLastError();
00081     return OSERR2HRESULT(ret);
00082   }
00083 
00084   ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&interval, sizeof(interval));
00085   if(ret < 0) {
00086     ret = DNGetLastError();
00087     return OSERR2HRESULT(ret);
00088   }
00089 
00090   ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (char *)&count, sizeof(count));
00091   if(ret < 0) {
00092     ret = DNGetLastError();
00093     return OSERR2HRESULT(ret);
00094   }
00095 
00096   return S_OK;
00097 }
00098 #endif
00099 
00106 HRESULT
00107 tcp_open_client(void *param, int *sock)
00108 {
00109   int ret;
00110   HRESULT hr;
00111   struct sockaddr_in server;
00112   const struct CONN_PARAM_ETH *eth_param = (const struct CONN_PARAM_ETH *) param;
00113 #if defined(_USE_WIN_API)
00114   WSAEVENT connevt = NULL;
00115   WSANETWORKEVENTS events;
00116 #else
00117   int funcval = 0;
00118   fd_set fds;
00119   struct timeval tv;
00120 #endif
00121 
00122   if (param == NULL || sock == NULL) {
00123     hr = E_INVALIDARG;
00124     goto exit_proc;
00125   }
00126 
00127   hr = socket_open(SOCK_STREAM, sock);
00128   if (FAILED(hr)) {
00129     goto exit_proc;
00130   }
00131 
00132   memset(&server, 0, sizeof(server));
00133   server.sin_addr.s_addr = eth_param->dst_addr;
00134   server.sin_port = eth_param->dst_port;
00135   server.sin_family = AF_INET;
00136 
00137   if(tcp_conn_timeout > 0) {
00138 #if defined(_USE_WIN_API)
00139     connevt = WSACreateEvent();
00140     if(connevt == WSA_INVALID_EVENT) {
00141       hr = OSERR2HRESULT(WSAGetLastError());
00142       goto exit_proc;
00143     }
00144     ret = WSAEventSelect(*sock, connevt, FD_CONNECT);
00145     if(ret == SOCKET_ERROR) {
00146       hr = OSERR2HRESULT(WSAGetLastError());
00147       goto exit_proc;
00148     }
00149 #else
00150     funcval = fcntl(*sock, F_GETFL, 0);
00151     if(funcval < 0) {
00152       hr = OSERR2HRESULT(DNGetLastError());
00153       goto exit_proc;
00154     }
00155     ret = fcntl(*sock, F_SETFL, funcval | O_NONBLOCK);
00156     if(ret < 0) {
00157       hr = OSERR2HRESULT(DNGetLastError());
00158       goto exit_proc;
00159     }
00160 #endif
00161   }
00162 
00163   ret = connect(*sock, (struct sockaddr *) &server, sizeof(server));
00164   if (ret < 0) {
00165 #if defined(_USE_WIN_API)
00166     ret = WSAGetLastError();
00167     if(ret != WSAEWOULDBLOCK) {
00168       hr = OSERR2HRESULT(ret);
00169       goto exit_proc;
00170     }
00171 
00172     ret = WSAWaitForMultipleEvents(1, &connevt,
00173         FALSE, tcp_conn_timeout, FALSE);
00174     if (ret != WSA_WAIT_EVENT_0) {
00175       if (ret == WSA_WAIT_TIMEOUT) {
00176         hr = E_TIMEOUT;
00177       } else {
00178         hr = OSERR2HRESULT(WSAGetLastError());
00179       }
00180       goto exit_proc;
00181     }
00182 
00183     ret = WSAEnumNetworkEvents(*sock, connevt, &events);
00184     if (ret == SOCKET_ERROR) {
00185       hr = OSERR2HRESULT(WSAGetLastError());
00186       goto exit_proc;
00187     }
00188     if (!(events.lNetworkEvents & FD_CONNECT)) {
00189       hr = E_FAIL;
00190       goto exit_proc;
00191     }
00192     if (events.iErrorCode[FD_CONNECT_BIT] != 0) {
00193       hr = OSERR2HRESULT(events.iErrorCode[FD_CONNECT_BIT]);
00194       goto exit_proc;
00195     }
00196 #else
00197     ret = DNGetLastError();
00198     if (ret != EINPROGRESS) {
00199       hr = OSERR2HRESULT(ret);
00200       goto exit_proc;
00201     }
00202 
00203     FD_ZERO(&fds);
00204     FD_SET(*sock, &fds);
00205 
00206     tv.tv_sec = tcp_conn_timeout / 1000;
00207     tv.tv_usec = (tcp_conn_timeout % 1000) * 1000;
00208 
00209     ret = select(*sock + 1, NULL, &fds, NULL, &tv);
00210     if (ret == 0) {
00211       hr = E_TIMEOUT;
00212       goto exit_proc;
00213     }
00214     else if (ret < 0) {
00215       ret = DNGetLastError();
00216       hr = OSERR2HRESULT(ret);
00217       goto exit_proc;
00218     }
00219 #endif
00220   }
00221 
00222 exit_proc:
00223   if((sock != NULL) && (*sock != 0)) {
00224 #if defined(_USE_WIN_API)
00225     DWORD dwTemp = 0;
00226     WSAEventSelect(*sock, NULL, 0);
00227     ioctlsocket(*sock, FIONBIO, &dwTemp);
00228 
00229     if(connevt != NULL) {
00230       WSACloseEvent(connevt);
00231     }
00232 #else
00233     fcntl(*sock, F_SETFL, funcval & ~O_NONBLOCK);
00234 #endif
00235 
00236     if(FAILED(hr)) {
00237       socket_close(sock);
00238     }
00239   }
00240 
00241   /* Reset connection timeout */
00242   tcp_conn_timeout = 0;
00243 
00244   return hr;
00245 }
00246 
00253 HRESULT
00254 tcp_open_server(void *param, int *sock)
00255 {
00256   int ret, flag;
00257   HRESULT hr;
00258   const struct CONN_PARAM_ETH *eth_param = (const struct CONN_PARAM_ETH *) param;
00259 
00260   if (param == NULL || sock == NULL)
00261     return E_INVALIDARG;
00262 
00263   if (eth_param->src_port == 0)
00264     return E_INVALIDARG;
00265 
00266   hr = socket_open(SOCK_STREAM, sock);
00267   if (FAILED(hr))
00268     return hr;
00269 
00270   /* Sets reuse address option */
00271   flag = 1;
00272   ret = setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &flag,
00273       sizeof(flag));
00274   if (ret < 0) {
00275     ret = DNGetLastError();
00276     socket_close(sock);
00277     return OSERR2HRESULT(ret);
00278   }
00279 
00280   /* Binds the created socket */
00281   hr = socket_bind(eth_param, sock);
00282   if (FAILED(hr)) {
00283     socket_close(sock);
00284     return hr;
00285   }
00286 
00287   if (SUCCEEDED(hr)) {
00288     ret = listen(*sock, 1);
00289     if (ret < 0) {
00290       ret = DNGetLastError();
00291       socket_close(sock);
00292       hr = OSERR2HRESULT(ret);
00293     }
00294   }
00295 
00296   return hr;
00297 }
00298 
00304 HRESULT
00305 tcp_close(int *sock)
00306 {
00307   return socket_close(sock);
00308 }
00309 
00318 HRESULT
00319 tcp_send(int sock, const char *buf, uint32_t len_buf, void *arg)
00320 {
00321   int ret, flag = 0;
00322   uint32_t len_send, len_sended;
00323 
00324   if (sock <= 0)
00325     return E_HANDLE;
00326   if (buf == NULL || strlen(buf) == 0)
00327     return E_INVALIDARG;
00328 
00329 #ifdef MSG_NOSIGNAL
00330   flag |= MSG_NOSIGNAL;
00331 #endif
00332 
00333   if (arg != NULL) {
00334     flag |= *(int *) arg;
00335   }
00336 
00337   len_send = (len_buf != 0) ? len_buf : strlen(buf);
00338 
00339   ret = send(sock, buf, len_send, flag);
00340   len_sended = ret;
00341 
00342   if (ret < 0) {
00343     ret = DNGetLastError();
00344     return OSERR2HRESULT(ret);
00345   }
00346 
00347   if (len_send > len_sended) {
00348     return E_TIMEOUT;
00349   }
00350 
00351   return S_OK;
00352 }
00353 
00363 HRESULT
00364 tcp_recv(int sock, char *buf, uint32_t len_buf, uint32_t *len_recved,
00365     uint32_t timeout, void *arg)
00366 {
00367   int ret, flag = 0;
00368   HRESULT hr;
00369 
00370   if (sock <= 0)
00371     return E_HANDLE;
00372   if (buf == NULL || len_recved == NULL)
00373     return E_INVALIDARG;
00374 
00375   if (arg != NULL) {
00376     flag |= *(int *) arg;
00377   }
00378 
00379   hr = check_timeout(sock, timeout);
00380   if (FAILED(hr))
00381     return hr;
00382 
00383   ret = recv(sock, buf, len_buf, flag);
00384   *len_recved = ret;
00385 
00386   if (ret < 0) {
00387     ret = DNGetLastError();
00388     return OSERR2HRESULT(ret);
00389   }
00390 
00391   if (*len_recved == 0) {
00392     return E_ACCESSDENIED;
00393   }
00394 
00395   return S_OK;
00396 }
00397 
00404 HRESULT
00405 tcp_set_timeout(int sock, uint32_t timeout)
00406 {
00407   return socket_set_timeout(sock, timeout);
00408 }
00409 
00416 HRESULT
00417 tcp_clear(int sock, uint32_t timeout)
00418 {
00419   uint32_t len_recv = DEV_BUF_MAX, len_recved;
00420   char buf_tmp[DEV_BUF_MAX];
00421   HRESULT hr;
00422 
00423   if (sock <= 0)
00424     return E_HANDLE;
00425 
00426   hr = tcp_set_timeout(sock, 0);
00427   if (FAILED(hr))
00428     return hr;
00429 
00430   do {
00431     hr = tcp_recv(sock, buf_tmp, len_recv, &len_recved, 0, NULL);
00432   } while (SUCCEEDED(hr));
00433 
00434   hr = tcp_set_timeout(sock, timeout);
00435 
00436   return hr;
00437 }
00438 
00447 HRESULT
00448 tcp_accept(int sock, int *client)
00449 {
00450   int ret;
00451   extern int socket_counter;
00452   HRESULT hr;
00453 
00454   if (sock <= 0)
00455     return E_HANDLE;
00456   if (client == NULL)
00457     return E_INVALIDARG;
00458 
00459   hr = check_timeout(sock, 0);
00460   if (FAILED(hr))
00461     return hr;
00462 
00463   *client = accept(sock, NULL, NULL);
00464   if (*client < 0) {
00465     *client = 0;
00466     ret = DNGetLastError();
00467     return OSERR2HRESULT(ret);
00468   }
00469 
00470   socket_counter++;
00471 
00472   return hr;
00473 }
00474 
00484 HRESULT
00485 tcp_set_keepalive(int sock, int enable, uint32_t idle, uint32_t interval,
00486     uint32_t count)
00487 {
00488   if (sock <= 0)
00489     return E_HANDLE;
00490   return _tcp_set_keepalive(sock, enable, idle, interval, count);
00491 }
00492 
00499 HRESULT
00500 tcp_set_nodelay(int sock, int enable)
00501 {
00502   int ret;
00503 
00504   if (sock <= 0)
00505     return E_HANDLE;
00506 
00507   enable = (enable != 0) ? 1 : 0;
00508   ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &enable,
00509       sizeof(enable));
00510   if (ret < 0) {
00511     ret = DNGetLastError();
00512     return OSERR2HRESULT(ret);
00513   }
00514 
00515   return S_OK;
00516 }


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