serial_cmd.c

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

Generated on Mon May 12 16:38:59 2008 by  doxygen 1.5.1