#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_t * | net_protocol_dup (pi_protocol_t *prot) |
| static void | net_protocol_free (pi_protocol_t *prot) |
| pi_protocol_t * | net_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) |
| 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:
