/* * 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 #include #include #include #include #include #include #include #include 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 */ }