#include "Asterisk.h" //there is no notification that there is someone in the queue //but there is a status message you can check periodically... std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while(std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } Asterisk::~Asterisk() { stopThread(); pclose(file); printf("asterisk closed\n"); } /* Use a thread to track status with a blocking popen() gameQ has 1 calls (max unlimited) in 'rrmemory' strategy (8s holdtime, 50s talktime), W:0, C:38, A:26, SL:36.8% within 0s Members: Game AGI (Local/9999@default) with penalty 1 (In use) has taken 31 calls (last was 5333 secs ago) Callers: 1. SIP/sip_proxy-00000045 (wait: 0:06, prio: 0) */ int Asterisk::getUpdateTime(){ return ofGetElapsedTimeMillis()-cmdtime; } void Asterisk::threadedFunction(){ while( isThreadRunning() != 0 ){ //if (lock()) { cmdtime=ofGetElapsedTimeMillis(); FILE *f = popen("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"queue show gameQ\"'", "re"); //e ?? int fn=fileno(f); char buf[1000]; ssize_t r = read(fn, buf, 1000); pclose(f); string msg=string(buf); //received data is always a command ACKNOWLEDGEMENT if (msg.compare(0,5,"gameQ")==0) { vector lines; split(msg,'\n',lines); queued=0; for (int i=4;i0) startThread(false, false); // blocking, verbose } void Asterisk::startGame(){ //if (lock()) { if (state==ASTERISK_IDLE&&queued) { cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"devstate change Custom:GAME NOT_INUSE\"'"); printf("Asterisk: attempting to dequeue\n"); } //unlock(); //} } void Asterisk::endGame(string score){ printf("Asterisk: request hangup %s\n",playerCode.c_str()); if (state==ASTERISK_PLAYING) { //cmd("ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"database put GAME statuscode "+score+"\"'"); string emsg="ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx \"hangup request "+playerCode+"\"'"; cmd(emsg); printf("Asterisk: hanging up %s\n",playerCode.c_str()); } } void Asterisk::cmd(string s) { //non blocking command for anync messages //pclose(file); always closing before open crashes //printf("open file\n"); file = popen(s.c_str(), "re"); //"e" seems necessary for non blocking but with it getting crash when dequeuing. can't seem to trace it filenum=fileno(file); fcntl(filenum, F_SETFL, O_NONBLOCK); state=ASTERISK_WAITING; } void Asterisk::scmd(string s) { //non blocking command for anync messages //pclose(file); always closing before open crashes //printf("open file\n"); file = popen(s.c_str(), "re"); //"e" seems necessary for non blocking but with it getting crash when dequeuing. can't seem to trace it filenum=fileno(file); fcntl(filenum, F_SETFL, O_NONBLOCK); //printf("close file\n"); pclose(file); //is blocking! } /*Child process PID: 4265 Program received signal SIGABRT, Aborted. In __GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 () Cannot open file: /home/tim/workspace/VFxmas/vfg/iofclose.c */ int Asterisk::update(){ //capture stdin response from popen if (state==ASTERISK_WAITING) { char buf[100]; ssize_t r = read(filenum, buf, 1000); //if (r == -1 && errno == EAGAIN) //no data yet //else if (r > 0) { //is it here? //printf("close file\n"); pclose(file); string msg=string(buf); state=ASTERISK_IDLE; //received data is always a command ACKNOWLEDGEMENT //can never issue a new one until last one returns? if (msg.compare(0,8,"Changing")==0) { printf("player dequeued\n"); state=ASTERISK_STARTING; } else { printf("stdin says: %s\n",buf); } } } //check udp messages, return new keypresses char udpMessage[10000]; udpConnection.Receive(udpMessage,10000); string msg=udpMessage; if(msg!=""){ //printf("Asterisk: %s\n",msg.c_str()); if (msg.length()>3) { //printf("status msg: %s\n",msg.c_str()); if (msg.substr(0,6)=="Hangup") { state=ASTERISK_IDLE; return ASTERISK_GAMEOVER; } if (msg.substr(0,5)=="Local"&&state==ASTERISK_STARTING) { state=ASTERISK_PLAYING; playerCode=msg.substr(0,msg.length()-1); printf("Asterisk: game started: code %s\n",playerCode.c_str()); return ASTERISK_GAMESTARTED; } return 0; } else { //message length of <3 is a key if (state!=ASTERISK_PLAYING) state=ASTERISK_PLAYING; //catch missed game acknowledgement return ofToInt(msg); } } else return 0; }