#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include "pi-debug.h"
#include "pi-source.h"
#include "pi-inet.h"
#include "pi-cmp.h"
#include "pi-net.h"
Include dependency graph for inet.c:

Go to the source code of this file.
Functions | |
| static void | pi_inet_device_free (pi_device_t *dev) |
| static pi_protocol_t * | pi_inet_protocol (pi_device_t *dev) |
| static pi_protocol_t * | pi_inet_protocol_dup (pi_protocol_t *prot) |
| static void | pi_inet_protocol_free (pi_protocol_t *prot) |
| static int | pi_inet_close (pi_socket_t *ps) |
| static int | pi_inet_connect (pi_socket_t *ps, struct sockaddr *addr, size_t addrlen) |
| static int | pi_inet_bind (pi_socket_t *ps, struct sockaddr *addr, size_t addrlen) |
| static int | pi_inet_listen (pi_socket_t *ps, int backlog) |
| static int | pi_inet_accept (pi_socket_t *ps, struct sockaddr *addr, size_t *addrlen) |
| static ssize_t | pi_inet_read (pi_socket_t *ps, pi_buffer_t *msg, size_t len, int flags) |
| static ssize_t | pi_inet_write (pi_socket_t *ps, const unsigned char *msg, size_t len, int flags) |
| static int | pi_inet_getsockopt (pi_socket_t *ps, int level, int option_name, void *option_value, size_t *option_len) |
| static int | pi_inet_setsockopt (pi_socket_t *ps, int level, int option_name, const void *option_value, size_t *option_len) |
| static int | pi_inet_flush (pi_socket_t *ps, int flags) |
| int | pi_socket_init (pi_socket_t *ps) |
| pi_device_t * | pi_inet_device (int type) |
| static int pi_inet_accept | ( | pi_socket_t * | ps, | |
| struct sockaddr * | addr, | |||
| size_t * | addrlen | |||
| ) | [static] |
Definition at line 329 of file inet.c.
References pi_socket::cmd, CMP_FL_LONG_PACKET_SUPPORT, cmp_rx_handshake(), pi_socket::command, pi_socket::dlprecord, fail(), LOG, net_rx_handshake(), PI_CMD_CMP, PI_CMD_NET, PI_CMP_FLAGS, PI_DBG_DEV, PI_DBG_LVL_INFO, PI_ERR_GENERIC_SYSTEM, pi_getsockopt(), PI_LEVEL_CMP, PI_LEVEL_NET, PI_LEVEL_PADP, PI_NET_SPLIT_WRITES, PI_NET_WRITE_CHUNKSIZE, PI_PADP_USE_LONG_FORMAT, pi_set_error(), pi_setsockopt(), PI_SOCK_CONN_ACCEPT, pi_socket_init(), pi_socket_setsd(), pi_socket::sd, sd, size, and pi_socket::state.
Referenced by pi_inet_device().
00330 { 00331 int sd, 00332 err, 00333 split = 0, 00334 chunksize = 0; 00335 size_t len, 00336 size; 00337 pl_socklen_t l = 0; 00338 unsigned char cmp_flags; 00339 00340 if (addrlen) 00341 l = *addrlen; 00342 sd = accept(ps->sd, addr, &l); 00343 if (addrlen) 00344 *addrlen = l; 00345 if (sd < 0) { 00346 pi_set_error(ps->sd, sd); 00347 err = PI_ERR_GENERIC_SYSTEM; 00348 goto fail; 00349 } 00350 00351 pi_socket_setsd(ps, sd); 00352 pi_socket_init(ps); 00353 00354 switch (ps->cmd) { 00355 case PI_CMD_CMP: 00356 if ((err = cmp_rx_handshake(ps, 57600, 0)) < 0) 00357 goto fail; 00358 00359 /* propagate the long packet format flag to both command and non-command stacks */ 00360 size = sizeof(cmp_flags); 00361 pi_getsockopt(ps->sd, PI_LEVEL_CMP, PI_CMP_FLAGS, &cmp_flags, &size); 00362 if (cmp_flags & CMP_FL_LONG_PACKET_SUPPORT) { 00363 int use_long_format = 1; 00364 size = sizeof(int); 00365 pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT, 00366 &use_long_format, &size); 00367 ps->command ^= 1; 00368 pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT, 00369 &use_long_format, &size); 00370 ps->command ^= 1; 00371 } 00372 00373 break; 00374 case PI_CMD_NET: 00375 /* network: make sure we don't split writes. set socket option 00376 * on both the command and non-command instances of the protocol 00377 */ 00378 len = sizeof (split); 00379 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES, 00380 &split, &len); 00381 len = sizeof (chunksize); 00382 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE, 00383 &chunksize, &len); 00384 00385 ps->command ^= 1; 00386 len = sizeof (split); 00387 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES, 00388 &split, &len); 00389 len = sizeof (chunksize); 00390 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE, 00391 &chunksize, &len); 00392 ps->command ^= 1; 00393 00394 if ((err = net_rx_handshake(ps)) < 0) 00395 goto fail; 00396 break; 00397 } 00398 00399 ps->state = PI_SOCK_CONN_ACCEPT; 00400 ps->command = 0; 00401 ps->dlprecord = 0; 00402 00403 LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV INET ACCEPT accepted\n")); 00404 00405 return ps->sd; 00406 00407 fail: 00408 return err; 00409 }
Here is the call graph for this function:

| static int pi_inet_bind | ( | pi_socket_t * | ps, | |
| struct sockaddr * | addr, | |||
| size_t | addrlen | |||
| ) | [static] |
Definition at line 171 of file inet.c.
References LOG, PI_DBG_DEV, PI_DBG_LVL_ERR, PI_DBG_LVL_INFO, pi_sockaddr::pi_device, PI_ERR_GENERIC_SYSTEM, pi_set_error(), pi_socket_setsd(), port, pi_socket::sd, and sd.
Referenced by pi_inet_device().
00172 { 00173 int opt, 00174 sd, 00175 err; 00176 size_t optlen; 00177 struct pi_sockaddr *paddr = (struct pi_sockaddr *) addr; 00178 struct sockaddr_in serv_addr; 00179 char *device = paddr->pi_device, 00180 *port = NULL; 00181 00182 /* Figure out the addresses to allow */ 00183 memset(&serv_addr, 0, sizeof(serv_addr)); 00184 serv_addr.sin_family = AF_INET; 00185 if (strlen(device) > 1 && strncmp(device, "any", 3)) { 00186 serv_addr.sin_addr.s_addr = inet_addr(device); 00187 if (serv_addr.sin_addr.s_addr == (in_addr_t)-1) { 00188 struct hostent *hostent = gethostbyname(device); 00189 00190 if (!hostent) 00191 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00192 00193 memcpy((char *) &serv_addr.sin_addr.s_addr, 00194 hostent->h_addr, (size_t)hostent->h_length); 00195 } 00196 } else { 00197 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 00198 } 00199 if ((port = strchr(device, ':')) != NULL) { 00200 serv_addr.sin_port = htons(atoi(++port)); 00201 } else { 00202 serv_addr.sin_port = htons(14238); 00203 } 00204 00205 sd = socket(AF_INET, SOCK_STREAM, 0); 00206 if (sd < 0) { 00207 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, 00208 "DEV BIND Inet: Unable to create socket\n")); 00209 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00210 } 00211 if ((err = pi_socket_setsd (ps, sd)) < 0) 00212 return err; 00213 00214 opt = 1; 00215 optlen = sizeof(opt); 00216 00217 if (setsockopt(ps->sd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, 00218 (int)optlen) < 0) { 00219 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00220 } 00221 00222 if (bind(ps->sd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 00223 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00224 00225 LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, 00226 "DEV BIND Inet Bound to %s\n", device)); 00227 00228 ps->raddr = malloc(addrlen); 00229 memcpy(ps->raddr, addr, addrlen); 00230 ps->raddrlen = addrlen; 00231 ps->laddr = malloc(addrlen); 00232 memcpy(ps->laddr, addr, addrlen); 00233 ps->laddrlen = addrlen; 00234 00235 return 0; 00236 }
Here is the call graph for this function:

| static int pi_inet_close | ( | pi_socket_t * | ps | ) | [static] |
Definition at line 412 of file inet.c.
References pi_socket::laddr, pi_socket::raddr, and pi_socket::sd.
Referenced by pi_inet_device().
00413 { 00414 if (ps->sd) { 00415 close(ps->sd); 00416 ps->sd = 0; 00417 } 00418 if (ps->laddr) { 00419 free(ps->laddr); 00420 ps->laddr = NULL; 00421 } 00422 if (ps->raddr) { 00423 free(ps->raddr); 00424 ps->raddr = NULL; 00425 } 00426 return 0; 00427 }
| static int pi_inet_connect | ( | pi_socket_t * | ps, | |
| struct sockaddr * | addr, | |||
| size_t | addrlen | |||
| ) | [static] |
Definition at line 239 of file inet.c.
References cmp_tx_handshake(), fail(), LOG, net_tx_handshake(), PI_CMD_CMP, PI_CMD_NET, PI_DBG_DEV, PI_DBG_LVL_ERR, PI_DBG_LVL_INFO, pi_sockaddr::pi_device, PI_ERR_GENERIC_SYSTEM, pi_set_error(), PI_SOCK_CONN_INIT, pi_socket_setsd(), pi_socket::sd, and sd.
Referenced by pi_inet_device().
00240 { 00241 int sd, 00242 err; 00243 00244 struct pi_sockaddr *paddr = (struct pi_sockaddr *) addr; 00245 struct sockaddr_in serv_addr; 00246 char *device = paddr->pi_device; 00247 00248 /* Figure out the addresses to allow */ 00249 memset(&serv_addr, 0, sizeof(serv_addr)); 00250 serv_addr.sin_family = AF_INET; 00251 if (strlen(device) > 1) { 00252 serv_addr.sin_addr.s_addr = inet_addr(device); 00253 if (serv_addr.sin_addr.s_addr == (in_addr_t)-1) { 00254 struct hostent *hostent = gethostbyname(device); 00255 00256 if (!hostent) { 00257 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, 00258 "DEV CONNECT Inet: Unable" 00259 " to determine host\n")); 00260 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00261 } 00262 00263 memcpy((char *) &serv_addr.sin_addr.s_addr, 00264 hostent->h_addr, (size_t)hostent->h_length); 00265 } 00266 } else { 00267 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 00268 } 00269 serv_addr.sin_port = htons(14238); 00270 00271 sd = socket(AF_INET, SOCK_STREAM, 0); 00272 00273 if (sd < 0) { 00274 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, 00275 "DEV CONNECT Inet: Unable to create socket\n")); 00276 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00277 } 00278 00279 if ((err = pi_socket_setsd (ps, sd)) < 0) 00280 return err; 00281 00282 if (connect (ps->sd, (struct sockaddr *) &serv_addr, 00283 sizeof(serv_addr)) < 0) { 00284 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, 00285 "DEV CONNECT Inet: Unable to connect\n")); 00286 return pi_set_error(ps->sd, PI_ERR_GENERIC_SYSTEM); 00287 } 00288 00289 ps->raddr = malloc(addrlen); 00290 memcpy(ps->raddr, addr, addrlen); 00291 ps->raddrlen = addrlen; 00292 ps->laddr = malloc(addrlen); 00293 memcpy(ps->laddr, addr, addrlen); 00294 ps->laddrlen = addrlen; 00295 00296 switch (ps->cmd) { 00297 case PI_CMD_CMP: 00298 if ((err = cmp_tx_handshake(ps)) < 0) 00299 goto fail; 00300 break; 00301 case PI_CMD_NET: 00302 if ((err = net_tx_handshake(ps)) < 0) 00303 goto fail; 00304 break; 00305 } 00306 ps->state = PI_SOCK_CONN_INIT; 00307 ps->command = 0; 00308 00309 LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV CONNECT Inet: Connected\n")); 00310 return 0; 00311 00312 fail: 00313 return err; 00314 }
Here is the call graph for this function:

| pi_device_t* pi_inet_device | ( | int | type | ) |
Definition at line 66 of file inet.c.
References pi_device::accept, pi_device::bind, pi_device::close, pi_device::connect, pi_device::data, pi_device::free, pi_device::listen, pi_inet_accept(), pi_inet_bind(), pi_inet_close(), pi_inet_connect(), pi_inet_device_free(), pi_inet_listen(), pi_inet_protocol(), pi_device::protocol, pi_inet_data::rx_bytes, pi_inet_data::rx_errors, pi_inet_data::timeout, pi_inet_data::tx_bytes, and pi_inet_data::tx_errors.
Referenced by pi_devsocket().
00067 { 00068 pi_device_t *dev = NULL; 00069 pi_inet_data_t *data = NULL; 00070 00071 dev = (pi_device_t *)malloc (sizeof (pi_device_t)); 00072 if (dev != NULL) { 00073 data = (pi_inet_data_t *)malloc (sizeof (pi_inet_data_t)); 00074 if (data == NULL) { 00075 free(dev); 00076 dev = NULL; 00077 } 00078 } 00079 00080 if (dev != NULL && data != NULL) { 00081 dev->free = pi_inet_device_free; 00082 dev->protocol = pi_inet_protocol; 00083 dev->bind = pi_inet_bind; 00084 dev->listen = pi_inet_listen; 00085 dev->accept = pi_inet_accept; 00086 dev->connect = pi_inet_connect; 00087 dev->close = pi_inet_close; 00088 00089 data->timeout = 0; 00090 data->rx_bytes = 0; 00091 data->rx_errors = 0; 00092 data->tx_bytes = 0; 00093 data->tx_errors = 0; 00094 dev->data = data; 00095 } 00096 00097 return dev; 00098 }
Here is the call graph for this function:

| static void pi_inet_device_free | ( | pi_device_t * | dev | ) | [static] |
Definition at line 101 of file inet.c.
References ASSERT, and pi_device::data.
Referenced by pi_inet_device().
00102 { 00103 ASSERT (dev != NULL); 00104 if (dev != NULL) { 00105 if (dev->data != NULL) 00106 free(dev->data); 00107 free(dev); 00108 } 00109 }
| static int pi_inet_flush | ( | pi_socket_t * | ps, | |
| int | flags | |||
| ) | [static] |
Definition at line 430 of file inet.c.
References buf, O_NONBLOCK, PI_FLUSH_INPUT, and pi_socket::sd.
Referenced by pi_inet_protocol().
00431 { 00432 char buf[256]; 00433 int fl; 00434 00435 if (flags & PI_FLUSH_INPUT) { 00436 if ((fl = fcntl(ps->sd, F_GETFL, 0)) != -1) { 00437 fcntl(ps->sd, F_SETFL, fl | O_NONBLOCK); 00438 while (recv(ps->sd, buf, sizeof(buf), 0) > 0) 00439 ; 00440 fcntl(ps->sd, F_SETFL, fl); 00441 } 00442 } 00443 return 0; 00444 }
| static int pi_inet_getsockopt | ( | pi_socket_t * | ps, | |
| int | level, | |||
| int | option_name, | |||
| void * | option_value, | |||
| size_t * | option_len | |||
| ) | [static] |
Definition at line 550 of file inet.c.
References pi_device::data, pi_socket::device, PI_DEV_TIMEOUT, PI_ERR_GENERIC_ARGUMENT, pi_set_error(), pi_socket::sd, and pi_inet_data::timeout.
Referenced by pi_inet_protocol().
00552 { 00553 pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; 00554 00555 switch (option_name) { 00556 case PI_DEV_TIMEOUT: 00557 if (*option_len != sizeof (data->timeout)) { 00558 errno = EINVAL; 00559 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT); 00560 } 00561 memcpy (option_value, &data->timeout, 00562 sizeof (data->timeout)); 00563 *option_len = sizeof (data->timeout); 00564 break; 00565 } 00566 00567 return 0; 00568 }
Here is the call graph for this function:

| static int pi_inet_listen | ( | pi_socket_t * | ps, | |
| int | backlog | |||
| ) | [static] |
Definition at line 317 of file inet.c.
References PI_SOCK_LISTEN, pi_socket::sd, and pi_socket::state.
Referenced by pi_inet_device().
00318 { 00319 int result; 00320 00321 result = listen(ps->sd, backlog); 00322 if (result == 0) 00323 ps->state = PI_SOCK_LISTEN; 00324 00325 return result; 00326 }
| static pi_protocol_t * pi_inet_protocol | ( | pi_device_t * | dev | ) | [static] |
Definition at line 112 of file inet.c.
References ASSERT, pi_protocol::data, pi_device::data, pi_protocol::dup, pi_protocol::flush, pi_protocol::free, pi_protocol::getsockopt, pi_protocol::level, pi_inet_flush(), pi_inet_getsockopt(), pi_inet_protocol_dup(), pi_inet_protocol_free(), pi_inet_read(), pi_inet_setsockopt(), pi_inet_write(), PI_LEVEL_DEV, pi_protocol::read, pi_protocol::setsockopt, and pi_protocol::write.
Referenced by pi_inet_device().
00113 { 00114 pi_protocol_t *prot; 00115 pi_inet_data_t *data; 00116 00117 ASSERT (dev != NULL); 00118 00119 data = dev->data; 00120 00121 prot = (pi_protocol_t *)malloc (sizeof (pi_protocol_t)); 00122 00123 if (prot != NULL) { 00124 prot->level = PI_LEVEL_DEV; 00125 prot->dup = pi_inet_protocol_dup; 00126 prot->free = pi_inet_protocol_free; 00127 prot->read = pi_inet_read; 00128 prot->write = pi_inet_write; 00129 prot->flush = pi_inet_flush; 00130 prot->getsockopt = pi_inet_getsockopt; 00131 prot->setsockopt = pi_inet_setsockopt; 00132 prot->data = NULL; 00133 } 00134 00135 return prot; 00136 }
Here is the call graph for this function:

| static pi_protocol_t * pi_inet_protocol_dup | ( | pi_protocol_t * | prot | ) | [static] |
Definition at line 139 of file inet.c.
References ASSERT, pi_protocol::data, pi_protocol::dup, pi_protocol::flush, pi_protocol::free, pi_protocol::getsockopt, pi_protocol::level, pi_protocol::read, pi_protocol::setsockopt, and pi_protocol::write.
Referenced by pi_inet_protocol().
00140 { 00141 pi_protocol_t *new_prot; 00142 00143 ASSERT (prot != NULL); 00144 00145 new_prot = (pi_protocol_t *)malloc (sizeof (pi_protocol_t)); 00146 00147 if (new_prot != NULL) { 00148 new_prot->level = prot->level; 00149 new_prot->dup = prot->dup; 00150 new_prot->free = prot->free; 00151 new_prot->read = prot->read; 00152 new_prot->write = prot->write; 00153 new_prot->flush = prot->flush; 00154 new_prot->getsockopt = prot->getsockopt; 00155 new_prot->setsockopt = prot->setsockopt; 00156 new_prot->data = NULL; 00157 } 00158 00159 return new_prot; 00160 }
| static void pi_inet_protocol_free | ( | pi_protocol_t * | prot | ) | [static] |
Definition at line 163 of file inet.c.
References ASSERT.
Referenced by pi_inet_protocol().
00164 { 00165 ASSERT (prot != NULL); 00166 if (prot != NULL) 00167 free(prot); 00168 }
| static ssize_t pi_inet_read | ( | pi_socket_t * | ps, | |
| pi_buffer_t * | msg, | |||
| size_t | len, | |||
| int | flags | |||
| ) | [static] |
Definition at line 495 of file inet.c.
References pi_device::data, pi_socket::device, LOG, pi_buffer_expect(), PI_DBG_DEV, PI_DBG_LVL_INFO, PI_DBG_LVL_WARN, PI_ERR_GENERIC_MEMORY, PI_ERR_SOCK_DISCONNECTED, PI_ERR_SOCK_IO, PI_ERR_SOCK_TIMEOUT, PI_MSG_PEEK, pi_set_error(), PI_SOCK_CONN_BREAK, pi_inet_data::rx_bytes, pi_inet_data::rx_errors, pi_socket::sd, pi_socket::state, and pi_inet_data::timeout.
Referenced by pi_inet_protocol().
00496 { 00497 int r, 00498 fl = 0; 00499 pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; 00500 fd_set ready; 00501 struct timeval t; 00502 00503 if (pi_buffer_expect (msg, len) == NULL) { 00504 errno = ENOMEM; 00505 return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY); 00506 } 00507 00508 if (flags == PI_MSG_PEEK) 00509 fl = MSG_PEEK; 00510 00511 FD_ZERO(&ready); 00512 FD_SET(ps->sd, &ready); 00513 00514 /* If timeout == 0, wait forever for packet, otherwise wait till 00515 timeout milliseconds */ 00516 if (data->timeout == 0) 00517 select(ps->sd + 1, &ready, 0, 0, 0); 00518 else { 00519 t.tv_sec = data->timeout / 1000; 00520 t.tv_usec = (data->timeout % 1000) * 1000; 00521 if (select(ps->sd + 1, &ready, 0, 0, &t) == 0) 00522 return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); 00523 } 00524 00525 /* If data is available in time, read it */ 00526 if (FD_ISSET(ps->sd, &ready)) { 00527 r = recv(ps->sd, msg->data + msg->used, len, fl); 00528 if (r < 0) { 00529 if (errno == EPIPE || errno == EBADF) { 00530 ps->state = PI_SOCK_CONN_BREAK; 00531 return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); 00532 } 00533 return pi_set_error(ps->sd, PI_ERR_SOCK_IO); 00534 } 00535 00536 data->rx_bytes += r; 00537 msg->used += r; 00538 00539 LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV RX Inet Bytes: %d\n", r)); 00540 return r; 00541 } 00542 00543 /* otherwise throw out any current packet and return */ 00544 LOG((PI_DBG_DEV, PI_DBG_LVL_WARN, "DEV RX Inet timeout\n")); 00545 data->rx_errors++; 00546 return 0; 00547 }
Here is the call graph for this function:

