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 
PI_BUF_MILLIS_MAX
#define PI_BUF_MILLIS_MAX
Definition: pigpio.h:825
PI_DISABLE_ALERT
#define PI_DISABLE_ALERT
Definition: pigpio.h:850
PI_LOCALHOST_SOCK_IF
#define PI_LOCALHOST_SOCK_IF
Definition: pigpio.h:849
bufferSizeMilliseconds
static unsigned bufferSizeMilliseconds
Definition: pigpiod.c:54
gpioCfgMemAlloc
int gpioCfgMemAlloc(unsigned memAllocMode)
Definition: pigpio.c:13457
foreground
static int foreground
Definition: pigpiod.c:58
PI_DEFAULT_DMA_PRIMARY_CHANNEL
#define PI_DEFAULT_DMA_PRIMARY_CHANNEL
Definition: pigpio.h:6427
main
int main(int argc, char **argv)
Definition: pigpiod.c:307
gpioCfgSocketPort
int gpioCfgSocketPort(unsigned port)
Definition: pigpio.c:13440
PI_CLOCK_PCM
#define PI_CLOCK_PCM
Definition: pigpio.h:832
usage
void usage()
Definition: pigpiod.c:91
PI_BUF_MILLIS_MIN
#define PI_BUF_MILLIS_MIN
Definition: pigpio.h:824
MAX_CONNECT_ADDRESSES
#define MAX_CONNECT_ADDRESSES
Definition: pigpio.h:906
PI_MIN_DMA_CHANNEL
#define PI_MIN_DMA_CHANNEL
Definition: pigpio.h:836
gpioTerminate
void gpioTerminate(void)
Definition: pigpio.c:8495
PI_DEFAULT_FOREGROUND
#define PI_DEFAULT_FOREGROUND
Definition: pigpio.h:6425
clockPeripheral
static unsigned clockPeripheral
Definition: pigpiod.c:56
gpioInitialise
int gpioInitialise(void)
Definition: pigpio.c:8459
updateMask
static uint64_t updateMask
Definition: pigpiod.c:63
PI_DEFAULT_CLK_MICROS
#define PI_DEFAULT_CLK_MICROS
Definition: pigpio.h:6422
PI_CFG_ILLEGAL_VAL
#define PI_CFG_ILLEGAL_VAL
Definition: pigpio.h:871
memAllocMode
static unsigned memAllocMode
Definition: pigpiod.c:62
PI_MAX_SOCKET_PORT
#define PI_MAX_SOCKET_PORT
Definition: pigpio.h:842
PI_MEM_ALLOC_AUTO
#define PI_MEM_ALLOC_AUTO
Definition: pigpio.h:854
gpioCfgInterfaces
int gpioCfgInterfaces(unsigned ifFlags)
Definition: pigpio.c:13424
PI_DISABLE_FIFO_IF
#define PI_DISABLE_FIFO_IF
Definition: pigpio.h:847
cfgInternals
static uint32_t cfgInternals
Definition: pigpiod.c:65
PI_DEFAULT_BUFFER_MILLIS
#define PI_DEFAULT_BUFFER_MILLIS
Definition: pigpio.h:6421
errFifo
static FILE * errFifo
Definition: pigpiod.c:69
terminate
void terminate(int signum)
Definition: pigpiod.c:289
getNum
static uint64_t getNum(char *str, int *err)
Definition: pigpiod.c:119
checkAddr
static uint32_t checkAddr(char *addrStr)
Definition: pigpiod.c:130
gpioCfgClock
int gpioCfgClock(unsigned micros, unsigned peripheral, unsigned source)
Definition: pigpio.c:13342
gpioSetSignalFunc
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
Definition: pigpio.c:12401
PI_MIN_SOCKET_PORT
#define PI_MIN_SOCKET_PORT
Definition: pigpio.h:841
initOpts
static void initOpts(int argc, char *argv[])
Definition: pigpiod.c:160
PI_DEFAULT_IF_FLAGS
#define PI_DEFAULT_IF_FLAGS
Definition: pigpio.h:6424
argv
argv
socketPort
static unsigned socketPort
Definition: pigpiod.c:61
gpioCfgNetAddr
int gpioCfgNetAddr(int numSockAddr, uint32_t *sockAddr)
Definition: pigpio.c:13474
PI_ERRFIFO
#define PI_ERRFIFO
Definition: pigpio.h:382
PI_DEFAULT_DMA_SECONDARY_CHANNEL
#define PI_DEFAULT_DMA_SECONDARY_CHANNEL
Definition: pigpio.h:6428
DMAsecondaryChannel
static unsigned DMAsecondaryChannel
Definition: pigpiod.c:60
pigpio.h
DMAprimaryChannel
static unsigned DMAprimaryChannel
Definition: pigpiod.c:59
PI_DEFAULT_CFG_INTERNALS
#define PI_DEFAULT_CFG_INTERNALS
Definition: pigpio.h:6442
PI_CLOCK_PWM
#define PI_CLOCK_PWM
Definition: pigpio.h:831
PI_DEFAULT_SOCKET_PORT_STR
#define PI_DEFAULT_SOCKET_PORT_STR
Definition: pigpio.h:6430
PI_DEFAULT_CLK_PERIPHERAL
#define PI_DEFAULT_CLK_PERIPHERAL
Definition: pigpio.h:6423
PI_ENVPORT
#define PI_ENVPORT
Definition: pigpio.h:384
numSockNetAddr
static int numSockNetAddr
Definition: pigpiod.c:73
gpioCfgBufferSize
int gpioCfgBufferSize(unsigned millis)
Definition: pigpio.c:13325
gpioCfgPermissions
int gpioCfgPermissions(uint64_t updateMask)
Definition: pigpio.c:13408
PI_MEM_ALLOC_MAILBOX
#define PI_MEM_ALLOC_MAILBOX
Definition: pigpio.h:856
PI_DISABLE_SOCK_IF
#define PI_DISABLE_SOCK_IF
Definition: pigpio.h:848
PI_DEFAULT_MEM_ALLOC_MODE
#define PI_DEFAULT_MEM_ALLOC_MODE
Definition: pigpio.h:6440
ifFlags
static unsigned ifFlags
Definition: pigpiod.c:57
gpioCfgDMAchannels
int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel)
Definition: pigpio.c:13383
updateMaskSet
static int updateMaskSet
Definition: pigpiod.c:67
fatal
void fatal(char *fmt,...)
Definition: pigpiod.c:75
gpioCfgSetInternals
int gpioCfgSetInternals(uint32_t cfgVal)
Definition: pigpio.c:13504
PI_MAX_DMA_CHANNEL
#define PI_MAX_DMA_CHANNEL
Definition: pigpio.h:837
PI_DEFAULT_SOCKET_PORT
#define PI_DEFAULT_SOCKET_PORT
Definition: pigpio.h:6429
clockMicros
static unsigned clockMicros
Definition: pigpiod.c:55
PIGPIO_VERSION
#define PIGPIO_VERSION
Definition: pigpio.h:34
sockNetAddr
static uint32_t sockNetAddr[MAX_CONNECT_ADDRESSES]
Definition: pigpiod.c:71


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Fri Aug 2 2024 09:40:56