Bumped the version to 2.40 - correctly this time, I hope.

Added fixed for a few minor things. pin driver for rht03/dht type
sensors. Network stuff is experimental - for now.
This commit is contained in:
Gordon Henderson 2017-02-27 19:51:32 +00:00
parent e687f3f2c6
commit 70fa99a127
28 changed files with 2069 additions and 87 deletions

View File

@ -1 +1 @@
2.39 2.40

8
build
View File

@ -160,6 +160,14 @@ fi
$sudo make install $sudo make install
check_make_ok check_make_ok
echo
echo "wiringPi Daemon"
cd ../wiringPiD
make -j5
check_make_ok
$sudo make install
check_make_ok
# echo # echo
# echo "Examples" # echo "Examples"
# cd ../examples # cd ../examples

View File

@ -1,5 +1,5 @@
Package: wiringpi Package: wiringpi
Version: 2.38 Version: 2.40
Section: libraries Section: libraries
Priority: optional Priority: optional
Architecture: armhf Architecture: armhf

View File

@ -33,7 +33,7 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib LDFLAGS = -L/usr/local/lib
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt
# Should not alter anything below this line # Should not alter anything below this line
############################################################################### ###############################################################################

61
examples/blink8-drcn.c Normal file
View File

@ -0,0 +1,61 @@
/*
* blink8-drcn.c:
* Simple sequence over the first 8 GPIO pins - LEDs
* Aimed at the Ladder board, but it's fairly generic.
*
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <stdio.h>
#include <wiringPi.h>
#include <drcNet.h>
int main (void)
{
int i, led ;
printf ("Raspberry Pi - 8-LED Sequencer\n") ;
printf ("==============================\n") ;
printf ("\n") ;
printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ;
int pinBase = 100 ;
// wiringPiSetup () ;
drcSetupNet (pinBase, 100, "192.168.254.21", "6124", "123456") ;
for (i = 0 ; i < 8 ; ++i)
pinMode (i + pinBase, OUTPUT) ;
for (;;)
{
for (led = 0 ; led < 8 ; ++led)
{
digitalWrite (led + pinBase, 1) ;
delay (10) ;
}
for (led = 0 ; led < 8 ; ++led)
{
digitalWrite (led + pinBase, 0) ;
delay (10) ;
}
}
}

View File

@ -37,7 +37,7 @@ INCLUDE = -I$(DESTDIR)$(PREFIX)/include
CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe
LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib
LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt
# May not need to alter anything below this line # May not need to alter anything below this line
############################################################################### ###############################################################################

View File

@ -9,15 +9,15 @@ gpio \- Command-line access to Raspberry Pi's GPIO
.PP .PP
.B gpio .B gpio
.B [ \-g | \-1 ] .B [ \-g | \-1 ]
.B mode/read/write/aread/awrite/wb/pwm/clock ... .B mode/read/write/aread/awrite/wb/pwm/clock/toggle/blink ...
.PP .PP
.B gpio .B gpio
.B [ \-x extension:params ] .B [ \-x extension:params ]
.B mode/read/write/aread/awrite/pwm/pwmTone ... .B mode/read/write/aread/awrite/pwm/toggle/blink ...
.PP .PP
.B gpio .B gpio
.B [ \-p ] .B [ \-p ]
.B read/write/toggle/wb .B read/write/toggle/blink
.B ... .B ...
.PP .PP
.B gpio .B gpio
@ -118,11 +118,23 @@ respective logic levels.
Write the given value (0 or 1) to the pin. You need to set the pin Write the given value (0 or 1) to the pin. You need to set the pin
to output mode first. to output mode first.
.TP
.B toggle <pin>
Changes the state of a GPIO pin; 0 to 1, or 1 to 0.
Note unlike the blink command, the pin must be in output mode first.
.TP
.B blink <pin>
Blinks the given pin on/off. Press Control-C to exit.
Note: This command explicitly sets the pin to output mode.
.TP .TP
.B aread <pin> .B aread <pin>
Read the analog value of the given pin. This needs to be uses in Read the analog value of the given pin. This needs to be used in
conjunction with a -x flag to add in an extension that handles analog conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels. inputs.
e.g. gpio -x mcp3002:200:0 aread 200 e.g. gpio -x mcp3002:200:0 aread 200
@ -132,7 +144,7 @@ will read the first analog input on an mcp3002 SPI ADC chip.
.B awrite <pin> <value> .B awrite <pin> <value>
Write the analog value to the given pin. This needs to be used in Write the analog value to the given pin. This needs to be used in
conjunction with a -x flag to add in an extension that handles analog conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels. inputs.
e.g. gpio -x mcp4802:200:0 awrite 200 128 e.g. gpio -x mcp4802:200:0 awrite 200 128
@ -234,7 +246,7 @@ absolutely sure you know what you're doing.
high | low high | low
Change the USB current limiter to high (1.2 amps) or low (the default, 600mA) Change the USB current limiter to high (1.2 amps) or low (the default, 600mA)
This is only applicable to the model B+ This is only applicable to the Model B+ and the Model B, v2.
.TP .TP
.B pwm-bal/pwm-ms .B pwm-bal/pwm-ms
@ -253,7 +265,6 @@ them. Optionally it will set the I2C baudrate to that supplied in Kb/sec
Note: On recent kernels with the device tree enabled you should use the Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the I2C device at boot time. raspi-config program to load/unload the I2C device at boot time.
(or disable the device tree to continue to use this method)
.TP .TP
.B load spi .B load spi
@ -268,7 +279,6 @@ e.g. 8192 bytes then reboot.
Note: On recent kernels with the device tree enabled you should use the Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the SPI device at boot time. raspi-config program to load/unload the SPI device at boot time.
(or disable the device tree to continue to use this method)
.TP .TP
.B gbr .B gbr

View File

@ -1443,6 +1443,16 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_PIFACE ; wpMode = WPI_MODE_PIFACE ;
} }
// Check for -z argument so we don't actually initialise wiringPi
else if (strcasecmp (argv [1], "-z") == 0)
{
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
wpMode = WPI_MODE_UNINITIALISED ;
}
// Default to wiringPi mode // Default to wiringPi mode
else else
@ -1460,12 +1470,15 @@ int main (int argc, char *argv [])
{ {
if (argc < 3) if (argc < 3)
{ {
fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ; fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ;
exit (EXIT_FAILURE) ; exit (EXIT_FAILURE) ;
} }
if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages if (!loadWPiExtension (argv [0], argv [2], TRUE))
{
fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ;
exit (EXIT_FAILURE) ; exit (EXIT_FAILURE) ;
}
// Shift args down by 2 // Shift args down by 2

View File

@ -1,3 +1,3 @@
#define VERSION "2.38" #define VERSION "2.40"
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 38 #define VERSION_MINOR 40

View File

@ -57,8 +57,8 @@ SRC = wiringPi.c \
mcp3002.c mcp3004.c mcp4802.c mcp3422.c \ mcp3002.c mcp3004.c mcp4802.c mcp3422.c \
max31855.c max5322.c ads1115.c \ max31855.c max5322.c ads1115.c \
sn3218.c \ sn3218.c \
bmp180.c htu21d.c ds18b20.c \ bmp180.c htu21d.c ds18b20.c rht03.c \
drcSerial.c \ drcSerial.c drcNet.c \
pseudoPins.c \ pseudoPins.c \
wpiExtensions.c wpiExtensions.c

405
wiringPi/drcNet.c Normal file
View File

@ -0,0 +1,405 @@
/*
* drcNet.h:
* Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <crypt.h>
#include "wiringPi.h"
#include "drcNet.h"
#include "../wiringPiD/drcNetCmd.h"
/*
* remoteReadline:
* Read in a line of data from the remote server, ending with a newline
* character which is not stored. Returns the length or < 0 on
* any sort of failure.
*********************************************************************************
*/
static int remoteReadline (int fd, char *buf, int max)
{
int len = 0 ;
char c ;
for (;;)
{
if (read (fd, &c, 1) < 1)
return -1 ;
if (c == '\n')
return len ;
*buf++ = c ;
if (++len == max)
return len ;
}
}
/*
* getChallenge:
* Read in lines from the remote site until we get one identified
* as the challenge. This line contains the password salt.
*********************************************************************************
*/
static char *getChallenge (int fd)
{
static char buf [1024] ;
int num ;
for (;;)
{
if ((num = remoteReadline (fd, buf, 1023)) < 0)
return NULL ;
buf [num] = 0 ;
if (strncmp (buf, "Challenge ", 10) == 0)
return &buf [10] ;
}
}
/*
* authenticate:
* Read in the challenge from the server, use it to encrypt our password
* and send it back to the server. Wait for a reply back from the server
* to say that we're good to go.
* The server will simply disconnect on a bad response. No 3 chances here.
*********************************************************************************
*/
static int authenticate (int fd, const char *pass)
{
char *challenge ;
char *encrypted ;
char salted [1024] ;
if ((challenge = getChallenge (fd)) == NULL)
return -1 ;
sprintf (salted, "$6$%s$", challenge) ;
encrypted = crypt (pass, salted) ;
// This is an assertion, or sanity check on my part...
// The '20' comes from the $6$ then the 16 characters of the salt,
// then the terminating $.
if (strncmp (encrypted, salted, 20) != 0)
{
errno = EBADE ;
return -1 ;
}
// 86 characters is the length of the SHA-256 hash
if (write (fd, encrypted + 20, 86) == 86)
return 0 ;
else
return -1 ;
}
/*
* _drcSetupNet:
* Do the hard work of establishing a network connection and authenticating
* the password.
*********************************************************************************
*/
int _drcSetupNet (const char *ipAddress, const char *port, const char *password)
{
struct addrinfo hints;
struct addrinfo *result, *rp ;
struct in6_addr serveraddr ;
int remoteFd ;
// Start by seeing if we've been given a (textual) numeric IP address
// which will save lookups in getaddrinfo()
memset (&hints, 0, sizeof (hints)) ;
hints.ai_flags = AI_NUMERICSERV ;
hints.ai_family = AF_UNSPEC ;
hints.ai_socktype = SOCK_STREAM ;
hints.ai_protocol = 0 ;
if (inet_pton (AF_INET, ipAddress, &serveraddr) == 1) // Valid IPv4
{
hints.ai_family = AF_INET ;
hints.ai_flags |= AI_NUMERICHOST ;
}
else
{
if (inet_pton (AF_INET6, ipAddress, &serveraddr) == 1) // Valid IPv6
{
hints.ai_family = AF_INET6 ;
hints.ai_flags |= AI_NUMERICHOST ;
}
}
// Now use getaddrinfo() with the newly supplied hints
if (getaddrinfo (ipAddress, port, &hints, &result) != 0)
return -1 ;
// Now try each address in-turn until we get one that connects...
for (rp = result; rp != NULL; rp = rp->ai_next)
{
if ((remoteFd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
continue ;
if (connect (remoteFd, rp->ai_addr, rp->ai_addrlen) < 0)
continue ;
if (authenticate (remoteFd, password) < 0)
{
close (remoteFd) ;
errno = EACCES ; // Permission denied
return -1 ;
}
else
return remoteFd ;
}
errno = EHOSTUNREACH ; // Host unreachable - may not be right, but good enough
return -1 ; // Nothing connected
}
/*
* myPinMode:
* Change the pin mode on the remote DRC device
*********************************************************************************
*/
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PIN_MODE ;
cmd.data = mode ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
/*
* myPullUpDnControl:
*********************************************************************************
*/
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PULL_UP_DN ;
cmd.data = mode ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
/*
* myDigitalWrite:
*********************************************************************************
*/
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_WRITE ;
cmd.data = value ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
/*
* myDigitalWrite8:
*********************************************************************************
static void myDigitalWrite8 (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_WRITE8 ;
cmd.data = value ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
*/
/*
* myAnalogWrite:
*********************************************************************************
*/
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_ANALOG_WRITE ;
cmd.data = value ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
/*
* myPwmWrite:
*********************************************************************************
*/
static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PWM_WRITE ;
cmd.data = value ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
/*
* myAnalogRead:
*********************************************************************************
*/
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_ANALOG_READ ;
cmd.data = 0 ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
return cmd.data ;
}
/*
* myDigitalRead:
*********************************************************************************
*/
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_READ ;
cmd.data = 0 ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
return cmd.data ;
}
/*
* myDigitalRead8:
*********************************************************************************
static unsigned int myDigitalRead8 (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;
cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_READ8 ;
cmd.data = 0 ;
(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
return cmd.data ;
}
*/
/*
* drcNet:
* Create a new instance of an DRC GPIO interface.
* Could be a variable nunber of pins here - we might not know in advance.
*********************************************************************************
*/
int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password)
{
int fd, len ;
struct wiringPiNodeStruct *node ;
if ((fd = _drcSetupNet (ipAddress, port, password)) < 0)
return FALSE ;
len = sizeof (struct drcNetComStruct) ;
if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return FALSE ;
node = wiringPiNewNode (pinBase, numPins) ;
node->fd = fd ;
node->pinMode = myPinMode ;
node->pullUpDnControl = myPullUpDnControl ;
node->analogRead = myAnalogRead ;
node->analogRead = myAnalogRead ;
node->analogWrite = myAnalogWrite ;
node->digitalRead = myDigitalRead ;
node->digitalWrite = myDigitalWrite ;
//node->digitalRead8 = myDigitalRead8 ;
//node->digitalWrite8 = myDigitalWrite8 ;
node->pwmWrite = myPwmWrite ;
return TRUE ;
}

