net.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "pi-debug.h"
#include "pi-source.h"
#include "pi-net.h"
#include "pi-error.h"

Include dependency graph for net.c:

Go to the source code of this file.

Defines

#define PI_NET_TIMEOUT   30*1000

Functions

static int net_flush (pi_socket_t *ps, int flags)
static int net_getsockopt (pi_socket_t *ps, int level, int option_name, void *option_value, size_t *option_len)
static int net_setsockopt (pi_socket_t *ps, int level, int option_name, const void *option_value, size_t *option_len)
static pi_protocol_tnet_protocol_dup (pi_protocol_t *prot)
static void net_protocol_free (pi_protocol_t *prot)
pi_protocol_tnet_protocol (void)
int net_rx_handshake (pi_socket_t *ps)
int net_tx_handshake (pi_socket_t *ps)
ssize_t net_tx (pi_socket_t *ps, const unsigned char *msg, size_t len, int flags)
ssize_t net_rx (pi_socket_t *ps, pi_buffer_t *msg, size_t len, int flags)
void net_dump_header (unsigned char *data, int rxtx, int sd)
void net_dump (unsigned char *header, unsigned char *data)


Define Documentation

#define PI_NET_TIMEOUT   30*1000

Definition at line 40 of file net.c.

Referenced by net_rx().


Function Documentation

void net_dump ( unsigned char *  header,
unsigned char *  data 
)

Definition at line 702 of file net.c.

References get_long, pi_dumpdata(), PI_NET_OFFSET_SIZE, and size.

Referenced by net_rx().

00703 {
00704         size_t  size;
00705 
00706         size = get_long(&header[PI_NET_OFFSET_SIZE]);
00707         pi_dumpdata((char *)data, size);
00708 }

Here is the call graph for this function:

void net_dump_header ( unsigned char *  data,
int  rxtx,
int  sd 
)

Definition at line 678 of file net.c.

References get_byte, get_long, LOG, PI_DBG_LVL_NONE, PI_DBG_NET, PI_NET_OFFSET_SIZE, PI_NET_OFFSET_TXID, and PI_NET_OFFSET_TYPE.

Referenced by net_rx(), and net_tx().

00679 {
00680         LOG((PI_DBG_NET, PI_DBG_LVL_NONE,
00681             "NET %s sd=%i type=%d txid=0x%.2x len=0x%.4x\n",
00682             rxtx ? "TX" : "RX",
00683             sd,
00684             get_byte(&data[PI_NET_OFFSET_TYPE]),
00685             get_byte(&data[PI_NET_OFFSET_TXID]),
00686             get_long(&data[PI_NET_OFFSET_SIZE])));
00687 }

int net_flush ( pi_socket_t ps,
int  flags 
) [static]

Definition at line 277 of file net.c.

References pi_protocol::flush, PI_ERR_SOCK_INVALID, PI_LEVEL_NET, pi_protocol(), pi_protocol_next(), pi_set_error(), and pi_socket::sd.

Referenced by net_protocol().

00278 {
00279         pi_protocol_t   *prot,
00280                         *next;
00281 
00282         prot = pi_protocol(ps->sd, PI_LEVEL_NET);
00283         if (prot == NULL)
00284                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00285 
00286         next = pi_protocol_next(ps->sd, PI_LEVEL_NET);
00287         if (next == NULL)
00288                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00289 
00290         return next->flush(ps, flags);
00291 }

Here is the call graph for this function:

static int net_getsockopt ( pi_socket_t ps,
int  level,
int  option_name,
void *  option_value,
size_t *  option_len 
) [static]

Definition at line 573 of file net.c.

References pi_protocol::data, PI_ERR_GENERIC_ARGUMENT, PI_ERR_SOCK_INVALID, PI_LEVEL_NET, PI_NET_TYPE, pi_protocol(), pi_set_error(), pi_socket::sd, and pi_net_data::type.

Referenced by net_protocol().

