41 #include <sys/types.h> 44 #include <sys/socket.h> 45 #include <netinet/tcp.h> 46 #include <sys/select.h> 48 #include <arpa/inet.h> 55 #define PI_MAX_REPORTS_PER_READ 4096 57 #define STACK_SIZE (256*1024) 119 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
130 pthread_setcancelstate(cancelState, NULL);
147 if (send(
gPigCommand[pi], &cmd,
sizeof(cmd), 0) !=
sizeof(cmd))
153 if (recv(
gPigCommand[pi], &cmd,
sizeof(cmd), MSG_WAITALL) !=
sizeof(cmd))
178 if (send(
gPigNotify[pi], &cmd,
sizeof(cmd), 0) !=
sizeof(cmd))
184 if (recv(
gPigNotify[pi], &cmd,
sizeof(cmd), MSG_WAITALL) !=
sizeof(cmd))
196 (
int pi,
int command,
int p1,
int p2,
int p3,
212 if (send(
gPigCommand[pi], &cmd,
sizeof(cmd), 0) !=
sizeof(cmd))
218 for (i=0; i<extents; i++)
220 if (send(
gPigCommand[pi], ext[i].ptr, ext[i].size, 0) != ext[i].size)
227 if (recv(
gPigCommand[pi], &cmd,
sizeof(cmd), MSG_WAITALL) !=
sizeof(cmd))
240 struct addrinfo hints, *res, *rp;
241 const char *addrStr, *portStr;
247 if ((!addrStr) || (!strlen(addrStr)))
258 if ((!portStr) || (!strlen(portStr)))
265 memset (&hints, 0,
sizeof (hints));
267 hints.ai_family = PF_UNSPEC;
268 hints.ai_socktype = SOCK_STREAM;
269 hints.ai_flags |= AI_CANONNAME;
271 err = getaddrinfo (addrStr, portStr, &hints, &res);
275 for (rp=res; rp!=NULL; rp=rp->ai_next)
277 sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
279 if (sock == -1)
continue;
283 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (
char*)&opt,
sizeof(
int));
285 if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
break;
317 if (((p->
pi) == pi) && (changed & (1<<(p->
gpio))))
319 if ((r->
level) & (1<<(p->
gpio))) l = 1;
else l = 0;
339 if (((p->
pi) ==
pi) && ((p->
gpio) == g))
355 if (((ep->
pi) ==
pi) && ((ep->
event) == g))
378 bytes = read(
gPigNotify[pi], (
char*)&report+got,
sizeof(report)-got);
380 if (bytes > 0) got += bytes;
396 if (got && r) report[0] = report[
r];
399 fprintf(stderr,
"notify thread for pi %d broke with read error %d\n",
416 if (p->
pi == pi) bits |= (1<<(p->
gpio));
428 int pi,
unsigned user_gpio,
unsigned level, uint32_t tick,
void *
user)
434 int pi,
unsigned user_gpio,
unsigned edge,
void *
f,
void *
user,
int ex)
439 if ((user_gpio >=0) && (user_gpio < 32) && (edge >=0) && (edge <= 2) && f)
448 (p->
gpio == user_gpio) &&
461 if (!gCallBackFirst) gCallBackFirst = p;
496 if (ep->
pi == pi) bits |= (1<<(ep->
event));
508 int pi,
unsigned event, uint32_t tick,
void *
user)
514 int pi,
unsigned event,
void *
f,
void *
user,
int ex)
519 if ((event >=0) && (event < 32) && f)
527 if ((ep->
pi == pi) &&
528 (ep->
event == event) &&
540 if (!geCallBackFirst) geCallBackFirst = ep;
565 static int recvMax(
int pi,
void *buf,
int bufsize,
int sent)
571 uint8_t scratch[4096];
572 int remaining, fetch, count;
574 if (sent < bufsize) count = sent;
else count = bufsize;
576 if (count) recv(
gPigCommand[pi], buf, count, MSG_WAITALL);
578 remaining = sent - count;
583 if (fetch >
sizeof(scratch)) fetch =
sizeof(scratch);
584 recv(
gPigCommand[pi], scratch, fetch, MSG_WAITALL);
598 gettimeofday(&tv, 0);
600 t = (double)tv.tv_sec + ((
double)tv.tv_usec / 1E6);
607 struct timespec ts, rem;
612 ts.tv_nsec = (seconds-(double)ts.tv_sec) * 1E9;
614 while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
617 ts.tv_sec = rem.tv_sec;
618 ts.tv_nsec = rem.tv_nsec;
625 if (errnum > -1000)
return cmdErrStr(errnum);
631 return "failed to send to pigpiod";
633 return "failed to receive from pigpiod";
635 return "failed to find address of pigpiod";
637 return "failed to connect to pigpiod";
639 return "failed to create socket";
641 return "failed to open notification in band";
643 return "identical callback exists";
645 return "failed to malloc";
647 return "bad callback parameter";
649 return "failed to create notification thread";
651 return "callback not found";
653 return "not connected to Pi";
655 return "too many connected Pis";
658 return "unknown error";
671 pthread_attr_t pthAttr;
673 pth = malloc(
sizeof(pthread_t));
677 if (pthread_attr_init(&pthAttr))
679 perror(
"pthread_attr_init failed");
684 if (pthread_attr_setstacksize(&pthAttr,
STACK_SIZE))
686 perror(
"pthread_attr_setstacksize failed");
691 if (pthread_create(pth, &pthAttr, thread_func, userdata))
693 perror(
"pthread_create socket failed");
705 pthread_cancel(*pth);
706 pthread_join(*pth, NULL);
716 if ((!addrStr) || (strlen(addrStr) == 0))
718 addrStr =
"localhost";
721 for (pi=0; pi<
MAX_PI; pi++)
730 pthread_mutex_init(&
gCmdMutex[pi], NULL);
748 userdata = malloc(
sizeof(*userdata));
884 ext[0].
size =
sizeof(dutycycle);
885 ext[0].
ptr = &dutycycle;
888 pi,
PI_CMD_HP, gpio, frequency,
sizeof(dutycycle), 1, ext, 1);
918 if (!numPulses)
return 0;
928 int pi,
unsigned user_gpio,
unsigned baud, uint32_t databits,
929 uint32_t stophalfbits, uint32_t offset,
unsigned numChar,
char *str)
945 if (!numChar)
return 0;
947 memcpy(buf, &databits, 4);
948 memcpy(buf+4, &stophalfbits, 4);
949 memcpy(buf+8, &offset, 4);
951 ext[0].
size =
sizeof(buf);
954 ext[1].
size = numChar;
958 user_gpio, baud, numChar+
sizeof(buf), 2, ext, 1);
994 ext[0].
size = bufSize;
1037 int gpio_trigger(
int pi,
unsigned user_gpio,
unsigned pulseLen, uint32_t level)
1049 ext[0].
size =
sizeof(uint32_t);
1050 ext[0].
ptr = &level;
1053 pi,
PI_CMD_TRIG, user_gpio, pulseLen, 4, 1, ext, 1);
1071 ext[0].
size =
sizeof(uint32_t);
1072 ext[0].
ptr = &active;
1075 pi,
PI_CMD_FN, user_gpio, steady, 4, 1, ext, 1);
1091 len = strlen(script);
1096 ext[0].
ptr = script;
1101 int run_script(
int pi,
unsigned script_id,
unsigned numPar, uint32_t *param)
1113 ext[0].
size = 4 * numPar;
1132 ext[0].
size = 4 * numPar;
1148 recvMax(pi, p,
sizeof(p), status);
1150 if (param) memcpy(param, p+1,
sizeof(p)-4);
1176 ext[0].
size =
sizeof(uint32_t);
1177 ext[0].
ptr = &bbBits;
1191 bytes =
recvMax(pi, buf, bufSize, bytes);
1205 int i2c_open(
int pi,
unsigned i2c_bus,
unsigned i2c_addr, uint32_t i2c_flags)
1217 ext[0].
size =
sizeof(uint32_t);
1218 ext[0].
ptr = &i2c_flags;
1221 (pi,
PI_CMD_I2CO, i2c_bus, i2c_addr, 4, 1, ext, 1);
1248 ext[0].
size =
sizeof(uint32_t);
1267 ext[0].
size =
sizeof(uint32_t);
1292 ext[0].
size =
sizeof(uint32_t);
1300 int pi,
unsigned handle,
unsigned reg,
char *buf,
unsigned count)
1312 ext[0].
size = count;
1327 bytes =
recvMax(pi, buf, 32, bytes);
1336 int pi,
unsigned handle,
unsigned reg,
char *buf,
unsigned count)
1349 ext[0].
size = count;
1357 bytes =
recvMax(pi, buf, 32, bytes);
1366 int pi,
unsigned handle,
unsigned reg,
char *buf, uint32_t count)
1379 ext[0].
size =
sizeof(uint32_t);
1380 ext[0].
ptr = &count;
1387 bytes =
recvMax(pi, buf, count, bytes);
1397 int pi,
unsigned handle,
unsigned reg,
char *buf,
unsigned count)
1409 ext[0].
size = count;
1424 bytes =
recvMax(pi, buf, count, bytes);
1444 ext[0].
size = count;
1470 ext[0].
size = inLen;
1478 bytes =
recvMax(pi, outBuf, outLen, bytes);
1498 ext[0].
size =
sizeof(uint32_t);
1527 ext[0].
size = inLen;
1535 bytes =
recvMax(pi, outBuf, outLen, bytes);
1545 unsigned CS,
unsigned MISO,
unsigned MOSI,
unsigned SCLK,
1546 unsigned baud,
unsigned spiFlags)
1566 memcpy(buf + 0, &MISO, 4);
1567 memcpy(buf + 4, &MOSI, 4);
1568 memcpy(buf + 8, &SCLK, 4);
1569 memcpy(buf + 12, &baud, 4);
1570 memcpy(buf + 16, &spiFlags, 4);
1597 ext[0].
size = count;
1605 bytes =
recvMax(pi, rxBuf, count, bytes);
1613 int spi_open(
int pi,
unsigned channel,
unsigned speed, uint32_t flags)
1625 ext[0].
size =
sizeof(uint32_t);
1626 ext[0].
ptr = &flags;
1644 bytes =
recvMax(pi, buf, count, bytes);
1664 ext[0].
size = count;
1684 ext[0].
size = count;
1692 bytes =
recvMax(pi, rxBuf, count, bytes);
1743 ext[0].
size = count;
1759 bytes =
recvMax(pi, buf, count, bytes);
1770 int custom_1(
int pi,
unsigned arg1,
unsigned arg2,
char *argx,
unsigned count)
1782 ext[0].
size = count;
1786 pi,
PI_CMD_CF1, arg1, arg2, count, 1, ext, 1);
1790 int custom_2(
int pi,
unsigned arg1,
char *argx,
unsigned count,
1791 char *retBuf, uint32_t retMax)
1804 ext[0].
size = count;
1808 (pi,
PI_CMD_CF2, arg1, retMax, count, 1, ext, 0);
1812 bytes =
recvMax(pi, retBuf, retMax, bytes);
1826 int shell_(
int pi,
char *scriptName,
char *scriptString)
1831 ln = strlen(scriptName);
1832 ls = strlen(scriptString);
1841 ext[0].
size = ln + 1;
1842 ext[0].
ptr = scriptName;
1845 ext[1].
ptr = scriptString;
1870 (pi,
PI_CMD_FO, mode, 0, len, 1, ext, 1);
1888 ext[0].
size = count;
1892 (pi,
PI_CMD_FW, handle, 0, count, 1, ext, 1);
1904 bytes =
recvMax(pi, buf, count, bytes);
1924 ext[0].
size =
sizeof(uint32_t);
1925 ext[0].
ptr = &seekFrom;
1928 (pi,
PI_CMD_FS, handle, seekOffset, 4, 1, ext, 1);
1931 int file_list(
int pi,
char *fpat,
char *buf,
unsigned count)
1954 bytes =
recvMax(pi, buf, count, bytes);
1963 {
return intCallback(pi, user_gpio, edge, f, 0, 0);}
1967 {
return intCallback(pi, user_gpio, edge, f, user, 1);}
1983 else {gCallBackFirst = p->
next;}
1986 else {gCallBackLast = p->
prev;}
2008 if (timeout <= 0.0)
return 0;
2044 status = ntohl(status);
2047 bscxfer->
rxCnt = bytes;
2064 if (i2c_addr) control = (i2c_addr<<16) | 0x305;
2091 else {geCallBackFirst = ep->
next;}
2094 else {geCallBackLast = ep->
prev;}
2116 if (timeout <= 0.0)
return 0;
int notify_close(int pi, unsigned handle)
int wave_tx_start(int pi)
int bb_i2c_zip(int pi, unsigned SDA, char *inBuf, unsigned inLen, char *outBuf, unsigned outLen)
int file_seek(int pi, unsigned handle, int32_t seekOffset, int seekFrom)
static int gPiInUse[MAX_PI]
char rxBuf[BSC_FIFO_SIZE]
int bsc_i2c(int pi, int i2c_addr, bsc_xfer_t *bscxfer)
int bb_serial_read_open(int pi, unsigned user_gpio, unsigned baud, uint32_t bbBits)
int spi_open(int pi, unsigned channel, unsigned speed, uint32_t flags)
int wave_send_repeat(int pi, unsigned wave_id)
int wave_get_max_micros(int pi)
static int pigpio_command_ext(int pi, int command, int p1, int p2, int p3, int extents, gpioExtent_t *ext, int rl)
int set_glitch_filter(int pi, unsigned user_gpio, unsigned steady)
static uint32_t gEventBits[MAX_PI]
int i2c_zip(int pi, unsigned handle, char *inBuf, unsigned inLen, char *outBuf, unsigned outLen)
int wave_tx_repeat(int pi)
int set_watchdog(int pi, unsigned user_gpio, unsigned timeout)
int bsc_xfer(int pi, bsc_xfer_t *bscxfer)
int gpio_read(int pi, unsigned gpio)
int custom_1(int pi, unsigned arg1, unsigned arg2, char *argx, unsigned count)
static void _wfe(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void *user)
#define PI_NTFY_FLAGS_EVENT
int i2c_write_byte_data(int pi, unsigned handle, unsigned reg, uint32_t val)
int get_PWM_dutycycle(int pi, unsigned user_gpio)
uint32_t get_pigpio_version(int pi)
unsigned pigpiod_if_version(void)
static int pigpio_command(int pi, int command, int p1, int p2, int rl)
int set_PWM_range(int pi, unsigned user_gpio, unsigned range)
void(* CBFunc_t)(unsigned user_gpio, unsigned level, uint32_t tick)
int event_callback(int pi, unsigned event, evtCBFunc_t f)
static int intCallback(int pi, unsigned user_gpio, unsigned edge, void *f, void *user, int ex)
int file_write(int pi, unsigned handle, char *buf, unsigned count)
int wave_add_generic(int pi, unsigned numPulses, gpioPulse_t *pulses)
#define PI_MAX_REPORTS_PER_READ
int get_mode(int pi, unsigned gpio)
int gpio_write(int pi, unsigned gpio, unsigned level)
int set_PWM_dutycycle(int pi, unsigned user_gpio, unsigned dutycycle)
int wait_for_edge(int pi, unsigned user_gpio, unsigned edge, double timeout)
int custom_2(int pi, unsigned arg1, char *argx, unsigned count, char *retBuf, uint32_t retMax)
int get_PWM_range(int pi, unsigned user_gpio)
int wave_get_high_pulses(int pi)
int update_script(int pi, unsigned script_id, unsigned numPar, uint32_t *param)
int i2c_read_block_data(int pi, unsigned handle, unsigned reg, char *buf)
int wave_chain(int pi, char *buf, unsigned bufSize)
uint32_t read_bank_1(int pi)
int spi_write(int pi, unsigned handle, char *buf, unsigned count)
int wave_send_once(int pi, unsigned wave_id)
int i2c_read_word_data(int pi, unsigned handle, unsigned reg)
int wave_get_max_pulses(int pi)
int i2c_read_device(int pi, unsigned handle, char *buf, unsigned count)
int bb_serial_read_close(int pi, unsigned user_gpio)
static int recvMax(int pi, void *buf, int bufsize, int sent)
int get_pad_strength(int pi, unsigned pad)
void stop_thread(pthread_t *pth)
static callback_t * gCallBackLast
int hardware_PWM(int pi, unsigned gpio, unsigned frequency, uint32_t dutycycle)
static void dispatch_notification(int pi, gpioReport_t *r)
static int gPigCommand[MAX_PI]
int bb_serial_read(int pi, unsigned user_gpio, void *buf, size_t bufSize)
int shell_(int pi, char *scriptName, char *scriptString)
int gpio_trigger(int pi, unsigned user_gpio, unsigned pulseLen, uint32_t level)
int set_noise_filter(int pi, unsigned user_gpio, unsigned steady, unsigned active)
int i2c_block_process_call(int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
int i2c_close(int pi, unsigned handle)
int i2c_write_device(int pi, unsigned handle, char *buf, unsigned count)
void(* CBFuncEx_t)(unsigned user_gpio, unsigned level, uint32_t tick, void *user)
int get_PWM_frequency(int pi, unsigned user_gpio)
int file_close(int pi, unsigned handle)
void(* evtCBFunc_t)(int pi, unsigned event, uint32_t tick)
int set_bank_2(int pi, uint32_t levels)
uint32_t read_bank_2(int pi)
int set_bank_1(int pi, uint32_t levels)
static pthread_mutex_t gCmdMutex[MAX_PI]
#define PI_MAX_SCRIPT_PARAMS
int i2c_read_byte_data(int pi, unsigned handle, unsigned reg)
int callback_cancel(unsigned id)
int spi_xfer(int pi, unsigned handle, char *txBuf, char *rxBuf, unsigned count)
int bb_i2c_open(int pi, unsigned SDA, unsigned SCL, unsigned baud)
int set_pad_strength(int pi, unsigned pad, unsigned padStrength)
static evtCallback_t * geCallBackFirst
void(* evtCBFuncEx_t)(int pi, unsigned event, uint32_t tick, void *userdata)
int file_read(int pi, unsigned handle, char *buf, unsigned count)
static uint32_t gLastLevel[MAX_PI]
int callback_ex(int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *user)
int hardware_clock(int pi, unsigned gpio, unsigned frequency)
int serial_data_available(int pi, unsigned handle)
static int intEventCallback(int pi, unsigned event, void *f, void *user, int ex)
static void * pthNotifyThread(void *x)
pthread_t * start_thread(gpioThreadFunc_t thread_func, void *userdata)
int wave_get_pulses(int pi)
static callback_t * gCallBackFirst
int bb_serial_invert(int pi, unsigned user_gpio, unsigned invert)
int event_trigger(int pi, unsigned event)
void *( gpioThreadFunc_t)(void *)
char txBuf[BSC_FIFO_SIZE]
int spi_close(int pi, unsigned handle)
int event_callback_cancel(unsigned id)
int i2c_write_byte(int pi, unsigned handle, unsigned val)
#define PI_NTFY_FLAGS_WDOG
int clear_bank_2(int pi, uint32_t levels)
int i2c_open(int pi, unsigned i2c_bus, unsigned i2c_addr, uint32_t i2c_flags)
int i2c_write_i2c_block_data(int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
int clear_bank_1(int pi, uint32_t levels)
int spi_read(int pi, unsigned handle, char *buf, unsigned count)
static int gPigNotify[MAX_PI]
static pthread_t * gPthNotify[MAX_PI]
int wave_get_high_cbs(int pi)
static int pigpio_notify(int pi)
int i2c_write_quick(int pi, unsigned handle, unsigned bit)
char * pigpio_error(int errnum)
int pigpio_start(char *addrStr, char *portStr)
int serial_read(int pi, unsigned handle, char *buf, unsigned count)
int wave_delete(int pi, unsigned wave_id)
static evtCallback_t * geCallBackLast
static int gCancelState[MAX_PI]
int serial_read_byte(int pi, unsigned handle)
int serial_close(int pi, unsigned handle)
int i2c_write_block_data(int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
#define PIGPIOD_IF2_VERSION
int stop_script(int pi, unsigned script_id)
int i2c_read_i2c_block_data(int pi, unsigned handle, unsigned reg, char *buf, uint32_t count)
int set_mode(int pi, unsigned gpio, unsigned mode)
int bb_spi_open(int pi, unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK, unsigned baud, unsigned spiFlags)
int wave_add_serial(int pi, unsigned user_gpio, unsigned baud, uint32_t databits, uint32_t stophalfbits, uint32_t offset, unsigned numChar, char *str)
int bb_spi_close(int pi, unsigned CS)
int i2c_write_word_data(int pi, unsigned handle, unsigned reg, uint32_t val)
int store_script(int pi, char *script)
static int pigpioOpenSocket(char *addr, char *port)
int set_pull_up_down(int pi, unsigned gpio, unsigned pud)
int bb_i2c_close(int pi, unsigned SDA)
#define PI_DEFAULT_SOCKET_ADDR_STR
static void findEventBits(int pi)
void time_sleep(double seconds)
#define PI_DEFAULT_SOCKET_PORT_STR
int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)
int get_PWM_real_range(int pi, unsigned user_gpio)
static uint32_t gNotifyBits[MAX_PI]
int notify_pause(int pi, unsigned handle)
int file_list(int pi, char *fpat, char *buf, unsigned count)
int serial_write_byte(int pi, unsigned handle, unsigned val)
int delete_script(int pi, unsigned script_id)
int event_callback_ex(int pi, unsigned event, evtCBFuncEx_t f, void *user)
int notify_begin(int pi, unsigned handle, uint32_t bits)
static void _ewfe(int pi, unsigned event, uint32_t tick, void *user)
int set_PWM_frequency(int pi, unsigned user_gpio, unsigned frequency)
uint32_t get_current_tick(int pi)
int run_script(int pi, unsigned script_id, unsigned numPar, uint32_t *param)
uint32_t get_hardware_revision(int pi)
int callback(int pi, unsigned user_gpio, unsigned edge, CBFunc_t f)
int serial_open(int pi, char *dev, unsigned baud, unsigned flags)
int set_servo_pulsewidth(int pi, unsigned user_gpio, unsigned pulsewidth)
int wave_get_max_cbs(int pi)
int wait_for_event(int pi, unsigned event, double timeout)
int bb_spi_xfer(int pi, unsigned CS, char *txBuf, char *rxBuf, unsigned count)
char * cmdErrStr(int error)
int get_servo_pulsewidth(int pi, unsigned user_gpio)
int wave_get_micros(int pi)
int i2c_read_byte(int pi, unsigned handle)
static int gPigHandle[MAX_PI]
int script_status(int pi, unsigned script_id, uint32_t *param)
void report(int err, char *fmt,...)
static void findNotifyBits(int pi)
int wave_get_high_micros(int pi)
int serial_write(int pi, unsigned handle, char *buf, unsigned count)
int i2c_process_call(int pi, unsigned handle, unsigned reg, uint32_t val)
int file_open(int pi, char *file, unsigned mode)