pigs.c
Go to the documentation of this file.
1 /*
2 This is free and unencumbered software released into the public domain.
3 
4 Anyone is free to copy, modify, publish, use, compile, sell, or
5 distribute this software, either in source code form or as a compiled
6 binary, for any purpose, commercial or non-commercial, and by any
7 means.
8 
9 In jurisdictions that recognize copyright laws, the author or authors
10 of this software dedicate any and all copyright interest in the
11 software to the public domain. We make this dedication for the benefit
12 of the public at large and to the detriment of our heirs and
13 successors. We intend this dedication to be an overt act of
14 relinquishment in perpetuity of all present and future rights to this
15 software under copyright law.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 
25 For more information, please refer to <http://unlicense.org/>
26 */
27 
28 /*
29 This version is for pigpio version 67+
30 */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <unistd.h>
38 #include <sys/socket.h>
39 #include <sys/types.h>
40 #include <netdb.h>
41 #include <arpa/inet.h>
42 
43 #include "pigpio.h"
44 #include "command.h"
45 #include "pigs.h"
46 
47 /*
48 This program provides a socket interface to some of
49 the commands available from pigpio.
50 */
51 
54 
55 int printFlags = 0;
56 
58 
59 #define SOCKET_OPEN_FAILED -1
60 
61 #define PRINT_HEX 1
62 #define PRINT_ASCII 2
63 
64 void report(int err, char *fmt, ...)
65 {
66  char buf[128];
67  va_list ap;
68 
69  if (err > status) status = err;
70 
71  va_start(ap, fmt);
72  vsnprintf(buf, sizeof(buf), fmt, ap);
73  va_end(ap);
74 
75  fprintf(stderr, "%s\n", buf);
76 
77  fflush(stderr);
78 }
79 
80 static int initOpts(int argc, char *argv[])
81 {
82  int opt, args;
83 
84  opterr = 0;
85 
86  args = 1;
87 
88  while ((opt = getopt(argc, argv, "ax")) != -1)
89  {
90  switch (opt)
91  {
92  case 'a':
94  args++;
95  break;
96 
97  case 'x':
99  args++;
100  break;
101 
102  default:
103  args++;
104  report(PIGS_OPTION_ERR, "ERROR: bad option %c", optopt);
105  }
106  }
107  return args;
108 }
109 
110 static int openSocket(void)
111 {
112  int sock, err;
113  struct addrinfo hints, *res, *rp;
114  const char *addrStr, *portStr;
115 
116  portStr = getenv(PI_ENVPORT);
117 
118  if (!portStr) portStr = PI_DEFAULT_SOCKET_PORT_STR;
119 
120  addrStr = getenv(PI_ENVADDR);
121 
122  if (!addrStr) addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
123 
124  memset (&hints, 0, sizeof (hints));
125 
126  hints.ai_family = PF_UNSPEC;
127  hints.ai_socktype = SOCK_STREAM;
128  hints.ai_flags |= AI_CANONNAME;
129 
130  err = getaddrinfo(addrStr, portStr, &hints, &res);
131 
132  if (err) return SOCKET_OPEN_FAILED;
133 
134  for (rp=res; rp!=NULL; rp=rp->ai_next)
135  {
136  sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
137 
138  if (sock == -1) continue;
139 
140  if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
141  }
142 
143  freeaddrinfo(res);
144 
145  if (rp == NULL) return SOCKET_OPEN_FAILED;
146 
147  return sock;
148 }
149 
150 void print_result(int sock, int rv, cmdCmd_t cmd)
151 {
152  int i, r, ch;
153  uint32_t *p;
154 
155  r = cmd.res;
156 
157  switch (rv)
158  {
159  case 0:
160  case 1:
161  if (r < 0)
162  {
163  printf("%d\n", r);
164  report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
165  }
166  break;
167 
168  case 2:
169  printf("%d\n", r);
170  if (r < 0) report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
171  break;
172 
173  case 3:
174  printf("%08X\n", cmd.res);
175  break;
176 
177  case 4:
178  printf("%u\n", cmd.res);
179  break;
180 
181  case 5:
182  printf("%s", cmdUsage);
183  break;
184 
185  case 6: /*
186  BI2CZ CF2 FL FR I2CPK I2CRD I2CRI I2CRK
187  I2CZ SERR SLR SPIX SPIR
188  */
189  printf("%d", r);
190  if (r < 0) report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
191  if (r > 0)
192  {
193  if (printFlags == PRINT_ASCII) printf(" ");
194 
195  for (i=0; i<r; i++)
196  {
197  ch = response_buf[i];
198 
199  if (printFlags & PRINT_HEX) printf(" %hhx", ch);
200 
201  else if (printFlags & PRINT_ASCII)
202  {
203  if (isprint(ch) || (ch == '\n') || (ch == '\r'))
204  printf("%c", ch);
205  else printf("\\x%02hhx", ch);
206  }
207  else printf(" %hhu", response_buf[i]);
208  }
209  }
210  printf("\n");
211  break;
212 
213  case 7: /* PROCP */
214  if (r != (4 + (4*PI_MAX_SCRIPT_PARAMS)))
215  {
216  printf("%d", r);
217  report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
218  }
219  else
220  {
221  p = (uint32_t *)response_buf;
222  printf("%d", p[0]);
223  for (i=0; i<PI_MAX_SCRIPT_PARAMS; i++)
224  {
225  printf(" %d", p[i+1]);
226  }
227  }
228  printf("\n");
229  break;
230 
231  case 8: /*
232  BSCX
233  */
234  if (r < 0)
235  {
236  printf("%d", r);
237  report(PIGS_SCRIPT_ERR, "ERROR: %s", cmdErrStr(r));
238  }
239 
240  p = (uint32_t *)response_buf;
241  printf("%d %d", r-3, p[0]);
242 
243  if (r > 4)
244  {
245  if (printFlags == PRINT_ASCII) printf(" ");
246 
247  for (i=4; i<r; i++)
248  {
249  ch = response_buf[i];
250 
251  if (printFlags & PRINT_HEX) printf(" %hhx", ch);
252 
253  else if (printFlags & PRINT_ASCII)
254  {
255  if (isprint(ch) || (ch == '\n') || (ch == '\r'))
256  printf("%c", ch);
257  else printf("\\x%02hhx", ch);
258  }
259  else printf(" %hhu", response_buf[i]);
260  }
261  }
262  printf("\n");
263  break;
264 
265  }
266 }
267 
268 void get_extensions(int sock, int command, int res)
269 {
270  switch (command)
271  {
272  case PI_CMD_BI2CZ:
273  case PI_CMD_BSCX:
274  case PI_CMD_BSPIX:
275  case PI_CMD_CF2:
276  case PI_CMD_FL:
277  case PI_CMD_FR:
278  case PI_CMD_I2CPK:
279  case PI_CMD_I2CRD:
280  case PI_CMD_I2CRI:
281  case PI_CMD_I2CRK:
282  case PI_CMD_I2CZ:
283  case PI_CMD_PROCP:
284  case PI_CMD_SERR:
285  case PI_CMD_SLR:
286  case PI_CMD_SPIX:
287  case PI_CMD_SPIR:
288 
289  if (res > 0)
290  {
291  recv(sock, response_buf, res, MSG_WAITALL);
292  response_buf[res] = 0;
293  }
294  break;
295  }
296 }
297 
298 int main(int argc , char *argv[])
299 {
300  int sock, command;
301  int args, idx, i, pp, l, len;
302  cmdCmd_t cmd;
303  uint32_t p[CMD_P_ARR];
304  cmdCtlParse_t ctl;
305  cmdScript_t s;
306  char v[CMD_MAX_EXTENSION];
307 
308  sock = openSocket();
309 
310  args = initOpts(argc, argv);
311 
312  command_buf[0] = 0;
313  l = 0;
314  pp = 0;
315 
316  for (i=args; i<argc; i++)
317  {
318  l += (strlen(argv[i]) + 1);
319  if (l < sizeof(command_buf))
320  {sprintf(command_buf+pp, "%s ", argv[i]); pp=l;}
321  }
322 
323  if (pp) {command_buf[--pp] = 0;}
324 
325  ctl.eaten = 0;
326 
327  len = strlen(command_buf);
328  idx = 0;
329 
330  while ((idx >= 0) && (ctl.eaten < len))
331  {
332  if ((idx=cmdParse(command_buf, p, CMD_MAX_EXTENSION, v, &ctl)) >= 0)
333  {
334  command = p[0];
335 
336  if (command < PI_CMD_SCRIPT)
337  {
338  if (command == PI_CMD_HELP)
339  {
340  printf("%s", cmdUsage);
341  }
342  else if (command == PI_CMD_PARSE)
343  {
344  cmdParseScript(v, &s, 1);
345  if (s.par) free (s.par);
346  }
347  else
348  {
349  cmd.cmd = command;
350  cmd.p1 = p[1];
351  cmd.p2 = p[2];
352  cmd.p3 = p[3];
353 
354  if (sock != SOCKET_OPEN_FAILED)
355  {
356  if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
357  sizeof(cmdCmd_t))
358  {
359  if (p[3]) send(sock, v, p[3], 0); /* send extensions */
360 
361  if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
362  sizeof(cmdCmd_t))
363  {
364  get_extensions(sock, command, cmd.res);
365 
366  print_result(sock, cmdInfo[idx].rv, cmd);
367  }
368  else report(PIGS_CONNECT_ERR, "socket receive failed");
369  }
370  else report(PIGS_CONNECT_ERR, "socket send failed");
371  }
372  else report(PIGS_CONNECT_ERR, "socket connect failed");
373  }
374  }
375  else report(PIGS_SCRIPT_ERR,
376  "%s only allowed within a script", cmdInfo[idx].name);
377  }
378  else
379  {
380  if (idx == CMD_UNKNOWN_CMD)
382  "%s? unknown command, pigs h for help", cmdStr());
383  else
385  "%s: bad parameter, pigs h for help", cmdStr());
386  }
387  }
388 
389  if (sock >= 0) close(sock);
390 
391  return status;
392 }
393 
#define PI_CMD_FL
Definition: pigpio.h:6186
#define SOCKET_OPEN_FAILED
Definition: pigs.c:59
s
Definition: DHT22.py:257
cmdInfo_t cmdInfo[]
Definition: command.c:41
#define PI_ENVADDR
Definition: pigpio.h:385
#define CMD_P_ARR
Definition: command.h:47
#define PI_CMD_PARSE
Definition: pigpio.h:6109
int * par
Definition: command.h:100
uint32_t p3
Definition: command.h:61
#define PRINT_HEX
Definition: pigs.c:61
char response_buf[CMD_MAX_EXTENSION]
Definition: pigs.c:53
#define PI_CMD_SPIR
Definition: pigpio.h:6136
#define PI_CMD_SPIX
Definition: pigpio.h:6138
#define PIGS_OPTION_ERR
Definition: pigs.h:37
#define CMD_MAX_EXTENSION
Definition: command.h:41
#define PI_CMD_I2CRK
Definition: pigpio.h:6127
uint32_t p1
Definition: command.h:57
name
Definition: setup.py:5
#define PIGS_SCRIPT_ERR
Definition: pigs.h:38
#define PI_CMD_FR
Definition: pigpio.h:6183
int cmdParseScript(char *script, cmdScript_t *s, int diags)
Definition: command.c:1259
int main(int argc, char *argv[])
Definition: pigs.c:298
void get_extensions(int sock, int command, int res)
Definition: pigs.c:268
#define PI_CMD_SLR
Definition: pigpio.h:6104
#define PIGS_OK
Definition: pigs.h:35
#define PI_MAX_SCRIPT_PARAMS
Definition: pigpio.h:799
#define PI_CMD_BI2CZ
Definition: pigpio.h:6159
char command_buf[CMD_MAX_EXTENSION]
Definition: pigs.c:52
uint32_t res
Definition: command.h:63
ROSLIB_DECL std::string command(const std::string &cmd)
#define PI_CMD_BSCX
Definition: pigpio.h:6194
void print_result(int sock, int rv, cmdCmd_t cmd)
Definition: pigs.c:150
int r
Definition: DHT22.py:259
#define CMD_UNKNOWN_CMD
Definition: command.h:43
static int initOpts(int argc, char *argv[])
Definition: pigs.c:80
char * cmdStr(void)
Definition: command.c:624
#define PI_CMD_SERR
Definition: pigpio.h:6144
static int openSocket(void)
Definition: pigs.c:110
int status
Definition: pigs.c:57
#define PI_CMD_I2CRD
Definition: pigpio.h:6118
#define PI_CMD_I2CRI
Definition: pigpio.h:6129
int cmdParse(char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl)
Definition: command.c:629
#define PRINT_ASCII
Definition: pigs.c:62
int printFlags
Definition: pigs.c:55
#define PI_CMD_SCRIPT
Definition: pigpio.h:6215
#define PI_CMD_I2CPK
Definition: pigpio.h:6132
char * cmdUsage
Definition: command.c:264
#define PI_CMD_HELP
Definition: pigpio.h:6086
#define PI_CMD_I2CZ
Definition: pigpio.h:6161
#define PI_DEFAULT_SOCKET_ADDR_STR
Definition: pigpio.h:6431
#define PI_DEFAULT_SOCKET_PORT_STR
Definition: pigpio.h:6430
#define PI_CMD_CF2
Definition: pigpio.h:6155
#define PI_CMD_PROCP
Definition: pigpio.h:6106
#define PIGS_CONNECT_ERR
Definition: pigs.h:36
#define PI_ENVPORT
Definition: pigpio.h:384
char * cmdErrStr(int error)
Definition: command.c:1248
#define PI_CMD_BSPIX
Definition: pigpio.h:6192
void report(int err, char *fmt,...)
Definition: pigs.c:64
uint32_t p2
Definition: command.h:58
uint32_t cmd
Definition: command.h:56


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Tue Oct 20 2020 03:35:57