serial_cmd.c

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

Generated on Mon Mar 21 14:14:55 2011 by  doxygen 1.4.7