| static int pi_inet_setsockopt | ( | pi_socket_t * | ps, | |
| int | level, | |||
| int | option_name, | |||
| const void * | option_value, | |||
| size_t * | option_len | |||
| ) | [static] |
Definition at line 571 of file inet.c.
References pi_device::data, pi_socket::device, PI_DEV_TIMEOUT, PI_ERR_GENERIC_ARGUMENT, pi_set_error(), pi_socket::sd, and pi_inet_data::timeout.
Referenced by pi_inet_protocol().
00573 { 00574 pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; 00575 00576 switch (option_name) { 00577 case PI_DEV_TIMEOUT: 00578 if (*option_len != sizeof (data->timeout)) { 00579 errno = EINVAL; 00580 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT); 00581 } 00582 memcpy (&data->timeout, option_value, 00583 sizeof (data->timeout)); 00584 break; 00585 } 00586 00587 return 0; 00588 }
Here is the call graph for this function:

| static ssize_t pi_inet_write | ( | pi_socket_t * | ps, | |
| const unsigned char * | msg, | |||
| size_t | len, | |||
| int | flags | |||
| ) | [static] |
Definition at line 447 of file inet.c.
References pi_device::data, pi_socket::device, LOG, PI_DBG_DEV, PI_DBG_LVL_INFO, PI_ERR_SOCK_DISCONNECTED, PI_ERR_SOCK_IO, PI_ERR_SOCK_TIMEOUT, pi_set_error(), PI_SOCK_CONN_BREAK, pi_socket::sd, pi_socket::state, pi_inet_data::timeout, and pi_inet_data::tx_bytes.
Referenced by pi_inet_protocol().
00448 { 00449 int total, 00450 nwrote; 00451 pi_inet_data_t *data = (pi_inet_data_t *)ps->device->data; 00452 struct timeval t; 00453 fd_set ready; 00454 00455 FD_ZERO(&ready); 00456 FD_SET(ps->sd, &ready); 00457 00458 total = len; 00459 while (total > 0) { 00460 if (data->timeout == 0) { 00461 if (select(ps->sd + 1, 0, &ready, 0, 0) < 0 00462 && errno == EINTR) 00463 continue; 00464 } else { 00465 t.tv_sec = data->timeout / 1000; 00466 t.tv_usec = (data->timeout % 1000) * 1000; 00467 if (select(ps->sd + 1, 0, &ready, 0, &t) == 0) 00468 return pi_set_error(ps->sd, PI_ERR_SOCK_TIMEOUT); 00469 } 00470 if (!FD_ISSET(ps->sd, &ready)) { 00471 ps->state = PI_SOCK_CONN_BREAK; 00472 return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); 00473 } 00474 00475 nwrote = write(ps->sd, msg, len); 00476 if (nwrote < 0) { 00477 /* test errno to properly set the socket error */ 00478 if (errno == EPIPE || errno == EBADF) { 00479 ps->state = PI_SOCK_CONN_BREAK; 00480 return pi_set_error(ps->sd, PI_ERR_SOCK_DISCONNECTED); 00481 } 00482 return pi_set_error(ps->sd, PI_ERR_SOCK_IO); 00483 } 00484 00485 total -= nwrote; 00486 } 00487 data->tx_bytes += len; 00488 00489 LOG((PI_DBG_DEV, PI_DBG_LVL_INFO, "DEV TX Inet Bytes: %d\n", len)); 00490 00491 return len; 00492 }
Here is the call graph for this function:

| int pi_socket_init | ( | pi_socket_t * | ps | ) |