42
wiringPi/drcNet.h Normal file
View File

@ -0,0 +1,42 @@
/*
* drcNet.h:
* Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
/*********
struct drcNetStruct
{
uint32_t pin ;
uint32_t cmd ;
uint32_t data ;
} ;
**************/
#ifdef __cplusplus
extern "C" {
#endif
extern int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password) ;
#ifdef __cplusplus
}
#endif

126
wiringPi/rht03.c Normal file
View File

@ -0,0 +1,126 @@
/*
* rht03.c:
* Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <fcntl.h>
//#include <unistd.h>
//#include <stdint.h>
#include <stdio.h>
//#include <string.h>
#include <time.h>
//#include <ctype.h>
#include "wiringPi.h"
#include "../devLib/maxdetect.h"
#include "rht03.h"
/*
* myReadRHT03:
* Read the Temperature & Humidity from an RHT03 sensor
* Values returned are *10, so 123 is 12.3.
*********************************************************************************
*/
static int myReadRHT03 (const int pin, int *temp, int *rh)
{
int result ;
unsigned char buffer [4] ;
// Read ...
result = maxDetectRead (pin, buffer) ;
if (!result)
return FALSE ;
*rh = (buffer [0] * 256 + buffer [1]) ;
*temp = (buffer [2] * 256 + buffer [3]) ;
if ((*temp & 0x8000) != 0) // Negative
{
*temp &= 0x7FFF ;
*temp = -*temp ;
}
// Discard obviously bogus readings - the checksum can't detect a 2-bit error
// (which does seem to happen - no realtime here)
if ((*rh > 999) || (*temp > 800) || (*temp < -400))
return FALSE ;
return TRUE ;
}
/*
* myAnalogRead:
*********************************************************************************
*/
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int piPin = node->fd ;
int chan = pin - node->pinBase ;
int temp = -9997 ;
int rh = -9997 ;
int try ;
if (chan > 1)
return -9999 ; // Bad parameters
for (try = 0 ; try < 10 ; ++try)
{
if (myReadRHT03 (piPin, &temp, &rh))
return chan == 0 ? temp : rh ;
}
return -9998 ;
}
/*
* rht03Setup:
* Create a new instance of an RHT03 temperature sensor.
*********************************************************************************
*/
int rht03Setup (const int pinBase, const int piPin)
{
struct wiringPiNodeStruct *node ;
if ((piPin & PI_GPIO_MASK) != 0) // Must be an on-board pin
return FALSE ;
// 2 pins - temperature and humidity
node = wiringPiNewNode (pinBase, 2) ;
node->fd = piPin ;
node->analogRead = myAnalogRead ;
return TRUE ;
}