00575 {
00576         pi_protocol_t *prot;
00577         pi_net_data_t *data;
00578 
00579         prot = pi_protocol(ps->sd, PI_LEVEL_NET);
00580         if (prot == NULL)
00581                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00582 
00583         data = (pi_net_data_t *)prot->data;
00584 
00585         switch (option_name) {
00586                 case PI_NET_TYPE:
00587                         if (*option_len != sizeof (data->type)) {
00588                                 errno = EINVAL;
00589                                 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00590                         }
00591                         memcpy (option_value, &data->type,
00592                                 sizeof (data->type));
00593                         *option_len = sizeof (data->type);
00594                         break;
00595         }
00596 
00597         return 0;
00598 }

Here is the call graph for this function:

pi_protocol_t* net_protocol ( void   ) 

Definition at line 135 of file net.c.

References pi_protocol::data, pi_protocol::dup, pi_protocol::flush, pi_protocol::free, pi_protocol::getsockopt, pi_protocol::level, net_flush(), net_getsockopt(), net_protocol_dup(), net_protocol_free(), net_rx(), net_setsockopt(), net_tx(), PI_LEVEL_NET, PI_NET_TYPE_DATA, pi_protocol::read, pi_protocol::setsockopt, pi_net_data::split_writes, pi_net_data::txid, pi_net_data::type, pi_protocol::write, and pi_net_data::write_chunksize.

00136 {
00137         pi_protocol_t *prot = NULL;
00138         pi_net_data_t *data = NULL;
00139 
00140         prot = (pi_protocol_t *)malloc (sizeof (pi_protocol_t));        
00141         if (prot != NULL) {
00142                 data = (pi_net_data_t *)malloc (sizeof (pi_net_data_t));
00143                 if (data == NULL) {
00144                         free(prot);
00145                         prot = NULL;
00146                 }
00147         }
00148 
00149         if (prot != NULL && data != NULL) {
00150                 prot->level             = PI_LEVEL_NET;
00151                 prot->dup               = net_protocol_dup;
00152                 prot->free              = net_protocol_free;
00153                 prot->read              = net_rx;
00154                 prot->write             = net_tx;
00155                 prot->flush             = net_flush;
00156                 prot->getsockopt        = net_getsockopt;
00157                 prot->setsockopt        = net_setsockopt;
00158 
00159                 data->type              = PI_NET_TYPE_DATA;
00160                 data->split_writes      = 1;        /* write packet header and data separately */
00161                 data->write_chunksize   = 4096;     /* and push data in 4k chunks. Required for some USB devices */
00162                 data->txid              = 0x00;
00163                 prot->data              = data;
00164         }
00165 
00166         return prot;
00167 }

Here is the call graph for this function:

static pi_protocol_t* net_protocol_dup ( pi_protocol_t prot  )  [static]

Definition at line 60 of file net.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, pi_net_data::split_writes, pi_net_data::txid, pi_net_data::type, pi_protocol::write, and pi_net_data::write_chunksize.

Referenced by net_protocol().

00061 {
00062         pi_protocol_t *new_prot = NULL;
00063         pi_net_data_t   *data = NULL,
00064                         *new_data = NULL;
00065 
00066         ASSERT(prot != NULL);
00067         
00068         new_prot = (pi_protocol_t *)malloc (sizeof (pi_protocol_t));
00069         if (new_prot != NULL) {
00070                 new_data = (pi_net_data_t *)malloc (sizeof (pi_net_data_t));
00071                 if (new_data == NULL) {
00072                         free(new_prot);
00073                         new_prot = NULL;
00074                 }
00075         }
00076 
00077         if (new_prot != NULL && new_data != NULL) {
00078                 new_prot->level         = prot->level;
00079                 new_prot->dup           = prot->dup;
00080                 new_prot->free          = prot->free;
00081                 new_prot->read          = prot->read;
00082                 new_prot->write         = prot->write;
00083                 new_prot->flush         = prot->flush;
00084                 new_prot->getsockopt    = prot->getsockopt;
00085                 new_prot->setsockopt    = prot->setsockopt;
00086 
00087                 data                    = (pi_net_data_t *)prot->data;
00088                 new_data->type          = data->type;
00089                 new_data->split_writes  = data->split_writes;
00090                 new_data->write_chunksize       = data->write_chunksize;
00091                 new_data->txid          = data->txid;
00092                 new_prot->data          = new_data;
00093         }
00094 
00095         return new_prot;
00096 }

static void net_protocol_free ( pi_protocol_t prot  )  [static]

Definition at line 111 of file net.c.

References ASSERT, and pi_protocol::data.

Referenced by net_protocol().

00112 {
00113         ASSERT (prot != NULL);
00114 
00115         if (prot != NULL) {
00116                 if (prot->data != NULL)
00117                         free(prot->data);
00118                 free(prot);
00119         }
00120 }

ssize_t net_rx ( pi_socket_t ps,
pi_buffer_t msg,
size_t  len,
int  flags 
)

Definition at line 407 of file net.c.

References CHECK, pi_socket::command, pi_buffer_t::data, pi_protocol::data, pi_protocol::flush, get_long, LOG, net_dump(), net_dump_header(), pi_buffer_free(), pi_buffer_new(), PI_DBG_LVL_DEBUG, PI_DBG_LVL_ERR, PI_DBG_LVL_INFO, PI_DBG_NET, PI_DEV_TIMEOUT, pi_dumpdata(), PI_ERR_GENERIC_MEMORY, PI_ERR_PROT_BADPACKET, PI_ERR_SOCK_INVALID, PI_FLUSH_INPUT, pi_getsockopt(), PI_LEVEL_DEV, PI_LEVEL_NET, PI_LEVEL_SOCK, PI_NET_HEADER_LEN, PI_NET_OFFSET_SIZE, PI_NET_OFFSET_TXID, PI_NET_OFFSET_TYPE, PI_NET_TIMEOUT, PI_NET_TYPE_DATA, PI_NET_TYPE_TCKL, pi_protocol(), pi_protocol_next(), pi_set_error(), pi_setsockopt(), PI_SOCK_CONN_INIT, PI_SOCK_HONOR_RX_TIMEOUT, pi_protocol::read, pi_socket::sd, set_long, size, pi_socket::state, pi_net_data::txid, pi_net_data::type, and pi_buffer_t::used.

Referenced by net_protocol(), net_rx_handshake(), and net_tx_handshake().

