00001 #include "EventLogger.h"
00002 #include "Events/EventRouter.h"
00003 #include "Motion/MMAccessor.h"
00004 #include "Motion/LedMC.h"
00005 #include "ValueEditControl.h"
00006 #include "StringInputControl.h"
00007 #include "NullControl.h"
00008 #include <sstream>
00009 #include "Sound/SoundManager.h"
00010 #include "Vision/FilterBankGenerator.h"
00011 #include "Shared/Base64.h"
00012
00013 #include <libxml/xmlmemory.h>
00014 #include <libxml/parser.h>
00015
00016 Socket* EventLogger::logSocket=NULL;
00017 unsigned int EventLogger::logSocketRefCount=0;
00018 int EventLogger::port=10080;
00019
00020 EventLogger::EventLogger() : ControlBase("Event Logger","Allows you to see/log all of the un-trapped events as they are generated"), logfilePath(), logfile(), verbosity(0) {
00021 for(unsigned int i=0; i<EventBase::numEGIDs; i++) {
00022 std::string tmp=EventBase::EventGeneratorNames[i];
00023 pushSlot(new NullControl(("[ ] "+tmp).c_str(),"Show/hide events from "+tmp));
00024 }
00025 pushSlot(NULL);
00026 pushSlot(new ValueEditControl<unsigned int>("Verbosity","Controls verbosity level: 0=(gen,source,type); 1=0+gen_id,source_id,type_id; 2=1+duration,timestamp; 3=2+magnitude; additional columns may be added for subclass info","Please enter a new verbosity level: 0=(gen,source,type); 1=0+gen_id,source_id,type_id; 2=1+duration,timestamp; 3=2+magnitude; additional columns may be added for subclass info",&verbosity));
00027 pushSlot(new ControlBase("[X] Console Output","If selected, outputs events to the console"));
00028 pushSlot(new StringInputControl("[ ] File Output","Please enter the filename to log to (in /ms/...)"));
00029 if(logSocket==NULL) {
00030 ASSERT(logSocketRefCount==0,"logSocket is NULL, ref count is non-zero");
00031 logSocket=wireless->socket(SocketNS::SOCK_STREAM,1024,1<<15);
00032 wireless->setDaemon(logSocket);
00033 wireless->listen(logSocket,port);
00034 }
00035 logSocketRefCount++;
00036 }
00037
00038 EventLogger::~EventLogger() {
00039 clearSlots();
00040 if(--logSocketRefCount==0) {
00041 wireless->setDaemon(logSocket,false);
00042 wireless->close(logSocket);
00043 logSocket=NULL;
00044 }
00045 }
00046
00047 ControlBase* EventLogger::doSelect() {
00048 ControlBase* ans=this;
00049 for(unsigned int i=0; i<hilights.size(); i++) {
00050 unsigned int cur=hilights[i];
00051 if(cur<EventBase::numEGIDs) {
00052 if(options[cur]->getName()[1]!=' ') {
00053 erouter->removeListener(this,(EventBase::EventGeneratorID_t)(cur));
00054 setStatus(cur,' ');
00055 } else {
00056 erouter->addListener(this,(EventBase::EventGeneratorID_t)(cur));
00057 setStatus(cur,'X');
00058 }
00059 } else if(cur==EventBase::numEGIDs+1) {
00060 ans=options[cur];
00061 } else if(cur==EventBase::numEGIDs+2) {
00062 if(options[cur]->getName()[1]!=' ') {
00063 setStatus(cur,' ');
00064 } else {
00065 setStatus(cur,'X');
00066 }
00067 } else if(cur==EventBase::numEGIDs+3) {
00068 if(options[cur]->getName()[1]!=' ') {
00069 logfile.close();
00070 options[cur]->setName("[ ] File Output");
00071 } else {
00072 ans=options[cur];
00073 }
00074 }
00075 sndman->PlayFile(config->controller.select_snd);
00076 }
00077 if(ans==this)
00078 refresh();
00079 return ans;
00080 }
00081
00082 void EventLogger::refresh() {
00083 checkLogFile();
00084 ControlBase::refresh();
00085 }
00086
00087
00088 void EventLogger::processEvent(const EventBase& event) {
00089 std::string logdata = event.getDescription(true,verbosity);
00090 if(options[EventBase::numEGIDs+2]->getName()[1]=='X')
00091 sout->printf("EVENT: %s\n",logdata.c_str());
00092 if(logSocket!=NULL && wireless->isConnected(logSocket->sock)) {
00093 xmlDoc * doc = xmlNewDoc((const xmlChar*)"1.0");
00094 xmlNode * cur = xmlNewNode(NULL,(const xmlChar*)"");
00095 xmlSetProp(cur,(const xmlChar*)"type",(const xmlChar*)"log");
00096 xmlNode * desc = xmlNewNode(NULL,(const xmlChar*)"param");
00097 event.SaveXML(cur);
00098 xmlAddChild(cur,desc);
00099 xmlSetProp(desc,(const xmlChar*)"name",(const xmlChar*)"description");
00100 xmlSetProp(desc,(const xmlChar*)"value",(const xmlChar*)event.getDescription(true,3).c_str());
00101 xmlBuffer* buf=xmlBufferCreate();
00102 int n=xmlNodeDump(buf,doc,cur,0,1);
00103 xmlFreeDoc(doc);
00104 byte * nbuf = logSocket->getWriteBuffer(n+1);
00105 if(nbuf!=NULL) {
00106 memcpy(nbuf,xmlBufferContent(buf),n);
00107 nbuf[n]='\n';
00108 logSocket->write(n+1);
00109 }
00110 xmlBufferFree(buf);
00111 }
00112 checkLogFile();
00113 if(logfile)
00114 logfile << logdata << endl;
00115 }
00116
00117 void EventLogger::logImage(FilterBankGenerator& fbg, unsigned int layer, unsigned int channel, const BehaviorBase* source) {
00118 if(logSocket!=NULL && wireless->isConnected(logSocket->sock)) {
00119 fbg.selectSaveImage(layer,channel);
00120 unsigned int len=fbg.getBinSize();
00121 char * binbuf=new char[len];
00122 fbg.SaveBuffer(binbuf,len);
00123 string b64buf=base64::encode(binbuf,len);
00124
00125 xmlDoc * doc = xmlNewDoc((const xmlChar*)"1.0");
00126 xmlNode * cur = xmlNewNode(NULL,(const xmlChar*)"event");
00127 xmlSetProp(cur,(const xmlChar*)"type",(const xmlChar*)"image");
00128 if(source!=NULL)
00129 xmlSetProp(cur,(const xmlChar*)"sid",(const xmlChar*)source->getName().c_str());
00130 snprintf(binbuf,len,"%d",get_time());
00131 xmlSetProp(cur,(const xmlChar*)"time",(const xmlChar*)binbuf);
00132 delete [] binbuf;
00133 xmlNodeSetContent(cur,(const xmlChar*)b64buf.c_str());
00134 xmlBuffer* buf=xmlBufferCreate();
00135 int n=xmlNodeDump(buf,doc,cur,0,1);
00136 xmlFreeDoc(doc);
00137 byte * nbuf = logSocket->getWriteBuffer(n+1);
00138 if(nbuf!=NULL) {
00139 memcpy(nbuf,xmlBufferContent(buf),n);
00140 nbuf[n]='\n';
00141 logSocket->write(n+1);
00142 }
00143 xmlBufferFree(buf);
00144 }
00145 }
00146
00147 void EventLogger::logMessage(std::string msg, const BehaviorBase* source, const char* icon, unsigned int placement) {
00148 if(logSocket!=NULL && wireless->isConnected(logSocket->sock)) {
00149 xmlDoc * doc = xmlNewDoc((const xmlChar*)"1.0");
00150 xmlNode * cur = xmlNewNode(NULL,(const xmlChar*)"event");
00151 xmlSetProp(cur,(const xmlChar*)"type",(const xmlChar*)"userlog");
00152 if(source!=NULL)
00153 xmlSetProp(cur,(const xmlChar*)"sid",(const xmlChar*)source->getName().c_str());
00154 if(icon!=NULL)
00155 xmlSetProp(cur,(const xmlChar*)"icon",(const xmlChar*)icon);
00156 const unsigned int len=20;
00157 char sbuf[len];
00158 snprintf(sbuf,len,"%d",placement);
00159 xmlSetProp(cur,(const xmlChar*)"voff",(const xmlChar*)sbuf);
00160 snprintf(sbuf,len,"%d",get_time());
00161 xmlSetProp(cur,(const xmlChar*)"time",(const xmlChar*)sbuf);
00162 xmlNodeSetContent(cur,(const xmlChar*)msg.c_str());
00163 xmlBuffer* buf=xmlBufferCreate();
00164 int n=xmlNodeDump(buf,doc,cur,0,1);
00165 xmlFreeDoc(doc);
00166 byte * nbuf = logSocket->getWriteBuffer(n+1);
00167 if(nbuf!=NULL) {
00168 memcpy(nbuf,xmlBufferContent(buf),n);
00169 nbuf[n]='\n';
00170 logSocket->write(n+1);
00171 }
00172 xmlBufferFree(buf);
00173 }
00174 }
00175
00176 void EventLogger::logWebcam(const BehaviorBase* source) {
00177 if(logSocket!=NULL && wireless->isConnected(logSocket->sock)) {
00178 xmlDoc * doc = xmlNewDoc((const xmlChar*)"1.0");
00179 xmlNode * cur = xmlNewNode(NULL,(const xmlChar*)"event");
00180 xmlSetProp(cur,(const xmlChar*)"type",(const xmlChar*)"webcam");
00181 if(source!=NULL)
00182 xmlSetProp(cur,(const xmlChar*)"sid",(const xmlChar*)source->getName().c_str());
00183 const unsigned int len=20;
00184 char sbuf[len];
00185 snprintf(sbuf,len,"%d",get_time());
00186 xmlSetProp(cur,(const xmlChar*)"time",(const xmlChar*)sbuf);
00187 xmlNodeSetContent(cur,(const xmlChar*)" ");
00188 xmlBuffer* buf=xmlBufferCreate();
00189 int n=xmlNodeDump(buf,doc,cur,0,1);
00190 xmlFreeDoc(doc);
00191 byte * nbuf = logSocket->getWriteBuffer(n+1);
00192 if(nbuf!=NULL) {
00193 memcpy(nbuf,xmlBufferContent(buf),n);
00194 nbuf[n]='\n';
00195 logSocket->write(n+1);
00196 }
00197 xmlBufferFree(buf);
00198 }
00199 }
00200
00201 void EventLogger::clearSlots() {
00202 erouter->removeListener(this);
00203 ControlBase::clearSlots();
00204 }
00205
00206 void EventLogger::setStatus(unsigned int i, char c) {
00207 std::string tmp=options[i]->getName();
00208 tmp[1]=c;
00209 options[i]->setName(tmp);
00210 }
00211
00212 void EventLogger::checkLogFile() {
00213 unsigned int cur=EventBase::numEGIDs+3;
00214 StringInputControl * strin=dynamic_cast<StringInputControl*>(options[cur]);
00215 ASSERTRET(strin!=NULL,"The StringInputControl is misplaced");
00216 if(strin->getLastInput()!=logfilePath) {
00217 logfile.close();
00218 logfilePath=strin->getLastInput();
00219 logfile.clear();
00220 if(logfilePath.size()!=0) {
00221 sout->printf("Opening `%s'\n",(config->portPath(logfilePath)).c_str());
00222 logfile.open((config->portPath(logfilePath)).c_str());
00223 if(!logfile.fail()) {
00224 setStatus(cur,'X');
00225 strin->setName(strin->getName()+": "+logfilePath);
00226 } else {
00227 serr->printf("Opening `%s' failed\n",(config->portPath(logfilePath)).c_str());
00228 }
00229 }
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242