25
wiringPi/rht03.h Normal file
View File

@ -0,0 +1,25 @@
/*
* rht03.h:
* Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
extern int rht03Setup (const int pinBase, const int devicePin) ;

View File

@ -1,7 +1,7 @@
/* /*
* softPwm.c: * softPwm.c:
* Provide 2 channels of software driven PWM. * Provide many channels of software driven PWM.
* Copyright (c) 2012-2014 Gordon Henderson * Copyright (c) 2012-2017 Gordon Henderson
*********************************************************************** ***********************************************************************
* This file is part of wiringPi: * This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/ * https://projects.drogon.net/raspberry-pi/wiringpi/
@ -30,11 +30,11 @@
#include "softPwm.h" #include "softPwm.h"
// MAX_PINS: // MAX_PINS:
// This is more than the number of Pi pins because we can actually softPwm // This is more than the number of Pi pins because we can actually softPwm.
// pins that are on GPIO expanders. It's not that efficient and more than 1 or // Once upon a time I let pins on gpio expanders be softPwm'd, but it's really
// 2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however... // really not a good thing.
#define MAX_PINS 1024 #define MAX_PINS 64
// The PWM Frequency is derived from the "pulse time" below. Essentially, // The PWM Frequency is derived from the "pulse time" below. Essentially,
// the frequency is a function of the range and this pulse time. // the frequency is a function of the range and this pulse time.
@ -45,7 +45,7 @@
// It's possible to get a higher frequency by lowering the pulse time, // It's possible to get a higher frequency by lowering the pulse time,
// however CPU uage will skyrocket as wiringPi uses a hard-loop to time // however CPU uage will skyrocket as wiringPi uses a hard-loop to time
// periods under 100µS - this is because the Linux timer calls are just // periods under 100µS - this is because the Linux timer calls are just
// accurate at all, and have an overhead. // not accurate at all, and have an overhead.
// //
// Another way to increase the frequency is to reduce the range - however // Another way to increase the frequency is to reduce the range - however
// that reduces the overall output accuracy... // that reduces the overall output accuracy...
@ -106,8 +106,8 @@ static void *softPwmThread (void *arg)
void softPwmWrite (int pin, int value) void softPwmWrite (int pin, int value)
{ {
pin &= (MAX_PINS - 1) ; if (pin < MAX_PINS)
{
/**/ if (value < 0) /**/ if (value < 0)
value = 0 ; value = 0 ;
else if (value > range [pin]) else if (value > range [pin])
@ -115,6 +115,7 @@ void softPwmWrite (int pin, int value)
marks [pin] = value ; marks [pin] = value ;
} }
}
/* /*
@ -129,6 +130,9 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
pthread_t myThread ; pthread_t myThread ;
int *passPin ; int *passPin ;
if (pin >= MAX_PINS)
return -1 ;
if (range [pin] != 0) // Already running on this pin if (range [pin] != 0) // Already running on this pin
return -1 ; return -1 ;
@ -139,8 +143,8 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
if (passPin == NULL) if (passPin == NULL)
return -1 ; return -1 ;
pinMode (pin, OUTPUT) ;
digitalWrite (pin, LOW) ; digitalWrite (pin, LOW) ;
pinMode (pin, OUTPUT) ;
marks [pin] = initialValue ; marks [pin] = initialValue ;
range [pin] = pwmRange ; range [pin] = pwmRange ;
@ -165,6 +169,8 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
*/ */
void softPwmStop (int pin) void softPwmStop (int pin)
{
if (pin < MAX_PINS)
{ {
if (range [pin] != 0) if (range [pin] != 0)
{ {
@ -174,3 +180,4 @@ void softPwmStop (int pin)
digitalWrite (pin, LOW) ; digitalWrite (pin, LOW) ;
} }
} }
}