00408 {
00409         int     bytes, 
00410                 total_bytes, 
00411                 packet_len,
00412                 timeout,
00413                 honor_rx_timeout;
00414         size_t  size;
00415         pi_protocol_t   *prot,
00416                         *next;
00417         pi_buffer_t *header;
00418         pi_net_data_t *data;
00419 
00420         prot = pi_protocol(ps->sd, PI_LEVEL_NET);
00421         if (prot == NULL)
00422                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00423         
00424         data = (pi_net_data_t *)prot->data;
00425         next = pi_protocol_next(ps->sd, PI_LEVEL_NET);
00426         if (next == NULL)
00427                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00428 
00429         size = sizeof(honor_rx_timeout);
00430         pi_getsockopt(ps->sd, PI_LEVEL_SOCK, PI_SOCK_HONOR_RX_TIMEOUT,
00431                 &honor_rx_timeout, &size);
00432 
00433         timeout = honor_rx_timeout ? PI_NET_TIMEOUT : 0;
00434         size = sizeof(timeout);
00435         pi_setsockopt(ps->sd, PI_LEVEL_DEV, PI_DEV_TIMEOUT, 
00436                       &timeout, &size);
00437 
00438         header = pi_buffer_new (PI_NET_HEADER_LEN);
00439         if (header == NULL) {
00440                 errno = ENOMEM;
00441                 return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY);
00442         }
00443 
00444         /* loop until we find a non-tickle packet (if the other end
00445            sends us a tickle, we would receive it prior to getting
00446            the expected reply to one of our commands, so we need
00447            to make sure tickle packets don't get in the way) */
00448         total_bytes = 0;
00449         while (!total_bytes) {
00450                 if (data->txid == 0) {  
00451                         /* Peek to see if it is a headerless packet */
00452                         bytes = next->read(ps, header, 1, flags);
00453                         if (bytes <= 0) {
00454                                 pi_buffer_free (header);
00455                                 return bytes;
00456                         }
00457                         
00458                         LOG ((PI_DBG_NET, PI_DBG_LVL_INFO,
00459                                   "NET RX (%i): Checking for headerless packet %d\n",
00460                                   ps->sd, header->data[0]));
00461                         
00462                         if (header->data[0] == 0x90) {
00463                                 /* Cause the header bytes to be skipped */
00464                                 LOG ((PI_DBG_NET, PI_DBG_LVL_INFO,
00465                                           "NET RX (%i): Headerless packet\n",
00466                                           ps->sd));
00467                                 total_bytes = PI_NET_HEADER_LEN;
00468                                 header->data[PI_NET_OFFSET_TYPE] = PI_NET_TYPE_DATA;
00469                                 header->data[PI_NET_OFFSET_TXID] = 0x01;
00470                                 set_long (&header->data[PI_NET_OFFSET_SIZE], 21);
00471                                 break;
00472                         } else {
00473                                 total_bytes += bytes;
00474                         }
00475                 }
00476                 
00477                 /* bytes in what's left of the header */
00478                 while (total_bytes < PI_NET_HEADER_LEN) {
00479                         bytes = next->read(ps, header,
00480                                         (size_t)(PI_NET_HEADER_LEN - total_bytes), flags);
00481                         if (bytes <= 0) {
00482                                 pi_buffer_free (header);
00483                                 return bytes;
00484                         }
00485                         total_bytes += bytes;
00486                 }
00487                 
00488                 packet_len = get_long(&header->data[PI_NET_OFFSET_SIZE]);
00489                 data->type = header->data[PI_NET_OFFSET_TYPE];
00490 
00491                 switch (data->type) {
00492                         case PI_NET_TYPE_TCKL:
00493                                 if (packet_len != 0) {
00494                                         LOG ((PI_DBG_NET, PI_DBG_LVL_ERR,
00495                                                 "NET RX (%i): tickle packet with non-zero length\n",
00496                                                 ps->sd));
00497                                         pi_buffer_free(header);
00498                                         return pi_set_error(ps->sd, PI_ERR_PROT_BADPACKET);
00499                                 }
00500                                 /* valid tickle packet; continue reading. */
00501                                 LOG((PI_DBG_NET, PI_DBG_LVL_DEBUG,
00502                                         "NET RX (%i): received tickle packet\n",
00503                                         ps->sd));
00504                                 total_bytes = 0;
00505                                 header->used = 0;
00506                                 break;
00507                         
00508                         case PI_NET_TYPE_DATA:
00509                                 /* move on to reading the rest of the packet */
00510                                 break;
00511 
00512                         default:
00513                                 LOG ((PI_DBG_NET, PI_DBG_LVL_ERR,
00514                                         "NET RX (%i): Unknown packet type\n",
00515                                         ps->sd));
00516                                 CHECK(PI_DBG_NET, PI_DBG_LVL_INFO, pi_dumpdata((char *)header->data, PI_NET_HEADER_LEN));
00517                                 pi_buffer_free(header);
00518                                 return pi_set_error(ps->sd, PI_ERR_PROT_BADPACKET);
00519                 }
00520         }
00521 
00522         total_bytes = 0;
00523         packet_len = get_long(&header->data[PI_NET_OFFSET_SIZE]);
00524 
00525         /* shield against absurd packet lengths */
00526         if (packet_len < 0 || packet_len > 0x100000L) {
00527                 /* we see an invalid packet */
00528                 next->flush(ps, PI_FLUSH_INPUT);
00529                 LOG ((PI_DBG_NET, PI_DBG_LVL_ERR, "NET RX (%i): Invalid packet length (%ld)\n", ps->sd, packet_len));
00530                 pi_buffer_free(header);
00531                 return pi_set_error(ps->sd, PI_ERR_PROT_BADPACKET);
00532         }
00533 
00534         /* read the actual packet data */
00535         while (total_bytes < packet_len) {
00536                 bytes = next->read(ps, msg,
00537                         (size_t)(packet_len - total_bytes), flags);
00538                 if (bytes < 0) {
00539                         pi_buffer_free (header);
00540                         return bytes;
00541                 }
00542                 total_bytes += bytes;
00543         }
00544 
00545         CHECK(PI_DBG_NET, PI_DBG_LVL_INFO, net_dump_header(header->data, 0, ps->sd));
00546         CHECK(PI_DBG_NET, PI_DBG_LVL_DEBUG, net_dump(header->data, msg->data));
00547 
00548         /* Update the transaction id */
00549         if (ps->state == PI_SOCK_CONN_INIT || ps->command == 1)
00550                 data->txid = header->data[PI_NET_OFFSET_TXID];
00551         else {
00552                 data->txid++;
00553                 if (data->txid == 0xff)
00554                         data->txid = 1;
00555         }
00556 
00557         pi_buffer_free (header);
00558         return packet_len;
00559 }

Here is the call graph for this function:

int net_rx_handshake ( pi_socket_t ps  ) 

Definition at line 182 of file net.c.

References buffer, net_rx(), net_tx(), pi_buffer_free(), pi_buffer_new(), PI_ERR_GENERIC_MEMORY, pi_set_error(), and pi_socket::sd.

Referenced by pi_bluetooth_accept(), pi_inet_accept(), pi_serial_accept(), and pi_usb_accept().

00183 {
00184         static const unsigned char msg1[] =     /* 50 bytes */
00185                 "\x12\x01\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00"
00186                 "\x24\xff\xff\xff\xff\x3c\x00\x3c\x00\x00\x00\x00\x00"
00187                 "\x00\x00\x00\x00\xc0\xa8\xa5\x1f\x04\x27\x00\x00\x00"
00188                 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
00189         static const unsigned char msg2[] =     /* 46 bytes */
00190                 "\x13\x01\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00"
00191                 "\x20\xff\xff\xff\xff\x00\x3c\x00\x3c\x00\x00\x00\x00"
00192                 "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
00193                 "\x00\x00\x00\x00\x00\x00\x00";
00194         pi_buffer_t *buffer;
00195         int err;
00196 
00197         buffer = pi_buffer_new (256);
00198         if (buffer == NULL) {
00199                 errno = ENOMEM;
00200                 return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY);
00201         }
00202 
00203         if ((err = net_rx(ps, buffer, 256, 0)) >= 0  &&
00204                 (err = net_tx(ps, msg1, 50, 0)) >= 0    &&
00205                 (err = net_rx(ps, buffer, 50, 0)) >= 0  &&
00206                 (err = net_tx(ps, msg2, 46, 0)) >= 0    &&
00207                 (err = net_rx(ps, buffer, 8, 0)) >= 0)
00208         {
00209                 pi_buffer_free (buffer);
00210                 return 0;
00211         }
00212 
00213         pi_buffer_free (buffer);
00214         return err;
00215 }

Here is the call graph for this function:

static int net_setsockopt ( pi_socket_t ps,
int  level,
int  option_name,
const void *  option_value,
size_t *  option_len 
) [static]

Definition at line 613 of file net.c.

References pi_protocol::data, PI_ERR_GENERIC_ARGUMENT, PI_ERR_SOCK_INVALID, PI_LEVEL_NET, PI_NET_SPLIT_WRITES, PI_NET_TYPE, PI_NET_WRITE_CHUNKSIZE, pi_protocol(), pi_set_error(), pi_socket::sd, pi_net_data::split_writes, pi_net_data::type, and pi_net_data::write_chunksize.

Referenced by net_protocol().

