⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gena_server.c

📁 upnpsdk-1.0.4.tar.gz Intel UPnP SDK Source
💻 C
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000 Intel Corporation// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// * Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above copyright notice,// this list of conditions and the following disclaimer in the documentation// and/or other materials provided with the distribution.// * Neither name of Intel Corporation nor the names of its contributors// may be used to endorse or promote products derived from this software// without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.///////////////////////////////////////////////////////////////////////////////// $Revision: 1.1.1.4 $// $Date: 2001/06/15 00:22:15 $//     #include "../../inc/tools/config.h"#if EXCLUDE_GENA == 0#include "../inc/gena/gena.h"#include <sys/utsname.h>DEVICEONLY(int genaUnregisterDevice(UpnpDevice_Handle device_handle){  struct Handle_Info * handle_info;  HandleLock();  if (GetHandleInfo(device_handle, & handle_info)!=HND_DEVICE)  {    DBGONLY(UpnpPrintf(UPNP_CRITICAL,GENA,__FILE__,__LINE__,"genaUnregisterDevice : BAD Handle : %d\n",		       device_handle));    HandleUnlock();    return GENA_E_BAD_HANDLE;  }  freeServiceTable(&handle_info->ServiceTable);  HandleUnlock();    return UPNP_E_SUCCESS;}//********************************************************//*Name: createURL_list//*Description:   Function to parse//*               the Callback header Value in subscription requests//*               takes in a buffer containing URLS delimited by '<' and '>'//*               The entire buffer is copied into dynamic memory//*               and stored in the URL_list.//*               Pointers to the individual urls within this buffer //*               are allocated and stored in the URL_list.//*               Only URLs with network addresses are considered //*                (i.e. host:port or domain name)//* In:           buffer *URLS //* Out:          URL_list *out (storage space is passed in) , if successful, //*               then structure should be//*               deallocated at some time by : freeURL_list//* Return Codes: Returns the number of URLs parsed //* Error Codes:  UPNP_E_OUTOF_MEMORY//*               //********************************************************int createURL_list(token *URLS, URL_list *out){  int URLcount=0;  int i;  int return_code=0;    uri_type temp;  out->URLs=NULL;  out->parsedURLs=NULL;     for (i=0;i<URLS->size;i++)    {       if  ( (URLS->buff[i]=='<') && (i+1<URLS->size))	{	  if ( ((return_code=parse_uri(&URLS->buff[i+1],				       URLS->size-i+1,&temp))==HTTP_SUCCESS)	       && (temp.hostport.text.size!=0) )	    URLcount++;	  else	    if (return_code==UPNP_E_OUTOF_MEMORY)	      return return_code;	}    }      out->URLs=(char *) malloc(URLS->size+1);    out->parsedURLs=(uri_type *) malloc(sizeof(uri_type) * URLcount);   if ( (out->URLs==NULL) || (out->parsedURLs==NULL))     return UPNP_E_OUTOF_MEMORY;   memcpy(out->URLs,URLS->buff,URLS->size);   out->URLs[URLS->size]=0;   URLcount=0;   for (i=0;i<URLS->size;i++)     {       if  ( (URLS->buff[i]=='<') && (i+1<URLS->size))	{	  if ( ((return_code=parse_uri(&out->URLs[i+1],URLS->size-i+1,			  &out->parsedURLs[URLcount]))==HTTP_SUCCESS)	       && (out->parsedURLs[URLcount].hostport.text.size!=0) )	    URLcount++;	  else	    if (return_code==UPNP_E_OUTOF_MEMORY)	      {		free (out->URLs);		free (out->parsedURLs);		out->URLs=NULL;		out->parsedURLs=NULL;		return return_code;	      }	}     }   out->size=URLcount;      return URLcount;}//********************************************************//*Name: respondOK//*Description: Function to return OK message in the case of a subscription request.//*In:          sockfd (socket connection of request)//*             time_out (accepted duration)//*             subscription * sub (accepted subscription)//*Out:         returns error codes from respond or UPNP_E_OUTOF_MEMORY//********************************************************int respondOK(int sockfd,int time_out,subscription *sub){  char *temp;  int size=0;  int return_code;  struct utsname sys_info;  char server[128];    memset(&sys_info,0x00,sizeof(sys_info));  uname(&sys_info);    size+= strlen(HTTP_OK);  size+= HTTP_DATE_LENGTH;  size+= sprintf( server, "SERVER: %s/%s UPnP/1.0 Intel UPnP SDK/1.0\r\n",                  sys_info.sysname, sys_info.release );  //strlen(SERVER_GENA);  size+= strlen("SID: \r\n") + sizeof(Upnp_SID);  size+= strlen("TIMEOUT: Second-\r\n\r\n") + MAX_SECONDS +1;  temp = (char *) malloc(size);  if (temp==NULL)    {      respond(sockfd,UNABLE_MEMORY);      return UPNP_E_OUTOF_MEMORY;    }  strcpy(temp,HTTP_OK);  currentTmToHttpDate(&temp[strlen(temp)]);  strcat(temp,server);  strcat(temp,"SID: ");  strcat(temp,sub->sid);  strcat(temp,"\r\n");  if (time_out>=0)    sprintf(&temp[strlen(temp)],"TIMEOUT: Second-%d\r\n\r\n",time_out);  else    strcat(temp,"TIMEOUT: Second-infinite\r\n\r\n");  return_code=respond(sockfd,temp);  free(temp);  return return_code;}//********************************************************//*Name: GeneratePropertySet//*Description: Function to generate XML propery Set for Notifications//*             Note: XML_VERSION comment is NOT sent due to interop issues with Microsoft ME//*In:          char **names (each char* is null terminated), char ** values, int count //*Out:         char ** out (dynamically allocated must be freed by caller)//********************************************************int GeneratePropertySet(char **names, char ** values, int count,			char **out){  char *buffer;  int counter=0;  int size=0;   int temp_counter =0;  //  size+=strlen(XML_VERSION); Microsoft Windows Millenium interoperability currently will not work with the XML_VERSION   size+=strlen(XML_PROPERTYSET_HEADER);  size+=strlen("</e:propertyset>\n\n");       for (temp_counter=0,counter=0;counter<count;counter++)    {       size+=strlen("<e:property>\n</e:property>\n");             size+= (2*strlen(names[counter])+strlen(values[counter])+(strlen("<></>\n")));          }     buffer=(char*)malloc(size+1);   if (buffer==NULL)     {              return UPNP_E_OUTOF_MEMORY;     }   memset(buffer,0,size+1);     //   strcpy(buffer,XML_VERSION); Microsoft Windows interoperability currently doesn't accept the XML_VERSION tag   strcpy(buffer,XML_PROPERTYSET_HEADER);   for (counter=0;counter<count;counter++)     {       strcat(buffer,"<e:property>\n");       sprintf(&buffer[strlen(buffer)],"<%s>%s</%s>\n</e:property>\n",names[counter],values[counter],names[counter]);     }   strcat(buffer,"</e:propertyset>\n\n");     (*out)=buffer;      return XML_SUCCESS; }//********************************************************//* Name: free_notify_struct//* Description:  frees memory used in notify_threads//*               if the reference count is 0, actually frees the struct//* In:           notify_thread_struct * input//* Out:          None//* Return Codes: None//* Error Codes:  None//********************************************************void free_notify_struct(notify_thread_struct * input){  (*input->reference_count)--;  if ((*input->reference_count)==0)    {      free(input->headers);      free(input->propertySet);      free(input->servId);      free(input->UDN);      free(input->reference_count);    }  free(input);}//********************************************************//*Name: genaNotify//*Description: Function to Notify a particular subscription of a particular event//*             In general the service should NOT be blocked around this call. (this may cause deadlock with a client)//*             NOTIFY http request is sent and the reply is processed.//*In:          char * headers (null terminated) (includes all headers (including \r\n) except SID and SEQ)//*             char * propertySet (null terminated) XML//*             subscription *sub (subscription to be Notified, Assumes this is valid for life of function)//*Out:      //*Return Codes: GENA_SUCCESS  if the event was delivered   (all codes mapped to codes in upnp.h)//*Error Codes: UPNP_E_OUTOF_MEMORY//*             HTTP_E_BAD_URL             //*             HTTP_E_READ_SOCKET //*             HTTP_E_WRITE_SOCKET //*             HTTP_E_CONNECT_SOCKET //*             HTTP_E_SOCKET    //*             GENA_E_NOTIFY_UNACCEPTED//*             HTTP_E_BAD_RESPONSE //*             GENA_E_NOTIFY_UNACCEPTED_REMOVE (this subscription must be removed)//********************************************************int genaNotify(char * headers, 	       char * propertySet, subscription *sub){  int full_size=0;  char *full_message;  http_message parsed_response;  int i;  int return_code=GENA_E_NOTIFY_UNACCEPTED;  char * response;       full_size=strlen(headers)+strlen("SID: \r\n") + SID_SIZE+    strlen("SEQ: \r\n\r\n") + MAX_EVENTS + strlen(propertySet)+1;  full_message = (char *) malloc(full_size);  if (full_message==NULL)    return UPNP_E_OUTOF_MEMORY;      sprintf(full_message,"%sSID: %s\r\nSEQ: %d\r\n\r\n%s",headers,sub->sid,sub->ToSendEventKey,propertySet);     for (i=0;i<sub->DeliveryURLs.size;i++)    {          if (((return_code=transferHTTPparsedURL("NOTIFY", full_message,					      strlen(full_message)+1,					      &response,					      &sub->DeliveryURLs.parsedURLs[i])	    )==HTTP_SUCCESS))	{	  break;	}          }  free(full_message);    if (return_code==HTTP_SUCCESS)    {             //only error I really care about is Invalid SID      return_code=parse_http_response(response,&parsed_response,				      strlen(response));             if (return_code==HTTP_SUCCESS)	{	  if (!strncasecmp(parsed_response.status.status_code.buff,			   "200", strlen("200")))	    return_code=GENA_SUCCESS;	  else	  {	    if (!strncasecmp(parsed_response.status.status_code.buff,			     "412",strlen("412")))	      {		//Invalid SID gets removed		return_code=GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;	      }	    else	      return_code=GENA_E_NOTIFY_UNACCEPTED;	  }	  free_http_message(&parsed_response);	}            free (response);      return return_code;    }  return return_code;  }void genaNotifyThread(void * input){    subscription *sub;  service_info *service;  subscription sub_copy;  notify_thread_struct *in = (notify_thread_struct *) input;  int return_code;  struct Handle_Info * handle_info;  HandleLock();  //validate context  if ( GetHandleInfo(in->device_handle,&handle_info)!=HND_DEVICE)    {      free_notify_struct(in);      HandleUnlock();      return;    }    if ( ( (service = FindServiceId( &handle_info->ServiceTable, 				   in->servId, in->UDN)) ==NULL)       || (!service->active)        || ( (sub=GetSubscriptionSID(in->sid,service))==NULL)       || ( (copy_subscription(sub,&sub_copy)!=HTTP_SUCCESS)) )    {       free_notify_struct(in);      HandleUnlock();      return;    }     if (in->eventKey!=sub->ToSendEventKey)    {      tpool_Schedule( genaNotifyThread, input);       freeSubscription(&sub_copy);      HandleUnlock();      return;    }  HandleUnlock();    //transmit   return_code = genaNotify(in->headers,	     in->propertySet, &sub_copy);    freeSubscription(&sub_copy);  HandleLock();    if ( GetHandleInfo(in->device_handle,&handle_info)!=HND_DEVICE)    {      free_notify_struct(in);      HandleUnlock();      return;    }  //validate context  if ( ( (service = FindServiceId( &handle_info->ServiceTable, 				 in->servId, in->UDN)) ==NULL)       || (!service->active)       || ( (sub=GetSubscriptionSID(in->sid,service))==NULL) )    {       free_notify_struct(in);      HandleUnlock();      return;    }    sub->ToSendEventKey++;  if (sub->ToSendEventKey<0) //wrap to 1 for overflow    sub->ToSendEventKey=1;  if (return_code==GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB)    {      RemoveSubscriptionSID(in->sid,service);    }    free_notify_struct(in);  HandleUnlock();}int genaInitNotify(UpnpDevice_Handle device_handle,		   char *UDN,		   char *servId,		   char **VarNames,		   char **VarValues,		   int var_count,		   Upnp_SID sid){  char * UDN_copy=NULL;  char * servId_copy=NULL;  char * propertySet=NULL;  char * headers=NULL;  subscription * sub=NULL;  service_info *service=NULL;  int return_code=GENA_SUCCESS;  int headers_size;  int *reference_count=NULL;  struct Handle_Info * handle_info;  notify_thread_struct *thread_struct=NULL;  DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"GENA BEGIN INITIAL NOTIFY "));  reference_count= (int *) malloc(sizeof(int));     if (reference_count==NULL)    return UPNP_E_OUTOF_MEMORY;    (*reference_count)=0;  UDN_copy=(char *) malloc(strlen(UDN)+1);    if (UDN_copy==NULL)    {      free(reference_count);      return UPNP_E_OUTOF_MEMORY;    }  servId_copy=(char *) malloc(strlen(servId)+1);    if (servId_copy==NULL)    {      free(UDN_copy);      free(reference_count);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -