W3AIBO.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2003 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <OPENR/OSyslog.h>
00015 #include <OPENR/ODebug.h>
00016 #include <OPENR/OPENRAPI.h>
00017 #include <OPENR/core_macro.h>
00018 #include <ant.h>
00019 #include <EndpointTypes.h>
00020 #include <TCPEndpointMsg.h>
00021 #include "W3AIBO.h"
00022 #include "entry.h"
00023 
00024 W3AIBO::W3AIBO()
00025 {
00026 }
00027 
00028 OStatus
00029 W3AIBO::DoInit(const OSystemEvent& event)
00030 {
00031     OStatus result;
00032 
00033     NEW_ALL_SUBJECT_AND_OBSERVER;
00034     REGISTER_ALL_ENTRY;
00035     SET_ALL_READY_AND_NOTIFY_ENTRY;
00036 
00037     ipstackRef = antStackRef("IPStack");
00038 
00039     for (int index = 0; index < W3AIBO_CONNECTION_MAX; index++) {
00040         result = InitTCPConnection(index);
00041         if (result != oSUCCESS) {
00042             OSYSLOG1((osyslogERROR, "W3AIBO::DoInit() : NO MEMORY"));
00043         }
00044     }
00045 
00046     jpegEncoder.Init(ipstackRef);
00047 
00048     return oSUCCESS;
00049 }
00050 
00051 OStatus
00052 W3AIBO::DoStart(const OSystemEvent& event)
00053 {
00054     for (int index = 0; index < W3AIBO_CONNECTION_MAX; index++) {
00055         Listen(index);
00056     }
00057 
00058     ENABLE_ALL_SUBJECT;
00059     ASSERT_READY_TO_ALL_OBSERVER;
00060 
00061     return oSUCCESS;
00062 }    
00063 
00064 OStatus
00065 W3AIBO::DoStop(const OSystemEvent& event)
00066 {
00067     DISABLE_ALL_SUBJECT;
00068     DEASSERT_READY_TO_ALL_OBSERVER;
00069 
00070     return oSUCCESS;
00071 }
00072 
00073 OStatus
00074 W3AIBO::DoDestroy(const OSystemEvent& event)
00075 {
00076     DISABLE_ALL_SUBJECT;
00077     return oSUCCESS;
00078 }
00079 
00080 OStatus
00081 W3AIBO::InitTCPConnection(int index)
00082 {
00083     OSYSDEBUG(("W3AIBO::InitTCPConnection(%d)\n", index));
00084 
00085     connection[index].state = CONNECTION_CLOSED;
00086 
00087     // 
00088     // Allocate send buffer
00089     //
00090     antEnvCreateSharedBufferMsg sendBufferMsg(W3AIBO_HTTP_BUFSIZE);
00091 
00092     sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00093     if (sendBufferMsg.error != ANT_SUCCESS) {
00094         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
00095                   "W3AIBO::InitTCPConnection()",
00096                   "Can't allocate send buffer",
00097                   index, sendBufferMsg.error));
00098         return oFAIL;
00099     }
00100 
00101     connection[index].sendBuffer = sendBufferMsg.buffer;
00102     connection[index].sendBuffer.Map();
00103     connection[index].sendData
00104         = (byte*)(connection[index].sendBuffer.GetAddress());
00105     connection[index].sendSize = 0;
00106     
00107     //
00108     // Allocate receive buffer
00109     //
00110     antEnvCreateSharedBufferMsg recvBufferMsg(W3AIBO_HTTP_BUFSIZE);
00111     
00112     recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00113     if (recvBufferMsg.error != ANT_SUCCESS) {
00114         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
00115                   "W3AIBO::InitTCPConnection()",
00116                   "Can't allocate receive buffer",
00117                   index, recvBufferMsg.error));
00118         return oFAIL;
00119     }
00120 
00121     connection[index].recvBuffer = recvBufferMsg.buffer;
00122     connection[index].recvBuffer.Map();
00123     connection[index].recvData
00124         = (byte*)(connection[index].recvBuffer.GetAddress());
00125     connection[index].recvSize = 0;
00126 
00127     //
00128     // Allocate http buffer
00129     //
00130     connection[index].httpReq = (char*)malloc(W3AIBO_HTTP_BUFSIZE);
00131     if (connection[index].httpReq == 0) {
00132         OSYSLOG1((osyslogERROR, "%s : %s[%d]",
00133                   "W3AIBO::InitTCPConnection()",
00134                   "Can't allocate http buffer", index));
00135         return oFAIL;
00136     }
00137     connection[index].httpReqLen = 0;
00138 
00139     //
00140     // Initialize image info
00141     //
00142     connection[index].imageRequested = false;
00143     connection[index].layer          = ofbkimageLAYER_H;
00144     connection[index].reconstruction = false;
00145     connection[index].quality        = 75;
00146     connection[index].jpegData       = 0;
00147     connection[index].jpegSize       = 0;
00148 
00149     return oSUCCESS;
00150 }
00151 
00152 void
00153 W3AIBO::NotifyImage(const ONotifyEvent& event)
00154 {
00155     OFbkImageVectorData* imageVec = (OFbkImageVectorData*)event.Data(0);
00156 
00157     for (int index = 0; index < W3AIBO_CONNECTION_MAX; index++) {
00158         if (connection[index].imageRequested == true) {
00159         
00160             jpegEncoder.GetJPEG(imageVec, 
00161                                 connection[index].layer,
00162                                 connection[index].reconstruction,
00163                                 connection[index].quality,
00164                                 &(connection[index].jpegData),
00165                                 &(connection[index].jpegSize));
00166 
00167             HTTPResponse(index, HTTP_OK);
00168             connection[index].imageRequested = false;
00169         }
00170     }
00171 
00172     observer[event.ObsIndex()]->AssertReady(event.SenderID());
00173 }
00174 
00175 OStatus
00176 W3AIBO::Listen(int index)
00177 {
00178     OSYSDEBUG(("W3AIBO::Listen(%d)\n", index));
00179 
00180     if (connection[index].state != CONNECTION_CLOSED) return oFAIL;
00181 
00182     //
00183     // Create endpoint
00184     //
00185     antEnvCreateEndpointMsg tcpCreateMsg(EndpointType_TCP,
00186                                          W3AIBO_HTTP_BUFSIZE * 2);
00187     tcpCreateMsg.Call(ipstackRef, sizeof(tcpCreateMsg));
00188     if (tcpCreateMsg.error != ANT_SUCCESS) {
00189         OSYSLOG1((osyslogERROR, "%s : %s[%d] antError %d",
00190                   "W3AIBO::Listen()",
00191                   "Can't create endpoint",
00192                   index, tcpCreateMsg.error));
00193         return oFAIL;
00194     }
00195     connection[index].endpoint = tcpCreateMsg.moduleRef;
00196 
00197     //
00198     // Listen
00199     //
00200     TCPEndpointListenMsg listenMsg(connection[index].endpoint,
00201                                    IP_ADDR_ANY, W3AIBO_PORT);
00202     listenMsg.continuation = (void*)index;
00203 
00204     listenMsg.Send(ipstackRef, myOID_,
00205                    Extra_Entry[entryListenCont], sizeof(listenMsg));
00206     
00207     connection[index].state = CONNECTION_LISTENING;
00208 
00209     return oSUCCESS;
00210 }
00211 
00212 void
00213 W3AIBO::ListenCont(ANTENVMSG msg)
00214 {
00215     TCPEndpointListenMsg* listenMsg = (TCPEndpointListenMsg*)antEnvMsg::Receive(msg);
00216     int index = (int)listenMsg->continuation;
00217 
00218     OSYSDEBUG(("W3AIBO::ListenCont(%d)\n", index));
00219 
00220     if (listenMsg->error != TCP_SUCCESS) {
00221         OSYSLOG1((osyslogERROR, "%s : %s %d",
00222                   "W3AIBO::ListenCont()",
00223                   "FAILED. listenMsg->error", listenMsg->error));
00224         Close(index);
00225         return;
00226     }
00227 
00228     connection[index].state = CONNECTION_CONNECTED;
00229 
00230     Receive(index);
00231 }
00232 
00233 OStatus
00234 W3AIBO::Receive(int index)
00235 {
00236     OSYSDEBUG(("W3AIBO::Receive(%d)\n", index));
00237 
00238     if (connection[index].state != CONNECTION_CONNECTED &&
00239         connection[index].state != CONNECTION_SENDING) return oFAIL;
00240 
00241     connection[index].recvSize = W3AIBO_HTTP_BUFSIZE;
00242     connection[index].httpReqLen = 0;
00243 
00244     TCPEndpointReceiveMsg receiveMsg(connection[index].endpoint,
00245                                      connection[index].recvData,
00246                                      1, connection[index].recvSize);
00247     receiveMsg.continuation = (void*)index;
00248 
00249     receiveMsg.Send(ipstackRef, myOID_,
00250                     Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
00251 
00252     return oSUCCESS;
00253 }
00254 
00255 void
00256 W3AIBO::ReceiveCont(ANTENVMSG msg)
00257 {
00258     TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*)antEnvMsg::Receive(msg);
00259     int index = (int)(receiveMsg->continuation);
00260 
00261     OSYSDEBUG(("W3AIBO::ReceiveCont(%d)\n", index));
00262 
00263     if (receiveMsg->error != TCP_SUCCESS) {
00264         OSYSLOG1((osyslogERROR, "%s : %s %d",
00265                   "W3AIBO::ReceiveCont()",
00266                   "FAILED. receiveMsg->error", receiveMsg->error));
00267         Close(index);
00268         return;
00269     }
00270 
00271     memcpy((void*)(connection[index].httpReq + connection[index].httpReqLen),
00272            connection[index].recvData, receiveMsg->sizeMin);
00273 
00274     connection[index].httpReqLen += receiveMsg->sizeMin;
00275     connection[index].httpReq[connection[index].httpReqLen] = '\0';
00276 
00277 #ifdef OPENR_DEBUG
00278     DPRINTF(("receiveMsg->sizeMin %d\n", receiveMsg->sizeMin));
00279     for (int i = 0; i < receiveMsg->sizeMin; i++) {
00280         DPRINTF(("%02x ", connection[index].httpReq[i]));
00281     }
00282     DPRINTF(("\n"));
00283 #endif
00284 
00285     if (strstr(connection[index].httpReq, "\r\n\r\n")) {
00286 
00287         DPRINTF(("%s", connection[index].httpReq));
00288         ProcessHTTPRequest(index);
00289 
00290     } else {
00291 
00292         Receive(index);
00293 
00294     }
00295 }
00296 
00297 OStatus
00298 W3AIBO::SendHeader(int index)
00299 {
00300     OSYSDEBUG(("W3AIBO::SendHeader(%d)\n", index));
00301 
00302     if (connection[index].sendSize == 0 ||
00303         connection[index].state != CONNECTION_CONNECTED) return oFAIL;
00304 
00305     TCPEndpointSendMsg sendMsg(connection[index].endpoint,
00306                                connection[index].sendData,
00307                                connection[index].sendSize);
00308     sendMsg.continuation = (void*)index;
00309 
00310     sendMsg.Send(ipstackRef, myOID_,
00311                  Extra_Entry[entrySendHeaderCont],
00312                  sizeof(TCPEndpointSendMsg));
00313 
00314     connection[index].state = CONNECTION_SENDING;
00315     connection[index].sendSize = 0;
00316 
00317     return oSUCCESS;
00318 }
00319 
00320 void
00321 W3AIBO::SendHeaderCont(ANTENVMSG msg)
00322 {
00323     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)antEnvMsg::Receive(msg);
00324     int index = (int)(sendMsg->continuation);
00325 
00326     OSYSDEBUG(("W3AIBO::SendHeaderCont(%d)\n", index));
00327 
00328     if (sendMsg->error != TCP_SUCCESS) {
00329         OSYSLOG1((osyslogERROR, "%s : %s %d",
00330                   "W3AIBO::SendHeaderCont()",
00331                   "FAILED. sendMsg->error", sendMsg->error));
00332         Close(index);
00333         return;
00334     }
00335 
00336     connection[index].state = CONNECTION_CONNECTED;
00337     SendImage(index);
00338 }
00339 
00340 OStatus
00341 W3AIBO::SendImage(int index)
00342 {
00343     OSYSDEBUG(("W3AIBO::SendImage(%d)\n", index));
00344 
00345     if (connection[index].state != CONNECTION_CONNECTED) {
00346         OSYSLOG1((osyslogERROR, "W3AIBO::SendImage() : state error"));
00347         return oFAIL;
00348     }
00349     
00350     TCPEndpointSendMsg sendMsg(connection[index].endpoint,
00351                                connection[index].jpegData,
00352                                connection[index].jpegSize);
00353     sendMsg.continuation = (void*)index;
00354 
00355     sendMsg.Send(ipstackRef, myOID_,
00356                  Extra_Entry[entrySendImageCont],
00357                  sizeof(TCPEndpointSendMsg));
00358 
00359     connection[index].state = CONNECTION_SENDING;
00360     return oSUCCESS;
00361 }
00362 
00363 void
00364 W3AIBO::SendImageCont(ANTENVMSG msg)
00365 {
00366     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)antEnvMsg::Receive(msg);
00367     int index = (int)(sendMsg->continuation);
00368 
00369     OSYSDEBUG(("W3AIBO::SendImageCont(%d)\n", index));
00370 
00371     jpegEncoder.FreeJPEG(connection[index].jpegData);
00372 
00373     if (sendMsg->error != TCP_SUCCESS) {
00374         OSYSLOG1((osyslogERROR, "%s : %s %d",
00375                   "W3AIBO::SendImageCont()",
00376                   "FAILED. sendMsg->error", sendMsg->error));
00377         Close(index);
00378         return;
00379     }
00380 
00381     connection[index].state = CONNECTION_CONNECTED;
00382     Close(index);
00383 }
00384 
00385 OStatus
00386 W3AIBO::SendError(int index)
00387 {
00388     OSYSDEBUG(("W3AIBO::SendError(%d)\n", index));
00389 
00390     if (connection[index].sendSize == 0 ||
00391         connection[index].state != CONNECTION_CONNECTED) return oFAIL;
00392 
00393     TCPEndpointSendMsg sendMsg(connection[index].endpoint,
00394                                connection[index].sendData,
00395                                connection[index].sendSize);
00396     sendMsg.continuation = (void*)index;
00397 
00398     sendMsg.Send(ipstackRef, myOID_,
00399                  Extra_Entry[entrySendErrorCont],
00400                  sizeof(TCPEndpointSendMsg));
00401 
00402     connection[index].state = CONNECTION_SENDING;
00403     connection[index].sendSize = 0;
00404 
00405     return oSUCCESS;
00406 }
00407 
00408 void
00409 W3AIBO::SendErrorCont(ANTENVMSG msg)
00410 {
00411     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)antEnvMsg::Receive(msg);
00412     int index = (int)(sendMsg->continuation);
00413 
00414     OSYSDEBUG(("W3AIBO::SendErrorCont(%d)\n", index));
00415 
00416     if (sendMsg->error != TCP_SUCCESS) {
00417         OSYSLOG1((osyslogERROR, "%s : %s %d",
00418                   "W3AIBO::SendErrorCont()",
00419                   "FAILED. sendMsg->error", sendMsg->error));
00420         Close(index);
00421         return;
00422     }
00423 
00424     connection[index].state = CONNECTION_CONNECTED;
00425     Close(index);
00426 }
00427 
00428 OStatus
00429 W3AIBO::Close(int index)
00430 {
00431     OSYSDEBUG(("W3AIBO::Close(%d)\n", index));
00432 
00433     if (connection[index].state == CONNECTION_CLOSED ||
00434         connection[index].state == CONNECTION_CLOSING) return oFAIL;
00435 
00436     TCPEndpointCloseMsg closeMsg(connection[index].endpoint);
00437     closeMsg.continuation = (void*)index;
00438 
00439     closeMsg.Send(ipstackRef, myOID_,
00440                   Extra_Entry[entryCloseCont], sizeof(closeMsg));
00441 
00442     connection[index].state = CONNECTION_CLOSING;
00443 
00444     return oSUCCESS;
00445 }
00446 
00447 void
00448 W3AIBO::CloseCont(ANTENVMSG msg)
00449 {
00450     TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*)antEnvMsg::Receive(msg);
00451     int index = (int)(closeMsg->continuation);
00452 
00453     OSYSDEBUG(("W3AIBO::CloseCont(%d)\n", index));
00454 
00455     connection[index].state = CONNECTION_CLOSED;
00456     Listen(index);
00457 }
00458 
00459 void
00460 W3AIBO::ProcessHTTPRequest(int index)
00461 {
00462     char method[32];
00463     char uri[256];
00464     char httpVer[32];
00465   
00466     bool result = http.Parse(connection[index].httpReq, method, uri, httpVer);
00467     if (result != true) {
00468         HTTPResponse(index, HTTP_BAD_REQUEST);
00469         return;
00470     }
00471 
00472     OSYSDEBUG(("METHOD  : %s\n", method));
00473     OSYSDEBUG(("URI     : %s\n", uri));
00474     OSYSDEBUG(("VERSION : %s\n", httpVer));
00475 
00476     if (strcasecmp(method, "GET") != 0) {
00477         HTTPResponse(index, HTTP_NOT_IMPLEMENTED);
00478         return;
00479     } 
00480 
00481     if (strcmp(uri, W3AIBO_DEFAULT_URI) == 0 ||
00482         strcmp(uri, W3AIBO_LAYER_H_URI) == 0) {
00483 
00484         connection[index].layer = ofbkimageLAYER_H;
00485         connection[index].reconstruction = false;
00486 
00487     } else if (strcmp(uri, W3AIBO_LAYER_M_URI) == 0) {
00488 
00489         connection[index].layer = ofbkimageLAYER_M;
00490         connection[index].reconstruction = false;
00491 
00492     } else if (strcmp(uri, W3AIBO_LAYER_L_URI) == 0) {
00493 
00494         connection[index].layer = ofbkimageLAYER_L;
00495         connection[index].reconstruction = false;
00496 
00497     } else if (strcmp(uri, W3AIBO_LAYER_HR_URI) == 0) {
00498 
00499         connection[index].layer = ofbkimageLAYER_H;
00500         connection[index].reconstruction = true;
00501 
00502     } else if (strcmp(uri, W3AIBO_LAYER_MR_URI) == 0) {
00503 
00504         connection[index].layer = ofbkimageLAYER_M;
00505         connection[index].reconstruction = true;
00506 
00507     } else if (strcmp(uri, W3AIBO_LAYER_LR_URI) == 0) {
00508         
00509         connection[index].layer = ofbkimageLAYER_L;
00510         connection[index].reconstruction = true;
00511 
00512     } else {
00513         HTTPResponse(index, HTTP_NOT_FOUND);
00514         return;
00515     }
00516 
00517     connection[index].imageRequested = true;
00518 }
00519 
00520 void
00521 W3AIBO::HTTPResponse(int index, HTTPStatus st)
00522 {
00523     char* ptr;
00524     int len;
00525 
00526     ptr = (char*)connection[index].sendData;
00527     connection[index].sendSize = 0;
00528     
00529     len = http.Status(ptr, st);
00530     connection[index].sendSize += len;
00531     ptr += len;
00532 
00533     len = http.HeaderField(ptr, HTTP_SERVER, "W3AIBO/0.1");
00534     connection[index].sendSize += len;
00535     ptr += len;
00536 
00537     if (st == HTTP_OK) {
00538 
00539         len = http.HeaderField(ptr, HTTP_CONTENT_TYPE, "image/jpeg");
00540         connection[index].sendSize += len;
00541         ptr += len;
00542 
00543         len = http.HeaderField(ptr, HTTP_HEADER_END, NULL);
00544         connection[index].sendSize += len;
00545         ptr += len;
00546 
00547         SendHeader(index);
00548 
00549     } else { // HTTP error
00550 
00551         len = http.HeaderField(ptr, HTTP_CONTENT_TYPE, "text/html");
00552         connection[index].sendSize += len;
00553         ptr += len;
00554 
00555         len = http.HeaderField(ptr, HTTP_HEADER_END, NULL);
00556         connection[index].sendSize += len;
00557         ptr += len;
00558       
00559         if (st == HTTP_BAD_REQUEST) {
00560 
00561             OSYSDEBUG(("W3AIBO::HTTPResponse() : HTTP_BAD_REQUEST\n"));
00562 
00563             strcpy(ptr, "<html><body>400 Bad Request</body></html>");
00564             len = strlen("<html><body>400 Bad Request</body></html>");
00565             connection[index].sendSize += len;
00566             ptr += len;
00567 
00568         } else if (st == HTTP_NOT_IMPLEMENTED) {
00569 
00570             OSYSDEBUG(("W3AIBO::HTTPResponse() : HTTP_NOT_IMPLEMENTED\n"));
00571 
00572             strcpy(ptr, "<html><body>501 Not Implemented</body></html>");
00573             len = strlen("<html><body>501 Not Implemented</body></html>");
00574             connection[index].sendSize += len;
00575             ptr += len;
00576 
00577         } else if (st == HTTP_NOT_FOUND) {
00578 
00579             OSYSDEBUG(("W3AIBO::HTTPResponse() : HTTP_NOT_FOUND\n"));
00580 
00581             strcpy(ptr, "<html><body>404 Not Found</body></html>");
00582             len = strlen("<html><body>404 Not Found</body></html>");
00583             connection[index].sendSize += len;
00584             ptr += len;
00585 
00586         } else {
00587 
00588             OSYSLOG1((osyslogERROR, "W3AIBO::HTTPResponse() : INVALID ARG"));
00589             return;
00590 
00591         }
00592 
00593         SendError(index);
00594     }
00595 
00596 #ifdef OPENR_DEBUG
00597     *ptr = 0;
00598     DPRINTF(("%s", connection[index].sendData));
00599 #endif
00600 }

Generated on Sun Dec 2 23:04:31 2007 for openSDK by  doxygen 1.3.9.1