inet.c File Reference

#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_tpi_inet_protocol (pi_device_t *dev)
static pi_protocol_tpi_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_tpi_inet_device (int type)


Function Documentation

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  ) 


© 1996-2007 by pilot-link.org. All rights reserved.