00001
00012 #include "edtinc.h"
00013 #include "pciload.h"
00014
00015 #define SERBUFSIZE 512
00016
00017
00018 void print_ascii_string(char *buf);
00019 long PdvDispatch(int argc, char *argv[], char *edt_devname);
00020 long
00021 PdvSerialWriteRead(int argc, char *argv[], int unit, int hexin,
00022 int do_wait, int do_printflush, int inter, int timeout, int verbose,
00023 int baud, int readonly, int channel);
00024 long isascii_str(u_char *buf, int n);
00025 long ack_nak_str(u_char *buf, int n);
00026
00027 int print_inter_help()
00028 {
00029 puts("");
00030 puts("EDT serial_cmd, interactive mode help");
00031 puts("");
00032 puts("Enter any command that is valid for the camera. For example, to get camera");
00033 puts("status from a Kodak MEGAPLUS camera, type in STS? then press ENTER.");
00034 puts("");
00035 puts("If you don't get responses from query commands, make sure the camera is");
00036 puts("configured for RS-422 control. Kodak MEGAPLUS cameras may be factory");
00037 puts("configured for either RS-232 or RS-422 control, and must be switched");
00038 puts("to RS-422 to work with the EDT interface.");
00039 puts("");
00040 puts("See your camera users guide for control options and valid commands.");
00041 puts("Run \"serial_cmd -h\" for command line options.");
00042 puts("");
00043 return 0;
00044 }
00045
00046 int pnum=0;
00047 void
00048 printify(u_char *buf, u_char *dest, int n, int show_nonprint)
00049 {
00050 int has_lf = FALSE;
00051 int i, j;
00052
00053 for (i = 0; i < n; i++)
00054 {
00055 if (buf[i] == 10)
00056 has_lf = TRUE;
00057 }
00058
00059 for (i = 0, j = 0; i < n; i++)
00060 {
00061
00062 if (buf[i] == 13)
00063 {
00064 if (!has_lf)
00065 dest[j++] = '\n';
00066 }
00067 else if (buf[i] == 10 || (buf[i] >= ' ' && buf[i] < 127))
00068 dest[j++] = buf[i];
00069 else if (show_nonprint)
00070 {
00071 switch (buf[i])
00072 {
00073 case 0x06:
00074 strcpy((char *) dest + j, "<ACK>");
00075 break;
00076 case 0x15:
00077 strcpy((char *) dest + j, "<NAK>");
00078 break;
00079 case 0x02:
00080 strcpy((char *) dest + j, "<STX>");
00081 break;
00082 case 0x03:
00083 strcpy((char *) dest + j, "<ETX>");
00084 break;
00085 default:
00086 sprintf((char *) dest + j, "<%02x>", buf[i]);
00087 }
00088
00089 j = strlen((char *) dest);
00090
00091 }
00092
00093 dest[j] = 0;
00094 }
00095 }
00096
00097 int basler_framing = 0;
00098 int duncan_framing = 0;
00099
00100 void
00101 usage(char *err)
00102 {
00103 printf("%s", err);
00104 printf("Usage: \n");
00105 printf(
00106 " -?, /?, -h - Help message\n"
00107 " --help - Help message\n"
00108 " -u N - Unit number (default 0)\n"
00109 " -f N - FOI (fiber optic remote) unit #\n"
00110 " -c N - channel #\n"
00111 " -b baud - Set baud rate\n"
00112 " -v - Verbose\n"
00113 " -w - Wait before read\n"
00114 " -r - Read only\n"
00115 " -p - Print what's in the buffer on start\n"
00116 " -t - Serial timeout override value\n"
00117 " -B - Basler framing mode -- cmd should be hex cmd (bytes separated by\n"
00118 " -D - Duncan framing mode -- cmd should be hex cmd (bytes separated by\n"
00119 " spaces, with NO framing info (serial_cmd will add STX and Checksum)\n"
00120 " -x - Hex mode -- cmd should be hex bytes separared by spaces\n"
00121 " \"cmd\" - ASCII (default) or hex command(s) to send\n"
00122 );
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 #ifdef NO_MAIN
00134 #include "opt_util.h"
00135 char *argument ;
00136 int option ;
00137 int
00138 serial_cmd(char *command_line)
00139 #else
00140 int
00141 main(int argc, char **argv)
00142 #endif
00143 {
00144 long status;
00145 int unit = 0;
00146 int hexin = 0;
00147 int inter = 0;
00148 int verbose = 0;
00149 int do_wait = 0;
00150 int do_printflush = 0;
00151 int timeout = 0;
00152 int channel = 0;
00153 int readonly = 0;
00154 int baud = 0;
00155 #ifdef NO_MAIN
00156 char **argv = 0 ;
00157 int argc = 0 ;
00158 opt_create_argv("serial_cmd",command_line,&argc,&argv);
00159 #endif
00160
00161 --argc;
00162 ++argv;
00163 while ((argc > 0) && ((argv[0][0] == '-') || (argv[0][0] == '/')))
00164 {
00165 switch (argv[0][1])
00166 {
00167 case 'u':
00168 ++argv;
00169 --argc;
00170 if (argc < 1)
00171 {
00172 usage("Error: option 'u' requires a numeric argument\n");
00173 exit(1);
00174 }
00175 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00176 {
00177 unit = atoi(argv[0]);
00178 }
00179 else
00180 {
00181 usage("Error: option 'u' requires a numeric argument\n");
00182 exit(1);
00183 }
00184 break;
00185
00186 case 'x':
00187 hexin = 1;
00188 break;
00189
00190 case 'w':
00191 do_wait = 1;
00192 break;
00193
00194 case 'p':
00195 do_printflush = 1;
00196 break;
00197
00198 case 't':
00199 ++argv;
00200 --argc;
00201 if (argc < 1) {
00202 usage("Error: option 't' requires argument\n");
00203 exit(1);
00204 }
00205 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00206 timeout = atoi(argv[0]);
00207 break;
00208
00209 case 'b':
00210 ++argv;
00211 --argc;
00212 if (argc < 1) {
00213 usage("Error: option 'b' requires argument\n");
00214 exit(1);
00215 }
00216 baud = atoi(argv[0]);
00217 break;
00218
00219 case 'v':
00220 verbose = 1;
00221 break;
00222
00223 case '-':
00224 if (strcmp(argv[0], "--help") == 0) {
00225 usage("");
00226 exit(0);
00227 } else {
00228 fprintf(stderr, "unknown option: %s\n", argv[0]);
00229 usage("");
00230 exit(1);
00231 }
00232 break;
00233
00234 case 'h':
00235 case '?':
00236 usage("");
00237 exit(0);
00238 break;
00239
00240 case 'r':
00241 readonly = 1;
00242 break;
00243
00244 case 'c':
00245 ++argv;
00246 --argc;
00247 if (argc < 1)
00248 {
00249 usage("Error - channel # expected\n");
00250 exit(-1);
00251 }
00252 channel = atoi(argv[0]);
00253 break;
00254
00255 case 'B':
00256 basler_framing = 1;
00257 break;
00258
00259 case 'D':
00260 duncan_framing = 1;
00261 break;
00262
00263 default:
00264 usage("unknown flag\n");
00265 exit(1);
00266 break;
00267 }
00268 argc--;
00269 argv++;
00270 }
00271
00272 if ((argc < 1) && !readonly && !do_printflush)
00273 inter = 1;
00274
00275 if (readonly && (timeout == 0))
00276 timeout = 60000;
00277
00278 status = PdvSerialWriteRead(argc, argv, unit, hexin, do_wait, do_printflush, inter,
00279 timeout, verbose, baud, readonly, channel);
00280 #ifndef NO_MAIN
00281 exit(status);
00282 #endif
00283 return (0);
00284 }
00285
00286
00287 long
00288 PdvSerialWriteRead(int argc, char *argv[], int unit, int hexin,
00289 int do_wait, int do_printflush, int inter, int timeout, int verbose,
00290 int baud, int readonly, int channel)
00291 {
00292 int i;
00293 int ret;
00294 int nbytes;
00295 int length=0;
00296 u_char hbuf[SERBUFSIZE];
00297 char tmpbuf[SERBUFSIZE+1];
00298 char getbuf[SERBUFSIZE+1];
00299 char *ibuf_p;
00300 u_char lastbyte, waitc;
00301 char buf[SERBUFSIZE+1];
00302 char bs[32][3];
00303 EdtDev *ed;
00304
00305
00306 ed = pdv_open_channel(EDT_INTERFACE, unit, channel);
00307 if (ed == NULL)
00308 {
00309 pdv_perror(EDT_INTERFACE);
00310 return -1;
00311 }
00312
00313 pdv_serial_read_enable(ed);
00314
00315 if (timeout < 1)
00316 timeout = ed->dd_p->serial_timeout;
00317
00318 if (verbose)
00319 printf("serial timeout %d\n", timeout);
00320
00321 if (inter)
00322 {
00323 ibuf_p = getbuf;
00324 printf("\nEnter command (Ctrl-C to quit)\n\n");
00325 }
00326 else
00327 ibuf_p = argv[0];
00328
00329 if (baud)
00330 {
00331 pdv_set_baud(ed, baud);
00332 }
00333
00334 if ((pdv_serial_read(ed, buf, SERBUFSIZE) > 0) && do_printflush)
00335 {
00336 printf("%s\n", buf);
00337 exit (0);
00338 }
00339
00340 do
00341 {
00342 if (inter)
00343 {
00344 printf("> ");
00345 if (strlen(fgets(ibuf_p,SERBUFSIZE,stdin)) > SERBUFSIZE-1)
00346 {
00347 printf("Max command string length (%d) exceeded\n", SERBUFSIZE-1);
00348 continue;
00349 }
00350 }
00351
00352 if (!readonly)
00353 {
00354 if (hexin)
00355 {
00356 u_int val;
00357 i = 0;
00358
00359 strip_newline(ibuf_p);
00360
00361 while (*ibuf_p)
00362 {
00363 while ((*ibuf_p == ' ') || (*ibuf_p == '\t'))
00364 ++ibuf_p;
00365
00366 if (*ibuf_p == '\0')
00367 break;
00368
00369 if (sscanf(ibuf_p, "%x", &val) != 1)
00370 {
00371 printf("error reading input byte %d\n",i);
00372 i = 0;
00373 break;
00374 }
00375
00376 if (val > 0xff)
00377 {
00378 printf("Hex string format error -- expect hex bytes separated by spaces, e.g. '00 a0 ff ...' \n");
00379 i = 0;
00380 break;
00381 }
00382 else hbuf[i++] = val;
00383
00384 while ((*ibuf_p != ' ') && (*ibuf_p != '\t') && (*ibuf_p != '\0'))
00385 ++ibuf_p;
00386 }
00387
00388
00389
00390
00391
00392 if (i)
00393 pdv_serial_binary_command(ed, (char *) hbuf, i);
00394 }
00395 else if (duncan_framing)
00396 {
00397 nbytes = sscanf(ibuf_p, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
00398 bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
00399 bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
00400
00401 for (i = 0; i < nbytes; i++)
00402 {
00403 if (strlen(bs[i]) > 2)
00404 {
00405 printf("duncan command format error\n");
00406 break;
00407 }
00408 hbuf[i] = (u_char) (strtoul(bs[i], NULL, 16) & 0xff);
00409 }
00410
00411 pdv_send_duncan_frame(ed, hbuf, nbytes);
00412
00413 }
00414 else if (basler_framing)
00415 {
00416 nbytes = sscanf(ibuf_p, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
00417 bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7],
00418 bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15]);
00419
00420 for (i = 0; i < nbytes; i++)
00421 {
00422 if (strlen(bs[i]) > 2)
00423 {
00424 printf("basler command format error\n");
00425 break;
00426 }
00427 hbuf[i] = (u_char) (strtoul(bs[i], NULL, 16) & 0xff);
00428 }
00429
00430 pdv_send_basler_frame(ed, hbuf, nbytes);
00431
00432 }
00433 else
00434 {
00435 sprintf(tmpbuf, "%s\r", ibuf_p);
00436 if (verbose)
00437 printf("writing <%s>\n", ibuf_p);
00438 pdv_serial_command(ed, tmpbuf);
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447 if (duncan_framing)
00448 {
00449 ret = pdv_read_duncan_frame(ed, (u_char *)buf);
00450 printf("resp <");
00451 for (i = 0; i < ret; i++)
00452 printf("%02x%s", (u_char)buf[i], (i == ret-1)? ">\n" : " ");
00453 }
00454 else
00455 {
00456
00457 pdv_serial_wait(ed, timeout, 64);
00458
00459 if (do_wait)
00460 {
00461 printf("return to read response: ");
00462 getchar();
00463 }
00464
00465
00466
00467
00468
00469
00470
00471 do
00472 {
00473 ret = pdv_serial_read(ed, buf, SERBUFSIZE);
00474 if (verbose)
00475 printf("read returned %d\n", ret);
00476
00477 if (*buf)
00478 lastbyte = (u_char)buf[strlen(buf)-1];
00479
00480 if (ret != 0)
00481 {
00482 buf[ret + 1] = 0;
00483 if (hexin || basler_framing || duncan_framing)
00484 {
00485 int i;
00486
00487 if (ret)
00488 {
00489 printf("resp <");
00490 for (i = 0; i < ret; i++)
00491 printf("%s%02x", i ? " " : "", (u_char) buf[i]);
00492 printf(">\n");
00493 }
00494 }
00495 else
00496 print_ascii_string(buf);
00497 length += ret;
00498 }
00499
00500 if (ed->devid == PDVFOI_ID)
00501 ret = pdv_serial_wait(ed, 500, 0);
00502 else if (pdv_get_waitchar(ed, &waitc) && (lastbyte == waitc))
00503 ret = 0;
00504 else ret = pdv_serial_wait(ed, 500, 64);
00505 } while (ret > 0);
00506 }
00507
00508 printf("\n");
00509
00510 } while (inter);
00511
00512 pdv_close(ed);
00513
00514 return (1);
00515 }
00516
00517
00518
00519
00520
00521 void
00522 print_ascii_string(char *buf)
00523 {
00524 #if 0
00525 int i = 0;
00526 char *p = buf;
00527 #endif
00528 char tmpbuf[SERBUFSIZE];
00529
00530 printify((u_char *) buf, (u_char *) tmpbuf, strlen(buf), 1);
00531
00532 #if 0
00533 while (*p)
00534 {
00535 if ((*p == '\r' || *p == '\n')
00536 && (p != buf) && (*(p - 1) != '\n') && (*(p + 1) != '\n'))
00537 tmpbuf[i++] = '\n';
00538 else
00539 tmpbuf[i++] = *p;
00540 ++p;
00541 }
00542 if (tmpbuf[i - 1] != '\n')
00543 tmpbuf[i++] = '\n';
00544 tmpbuf[i] = '\0';
00545
00546 #endif
00547 fputs(tmpbuf, stdout);
00548 fflush(stdout);
00549 }
00550
00551 long
00552 isascii_str(u_char * buf, int n)
00553 {
00554 int i;
00555
00556 for (i = 0; i < n; i++)
00557 if ((buf[i] < ' ' || buf[i] > '~')
00558 && (buf[i] != '\t')
00559 && (buf[i] != '\n')
00560 && (buf[i] != '\r'))
00561 return 0;
00562 return 1;
00563 }
00564
00565 long
00566 ack_nak_str(u_char *buf, int n)
00567 {
00568 int i;
00569
00570
00571 for (i = 0; i < n; i++)
00572 if ((buf[i] < ' ' || buf[i] > '~')
00573 && (buf[i] != 0x15)
00574 && (buf[i] != 0x6)
00575 && (buf[i] != '\n')
00576 && (buf[i] != '\r'))
00577 return 0;
00578 return 1;
00579 }