00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031 #include <stdlib.h>
00032 #include <stdio.h>
00033 #include <signal.h>
00034 #include <fcntl.h>
00035 #include <string.h>
00036 #include <errno.h>
00037 #include <sys/types.h>
00038 #include <sys/socket.h>
00039 #include <sys/stat.h>
00040 #include <sys/time.h>
00041 #include <unistd.h>
00042
00043 #include "pi-debug.h"
00044 #include "pi-source.h"
00045 #include "pi-socket.h"
00046 #include "pi-serial.h"
00047 #include "pi-net.h"
00048 #include "pi-cmp.h"
00049 #include "pi-error.h"
00050 #include "pi-util.h"
00051
00052 #ifdef OS2
00053 #include <sys/select.h>
00054 #endif
00055
00056
00057 static int pi_serial_connect(pi_socket_t *ps, struct sockaddr *addr,
00058 size_t addrlen);
00059 static int pi_serial_bind(pi_socket_t *ps, struct sockaddr *addr,
00060 size_t addrlen);
00061 static int pi_serial_listen(pi_socket_t *ps, int backlog);
00062 static int pi_serial_accept(pi_socket_t *ps, struct sockaddr *addr,
00063 size_t *addrlen);
00064 static int pi_serial_getsockopt(pi_socket_t *ps, int level,
00065 int option_name, void *option_value,
00066 size_t *option_len);
00067 static int pi_serial_setsockopt(pi_socket_t *ps, int level,
00068 int option_name, const void *option_value,
00069 size_t *option_len);
00070 static int pi_serial_close(pi_socket_t *ps);
00071
00072 extern int pi_socket_init(pi_socket_t *ps);
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 static pi_protocol_t*
00088 pi_serial_protocol_dup (pi_protocol_t *prot)
00089 {
00090 pi_protocol_t *new_prot;
00091
00092 ASSERT (prot != NULL);
00093
00094 new_prot = (pi_protocol_t *) malloc(sizeof (pi_protocol_t));
00095
00096 if (new_prot != NULL) {
00097 new_prot->level = prot->level;
00098 new_prot->dup = prot->dup;
00099 new_prot->free = prot->free;
00100 new_prot->read = prot->read;
00101 new_prot->write = prot->write;
00102 new_prot->flush = prot->flush;
00103 new_prot->getsockopt = prot->getsockopt;
00104 new_prot->setsockopt = prot->setsockopt;
00105 new_prot->data = NULL;
00106 }
00107
00108 return new_prot;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 static void
00124 pi_serial_protocol_free (pi_protocol_t *prot)
00125 {
00126 ASSERT (prot != NULL);
00127
00128 if (prot != NULL)
00129 free(prot);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 static pi_protocol_t*
00145 pi_serial_protocol (pi_device_t *dev)
00146 {
00147 pi_protocol_t *prot;
00148 struct pi_serial_data *data;
00149
00150 ASSERT (dev != NULL);
00151
00152 prot = (pi_protocol_t *) malloc(sizeof (pi_protocol_t));
00153
00154 data = (struct pi_serial_data *)(dev->data);
00155
00156 if (prot != NULL) {
00157 prot->level = PI_LEVEL_DEV;
00158 prot->dup = pi_serial_protocol_dup;
00159 prot->free = pi_serial_protocol_free;
00160 prot->read = data->impl.read;
00161 prot->write = data->impl.write;
00162 prot->flush = data->impl.flush;
00163 prot->getsockopt = pi_serial_getsockopt;
00164 prot->setsockopt = pi_serial_setsockopt;
00165 prot->data = NULL;
00166 }
00167
00168 return prot;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 static void
00185 pi_serial_device_free (pi_device_t *dev)
00186 {
00187 ASSERT (dev != NULL);
00188
00189 free(dev->data);
00190 free(dev);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 pi_device_t*
00206 pi_serial_device (int type)
00207 {
00208 pi_device_t *dev;
00209 struct pi_serial_data *data;
00210
00211 dev = (pi_device_t *) malloc(sizeof (pi_device_t));
00212 if (dev == NULL)
00213 return NULL;
00214
00215 data = (struct pi_serial_data *) malloc(sizeof (struct pi_serial_data));
00216 if (data == NULL) {
00217 free(dev);
00218 return NULL;
00219 }
00220
00221 dev->free = pi_serial_device_free;
00222 dev->protocol = pi_serial_protocol;
00223 dev->bind = pi_serial_bind;
00224 dev->listen = pi_serial_listen;
00225 dev->accept = pi_serial_accept;
00226 dev->connect = pi_serial_connect;
00227 dev->close = pi_serial_close;
00228
00229 switch (type) {
00230 case PI_SERIAL_DEV:
00231 pi_serial_impl_init (&data->impl);
00232 break;
00233 default:
00234 pi_serial_impl_init (&data->impl);
00235 break;
00236 }
00237
00238 data->buf_size = 0;
00239 data->rate = -1;
00240 data->establishrate = -1;
00241 data->establishhighrate = -1;
00242 data->timeout = 0;
00243 data->rx_bytes = 0;
00244 data->rx_errors = 0;
00245 data->tx_bytes = 0;
00246 data->tx_errors = 0;
00247
00248 dev->data = data;
00249
00250 return dev;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 static int
00266 pi_serial_connect(pi_socket_t *ps, struct sockaddr *addr,
00267 size_t addrlen)
00268 {
00269 struct pi_serial_data *data =
00270 (struct pi_serial_data *)ps->device->data;
00271 struct pi_sockaddr *pa = (struct pi_sockaddr *) addr;
00272 int err;
00273
00274 if (ps->type == PI_SOCK_STREAM) {
00275 if (ps->protocol == PI_PF_SYS) {
00276 data->establishrate = data->rate = 57600;
00277 } else {
00278 if (data->establishrate == -1)
00279 get_pilot_rate(&data->establishrate, &data->establishhighrate);
00280
00281
00282 data->rate = 9600;
00283 }
00284 } else if (ps->type == PI_SOCK_RAW) {
00285
00286 data->establishrate = data->rate = 57600;
00287 }
00288
00289 if ((err = data->impl.open(ps, pa, addrlen)) < 0)
00290 return err;
00291
00292 ps->raddr = malloc(addrlen);
00293 memcpy(ps->raddr, addr, addrlen);
00294 ps->raddrlen = addrlen;
00295 ps->laddr = malloc(addrlen);
00296 memcpy(ps->laddr, addr, addrlen);
00297 ps->laddrlen = addrlen;
00298
00299 if (ps->type == PI_SOCK_STREAM) {
00300 size_t size;
00301 switch (ps->cmd) {
00302 case PI_CMD_CMP:
00303 if (cmp_tx_handshake(ps) < 0)
00304 goto fail;
00305
00306 size = sizeof(data->rate);
00307 pi_getsockopt(ps->sd, PI_LEVEL_CMP, PI_CMP_BAUD,
00308 &data->rate, &size);
00309
00310 if ((err = data->impl.changebaud(ps)) < 0)
00311 goto fail;
00312 break;
00313
00314 case PI_CMD_NET:
00315 if ((err = data->impl.changebaud(ps)) < 0)
00316 goto fail;
00317 break;
00318
00319 case PI_CMD_SYS:
00320 if ((err = data->impl.changebaud(ps)) < 0)
00321 goto fail;
00322 break;
00323 }
00324 }
00325 ps->state = PI_SOCK_CONN_INIT;
00326 ps->command = 0;
00327 return 0;
00328
00329 fail:
00330 return err;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 static int
00346 pi_serial_bind(pi_socket_t *ps, struct sockaddr *addr, size_t addrlen)
00347 {
00348 struct pi_serial_data *data =
00349 (struct pi_serial_data *)ps->device->data;
00350 struct pi_sockaddr *pa = (struct pi_sockaddr *) addr;
00351 int err, count = 0;
00352
00353 if (ps->type == PI_SOCK_STREAM) {
00354 if (data->establishrate == -1)
00355 get_pilot_rate(&data->establishrate, &data->establishhighrate);
00356
00357
00358 data->rate = 9600;
00359 } else if (ps->type == PI_SOCK_RAW) {
00360
00361 data->establishrate = data->rate = 57600;
00362 }
00363
00364 begin:
00365 if ((err = data->impl.open(ps, pa, addrlen)) < 0) {
00366 int save_errno = errno;
00367 #ifdef MAXPATHLEN
00368 char realport[MAXPATHLEN];
00369 #else
00370 # ifdef PATH_MAX
00371 char realport[PATH_MAX];
00372 # else
00373 char realport[4096];
00374 # endif
00375 #endif
00376
00377 realpath(pa->pi_device, realport);
00378 errno = save_errno;
00379
00380 if (errno == ENOENT) {
00381 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00382 " The device %s does not exist..\n",
00383 pa->pi_device));
00384 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00385 " Possible solution:\n\n\tmknod %s c "
00386 "<major> <minor>\n\n", pa->pi_device));
00387 } else if (errno == EACCES) {
00388 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00389 " Please check the "
00390 "permissions on %s..\n", realport));
00391 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00392 " Possible solution:\n\n\tchmod 0666 "
00393 "%s\n\n", realport));
00394 } else if (errno == ENODEV) {
00395 while (count <= 5) {
00396 if (isatty(fileno(stdout))) {
00397 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00398 "\r Port not connected,"
00399 " sleeping for 2 seconds, "));
00400 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00401 "%d retries..",
00402 5-count));
00403 }
00404 sleep(2);
00405 count++;
00406 goto begin;
00407 }
00408 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00409 "\n\n Device not found on %s, \
00410 Did you hit HotSync?\n\n", realport));
00411 } else if (errno == EISDIR) {
00412 LOG((PI_DBG_DEV, PI_DBG_LVL_ERR,
00413 " The port specified must"
00414 " contain a device name, and %s was"
00415 " a directory.\n"
00416 " Please change that to reference a"
00417 " real device, and try"
00418 " again\n\n", pa->pi_device));
00419 }
00420 return err;
00421 }
00422 ps->raddr = malloc(addrlen);
00423 memcpy(ps->raddr, addr, addrlen);
00424 ps->raddrlen = addrlen;
00425 ps->laddr = malloc(addrlen);
00426 memcpy(ps->laddr, addr, addrlen);
00427 ps->laddrlen = addrlen;
00428
00429 return 0;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 static int pi_serial_listen(pi_socket_t *ps, int backlog)
00444 {
00445 int result;
00446 struct pi_serial_data *data =
00447 (struct pi_serial_data *)ps->device->data;
00448
00449
00450 result = data->impl.changebaud(ps);
00451 if (result == 0)
00452 ps->state = PI_SOCK_LISTEN;
00453
00454 return result;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 static int
00469 pi_serial_accept(pi_socket_t *ps, struct sockaddr *addr,
00470 size_t *addrlen)
00471 {
00472 struct pi_serial_data *data =
00473 (struct pi_serial_data *)ps->device->data;
00474 size_t size;
00475 int err;
00476
00477
00478 #ifdef linux
00479 if (ps->accept_to) {
00480
00481 int result = data->impl.poll(ps, 1000);
00482 LOG((PI_DBG_DEV, PI_DBG_LVL_DEBUG, "%s: %d, poll result: %d.\n", __FILE__, __LINE__, result));
00483
00484 if (result < 0) {
00485 char buf[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
00486 data->impl.write(ps, buf, sizeof (buf), 1000);
00487 }
00488 }
00489 #endif
00490 if ((err = data->impl.poll(ps, ps->accept_to * 1000)) < 0)
00491 goto fail;
00492
00493 data->timeout = ps->accept_to * 1000;
00494
00495 pi_socket_init(ps);
00496 if (ps->type == PI_SOCK_STREAM) {
00497 struct timeval tv;
00498 unsigned char cmp_flags;
00499
00500 switch (ps->cmd) {
00501 case PI_CMD_CMP:
00502 if ((err = cmp_rx_handshake(ps, data->establishrate, data->establishhighrate)) < 0)
00503 goto fail;
00504
00505
00506 size = sizeof(cmp_flags);
00507 pi_getsockopt(ps->sd, PI_LEVEL_CMP, PI_CMP_FLAGS, &cmp_flags, &size);
00508 if (cmp_flags & CMP_FL_LONG_PACKET_SUPPORT) {
00509 int use_long_format = 1;
00510 size = sizeof(int);
00511 pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT,
00512 &use_long_format, &size);
00513 ps->command ^= 1;
00514 pi_setsockopt(ps->sd, PI_LEVEL_PADP, PI_PADP_USE_LONG_FORMAT,
00515 &use_long_format, &size);
00516 ps->command ^= 1;
00517 }
00518
00519
00520 size = sizeof(data->rate);
00521 pi_getsockopt(ps->sd, PI_LEVEL_CMP, PI_CMP_BAUD, &data->rate, &size);
00522 if ((err = data->impl.changebaud(ps)) < 0)
00523 goto fail;
00524
00525
00526 tv.tv_sec = 0;
00527 tv.tv_usec = 50000;
00528 select(0, 0, 0, 0, &tv);
00529 break;
00530
00531 case PI_CMD_NET:
00532
00533
00534
00535 #ifdef MACOSX
00536
00537
00538
00539
00540 {
00541 int split = 0;
00542 size_t chunksize = 0;
00543
00544 size = sizeof (split);
00545 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES,
00546 &split, &size);
00547 size = sizeof (chunksize);
00548 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE,
00549 &chunksize, &size);
00550
00551 ps->command ^= 1;
00552 size = sizeof (split);
00553 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_SPLIT_WRITES,
00554 &split, &size);
00555 size = sizeof (chunksize);
00556 pi_setsockopt(ps->sd, PI_LEVEL_NET, PI_NET_WRITE_CHUNKSIZE,
00557 &chunksize, &size);
00558 ps->command ^= 1;
00559 }
00560 #endif
00561 if ((err = net_rx_handshake(ps)) < 0)
00562 goto fail;
00563 break;
00564 }
00565 ps->dlprecord = 0;
00566 }
00567
00568 data->timeout = 0;
00569 ps->command = 0;
00570 ps->state = PI_SOCK_CONN_ACCEPT;
00571
00572 return ps->sd;
00573
00574 fail:
00575 return err;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 static int
00591 pi_serial_getsockopt(pi_socket_t *ps, int level, int option_name,
00592 void *option_value, size_t *option_len)
00593 {
00594 struct pi_serial_data *data =
00595 (struct pi_serial_data *)ps->device->data;
00596
00597 switch (option_name) {
00598 case PI_DEV_RATE:
00599 if (*option_len != sizeof (data->rate))
00600 goto error;
00601 memcpy (option_value, &data->rate, sizeof (data->rate));
00602 break;
00603
00604 case PI_DEV_ESTRATE:
00605 if (*option_len != sizeof (data->establishrate))
00606 goto error;
00607 memcpy (option_value, &data->establishrate, sizeof (data->establishrate));
00608 break;
00609
00610 case PI_DEV_HIGHRATE:
00611 if (*option_len != sizeof (data->establishhighrate))
00612 goto error;
00613 memcpy (option_value, &data->establishhighrate, sizeof (data->establishhighrate));
00614 break;
00615
00616 case PI_DEV_TIMEOUT:
00617 if (*option_len != sizeof (data->timeout))
00618 goto error;
00619 memcpy (option_value, &data->timeout, sizeof (data->timeout));
00620 break;
00621 }
00622
00623 return 0;
00624
00625 error:
00626 errno = EINVAL;
00627 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 static int
00643 pi_serial_setsockopt(pi_socket_t *ps, int level, int option_name,
00644 const void *option_value, size_t *option_len)
00645 {
00646 struct pi_serial_data *data =
00647 (struct pi_serial_data *)ps->device->data;
00648
00649
00650 switch (option_name) {
00651 case PI_DEV_ESTRATE:
00652 if (*option_len != sizeof (data->establishrate))
00653 goto error;
00654 memcpy (&data->establishrate, option_value, sizeof (data->establishrate));
00655 break;
00656
00657 case PI_DEV_HIGHRATE:
00658 if (*option_len != sizeof (data->establishhighrate))
00659 goto error;
00660 memcpy (&data->establishhighrate, option_value, sizeof (data->establishhighrate));
00661 break;
00662
00663 case PI_DEV_TIMEOUT:
00664 if (*option_len != sizeof (data->timeout))
00665 goto error;
00666 memcpy (&data->timeout, option_value, sizeof (data->timeout));
00667 break;
00668 }
00669
00670 return 0;
00671
00672 error:
00673 errno = EINVAL;
00674 return pi_set_error(ps->sd, PI_ERR_GENERIC_ARGUMENT);
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 static int pi_serial_close(pi_socket_t *ps)
00690 {
00691 struct pi_serial_data *data =
00692 (struct pi_serial_data *)ps->device->data;
00693
00694 if (ps->sd) {
00695 data->impl.close (ps);
00696 ps->sd = 0;
00697 }
00698
00699 if (ps->laddr) {
00700 free(ps->laddr);
00701 ps->laddr = NULL;
00702 }
00703
00704 if (ps->raddr) {
00705 free(ps->raddr);
00706 ps->raddr = NULL;
00707 }
00708
00709 return 0;
00710 }
00711
00712
00713
00714
00715
00716
00717