00001 00002 // 00003 // Copyright (c) 2000-2003 Intel Corporation 00004 // All rights reserved. 00005 // 00006 // Redistribution and use in source and binary forms, with or without 00007 // modification, are permitted provided that the following conditions are met: 00008 // 00009 // * Redistributions of source code must retain the above copyright notice, 00010 // this list of conditions and the following disclaimer. 00011 // * Redistributions in binary form must reproduce the above copyright notice, 00012 // this list of conditions and the following disclaimer in the documentation 00013 // and/or other materials provided with the distribution. 00014 // * Neither name of Intel Corporation nor the names of its contributors 00015 // may be used to endorse or promote products derived from this software 00016 // without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 00022 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00025 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00026 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 // 00031 00032 #ifndef _GENA_ 00033 #define _GENA_ 00034 #include "config.h" 00035 #include "service_table.h" 00036 #include "miniserver.h" 00037 #include "uri.h" 00038 #include "upnp.h" 00039 00040 #include <time.h> 00041 #include "ThreadPool.h" 00042 #include <string.h> 00043 #include "client_table.h" 00044 #include "httpparser.h" 00045 #include "sock.h" 00046 00047 #ifdef __cplusplus 00048 #define EXTERN_C extern "C" 00049 #else 00050 #ifndef EXTERN_C 00051 #define EXTERN_C 00052 #endif 00053 #endif 00054 00055 #define XML_VERSION "<?xml version='1.0' encoding='ISO-8859-1' ?>\n" 00056 #define XML_PROPERTYSET_HEADER \ 00057 "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n" 00058 00059 #define UNABLE_MEMORY "HTTP/1.1 500 Internal Server Error\r\n\r\n" 00060 #define UNABLE_SERVICE_UNKNOWN "HTTP/1.1 404 Not Found\r\n\r\n" 00061 #define UNABLE_SERVICE_NOT_ACCEPT \ 00062 "HTTP/1.1 503 Service Not Available\r\n\r\n" 00063 00064 00065 #define NOT_IMPLEMENTED "HTTP/1.1 501 Not Implemented\r\n\r\n" 00066 #define BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n\r\n" 00067 #define INVALID_NT BAD_CALLBACK 00068 #define BAD_CALLBACK "HTTP/1.1 412 Precondition Failed\r\n\r\n" 00069 #define HTTP_OK_CRLF "HTTP/1.1 200 OK\r\n\r\n" 00070 #define HTTP_OK_STR "HTTP/1.1 200 OK\r\n" 00071 #define INVALID_SID BAD_CALLBACK 00072 #define MISSING_SID BAD_CALLBACK 00073 #define MAX_CONTENT_LENGTH 20 00074 #define MAX_SECONDS 10 00075 #define MAX_EVENTS 20 00076 #define MAX_PORT_SIZE 10 00077 #define GENA_E_BAD_RESPONSE UPNP_E_BAD_RESPONSE 00078 #define GENA_E_BAD_SERVICE UPNP_E_INVALID_SERVICE 00079 #define GENA_E_SUBSCRIPTION_UNACCEPTED UPNP_E_SUBSCRIBE_UNACCEPTED 00080 #define GENA_E_BAD_SID UPNP_E_INVALID_SID 00081 #define GENA_E_UNSUBSCRIBE_UNACCEPTED UPNP_E_UNSUBSCRIBE_UNACCEPTED 00082 #define GENA_E_NOTIFY_UNACCEPTED UPNP_E_NOTIFY_UNACCEPTED 00083 #define GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB -9 00084 #define GENA_E_BAD_HANDLE UPNP_E_INVALID_HANDLE 00085 #define XML_ERROR -5 00086 #define XML_SUCCESS UPNP_E_SUCCESS 00087 #define GENA_SUCCESS UPNP_E_SUCCESS 00088 #define CALLBACK_SUCCESS 0 00089 #define DEFAULT_TIMEOUT 1801 00090 00091 00092 00093 extern ithread_mutex_t GlobalClientSubscribeMutex; 00094 00095 //Lock the subscription 00096 #define SubscribeLock() \ 00097 DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__, \ 00098 "Trying Subscribe Lock")); \ 00099 ithread_mutex_lock(&GlobalClientSubscribeMutex); \ 00100 DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscribe Lock");) 00101 00102 //Unlock the subscription 00103 #define SubscribeUnlock() \ 00104 DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__, \ 00105 "Trying Subscribe UnLock")); \ 00106 ithread_mutex_unlock(&GlobalClientSubscribeMutex); \ 00107 DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscribe UnLock");) 00108 00109 00110 //Structure to send NOTIFY message to all subscribed control points 00111 typedef struct NOTIFY_THREAD_STRUCT { 00112 char * headers; 00113 DOMString propertySet; 00114 char * servId; 00115 char * UDN; 00116 Upnp_SID sid; 00117 int eventKey; 00118 int *reference_count; 00119 UpnpDevice_Handle device_handle; 00120 } notify_thread_struct; 00121 00122 00123 /************************************************************************ 00124 * Function : genaCallback 00125 * 00126 * Parameters: 00127 * IN http_parser_t *parser: represents the parse state of the request 00128 * IN http_message_t* request: HTTP message containing GENA request 00129 * INOUT SOCKINFO *info: Structure containing information about the socket 00130 * 00131 * Description: 00132 * This is the callback function called by the miniserver to handle 00133 * incoming GENA requests. 00134 * 00135 * Returns: int 00136 * UPNP_E_SUCCESS if successful else appropriate error 00137 ***************************************************************************/ 00138 EXTERN_C void genaCallback (IN http_parser_t *parser, 00139 IN http_message_t* request, 00140 IN SOCKINFO *info); 00141 00142 /************************************************************************ 00143 * Function : genaSubscribe 00144 * 00145 * Parameters: 00146 * IN UpnpClient_Handle client_handle: 00147 * IN char * PublisherURL: NULL Terminated, of the form : 00148 * "http://134.134.156.80:4000/RedBulb/Event" 00149 * INOUT int * TimeOut: requested Duration, if -1, then "infinite". 00150 * in the OUT case: actual Duration granted 00151 * by Service, -1 for infinite 00152 * OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller 00153 * 00154 * Description: 00155 * This function subscribes to a PublisherURL ( also mentioned as EventURL 00156 * some places). It sends SUBSCRIBE http request to service processes 00157 * request. Finally adds a Subscription to 00158 * the clients subscription list, if service responds with OK 00159 * 00160 * Returns: int 00161 * return UPNP_E_SUCCESS if service response is OK else 00162 * returns appropriate error 00163 ***************************************************************************/ 00164 CLIENTONLY( 00165 EXTERN_C int genaSubscribe(UpnpClient_Handle client_handle, 00166 char * PublisherURL, 00167 int * TimeOut, 00168 Upnp_SID out_sid );) 00169 00170 00171 /************************************************************************ 00172 * Function : genaUnSubscribe 00173 * 00174 * Parameters: 00175 * IN UpnpClient_Handle client_handle: UPnP client handle 00176 * IN SID in_sid: The subscription ID 00177 * 00178 * Description: 00179 * This function unsubscribes a SID. It first validates the SID and 00180 * client_handle,copies the subscription, sends UNSUBSCRIBE http request 00181 * to service processes request and finally removes the subscription 00182 * 00183 * Returns: int 00184 * return UPNP_E_SUCCESS if service response is OK else 00185 * returns appropriate error 00186 ***************************************************************************/ 00187 CLIENTONLY(EXTERN_C int genaUnSubscribe(UpnpClient_Handle client_handle, 00188 const Upnp_SID in_sid);) 00189 00190 /************************************************************************ 00191 * Function : genaUnregisterClient 00192 * 00193 * Parameters: 00194 * IN UpnpClient_Handle client_handle: Handle containing all the control 00195 * point related information 00196 * 00197 * Description: 00198 * This function unsubcribes all the outstanding subscriptions and cleans 00199 * the subscription list. This function is called when control point 00200 * unregisters. 00201 * 00202 * Returns: int 00203 * return UPNP_E_SUCCESS if successful else returns appropriate error 00204 ***************************************************************************/ 00205 CLIENTONLY(EXTERN_C int genaUnregisterClient( 00206 UpnpClient_Handle client_handle);) 00207 00208 //server 00209 /************************************************************************ 00210 * Function : genaUnregisterDevice 00211 * 00212 * Parameters: 00213 * IN UpnpDevice_Handle device_handle: Handle of the root device 00214 * 00215 * Description: 00216 * This function cleans the service table of the device. 00217 * 00218 * Returns: int 00219 * returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE 00220 ****************************************************************************/ 00221 DEVICEONLY(EXTERN_C int genaUnregisterDevice( 00222 UpnpDevice_Handle device_handle);) 00223 00224 00225 /************************************************************************ 00226 * Function : genaRenewSubscription 00227 * 00228 * Parameters: 00229 * IN UpnpClient_Handle client_handle: Client handle 00230 * IN const Upnp_SID in_sid: subscription ID 00231 * INOUT int * TimeOut: requested Duration, if -1, then "infinite". 00232 * in the OUT case: actual Duration granted 00233 * by Service, -1 for infinite 00234 * 00235 * Description: 00236 * This function renews a SID. It first validates the SID and 00237 * client_handle and copies the subscription. It sends RENEW 00238 * (modified SUBSCRIBE) http request to service and processes 00239 * the response. 00240 * 00241 * Returns: int 00242 * return UPNP_E_SUCCESS if service response is OK else 00243 * returns appropriate error 00244 ***************************************************************************/ 00245 CLIENTONLY(EXTERN_C int genaRenewSubscription( 00246 IN UpnpClient_Handle client_handle, 00247 IN const Upnp_SID in_sid, 00248 OUT int * TimeOut);) 00249 /**************************************************************************** 00250 * Function : genaNotifyAll 00251 * 00252 * Parameters : 00253 * IN UpnpDevice_Handle device_handle : Device handle 00254 * IN char *UDN : Device udn 00255 * IN char *servId : Service ID 00256 * IN char **VarNames : array of varible names 00257 * IN char **VarValues : array of variable values 00258 * IN int var_count : number of variables 00259 * 00260 * Description : This function sends a notification to all the subscribed 00261 * control points 00262 * 00263 * Return : int 00264 * 00265 * Note : This function is similar to the genaNotifyAllExt. The only difference 00266 * is it takes event variable array instead of xml document. 00267 ****************************************************************************/ 00268 DEVICEONLY(EXTERN_C int genaNotifyAll(UpnpDevice_Handle device_handle, 00269 char *UDN, 00270 char *servId, 00271 char **VarNames, 00272 char **VarValues, 00273 int var_count 00274 );) 00275 00276 /**************************************************************************** 00277 * Function : genaNotifyAllExt 00278 * 00279 * Parameters : 00280 * IN UpnpDevice_Handle device_handle : Device handle 00281 * IN char *UDN : Device udn 00282 * IN char *servId : Service ID 00283 * IN IXML_Document *PropSet : XML document Event varible property set 00284 * 00285 * Description : This function sends a notification to all the subscribed 00286 * control points 00287 * 00288 * Return : int 00289 * 00290 * Note : This function is similar to the genaNotifyAll. the only difference 00291 * is it takes the document instead of event variable array 00292 ****************************************************************************/ 00293 DEVICEONLY(EXTERN_C int genaNotifyAllExt(UpnpDevice_Handle device_handle, 00294 char *UDN, char *servId,IN IXML_Document *PropSet);) 00295 00296 /**************************************************************************** 00297 * Function : genaInitNotify 00298 * 00299 * Parameters : 00300 * IN UpnpDevice_Handle device_handle : Device handle 00301 * IN char *UDN : Device udn 00302 * IN char *servId : Service ID 00303 * IN char **VarNames : Array of variable names 00304 * IN char **VarValues : Array of variable values 00305 * IN int var_count : array size 00306 * IN Upnp_SID sid : subscription ID 00307 * 00308 * Description : This function sends the intial state table dump to 00309 * newly subscribed control point. 00310 * 00311 * Return : int 00312 * returns GENA_E_SUCCESS if successful else returns appropriate error 00313 * 00314 * Note : No other event will be sent to this control point before the 00315 * intial state table dump. 00316 ****************************************************************************/ 00317 DEVICEONLY(EXTERN_C int genaInitNotify(IN UpnpDevice_Handle device_handle, 00318 IN char *UDN, 00319 IN char *servId, 00320 IN char **VarNames, 00321 IN char **VarValues, 00322 IN int var_count, 00323 IN Upnp_SID sid);) 00324 00325 /**************************************************************************** 00326 * Function : genaInitNotifyExt 00327 * 00328 * Parameters : 00329 * IN UpnpDevice_Handle device_handle : Device handle 00330 * IN char *UDN : Device udn 00331 * IN char *servId : Service ID 00332 * IN IXML_Document *PropSet : Document of the state table 00333 * IN Upnp_SID sid : subscription ID 00334 * 00335 * Description : This function is similar to the genaInitNofity. The only 00336 * difference is that it takes the xml document for the state table and 00337 * sends the intial state table dump to newly subscribed control point. 00338 * 00339 * Return : int 00340 * returns GENA_E_SUCCESS if successful else returns appropriate error 00341 * 00342 * Note : No other event will be sent to this control point before the 00343 * intial state table dump. 00344 ****************************************************************************/ 00345 DEVICEONLY(EXTERN_C int genaInitNotifyExt( 00346 IN UpnpDevice_Handle device_handle, 00347 IN char *UDN, 00348 IN char *servId, 00349 IN IXML_Document *PropSet, 00350 IN Upnp_SID sid);) 00351 00352 00353 /************************************************************************ 00354 * Function : error_respond 00355 * 00356 * Parameters: 00357 * IN SOCKINFO *info: Structure containing information about the socket 00358 * IN int error_code: error code that will be in the GENA response 00359 * IN http_message_t* hmsg: GENA request Packet 00360 * 00361 * Description: 00362 * This function send an error message to the control point in the case 00363 * incorrect GENA requests. 00364 * 00365 * Returns: int 00366 * UPNP_E_SUCCESS if successful else appropriate error 00367 ***************************************************************************/ 00368 void error_respond( IN SOCKINFO *info, IN int error_code, 00369 IN http_message_t* hmsg ); 00370 00371 00372 #endif // GENA
1.6.1