pigs.c
Go to the documentation of this file.
00001 /*
00002 This is free and unencumbered software released into the public domain.
00003 
00004 Anyone is free to copy, modify, publish, use, compile, sell, or
00005 distribute this software, either in source code form or as a compiled
00006 binary, for any purpose, commercial or non-commercial, and by any
00007 means.
00008 
00009 In jurisdictions that recognize copyright laws, the author or authors
00010 of this software dedicate any and all copyright interest in the
00011 software to the public domain. We make this dedication for the benefit
00012 of the public at large and to the detriment of our heirs and
00013 successors. We intend this dedication to be an overt act of
00014 relinquishment in perpetuity of all present and future rights to this
00015 software under copyright law.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00018 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
00021 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00023 OTHER DEALINGS IN THE SOFTWARE.
00024 
00025 For more information, please refer to <http://unlicense.org/>
00026 */
00027 
00028 /*
00029 This version is for pigpio version 67+
00030 */
00031 
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <stdarg.h>
00035 #include <string.h>
00036 #include <ctype.h>
00037 #include <unistd.h>
00038 #include <sys/socket.h>
00039 #include <sys/types.h>
00040 #include <netdb.h>
00041 #include <arpa/inet.h>
00042 
00043 #include "pigpio.h"
00044 #include "command.h"
00045 #include "pigs.h"
00046 
00047 /*
00048 This program provides a socket interface to some of
00049 the commands available from pigpio.
00050 */
00051 
00052 char command_buf[CMD_MAX_EXTENSION];
00053 char response_buf[CMD_MAX_EXTENSION];
00054 
00055 int printFlags = 0;
00056 
00057 int status = PIGS_OK;
00058 
00059 #define SOCKET_OPEN_FAILED -1
00060 
00061 #define PRINT_HEX 1
00062 #define PRINT_ASCII 2
00063 
00064 void report(int err, char *fmt, ...)
00065 {
00066    char buf[128];
00067    va_list ap;
00068 
00069    if (err > status) status = err;
00070 
00071    va_start(ap, fmt);
00072    vsnprintf(buf, sizeof(buf), fmt, ap);
00073    va_end(ap);
00074 
00075    fprintf(stderr, "%s\n", buf);
00076 
00077    fflush(stderr);
00078 }
00079 
00080 static int initOpts(int argc, char *argv[])
00081 {
00082    int opt, args;
00083 
00084    opterr = 0;
00085 
00086    args = 1;
00087 
00088    while ((opt = getopt(argc, argv, "ax")) != -1)
00089    {
00090       switch (opt)
00091       {
00092          case 'a':
00093             printFlags |= PRINT_ASCII;
00094             args++;
00095             break;
00096 
00097          case 'x':
00098             printFlags |= PRINT_HEX;
00099             args++;
00100             break;
00101 
00102          default:
00103             args++;
00104             report(PIGS_OPTION_ERR, "ERROR: bad option %c", optopt);
00105       }
00106     }
00107    return args;
00108 }
00109 
00110 static int openSocket(void)
00111 {
00112    int sock, err;
00113    struct addrinfo hints, *res, *rp;
00114    const char *addrStr, *portStr;
00115 
00116    portStr = getenv(PI_ENVPORT);
00117 
00118    if (!portStr) portStr = PI_DEFAULT_SOCKET_PORT_STR;
00119 
00120    addrStr = getenv(PI_ENVADDR);
00121 
00122    if (!addrStr) addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
00123 
00124    memset (&hints, 0, sizeof (hints));
00125 
00126    hints.ai_family   = PF_UNSPEC;
00127    hints.ai_socktype = SOCK_STREAM;
00128    hints.ai_flags   |= AI_CANONNAME;
00129 
00130    err = getaddrinfo(addrStr, portStr, &hints, &res);
00131 
00132    if (err) return SOCKET_OPEN_FAILED;
00133 
00134    for (rp=res; rp!=NULL; rp=rp->ai_next)
00135    {
00136       sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
00137 
00138       if (sock == -1) continue;
00139 
00140       if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
00141    }
00142 
00143    freeaddrinfo(res);
00144 
00145    if (rp == NULL) return SOCKET_OPEN_FAILED;
00146 
00147    return sock;
00148 }
00149 
00150 void print_result(int sock, int rv, cmdCmd_t cmd)
00151 {
00152    int i, r, ch;
00153    uint32_t *p;
00154 
00155    r = cmd.res;
00156 
00157    switch (rv)
00158    {
00159       case 0:
00160       case 1:
00161          if (r < 0)
00162          {
00163             printf("%d\n", r);
00164             report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
00165          }
00166          break;
00167 
00168       case 2:
00169          printf("%d\n", r);
00170          if (r < 0) report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
00171          break;
00172 
00173       case 3:
00174          printf("%08X\n", cmd.res);
00175          break;
00176 
00177       case 4:
00178          printf("%u\n", cmd.res);
00179          break;
00180 
00181       case 5:
00182          printf("%s", cmdUsage);
00183          break;
00184 
00185       case 6: /*
00186                  BI2CZ  CF2  FL  FR  I2CPK  I2CRD  I2CRI  I2CRK
00187                  I2CZ  SERR  SLR  SPIX  SPIR
00188               */
00189          printf("%d", r);
00190          if (r < 0) report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
00191          if (r > 0)
00192          {
00193             if (printFlags == PRINT_ASCII) printf(" ");
00194 
00195             for (i=0; i<r; i++)
00196             {
00197                ch = response_buf[i];
00198 
00199                if (printFlags & PRINT_HEX) printf(" %hhx", ch);
00200 
00201                else if (printFlags & PRINT_ASCII)
00202                {
00203                   if (isprint(ch) || (ch == '\n') || (ch == '\r'))
00204                      printf("%c", ch);
00205                   else printf("\\x%02hhx", ch);
00206                }
00207                else printf(" %hhu", response_buf[i]);
00208             }
00209          }
00210          printf("\n");
00211          break;
00212 
00213       case 7: /* PROCP */
00214          if (r != (4 + (4*PI_MAX_SCRIPT_PARAMS)))
00215          {
00216             printf("%d", r);
00217             report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
00218          }
00219          else
00220          {
00221             p = (uint32_t *)response_buf;
00222             printf("%d", p[0]);
00223             for (i=0; i<PI_MAX_SCRIPT_PARAMS; i++)
00224             {
00225                printf(" %d", p[i+1]);
00226             }
00227          }
00228          printf("\n");
00229          break;
00230 
00231       case 8: /*
00232                  BSCX
00233               */
00234          if (r < 0)
00235          {
00236             printf("%d", r);
00237             report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
00238          }
00239 
00240          p = (uint32_t *)response_buf;
00241          printf("%d %d", r-3, p[0]);
00242 
00243          if (r > 4)
00244          {
00245             if (printFlags == PRINT_ASCII) printf(" ");
00246 
00247             for (i=4; i<r; i++)
00248             {
00249                ch = response_buf[i];
00250 
00251                if (printFlags & PRINT_HEX) printf(" %hhx", ch);
00252 
00253                else if (printFlags & PRINT_ASCII)
00254                {
00255                   if (isprint(ch) || (ch == '\n') || (ch == '\r'))
00256                      printf("%c", ch);
00257                   else printf("\\x%02hhx", ch);
00258                }
00259                else printf(" %hhu", response_buf[i]);
00260             }
00261          }
00262          printf("\n");
00263          break;
00264 
00265    }
00266 }
00267 
00268 void get_extensions(int sock, int command, int res)
00269 {
00270    switch (command)
00271    {
00272       case PI_CMD_BI2CZ:
00273       case PI_CMD_BSCX:
00274       case PI_CMD_BSPIX:
00275       case PI_CMD_CF2:
00276       case PI_CMD_FL:
00277       case PI_CMD_FR:
00278       case PI_CMD_I2CPK:
00279       case PI_CMD_I2CRD:
00280       case PI_CMD_I2CRI:
00281       case PI_CMD_I2CRK:
00282       case PI_CMD_I2CZ:
00283       case PI_CMD_PROCP:
00284       case PI_CMD_SERR:
00285       case PI_CMD_SLR:
00286       case PI_CMD_SPIX:
00287       case PI_CMD_SPIR:
00288 
00289          if (res > 0)
00290          {
00291             recv(sock, response_buf, res, MSG_WAITALL);
00292             response_buf[res] = 0;
00293          }
00294          break;
00295    }
00296 }
00297 
00298 int main(int argc , char *argv[])
00299 {
00300    int sock, command;
00301    int args, idx, i, pp, l, len;
00302    cmdCmd_t cmd;
00303    uint32_t p[CMD_P_ARR];
00304    cmdCtlParse_t ctl;
00305    cmdScript_t s;
00306    char v[CMD_MAX_EXTENSION];
00307 
00308    sock = openSocket();
00309 
00310    args = initOpts(argc, argv);
00311 
00312    command_buf[0] = 0;
00313    l = 0;
00314    pp = 0;
00315 
00316    for (i=args; i<argc; i++)
00317    {
00318       l += (strlen(argv[i]) + 1);
00319       if (l < sizeof(command_buf))
00320          {sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
00321    }
00322 
00323    if (pp) {command_buf[--pp] = 0;}
00324 
00325    ctl.eaten = 0;
00326 
00327    len = strlen(command_buf);
00328    idx = 0;
00329 
00330    while ((idx >= 0) && (ctl.eaten < len))
00331    {
00332       if ((idx=cmdParse(command_buf, p, CMD_MAX_EXTENSION, v, &ctl)) >= 0)
00333       {
00334          command = p[0];
00335 
00336          if (command < PI_CMD_SCRIPT)
00337          {
00338             if (command == PI_CMD_HELP)
00339             {
00340                printf("%s", cmdUsage);
00341             }
00342             else if (command == PI_CMD_PARSE)
00343             {
00344                cmdParseScript(v, &s, 1);
00345                if (s.par) free (s.par);
00346             }
00347             else
00348             {
00349                cmd.cmd = command;
00350                cmd.p1 = p[1];
00351                cmd.p2 = p[2];
00352                cmd.p3 = p[3];
00353 
00354                if (sock != SOCKET_OPEN_FAILED)
00355                {
00356                   if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
00357                      sizeof(cmdCmd_t))
00358                   {
00359                      if (p[3]) send(sock, v, p[3], 0); /* send extensions */
00360 
00361                      if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
00362                         sizeof(cmdCmd_t))
00363                      {
00364                         get_extensions(sock, command, cmd.res);
00365 
00366                         print_result(sock, cmdInfo[idx].rv, cmd);
00367                      }
00368                      else report(PIGS_CONNECT_ERR, "socket receive failed");
00369                   }
00370                   else report(PIGS_CONNECT_ERR, "socket send failed");
00371                }
00372                else report(PIGS_CONNECT_ERR, "socket connect failed");
00373             }
00374          }
00375          else report(PIGS_SCRIPT_ERR,
00376                  "%s only allowed within a script", cmdInfo[idx].name);
00377       }
00378       else
00379       {
00380          if (idx == CMD_UNKNOWN_CMD)
00381             report(PIGS_SCRIPT_ERR,
00382                "%s? unknown command, pigs h for help", cmdStr());
00383          else
00384             report(PIGS_SCRIPT_ERR,
00385                "%s: bad parameter, pigs h for help", cmdStr());
00386       }
00387    }
00388 
00389    if (sock >= 0) close(sock);
00390 
00391    return status;
00392 }
00393 


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57