View File

@ -84,10 +84,8 @@
#define ENV_GPIOMEM "WIRINGPI_GPIOMEM" #define ENV_GPIOMEM "WIRINGPI_GPIOMEM"
// Mask for the bottom 64 pins which belong to the Raspberry Pi // Extend wiringPi with other pin-based devices and keep track of
// The others are available for the other devices // them in this structure
#define PI_GPIO_MASK (0xFFFFFFC0)
struct wiringPiNodeStruct *wiringPiNodes = NULL ; struct wiringPiNodeStruct *wiringPiNodes = NULL ;
@ -1246,6 +1244,8 @@ struct wiringPiNodeStruct *wiringPiFindNode (int pin)
static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; }
static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; }
static unsigned int digitalRead8Dummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return 0 ; }
static void digitalWrite8Dummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; }
static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
@ -1277,7 +1277,9 @@ struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
node->pinMode = pinModeDummy ; node->pinMode = pinModeDummy ;
node->pullUpDnControl = pullUpDnControlDummy ; node->pullUpDnControl = pullUpDnControlDummy ;
node->digitalRead = digitalReadDummy ; node->digitalRead = digitalReadDummy ;
//node->digitalRead8 = digitalRead8Dummy ;
node->digitalWrite = digitalWriteDummy ; node->digitalWrite = digitalWriteDummy ;
//node->digitalWrite8 = digitalWrite8Dummy ;
node->pwmWrite = pwmWriteDummy ; node->pwmWrite = pwmWriteDummy ;
node->analogRead = analogReadDummy ; node->analogRead = analogReadDummy ;
node->analogWrite = analogWriteDummy ; node->analogWrite = analogWriteDummy ;
@ -1492,6 +1494,27 @@ int digitalRead (int pin)
} }
/*
* digitalRead8:
* Read 8-bits (a byte) from given start pin.
*********************************************************************************
unsigned int digitalRead8 (int pin)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
return 0 ;
else
{
if ((node = wiringPiFindNode (pin)) == NULL)
return LOW ;
return node->digitalRead8 (node, pin) ;
}
}
*/
/* /*
* digitalWrite: * digitalWrite:
* Set an output bit * Set an output bit
@ -1535,6 +1558,26 @@ void digitalWrite (int pin, int value)
} }
/*
* digitalWrite8:
* Set an output 8-bit byte on the device from the given pin number
*********************************************************************************
void digitalWrite8 (int pin, int value)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
return ;
else
{
if ((node = wiringPiFindNode (pin)) != NULL)
node->digitalWrite8 (node, pin, value) ;
}
}
*/
/* /*
* pwmWrite: * pwmWrite:
* Set an output PWM value * Set an output PWM value

View File

@ -26,6 +26,7 @@
// C doesn't have true/false by default and I can never remember which // C doesn't have true/false by default and I can never remember which
// way round they are, so ... // way round they are, so ...
// (and yes, I know about stdbool.h but I like capitals for these and I'm old)
#ifndef TRUE #ifndef TRUE
# define TRUE (1==1) # define TRUE (1==1)
@ -36,6 +37,11 @@
#define UNU __attribute__((unused)) #define UNU __attribute__((unused))
// Mask for the bottom 64 pins which belong to the Raspberry Pi
// The others are available for the other devices
#define PI_GPIO_MASK (0xFFFFFFC0)
// Handy defines // Handy defines
// wiringPi modes // wiringPi modes
@ -143,7 +149,9 @@ struct wiringPiNodeStruct
void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ;
void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ;
int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ;
//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ;
void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ;
void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
@ -184,6 +192,8 @@ extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ; extern void pullUpDnControl (int pin, int pud) ;
extern int digitalRead (int pin) ; extern int digitalRead (int pin) ;
extern void digitalWrite (int pin, int value) ; extern void digitalWrite (int pin, int value) ;
extern unsigned int digitalRead8 (int pin) ;
extern void digitalWrite8 (int pin, int value) ;
extern void pwmWrite (int pin, int value) ; extern void pwmWrite (int pin, int value) ;
extern int analogRead (int pin) ; extern int analogRead (int pin) ;
extern void analogWrite (int pin, int value) ; extern void analogWrite (int pin, int value) ;
@ -204,12 +214,14 @@ extern int physPinToGpio (int physPin) ;
extern void setPadDrive (int group, int value) ; extern void setPadDrive (int group, int value) ;
extern int getAlt (int pin) ; extern int getAlt (int pin) ;
extern void pwmToneWrite (int pin, int freq) ; extern void pwmToneWrite (int pin, int freq) ;
extern void digitalWriteByte (int value) ;
extern unsigned int digitalReadByte (void) ;
extern void pwmSetMode (int mode) ; extern void pwmSetMode (int mode) ;
extern void pwmSetRange (unsigned int range) ; extern void pwmSetRange (unsigned int range) ;
extern void pwmSetClock (int divisor) ; extern void pwmSetClock (int divisor) ;
extern void gpioClockSet (int pin, int freq) ; extern void gpioClockSet (int pin, int freq) ;
extern unsigned int digitalReadByte (void) ;
extern unsigned int digitalReadByte2 (void) ;
extern void digitalWriteByte (int value) ;
extern void digitalWriteByte2 (int value) ;
// Interrupts // Interrupts
// (Also Pi hardware specific) // (Also Pi hardware specific)

View File

@ -55,10 +55,13 @@
#include "ads1115.h" #include "ads1115.h"
#include "sn3218.h" #include "sn3218.h"
#include "drcSerial.h" #include "drcSerial.h"
#include "drcNet.h"
#include "../wiringPiD/drcNetCmd.h"
#include "pseudoPins.h" #include "pseudoPins.h"
#include "bmp180.h" #include "bmp180.h"
#include "htu21d.h" #include "htu21d.h"
#include "ds18b20.h" #include "ds18b20.h"
#include "rht03.h"
#include "wpiExtensions.h" #include "wpiExtensions.h"
@ -134,12 +137,16 @@ static char *extractInt (char *progName, char *p, int *num)
/* /*
* extractStr: * extractStr:
* Check & return a string at the given location (prefixed by a :) * Check & return a string at the given location (prefixed by a :)
* Note: The string can be enclosed in []'s to escape colons. This is
* so we can handle IPv6 addresses which contain colons and the []'s is
* a common way to prepresent them.
********************************************************************************* *********************************************************************************
*/ */
static char *extractStr (char *progName, char *p, char **str) static char *extractStr (char *progName, char *p, char **str)
{ {
char *q, *r ; char *q, *r ;
int quoted = FALSE ;
if (*p != ':') if (*p != ':')
{ {
@ -149,21 +156,38 @@ static char *extractStr (char *progName, char *p, char **str)
++p ; ++p ;
if (!isprint (*p)) if (*p == '[')
{
quoted = TRUE ;
++p ;
}
if (!isprint (*p)) // Is this needed?
{ {
verbError ("%s: character expected", progName) ; verbError ("%s: character expected", progName) ;
return NULL ; return NULL ;
} }
q = p ; q = p ;
if (quoted)
{
while ((*q != 0) && (*q != ']'))
++q ;
}
else
{
while ((*q != 0) && (*q != ':')) while ((*q != 0) && (*q != ':'))
++q ; ++q ;
}
*str = r = calloc (q - p + 2, 1) ; // Zeros it *str = r = calloc (q - p + 2, 1) ; // Zeros it
while (p != q) while (p != q)
*r++ = *p++ ; *r++ = *p++ ;
if (quoted) // Skip over the ] to the :
++p ;
return p ; return p ;
} }
@ -495,6 +519,24 @@ static int doExtensionDs18b20 (char *progName, int pinBase, char *params)
} }
/*
* doExtensionRht03:
* Maxdetect 1-Wire Temperature & Humidity
* rht03:base:piPin
*********************************************************************************
*/
static int doExtensionRht03 (char *progName, int pinBase, char *params)
{
int piPin ;
if ((params = extractInt (progName, params, &piPin)) == NULL)
return FALSE ;
return rht03Setup (pinBase, piPin) ;
}
/* /*
* doExtensionMax31855: * doExtensionMax31855:
* Analog IO * Analog IO
@ -698,9 +740,9 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
if ((params = extractInt (progName, params, &pins)) == NULL) if ((params = extractInt (progName, params, &pins)) == NULL)
return FALSE ; return FALSE ;
if ((pins < 1) || (pins > 100)) if ((pins < 1) || (pins > 1000))
{ {
verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ; verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
return FALSE ; return FALSE ;
} }
@ -728,6 +770,59 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
} }
/*
* doExtensionDrcNet:
* Interface to a DRC Network system
* drcn:base:pins:ipAddress:port:password
*********************************************************************************
*/
static int doExtensionDrcNet (char *progName, int pinBase, char *params)
{
int pins ;
char *ipAddress, *port, *password ;
char pPort [1024] ;
if ((params = extractInt (progName, params, &pins)) == NULL)
return FALSE ;
if ((pins < 1) || (pins > 1000))
{
verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
return FALSE ;
}
if ((params = extractStr (progName, params, &ipAddress)) == NULL)
return FALSE ;
if (strlen (ipAddress) == 0)
{
verbError ("%s: ipAddress required", progName) ;
return FALSE ;
}
if ((params = extractStr (progName, params, &port)) == NULL)
return FALSE ;
if (strlen (port) == 0)
{
sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ;
port = pPort ;
}
if ((params = extractStr (progName, params, &password)) == NULL)
return FALSE ;
if (strlen (password) == 0)
{
verbError ("%s: password required", progName) ;
return FALSE ;
}
return drcSetupNet (pinBase, pins, ipAddress, port, password) ;
}
/* /*
* Function list * Function list
@ -748,6 +843,7 @@ static struct extensionFunctionStruct extensionFunctions [] =
{ "pseudoPins", &doExtensionPseudoPins }, { "pseudoPins", &doExtensionPseudoPins },
{ "htu21d", &doExtensionHtu21d }, { "htu21d", &doExtensionHtu21d },
{ "ds18b20", &doExtensionDs18b20 }, { "ds18b20", &doExtensionDs18b20 },
{ "rht03", &doExtensionRht03 },
{ "mcp3002", &doExtensionMcp3002 }, { "mcp3002", &doExtensionMcp3002 },
{ "mcp3004", &doExtensionMcp3004 }, { "mcp3004", &doExtensionMcp3004 },
{ "mcp4802", &doExtensionMcp4802 }, { "mcp4802", &doExtensionMcp4802 },
@ -757,6 +853,7 @@ static struct extensionFunctionStruct extensionFunctions [] =
{ "max5322", &doExtensionMax5322 }, { "max5322", &doExtensionMax5322 },
{ "sn3218", &doExtensionSn3218 }, { "sn3218", &doExtensionSn3218 },
{ "drcs", &doExtensionDrcS }, { "drcs", &doExtensionDrcS },
{ "drcn", &doExtensionDrcNet },
{ NULL, NULL }, { NULL, NULL },
} ; } ;
@ -826,6 +923,6 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors)
return extensionFn->function (progName, pinBase, p) ; return extensionFn->function (progName, pinBase, p) ;
} }
verbError ("%s: extension %s not found", progName, extension) ; fprintf (stderr, "%s: extension %s not found", progName, extension) ;
return FALSE ; return FALSE ;
} }

100
wiringPiD/Makefile Normal file
View File

@ -0,0 +1,100 @@
#
# Makefile:
# The wiringPiD utility:
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2017 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################
DESTDIR?=/usr
PREFIX?=/local
ifneq ($V,1)
Q ?= @
endif
#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I$(DESTDIR)$(PREFIX)/include
CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe
LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib
LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt
# May not need to alter anything below this line
###############################################################################
SRC = wiringpid.c network.c runRemote.c daemonise.c
OBJ = $(SRC:.c=.o)
all: wiringpid
wiringpid: $(OBJ)
$Q echo [Link]
$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
.c.o:
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@
.PHONY: clean
clean:
$Q echo "[Clean]"
$Q rm -f $(OBJ) wiringpid *~ core tags *.bak
.PHONY: tags
tags: $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)
.PHONY: install
install: wiringpid
$Q echo "[Install]"
$Q mkdir -p $(DESTDIR)$(PREFIX)/sbin
$Q cp wiringpid $(DESTDIR)$(PREFIX)/sbin
$Q chown root.root $(DESTDIR)$(PREFIX)/sbin/wiringpid
# $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man8
# $Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man8
.PHONY: install-deb
install-deb: gpio
$Q echo "[Install: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/man/man1
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/man/man1
.PHONY: uninstall
uninstall:
$Q echo "[UnInstall]"
$Q rm -f $(DESTDIR)$(PREFIX)/sbin/wiringpid
$Q rm -f $(DESTDIR)$(PREFIX)/man/man8/wiringpid.8
.PHONY: depend
depend:
makedepend -Y $(SRC)
# DO NOT DELETE
wiringpid.o: drcNetCmd.h network.h runRemote.h daemonise.h
network.o: network.h
runRemote.o: drcNetCmd.h network.h runRemote.h
daemonise.o: daemonise.h

82
wiringPiD/daemonise.c Normal file
View File

@ -0,0 +1,82 @@
/*
* daemonise.c:
* Fairly generic "Turn the current process into a daemon" code.
*
* Copyright (c) 2016-2017 Gordon Henderson.
*********************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <sys/stat.h>
#include "daemonise.h"
void daemonise (const char *pidFile)
{
pid_t pid ;
int i ;
FILE *fd ;
syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ;
// Fork from the parent
if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ;
exit (EXIT_FAILURE) ;
}
if (pid > 0) // Parent - terminate
exit (EXIT_SUCCESS) ;
// Now running on the child - become session leader
if (setsid() < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ;
exit (EXIT_FAILURE) ;
}
// Ignore a few signals
signal (SIGCHLD, SIG_IGN) ;
signal (SIGHUP, SIG_IGN) ;
// Fork again
if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ;
exit (EXIT_FAILURE) ;
}
if (pid > 0) // parent - terminate
exit (EXIT_SUCCESS) ;
// Tidying up - reset umask, change to / and close all files
umask (0) ;
chdir ("/") ;
for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i)
close (i) ;
// Write PID into /var/run
if (pidFile != NULL)
{
if ((fd = fopen (pidFile, "w")) == NULL)
{
syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ;
exit (EXIT_FAILURE) ;
}
fprintf (fd, "%d\n", getpid ()) ;
fclose (fd) ;
}
}

9
wiringPiD/daemonise.h Normal file
View File

@ -0,0 +1,9 @@
/*
* daemonise.h:
* Fairly generic "Turn the current process into a daemon" code.
*
* Copyright (c) 2016-2017 Gordon Henderson.
*********************************************************************************
*/
extern void daemonise (const char *pidFile) ;

