pigpiod.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 65+
30 */
31 
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <pwd.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <fcntl.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #include <syslog.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <ctype.h>
45 #include <sys/socket.h>
46 #include <netdb.h>
47 
48 #include "pigpio.h"
49 
50 /*
51 This program starts the pigpio library as a daemon.
52 */
53 
57 static unsigned ifFlags = PI_DEFAULT_IF_FLAGS;
63 static uint64_t updateMask = -1;
64 
66 
67 static int updateMaskSet = 0;
68 
69 static FILE * errFifo;
70 
72 
73 static int numSockNetAddr = 0;
74 
75 void fatal(char *fmt, ...)
76 {
77  char buf[128];
78  va_list ap;
79 
80  va_start(ap, fmt);
81  vsnprintf(buf, sizeof(buf), fmt, ap);
82  va_end(ap);
83 
84  fprintf(stderr, "%s\n", buf);
85 
86  fflush(stderr);
87 
88  exit(EXIT_FAILURE);
89 }
90 
91 void usage()
92 {
93  fprintf(stderr, "\n" \
94  "pigpio V%d\n" \
95  "Usage: sudo pigpiod [OPTION] ...\n" \
96  " -a value, DMA mode, 0=AUTO, 1=PMAP, 2=MBOX, default AUTO\n" \
97  " -b value, sample buffer size in ms, default 120\n" \
98  " -c value, library internal settings, default 0\n" \
99  " -d value, primary DMA channel, 0-14, default 14\n" \
100  " -e value, secondary DMA channel, 0-14, default 6\n" \
101  " -f, disable fifo interface, default enabled\n" \
102  " -g, run in foreground (do not fork), default disabled\n" \
103  " -k, disable socket interface, default enabled\n" \
104  " -l, localhost socket only default local+remote\n" \
105  " -m, disable alerts default enabled\n" \
106  " -n IP addr, allow address, name or dotted, default allow all\n" \
107  " -p value, socket port, 1024-32000, default 8888\n" \
108  " -s value, sample rate, 1, 2, 4, 5, 8, or 10, default 5\n" \
109  " -t value, clock peripheral, 0=PWM 1=PCM, default PCM\n" \
110  " -v, -V, display pigpio version and exit\n" \
111  " -x mask, GPIO which may be updated, default board GPIO\n" \
112  "EXAMPLE\n" \
113  "sudo pigpiod -s 2 -b 200 -f\n" \
114  " Set a sample rate of 2 microseconds with a 200 millisecond\n" \
115  " buffer. Disable the fifo interface.\n" \
116  "\n", PIGPIO_VERSION);
117 }
118 
119 static uint64_t getNum(char *str, int *err)
120 {
121  uint64_t val;
122  char *endptr;
123 
124  *err = 0;
125  val = strtoll(str, &endptr, 0);
126  if (*endptr) {*err = 1; val = -1;}
127  return val;
128 }
129 
130 static uint32_t checkAddr(char *addrStr)
131 {
132  int err;
133  struct addrinfo hints, *res;
134  struct sockaddr_in *sin;
135  const char *portStr;
136  uint32_t addr;
137 
138  portStr = getenv(PI_ENVPORT);
139 
140  if (!portStr) portStr = PI_DEFAULT_SOCKET_PORT_STR;
141 
142  memset (&hints, 0, sizeof (hints));
143 
144  hints.ai_family = AF_INET;
145  hints.ai_socktype = SOCK_STREAM;
146  hints.ai_flags |= AI_CANONNAME;
147 
148  err = getaddrinfo(addrStr, portStr, &hints, &res);
149 
150  if (err) return 0;
151 
152  sin = (struct sockaddr_in *)res->ai_addr;
153  addr = sin->sin_addr.s_addr;
154 
155  freeaddrinfo(res);
156 
157  return addr;
158 }
159 
160 static void initOpts(int argc, char *argv[])
161 {
162  int opt, err, i;
163  uint32_t addr;
164  int64_t mask;
165 
166  while ((opt = getopt(argc, argv, "a:b:c:d:e:fgkln:mp:s:t:x:vV")) != -1)
167  {
168  switch (opt)
169  {
170  case 'a':
171  i = getNum(optarg, &err);
172  if ((i >= PI_MEM_ALLOC_AUTO) && (i <= PI_MEM_ALLOC_MAILBOX))
173  memAllocMode = i;
174  else fatal("invalid -a option (%d)", i);
175  break;
176 
177  case 'b':
178  i = getNum(optarg, &err);
179  if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX))
181  else fatal("invalid -b option (%d)", i);
182  break;
183 
184  case 'c':
185  i = getNum(optarg, &err);
186  if ((i >= 0) && (i < PI_CFG_ILLEGAL_VAL))
187  cfgInternals = i;
188  else fatal("invalid -c option (%x)", i);
189  break;
190 
191  case 'd':
192  i = getNum(optarg, &err);
193  if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL))
194  DMAprimaryChannel = i;
195  else fatal("invalid -d option (%d)", i);
196  break;
197 
198  case 'e':
199  i = getNum(optarg, &err);
200  if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL))
202  else fatal("invalid -e option (%d)", i);
203  break;
204 
205  case 'f':
207  break;
208 
209  case 'g':
210  foreground = 1;
211  break;
212 
213  case 'k':
215  break;
216 
217  case 'l':
219  break;
220 
221  case 'm':
223  break;
224 
225  case 'n':
226  addr = checkAddr(optarg);
228  sockNetAddr[numSockNetAddr++] = addr;
229  else fatal("invalid -n option (%s)", optarg);
230  break;
231 
232  case 'p':
233  i = getNum(optarg, &err);
234  if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT))
235  socketPort = i;
236  else fatal("invalid -p option (%d)", i);
237  break;
238 
239  case 's':
240  i = getNum(optarg, &err);
241 
242  switch(i)
243  {
244  case 1:
245  case 2:
246  case 4:
247  case 5:
248  case 8:
249  case 10:
250  clockMicros = i;
251  break;
252 
253  default:
254  fatal("invalid -s option (%d)", i);
255  break;
256  }
257  break;
258 
259  case 't':
260  i = getNum(optarg, &err);
261  if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM))
262  clockPeripheral = i;
263  else fatal("invalid -t option (%d)", i);
264  break;
265 
266  case 'v':
267  case 'V':
268  printf("%d\n", PIGPIO_VERSION);
269  exit(EXIT_SUCCESS);
270  break;
271 
272  case 'x':
273  mask = getNum(optarg, &err);
274  if (!err)
275  {
276  updateMask = mask;
277  updateMaskSet = 1;
278  }
279  else fatal("invalid -x option (%s)", optarg);
280  break;
281 
282  default: /* '?' */
283  usage();
284  exit(EXIT_FAILURE);
285  }
286  }
287 }
288 
289 void terminate(int signum)
290 {
291  /* only registered for SIGHUP/SIGTERM */
292 
293  gpioTerminate();
294 
295  fprintf(errFifo, "SIGHUP/SIGTERM received\n");
296 
297  fflush(NULL);
298 
299  fclose(errFifo);
300 
301  unlink(PI_ERRFIFO);
302 
303  exit(0);
304 }
305 
306 
307 int main(int argc, char **argv)
308 {
309  pid_t pid;
310  int flags;
311 
312  /* check command line parameters */
313 
314  initOpts(argc, argv);
315 
316  if (!foreground) {
317  /* Fork off the parent process */
318 
319  pid = fork();
320 
321  if (pid < 0) { exit(EXIT_FAILURE); }
322 
323  /* If we got a good PID, then we can exit the parent process. */
324 
325  if (pid > 0) { exit(EXIT_SUCCESS); }
326 
327  /* Change the file mode mask */
328 
329  umask(0);
330 
331  /* Open any logs here */
332 
333  /* NONE */
334 
335  /* Create a new SID for the child process */
336 
337  if (setsid() < 0) fatal("setsid failed (%m)");
338 
339  /* Change the current working directory */
340 
341  if ((chdir("/")) < 0) fatal("chdir failed (%m)");
342 
343  /* Close out the standard file descriptors */
344 
345  fclose(stdin);
346  fclose(stdout);
347  }
348 
349  /* configure library */
350 
352 
354 
356 
358 
360 
362 
364 
366 
368 
369  /* start library */
370 
371  if (gpioInitialise()< 0) fatal("Can't initialise pigpio library");
372 
373  /* create pipe for error reporting */
374 
375  unlink(PI_ERRFIFO);
376 
377  mkfifo(PI_ERRFIFO, 0664);
378 
379  if (chmod(PI_ERRFIFO, 0664) < 0)
380  fatal("chmod %s failed (%m)", PI_ERRFIFO);
381 
382  errFifo = freopen(PI_ERRFIFO, "w+", stderr);
383 
384  if (errFifo)
385  {
386  /* set stderr non-blocking */
387 
388  flags = fcntl(fileno(errFifo), F_GETFL, 0);
389  fcntl(fileno(errFifo), F_SETFL, flags | O_NONBLOCK);
390 
391  /* request SIGHUP/SIGTERM from libarary for termination */
392 
393  gpioSetSignalFunc(SIGHUP, terminate);
394  gpioSetSignalFunc(SIGTERM, terminate);
395 
396  /* sleep forever */
397 
398  while (1)
399  {
400  /* cat /dev/pigerr to view daemon errors */
401 
402  sleep(5);
403 
404  fflush(errFifo);
405  }
406  }
407  else
408  {
409  fprintf(stderr, "freopen failed (%m)");
410 
411  gpioTerminate();
412  }
413 
414  return 0;
415 }
416 
417 
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
Definition: pigpio.c:12401
#define MAX_CONNECT_ADDRESSES
Definition: pigpio.h:906
static uint32_t sockNetAddr[MAX_CONNECT_ADDRESSES]
Definition: pigpiod.c:71
static uint64_t updateMask
Definition: pigpiod.c:63
static unsigned ifFlags
Definition: pigpiod.c:57
#define PI_DEFAULT_CLK_PERIPHERAL
Definition: pigpio.h:6423
int gpioInitialise(void)
Definition: pigpio.c:8459
static int updateMaskSet
Definition: pigpiod.c:67
int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel)
Definition: pigpio.c:13383
static unsigned clockMicros
Definition: pigpiod.c:55
static uint64_t getNum(char *str, int *err)
Definition: pigpiod.c:119
#define PI_LOCALHOST_SOCK_IF
Definition: pigpio.h:849
#define PI_DEFAULT_SOCKET_PORT
Definition: pigpio.h:6429
static int foreground
Definition: pigpiod.c:58
void fatal(char *fmt,...)
Definition: pigpiod.c:75
void terminate(int signum)
Definition: pigpiod.c:289
#define PI_DEFAULT_MEM_ALLOC_MODE
Definition: pigpio.h:6440
#define PI_DEFAULT_CFG_INTERNALS
Definition: pigpio.h:6442
int gpioCfgPermissions(uint64_t updateMask)
Definition: pigpio.c:13408
int gpioCfgSetInternals(uint32_t cfgVal)
Definition: pigpio.c:13504
static unsigned bufferSizeMilliseconds
Definition: pigpiod.c:54
static void initOpts(int argc, char *argv[])
Definition: pigpiod.c:160
#define PI_MAX_DMA_CHANNEL
Definition: pigpio.h:837
#define PI_BUF_MILLIS_MIN
Definition: pigpio.h:824
static unsigned clockPeripheral
Definition: pigpiod.c:56
static unsigned DMAprimaryChannel
Definition: pigpiod.c:59
static FILE * errFifo
Definition: pigpiod.c:69
int gpioCfgSocketPort(unsigned port)
Definition: pigpio.c:13440
#define PI_DISABLE_FIFO_IF
Definition: pigpio.h:847
#define PI_BUF_MILLIS_MAX
Definition: pigpio.h:825
#define PI_DEFAULT_DMA_PRIMARY_CHANNEL
Definition: pigpio.h:6427
static unsigned DMAsecondaryChannel
Definition: pigpiod.c:60
#define PI_DISABLE_SOCK_IF
Definition: pigpio.h:848
#define PI_DEFAULT_FOREGROUND
Definition: pigpio.h:6425
static uint32_t checkAddr(char *addrStr)
Definition: pigpiod.c:130
int gpioCfgClock(unsigned micros, unsigned peripheral, unsigned source)
Definition: pigpio.c:13342
static unsigned socketPort
Definition: pigpiod.c:61
#define PI_MAX_SOCKET_PORT
Definition: pigpio.h:842
void gpioTerminate(void)
Definition: pigpio.c:8495
#define PI_MIN_DMA_CHANNEL
Definition: pigpio.h:836
#define PIGPIO_VERSION
Definition: pigpio.h:34
static unsigned memAllocMode
Definition: pigpiod.c:62
int gpioCfgMemAlloc(unsigned memAllocMode)
Definition: pigpio.c:13457
int gpioCfgInterfaces(unsigned ifFlags)
Definition: pigpio.c:13424
#define PI_DEFAULT_DMA_SECONDARY_CHANNEL
Definition: pigpio.h:6428
static int numSockNetAddr
Definition: pigpiod.c:73
#define PI_DEFAULT_IF_FLAGS
Definition: pigpio.h:6424
#define PI_DEFAULT_SOCKET_PORT_STR
Definition: pigpio.h:6430
static uint32_t cfgInternals
Definition: pigpiod.c:65
void usage()
Definition: pigpiod.c:91
#define PI_CLOCK_PWM
Definition: pigpio.h:831
#define PI_MEM_ALLOC_AUTO
Definition: pigpio.h:854
int gpioCfgNetAddr(int numSockAddr, uint32_t *sockAddr)
Definition: pigpio.c:13474
#define PI_DEFAULT_CLK_MICROS
Definition: pigpio.h:6422
#define PI_DISABLE_ALERT
Definition: pigpio.h:850
#define PI_CLOCK_PCM
Definition: pigpio.h:832
#define PI_ENVPORT
Definition: pigpio.h:384
int gpioCfgBufferSize(unsigned millis)
Definition: pigpio.c:13325
int main(int argc, char **argv)
Definition: pigpiod.c:307
#define PI_MIN_SOCKET_PORT
Definition: pigpio.h:841
#define PI_ERRFIFO
Definition: pigpio.h:382
#define PI_CFG_ILLEGAL_VAL
Definition: pigpio.h:871
#define PI_DEFAULT_BUFFER_MILLIS
Definition: pigpio.h:6421
#define PI_MEM_ALLOC_MAILBOX
Definition: pigpio.h:856


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