diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/mts_wait_for_cell_reset.c | 108 | ||||
-rw-r--r-- | src/x | 108 |
3 files changed, 218 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 99145a4..7dadb83 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,10 +2,11 @@ AUTOMAKE_OPTIONS = gnu AM_CFLAGS = -Wall -bin_PROGRAMS = mts-id-eeprom +bin_PROGRAMS = mts-id-eeprom mts-wait-for-cell-reset sbin_PROGRAMS = mts-hashpwd mts-fpga-loader mts_hashpwd_SOURCES = hashpwd.cpp mts_id_eeprom_SOURCES = eeprom_main.c +mts_wait_for_cell_reset_SOURCES = mts_wait_for_cell_reset.c noinst_HEADERS = eeprom.h log.h mts_error_codes.h mts_fpga_hash.h mts_fpga_reg.h mts_fpga_spi.h mts_hashpwd_LDADD = -lcrypto diff --git a/src/mts_wait_for_cell_reset.c b/src/mts_wait_for_cell_reset.c new file mode 100644 index 0000000..9f7de31 --- /dev/null +++ b/src/mts_wait_for_cell_reset.c @@ -0,0 +1,108 @@ +/* + * mts-wait-for-cell-reset + * + * Block signal + * If not in reset, exit + * Register with mts-io for reset + * If not in reset, exit + * Suspend process for signal + * If signal occurs, exit + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> + +const char *name = "mts-wait-for-cell-reset"; +const int RST_SIG=SIGUSR2; // Wait for this signal +const char *MONITOR="/sys/devices/platform/mts-io/radio-reset-monitor"; +const char *RADIO_DISCOVERY="/sys/devices/platform/mts-io/radio-udev-discovery"; + +/* Return 0 if Cellular modem is being reset + * Return 1 if Cellular modem is not being reset + */ +int +not_reset(const char *attr_name) +{ + int not_in_reset, result; + char buf[256]; + int discovery; + + discovery = open(attr_name,O_RDONLY); + if (discovery == -1) { + fprintf(stderr,"FAILED: %s cannot open attribute %s: %s\n",name,attr_name,strerror(errno)); + exit(1); + } + result = read(discovery,buf,sizeof buf); + if (result > 0) + not_in_reset = atoi(buf); + else if (result == 0) { + fprintf(stderr,"FAILED: %s attribute %s has no state\n",name,attr_name); + exit(1); + } else { + fprintf(stderr,"FAILED: %s attribute %s error: %s\n",name,attr_name,strerror(errno)); + exit(1); + } + close(discovery); + return not_in_reset; +} + +void +handler(int sig) +{ + /* Normal way out of this program + * exit not safe from signal handler so + * use _exit() + */ + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + sigset_t blockedset,nullset; + int monitor; + int result; + char buf[128]; + struct sigaction action; + + memset(&action,0,sizeof action); + action.sa_handler = handler; + memset(&blockedset,0,sizeof blockedset); + sigaddset(&blockedset,RST_SIG); + memset(&nullset,0,sizeof nullset); + + sigprocmask(SIG_BLOCK,&blockedset,NULL); // Blocked RST_SIG + + sigaction(RST_SIG,&action,NULL); + + if (not_reset(RADIO_DISCOVERY)) + exit(0); // Not in reset + sprintf(buf,"%d %d",getpid(),RST_SIG); + + monitor = open(MONITOR,O_WRONLY); + if (monitor == -1) { + fprintf(stderr,"FAILED: %s cannot open attribute %s: %s\n",name,MONITOR,strerror(errno)); + exit(2); + } + result = write(monitor,buf,strlen(buf)); + if(result != strlen(buf)) { + if (result == -1) { + fprintf(stderr,"FAILED: %s attribute %s write error: %s\n",name,MONITOR,strerror(errno)); + exit(3); + } + fprintf(stderr,"FAILED: %s attribute %s incomplete write error: %d/%d\n",name,MONITOR,result,(int)strlen(buf)); + exit(4); + } + close(monitor); + if (not_reset(RADIO_DISCOVERY)) + exit(0); + + sigsuspend(&nullset); // Allow all signals + /* NOTREACHED */ +} @@ -0,0 +1,108 @@ +/* + * mts-wait-for-cell-reset + * + * Block signal + * If not in reset, exit + * Register with mts-io for reset + * If not in reset, exit + * Suspend process for signal + * If signal occurs, exit + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> + +const char *name = "mts-wait-for-cell-reset"; +const int RST_SIG=SIGUSR2; // Wait for this signal +const char *MONITOR="/sys/devices/platform/mts-io/radio-reset-monitor"; +const char *RADIO_DISCOVERY="/sys/devices/platform/mts-io/radio-udev-discovery"; + +/* Return 0 if Cellular modem is being reset + * Return 1 if Cellular modem is not being reset + */ +int +not_reset(const char *attr_name) +{ + int not_in_reset, result; + char buf[256]; + int discovery; + + discovery = open(attr_name,O_RDONLY); + if (discovery == -1) { + fprintf(stderr,"FAILED: %s cannot open attribute %s: %s\n",name,attr_name,strerror(errno)); + exit(1); + } + result = read(discovery,buf,sizeof buf); + if (result > 0) + not_in_reset = atoi(buf); + else if (result == 0) { + fprintf(stderr,"FAILED: %s attribute %s has no state\n",name,attr_name); + exit(1); + } else { + fprintf(stderr,"FAILED: %s attribute %s error: %s\n",name,attr_name,strerror(errno)); + exit(1); + } + close(discovery); + return not_in_reset; +} + +void +handler(int sig) +{ + /* Normal way out of this program + * exit not safe from signal handler so + * use _exit() + */ + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + sigset_t blockedset,nullset; + int monitor; + int result; + char buf[128]; + struct sigaction action; + + memset(&action,0,sizeof action); + action.sa_handler = handler; + memset(&blockedset,0,sizeof blockedset); + sigaddset(&blockedset,RST_SIG); + memset(&nullset,0,sizeof nullset); + + sigprocmask(SIG_BLOCK,&blockedset,NULL); // Blocked RST_SIG + + sigaction(RST_SIG,&action,NULL); + + if (not_reset(RADIO_DISCOVERY)) + exit(0); // Not in reset + sprintf(buf,"%d %d",getpid(),RST_SIG); + + monitor = open(MONITOR,O_WRONLY); + if (monitor == -1) { + fprintf(stderr,"FAILED: %s cannot open attribute %s: %s\n",name,MONITOR,strerror(errno)); + exit(2); + } + result = write(monitor,buf,strlen(buf)); + if(result != strlen(buf)) { + if (result == -1) { + fprintf(stderr,"FAILED: %s attribute %s write error: %s\n",name,MONITOR,strerror(errno)); + exit(3); + } + fprintf(stderr,"FAILED: %s attribute %s incomplete write error: %d/%d\n",name,MONITOR,result,(int)strlen(buf)); + exit(4); + } + close(monitor); + if (not_reset(RADIO_DISCOVERY)) + exit(0); + + sigsuspend(&nullset); // Allow all signals + /* NOTREACHED */ +} |