44
wiringPiD/drcNetCmd.h Normal file
View File

@ -0,0 +1,44 @@
/*
* drcNetCmd.c:
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#define DEFAULT_SERVER_PORT 6124
#define DRCN_PIN_MODE 1
#define DRCN_PULL_UP_DN 2
#define DRCN_DIGITAL_WRITE 3
#define DRCN_DIGITAL_WRITE8 4
#define DRCN_ANALOG_WRITE 5
#define DRCN_PWM_WRITE 6
#define DRCN_DIGITAL_READ 7
#define DRCN_DIGITAL_READ8 8
#define DRCN_ANALOG_READ 9
struct drcNetComStruct
{
uint32_t pin ;
uint32_t cmd ;
uint32_t data ;
} comDat ;

330
wiringPiD/network.c Normal file
View File

@ -0,0 +1,330 @@
/*
* network.c:
* Part of wiringPiD
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <malloc.h>
#include <fcntl.h>
#include <crypt.h>
#include "network.h"
#define TRUE (1==1)
#define FALSE (!TRUE)
// Local data
#define SALT_LEN 16
static char salt [SALT_LEN + 1] ;
static char *returnedHash = NULL ;
static int serverFd = -1 ;
// Union for the server Socket Address
static union
{
struct sockaddr_in sin ;
struct sockaddr_in6 sin6 ;
} serverSockAddr ;
// and client address
static union
{
struct sockaddr_in sin ;
struct sockaddr_in6 sin6 ;
} clientSockAddr ;
/*
* getClientIP:
* Returns a pointer to a static string containing the clients IP address
*********************************************************************************
*/
char *getClientIP (void)
{
char buf [INET6_ADDRSTRLEN] ;
static char ipAddress [1024] ;
if (clientSockAddr.sin.sin_family == AF_INET) // IPv4
{
if (snprintf (ipAddress, 1024, "IPv4: %s",
inet_ntop (clientSockAddr.sin.sin_family, (void *)&clientSockAddr.sin.sin_addr, buf, sizeof (buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
else // IPv6
{
if (clientSockAddr.sin.sin_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&clientSockAddr.sin6.sin6_addr))
{
if (snprintf (ipAddress, 1024, "IPv4in6: %s",
inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
else
{
if (snprintf (ipAddress, 1024, "IPv6: %s",
inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
}
return ipAddress ;
}
/*
* clientPstr: clientPrintf:
* Print over a network socket
*********************************************************************************
*/
static int clientPstr (int fd, char *s)
{
int len = strlen (s) ;
return (write (fd, s, len) == len) ? 0 : -1 ;
}
static int clientPrintf (const int fd, const char *message, ...)
{
va_list argp ;
char buffer [1024] ;
va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;
return clientPstr (fd, buffer) ;
}
/*
* sendGreeting:
* Send some text to the client device
*********************************************************************************
*/
int sendGreeting (int clientFd)
{
if (clientPrintf (clientFd, "200 Welcome to wiringPiD - http://wiringpi.com/\n") < 0)
return -1 ;
return clientPrintf (clientFd, "200 Connecting from: %s\n", getClientIP ()) ;
}
/*
* getSalt:
* Create a random 'salt' value for the password encryption process
*********************************************************************************
*/
static int getSalt (char drySalt [])
{
static const char *seaDog = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789/." ;
unsigned char wetSalt [SALT_LEN] ;
int i, fd ;
if ((fd = open ("/dev/urandom", O_RDONLY)) < 0)
return fd ;
if (read (fd, wetSalt, SALT_LEN) != SALT_LEN)
return -1 ;
close (fd) ;
for (i = 0 ; i < SALT_LEN ; ++i)
drySalt [i] = seaDog [wetSalt [i] & 63] ;
drySalt [SALT_LEN] = 0 ;
return 0 ;
}
/*
* sendChallenge:
* Create and send our salt (aka nonce) to the remote device
*********************************************************************************
*/
int sendChallenge (int clientFd)
{
if (getSalt (salt) < 0)
return -1 ;
return clientPrintf (clientFd, "Challenge %s\n", salt) ;
}
/*
* getResponse:
* Read the encrypted password from the remote device.
*********************************************************************************
*/
int getResponse (int clientFd)
{
char reply [1024] ;
int len ;
// Being sort of lazy about this. I'm expecting an SHA-512 hash back and these
// are exactly 86 characters long, so no reason not to, I guess...
len = 86 ;
if (setsockopt (clientFd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return -1 ;
len = recv (clientFd, reply, 86, 0) ;
if (len != 86)
return -1 ;
reply [len] = 0 ;
if ((returnedHash = malloc (len + 1)) == NULL)
return -1 ;
strcpy (returnedHash, reply) ;
return 0 ;
}
/*
* passwordMatch:
* See if there's a match. If not, we simply dump them.
*********************************************************************************
*/
int passwordMatch (const char *password)
{
char *encrypted ;
char salted [1024] ;
sprintf (salted, "$6$%s$", salt) ;
encrypted = crypt (password, salted) ;
// 20: $6$ then 16 characters of salt, then $
// 86 is the length of an SHA-512 hash
return strncmp (encrypted + 20, returnedHash, 86) == 0 ;
}
/*
* setupServer:
* Do what's needed to create a local server socket instance that can listen
* on both IPv4 and IPv6 interfaces.
*********************************************************************************
*/
int setupServer (int serverPort)
{
socklen_t clientSockAddrSize = sizeof (clientSockAddr) ;
int on = 1 ;
int family ;
socklen_t serverSockAddrSize ;
int clientFd ;
// Try to create an IPv6 socket
serverFd = socket (PF_INET6, SOCK_STREAM, 0) ;
// If it didn't work, then fall-back to IPv4.
if (serverFd < 0)
{
if ((serverFd = socket (PF_INET, SOCK_STREAM, 0)) < 0)
return -1 ;
family = AF_INET ;
serverSockAddrSize = sizeof (struct sockaddr_in) ;
}
else // We got an IPv6 socket
{
family = AF_INET6 ;
serverSockAddrSize = sizeof (struct sockaddr_in6) ;
}
if (setsockopt (serverFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
return -1 ;
// Setup the servers socket address - cope with IPv4 and v6.
memset (&serverSockAddr, 0, sizeof (serverSockAddr)) ;
switch (family)
{
case AF_INET:
serverSockAddr.sin.sin_family = AF_INET ;
serverSockAddr.sin.sin_addr.s_addr = htonl (INADDR_ANY) ;
serverSockAddr.sin.sin_port = htons (serverPort) ;
break;
case AF_INET6:
serverSockAddr.sin6.sin6_family = AF_INET6 ;
serverSockAddr.sin6.sin6_addr = in6addr_any ;
serverSockAddr.sin6.sin6_port = htons (serverPort) ;
}
// Bind, listen and accept
if (bind (serverFd, (struct sockaddr *)&serverSockAddr, serverSockAddrSize) < 0)
return -1 ;
if (listen (serverFd, 4) < 0) // Really only going to talk to one client at a time...
return -1 ;
if ((clientFd = accept (serverFd, (struct sockaddr *)&clientSockAddr, &clientSockAddrSize)) < 0)
return -1 ;
return clientFd ;
}
/*
* closeServer:
*********************************************************************************
*/
void closeServer (int clientFd)
{
if (serverFd != -1) close (serverFd) ;
if (clientFd != -1) close (clientFd) ;
serverFd = clientFd = -1 ;
}

31
wiringPiD/network.h Normal file
View File

@ -0,0 +1,31 @@
/*
* network.h:
* Part of wiringPiD
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
extern char *getClientIP (void) ;
extern int getResponce (int clientFd) ;
extern int setupServer (int serverPort) ;
extern int sendGreeting (int clientFd) ;
extern int sendChallenge (int clientFd) ;
extern int getResponse (int clientFd) ;
extern int passwordMatch (const char *password) ;
extern void closeServer (int clientFd) ;

126
wiringPiD/runRemote.c Normal file
View File

@ -0,0 +1,126 @@
/*
* runRemote.c:
* Run the remote commands passed over the network link.
*
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
//#include <stdarg.h>
#include <wiringPi.h>
#include <wpiExtensions.h>
#include "drcNetCmd.h"
#include "network.h"
#include "runRemote.h"
int noLocalPins = FALSE ;
void runRemoteCommands (int fd)
{
register uint32_t pin ;
int len ;
struct drcNetComStruct cmd ;
len = sizeof (struct drcNetComStruct) ;
if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return ;
for (;;)
{
if (recv (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) // Probably remote hangup
return ;
pin = cmd.pin ;
if (noLocalPins && ((pin & PI_GPIO_MASK) == 0))
{
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
continue ;
}
switch (cmd.cmd)
{
case DRCN_PIN_MODE:
pinMode (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_PULL_UP_DN:
pullUpDnControl (pin, cmd.data) ;
break ;
case DRCN_PWM_WRITE:
pwmWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_DIGITAL_WRITE:
digitalWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_DIGITAL_WRITE8:
//digitalWrite8 (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_DIGITAL_READ:
cmd.data = digitalRead (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_DIGITAL_READ8:
//cmd.data = digitalRead8 (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_ANALOG_WRITE:
analogWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
case DRCN_ANALOG_READ:
cmd.data = analogRead (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
}
}
}

29
wiringPiD/runRemote.h Normal file
View File

@ -0,0 +1,29 @@
/*
* runRemote.h:
* Run the remote commands passed over the network link.
*
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
// Globals
extern int noLocalPins ;
extern void runRemoteCommands (int fd) ;

BIN
wiringPiD/wiringpid Executable file

Binary file not shown.

382
wiringPiD/wiringpid.c Normal file
View File

@ -0,0 +1,382 @@
/*
* wiringPiD.c:
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <wiringPi.h>
#include <wpiExtensions.h>
#include "drcNetCmd.h"
#include "network.h"
#include "runRemote.h"
#include "daemonise.h"
#define PIDFILE "/var/run/wiringPiD.pid"
// Globals
static const char *usage = "[-h] [-d] [-g | -1 | -z] [[-x extension:pin:params] ...] password" ;
static int doDaemon = FALSE ;
//
static void logMsg (const char *message, ...)
{
va_list argp ;
char buffer [1024] ;
va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;
if (doDaemon)
syslog (LOG_DAEMON | LOG_INFO, "%s", buffer) ;
else
printf ("%s\n", buffer) ;
}
/*
* sigHandler:
* setupSigHandler:
* Somehing has happened that would normally terminate the program so try
* to close down nicely.
*********************************************************************************
*/
void sigHandler (int sig)
{
logMsg ("Exiting on signal %d: %s", sig, strsignal (sig)) ;
(void)unlink (PIDFILE) ;
exit (EXIT_FAILURE) ;
}
void setupSigHandler (void)
{
struct sigaction action ;
sigemptyset (&action.sa_mask) ;
action.sa_flags = 0 ;
// Ignore what we can
action.sa_handler = SIG_IGN ;
sigaction (SIGHUP, &action, NULL) ;
sigaction (SIGTTIN, &action, NULL) ;
sigaction (SIGTTOU, &action, NULL) ;
// Trap what we can to exit gracefully
action.sa_handler = sigHandler ;
sigaction (SIGINT, &action, NULL) ;
sigaction (SIGQUIT, &action, NULL) ;
sigaction (SIGILL, &action, NULL) ;
sigaction (SIGABRT, &action, NULL) ;
sigaction (SIGFPE, &action, NULL) ;
sigaction (SIGSEGV, &action, NULL) ;
sigaction (SIGPIPE, &action, NULL) ;
sigaction (SIGALRM, &action, NULL) ;
sigaction (SIGTERM, &action, NULL) ;
sigaction (SIGUSR1, &action, NULL) ;
sigaction (SIGUSR2, &action, NULL) ;
sigaction (SIGCHLD, &action, NULL) ;
sigaction (SIGTSTP, &action, NULL) ;
sigaction (SIGBUS, &action, NULL) ;
}
/*
* The works...
*********************************************************************************
*/
int main (int argc, char *argv [])
{
int clientFd ;
char *p, *password ;
int i ;
int port = DEFAULT_SERVER_PORT ;
int wpiSetup = 0 ;
if (argc < 2)
{
fprintf (stderr, "Usage: %s %s\n", argv [0], usage) ;
exit (EXIT_FAILURE) ;
}
// Help?
if (strcasecmp (argv [1], "-h") == 0)
{
printf ("Usage: %s %s\n", argv [0], usage) ;
return 0 ;
}
// Daemonize?
// Must come before the other args as e.g. some extensions
// open files which get closed on daemonise...
if (strcasecmp (argv [1], "-d") == 0)
{
if (geteuid () != 0)
{
fprintf (stderr, "%s: Must be root to run as a daemon.\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}
doDaemon = TRUE ;
daemonise (PIDFILE) ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
}
// Scan all other arguments
while (*argv [1] == '-')
{
// Look for wiringPi setup arguments:
// Same as the gpio command and rtb.
// -g - bcm_gpio
if (strcasecmp (argv [1], "-g") == 0)
{
if (wpiSetup == 0)
{
logMsg ("BCM_GPIO mode selected") ;
wiringPiSetupGpio () ;
}
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
++wpiSetup ;
continue ;
}
// -1 - physical pins
if (strcasecmp (argv [1], "-1") == 0)
{
if (wpiSetup == 0)
{
logMsg ("GPIO-PHYS mode selected") ;
wiringPiSetupPhys () ;
}
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
++wpiSetup ;
continue ;
}
// -z - no wiringPi - blocks remotes accessing local pins
if (strcasecmp (argv [1], "-z") == 0)
{
if (wpiSetup == 0)
logMsg ("No GPIO mode selected") ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
noLocalPins = TRUE ;
++wpiSetup ;
continue ;
}
// -p to select the port
if (strcasecmp (argv [1], "-p") == 0)
{
if (argc < 3)
{
logMsg ("-p missing extension port") ;
exit (EXIT_FAILURE) ;
}
logMsg ("Setting port to: %s", argv [2]) ;
port = atoi (argv [2]) ;
if ((port < 1) || (port > 65535))
{
logMsg ("Invalid server port: %d", port) ;
exit (EXIT_FAILURE) ;
}
// Shift args down by 2
for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
argc -= 2 ;
continue ;
}
// Check for -x argument to load in a new extension
// -x extension:base:args
// Can load many modules to extend the daemon.
if (strcasecmp (argv [1], "-x") == 0)
{
if (argc < 3)
{
logMsg ("-x missing extension name:data:etc.") ;
exit (EXIT_FAILURE) ;
}
logMsg ("Loading extension: %s", argv [2]) ;
if (!loadWPiExtension (argv [0], argv [2], TRUE))
{
logMsg ("Extension load failed: %s", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
// Shift args down by 2
for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
argc -= 2 ;
continue ;
}
logMsg ("Invalid parameter: %s", argv [1]) ;
exit (EXIT_FAILURE) ;
}
// Default to wiringPi mode
if (wpiSetup == 0)
{
logMsg ("WiringPi GPIO mode selected") ;
wiringPiSetup () ;
}
// Finally, should just be one arg left - the password...
if (argc != 2)
{
logMsg ("No password supplied") ;
exit (EXIT_FAILURE) ;
}
if (strlen (argv [1]) < 6)
{
logMsg ("Password too short - at least 6 chars, not %d", strlen (argv [1])) ;
exit (EXIT_FAILURE) ;
}
if ((password = malloc (strlen (argv [1]) + 1)) == NULL)
{
logMsg ("Out of memory") ;
exit (EXIT_FAILURE) ;
}
strcpy (password, argv [1]) ;
// Wipe out the password on the command-line in a vague attempt to try to
// hide it from snoopers
for (p = argv [1] ; *p ; ++p)
*p = ' ' ;
setupSigHandler () ;
// Enter our big loop
for (;;)
{
if (!doDaemon)
printf ("-=-\nWaiting for a new connection...\n") ;
if ((clientFd = setupServer (port)) < 0)
{
logMsg ("Unable to setup server: %s", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
logMsg ("New connection from: %s.", getClientIP ()) ;
if (!doDaemon)
printf ("Sending Greeting.\n") ;
if (sendGreeting (clientFd) < 0)
{
logMsg ("Unable to send greeting message: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}
if (!doDaemon)
printf ("Sending Challenge.\n") ;
if (sendChallenge (clientFd) < 0)
{
logMsg ("Unable to send challenge message: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}
if (!doDaemon)
printf ("Waiting for response.\n") ;
if (getResponse (clientFd) < 0)
{
logMsg ("Connection closed waiting for response: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}
if (!passwordMatch (password))
{
logMsg ("Password failure") ;
closeServer (clientFd) ;
continue ;
}
logMsg ("Password OK - Starting") ;
runRemoteCommands (clientFd) ;
closeServer (clientFd) ;
}
return 0 ;
}