Webcam Server.
Dependencies: uvchost FatFileSystem mbed HTTPServer NetServicesMin
WebcamHandler.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "WebcamServerConfig.h" 00025 #include "WebcamHandler.h" 00026 00027 //#define __DEBUG 00028 #include "mydbg.h" 00029 //#include "dbg/dbg.h" 00030 00031 #define _D(...) #__VA_ARGS__ 00032 00033 #if CAM_COUNT == 1 00034 const char* html_index = _D( 00035 <html> 00036 <head> 00037 <meta http-equiv="refresh" content="10"> 00038 </head> 00039 <body> 00040 <a href="/cam.jpg"><img src="/cam.jpg" width="320" height="240"></a> 00041 </body> 00042 </html> 00043 ); 00044 #endif 00045 00046 #if CAM_COUNT == 2 00047 const char* html_index = _D( 00048 <html> 00049 <head> 00050 <meta http-equiv="refresh" content="10"> 00051 </head> 00052 <body> 00053 <img src="/cam0.jpg"> 00054 <img src="/cam1.jpg"> 00055 </body> 00056 </html> 00057 ); 00058 #endif 00059 00060 #define CHUNK_SIZE 128 00061 00062 WebcamHandler::WebcamHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) 00063 : HTTPRequestHandler(rootPath, path, pTCPSocket) 00064 {} 00065 00066 void WebcamHandler::doGet() 00067 { 00068 DBG("\r\nIn WebcamHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str()); 00069 if (path().find("/cam") == 0) { 00070 int cam = 0; 00071 if (path().find("/cam0") == 0) { 00072 cam = 1; 00073 } 00074 DBG_ASSERT(cam >= 0); 00075 DBG_ASSERT(cam <= 1); 00076 m_buf = (char*)m_image[cam].buf; 00077 m_buf_len = m_image[cam].len; 00078 respHeaders()["Content-Type"] = "image/jpeg"; 00079 m_busy = true; 00080 } else if (path().length() == 0) { 00081 m_buf = const_cast<char*>(html_index); 00082 m_buf_len = strlen(html_index); 00083 respHeaders()["Content-Type"] = "text/html"; 00084 } else { 00085 m_buf = NULL; 00086 } 00087 if(m_buf == NULL) 00088 { 00089 setErrCode(404); 00090 const char* msg = "iamge not found."; 00091 setContentLen(strlen(msg)); 00092 respHeaders()["Content-Type"] = "text/html"; 00093 respHeaders()["Connection"] = "close"; 00094 writeData(msg,strlen(msg)); //Only send header 00095 DBG("\r\nExit WebcamHandler::doGet() w Error 404\r\n"); 00096 return; 00097 } 00098 m_pos = 0; 00099 DBG("m_buf_len=%d\n", m_buf_len); 00100 setContentLen(m_buf_len); 00101 respHeaders()["Connection"] = "close"; 00102 onWriteable(); 00103 } 00104 00105 void WebcamHandler::onWriteable() //Data has been written & buf is free 00106 { 00107 DBG("\r\nImageHandler::onWriteable() event\r\n"); 00108 if(m_buf == NULL) 00109 { 00110 //Error has been served, now exit 00111 close(); 00112 return; 00113 } 00114 00115 while(true) { 00116 int len; 00117 if ((m_buf_len - m_pos) > CHUNK_SIZE) { 00118 len = CHUNK_SIZE; 00119 } else { 00120 len = m_buf_len - m_pos; 00121 } 00122 if(len > 0) { 00123 int writtenLen = writeData(m_buf + m_pos, len); 00124 DBG("writtenLen=%d m_buf=%p m_pos=%d len=%d\n", writtenLen, m_buf, m_pos, len); 00125 if(writtenLen < 0) //Socket error 00126 { 00127 DBG("WebcamHandler: Socket error %d\n", writtenLen); 00128 if(writtenLen == TCPSOCKET_MEM) { 00129 return; //Wait for the queued TCP segments to be transmitted 00130 } else { 00131 //This is a critical error 00132 close(); 00133 return; 00134 } 00135 } 00136 else if(writtenLen < len) //Short write, socket's buffer is full 00137 { 00138 m_pos += writtenLen; 00139 return; 00140 } 00141 m_pos += writtenLen; 00142 } else { 00143 close(); //Data written, we can close the connection 00144 return; 00145 } 00146 } 00147 } 00148 00149 void WebcamHandler::onClose() 00150 { 00151 DBG("m_busy=%d\n", m_busy); 00152 m_busy = false; 00153 } 00154 00155 //static init 00156 struct stimage WebcamHandler::m_image[] = {{NULL,0},{NULL,0}}; 00157 bool WebcamHandler::m_busy = false; 00158 00159 void WebcamHandler::setImage(uint8_t* buf, int len, int cam) 00160 { 00161 DBG_ASSERT(cam >= 0); 00162 DBG_ASSERT(cam <= 1); 00163 m_image[cam].buf = buf; 00164 m_image[cam].len = len; 00165 }
Generated on Sat Jul 23 2022 11:10:59 by 1.7.2