00615 {
00616         pi_protocol_t *prot;
00617         pi_net_data_t *data;
00618 
00619         prot = pi_protocol(ps->sd, PI_LEVEL_NET);
00620         if (prot == NULL)
00621                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00622 
00623         data = (pi_net_data_t *)prot->data;
00624 
00625         switch (option_name) {
00626                 case PI_NET_TYPE:
00627                         if (*option_len != sizeof (data->type)) {
00628                                 errno = EINVAL;
00629                                 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00630                         }
00631                         memcpy (&data->type, option_value,
00632                                 sizeof (data->type));
00633                         break;
00634                 
00635                 /* this option, when set to != 0, instructs NET to separately
00636                  * write the NET header and the data block. Data can be further
00637                  * sent in chunks by also setting PI_NET_WRITE_CHUNKSIZE below.
00638                  */
00639                 case PI_NET_SPLIT_WRITES:
00640                         if (*option_len != sizeof (data->split_writes)) {
00641                                 errno = EINVAL;
00642                                 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00643                         }
00644                         memcpy (&data->split_writes, option_value,
00645                                 sizeof(data->split_writes));
00646                         break;
00647 
00648                 /* this option, when set to != 0, instructs NET to write the
00649                  * packet data in chunks of the given maximum size. If
00650                  * PI_NET_SPLIT_WRITES is not set, and this option is set, we
00651                  * chunk the whole write (including the NET header)
00652                  */
00653                 case PI_NET_WRITE_CHUNKSIZE:
00654                         if (*option_len != sizeof (data->write_chunksize)) {
00655                                 errno = EINVAL;
00656                                 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00657                         }
00658                         memcpy (&data->write_chunksize, option_value,
00659                                 sizeof(data->write_chunksize));
00660                         break;
00661         }
00662 
00663         return 0;
00664 }

Here is the call graph for this function:

ssize_t net_tx ( pi_socket_t ps,
const unsigned char *  msg,
size_t  len,
int  flags 
)

Definition at line 305 of file net.c.

References buf, CHECK, pi_protocol::data, net_dump_header(), PI_DBG_LVL_DEBUG, PI_DBG_LVL_INFO, PI_DBG_NET, pi_dumpdata(), PI_ERR_GENERIC_MEMORY, PI_ERR_SOCK_INVALID, PI_LEVEL_NET, PI_NET_HEADER_LEN, PI_NET_OFFSET_SIZE, PI_NET_OFFSET_TXID, PI_NET_OFFSET_TYPE, PI_NET_TYPE_TCKL, pi_protocol(), pi_protocol_next(), pi_set_error(), pi_socket::sd, set_long, pi_net_data::split_writes, pi_net_data::txid, pi_net_data::type, pi_protocol::write, and pi_net_data::write_chunksize.

00306 {
00307         int     bytes,
00308                         offset,
00309                         remain,
00310                         tosend;
00311         pi_protocol_t   *prot,
00312                         *next;
00313         pi_net_data_t *data;
00314         unsigned char *buf;
00315 
00316         prot = pi_protocol(ps->sd, PI_LEVEL_NET);
00317         if (prot == NULL)
00318                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00319         data = (pi_net_data_t *)prot->data;
00320 
00321         next = pi_protocol_next(ps->sd, PI_LEVEL_NET);
00322         if (next == NULL)
00323                 return pi_set_error(ps->sd, PI_ERR_SOCK_INVALID);
00324 
00325         /* Create the header */
00326         buf = (unsigned char *) malloc(PI_NET_HEADER_LEN + len);
00327         if (buf == NULL)
00328                 return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY);
00329         buf[PI_NET_OFFSET_TYPE] = data->type;
00330         if (data->type == PI_NET_TYPE_TCKL)
00331                 buf[PI_NET_OFFSET_TXID] = 0xff;
00332         else
00333                 buf[PI_NET_OFFSET_TXID] = data->txid;
00334         set_long(&buf[PI_NET_OFFSET_SIZE], len);
00335         memcpy(&buf[PI_NET_HEADER_LEN], msg, len);
00336 
00337         /* Write the header and body, possibly in one write, or in two,
00338          * or in more, depending on the current options. Crucial options
00339          * here are `split_writes' and `write_chunksize' in this protocol's
00340          * data (use net_setsockopt() to set them).
00341          */
00342         if (data->split_writes)
00343         {
00344                 /* Bugfix for USB send problems. If connected over
00345                  * USB, do the following:
00346                  * - send the 6 bytes of header first
00347                  * - split the rest of data into chunks if the write_chunksize opt is set
00348                  * This is what Palm Desktop does on Windows for the Zire 72
00349                  * (uses split writes and 4k chunks)
00350                  * -- FP
00351                  */
00352                 bytes = next->write(ps, buf, PI_NET_HEADER_LEN, flags);
00353                 if (bytes < PI_NET_HEADER_LEN)
00354                 {
00355                         free(buf);
00356                         return bytes;
00357                 }
00358                 offset = PI_NET_HEADER_LEN;
00359                 remain = len;
00360         }
00361         else
00362         {
00363                 offset = 0;
00364                 remain = PI_NET_HEADER_LEN + len;
00365         }
00366 
00367         while (remain > 0)
00368         {
00369                 if (data->write_chunksize)
00370                         tosend = (remain > data->write_chunksize) ? data->write_chunksize : remain;
00371                 else
00372                         tosend = remain;
00373 
00374                 bytes = next->write(ps, &buf[offset], tosend, flags);
00375                 if (bytes < tosend)
00376                 {
00377                         free(buf);
00378                         return bytes;
00379                 }
00380                 remain -= bytes;
00381                 offset += bytes;
00382         }
00383 
00384         CHECK(PI_DBG_NET, PI_DBG_LVL_INFO, net_dump_header(buf, 1, ps->sd));
00385         CHECK(PI_DBG_NET, PI_DBG_LVL_DEBUG, pi_dumpdata((char *)msg, len));
00386         
00387         free(buf);
00388         return len;
00389 }

Here is the call graph for this function:

int net_tx_handshake ( pi_socket_t ps  ) 

Definition at line 230 of file net.c.

References buffer, net_rx(), net_tx(), pi_buffer_free(), pi_buffer_new(), PI_ERR_GENERIC_MEMORY, pi_set_error(), and pi_socket::sd.

Referenced by pi_inet_connect(), and pi_usb_connect().

00231 {
00232         static const unsigned char msg1[] =     /* 22 bytes */
00233                 "\x90\x01\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00"
00234                 "\x08\x01\x00\x00\x00\x00\x00\x00\x00";
00235         static const unsigned char msg2[] =     /* 50 bytes */
00236                 "\x92\x01\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00"
00237                 "\x24\xff\xff\xff\xff\x00\x3c\x00\x3c\x40\x00\x00\x00"
00238                 "\x01\x00\x00\x00\xc0\xa8\xa5\x1e\x04\x01\x00\x00\x00"
00239                 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
00240         static const unsigned char msg3[] =     /* 8 bytes */
00241                 "\x93\x00\x00\x00\x00\x00\x00\x00";
00242         pi_buffer_t *buffer;
00243         int err;
00244 
00245         buffer = pi_buffer_new (256);
00246         if (buffer == NULL) {
00247                 errno = ENOMEM;
00248                 return pi_set_error(ps->sd, PI_ERR_GENERIC_MEMORY);
00249         }
00250         
00251         if ((err = net_tx(ps, msg1, 22, 0)) >= 0        &&
00252                 (err = net_rx(ps, buffer, 256, 0)) >= 0  &&
00253                 (err = net_tx(ps, msg2, 50, 0)) >= 0    &&
00254                 (err = net_rx(ps, buffer, 256, 0)) >= 0  &&
00255                 (err = net_tx(ps, msg3, 8, 0)) >= 0)
00256         {
00257                 pi_buffer_free (buffer);
00258                 return 0;
00259         }
00260 
00261         pi_buffer_free (buffer);
00262         return err;
00263 }

Here is the call graph for this function:


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