📄 gena_client.c
字号:
/////////////////////////////////////////////////////////////////////////////// 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"pthread_mutex_t GlobalClientSubscribeMutex= PTHREAD_MUTEX_INITIALIZER;CLIENTONLY(void GenaAutoRenewSubscription(void *input){ upnp_timeout *event =(upnp_timeout *) input; void * cookie; Upnp_FunPtr callback_fun; struct Handle_Info * handle_info; struct Upnp_Event_Subscribe * sub_struct= (struct Upnp_Event_Subscribe *) event->Event; int send_callback =0; int eventType=0; if (AUTO_RENEW_TIME==0) { DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"GENA SUB EXPIRED")); sub_struct->ErrCode=UPNP_E_SUCCESS; send_callback=1; eventType=UPNP_EVENT_SUBSCRIPTION_EXPIRED; } else { DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"GENA AUTO RENEW")); if ( ( (sub_struct->ErrCode=genaRenewSubscription(event->handle, sub_struct->Sid, &sub_struct->TimeOut))!=UPNP_E_SUCCESS) && (sub_struct->ErrCode!=GENA_E_BAD_SID) && (sub_struct->ErrCode!=GENA_E_BAD_HANDLE)) { send_callback=1; eventType=UPNP_EVENT_AUTORENEWAL_FAILED; } } if (send_callback) { HandleLock(); if ( GetHandleInfo(event->handle,&handle_info)!=HND_CLIENT) { HandleUnlock(); free_upnp_timeout(event); return; } DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"HANDLE IS VALID")); callback_fun=handle_info->Callback; cookie=handle_info->Cookie; HandleUnlock(); //make callback callback_fun(eventType, event->Event,cookie); } free_upnp_timeout(event); }int ScheduleGenaAutoRenew(int client_handle, int TimeOut, client_subscription * sub){ struct Upnp_Event_Subscribe *RenewEventStruct=NULL; upnp_timeout * RenewEvent=NULL; int return_code=GENA_SUCCESS; if (TimeOut==UPNP_INFINITE) return GENA_SUCCESS; RenewEventStruct= (struct Upnp_Event_Subscribe *) malloc (sizeof (struct Upnp_Event_Subscribe)); if (RenewEventStruct==NULL) return UPNP_E_OUTOF_MEMORY; RenewEvent= (upnp_timeout *) malloc(sizeof(upnp_timeout)); if ( RenewEvent==NULL) { free(RenewEventStruct); return UPNP_E_OUTOF_MEMORY; } //schedule expire event strcpy(RenewEventStruct->Sid,sub->sid); RenewEventStruct->ErrCode=UPNP_E_SUCCESS; strncpy(RenewEventStruct->PublisherUrl,sub->EventURL,NAME_SIZE-1); RenewEventStruct->TimeOut=TimeOut; //RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE; RenewEvent->handle=client_handle; RenewEvent->Event=RenewEventStruct; if ( (return_code= ScheduleTimerEvent(TimeOut-AUTO_RENEW_TIME, GenaAutoRenewSubscription, RenewEvent, &GLOBAL_TIMER_THREAD, &(RenewEvent->eventId))) !=UPNP_E_SUCCESS) { free(RenewEvent); free(RenewEventStruct); return return_code; } sub->RenewEventId=RenewEvent->eventId; return GENA_SUCCESS; }int genaUnregisterClient(UpnpClient_Handle client_handle){ int request_size=0; char * request=NULL; char * response =NULL; client_subscription sub_copy; int return_code=UPNP_E_SUCCESS; struct Handle_Info * handle_info=NULL; int done=0; while (!done) { HandleLock(); if (GetHandleInfo(client_handle,&handle_info)!=HND_CLIENT) { HandleUnlock(); return GENA_E_BAD_HANDLE; } if (handle_info->ClientSubList==NULL) { done=1; return_code=UPNP_E_SUCCESS; break; } if ( (return_code=copy_client_subscription(handle_info->ClientSubList, &sub_copy)!=HTTP_SUCCESS)) { done=1; break; } RemoveClientSubClientSID(&handle_info->ClientSubList,sub_copy.sid); HandleUnlock(); request_size=strlen("SID: \r\n\r\n")+ strlen(sub_copy.ActualSID)+1; request=(char *) malloc(request_size); if (request==NULL) { return UPNP_E_OUTOF_MEMORY; } sprintf(request,"SID: %s\r\n\r\n",sub_copy.ActualSID); return_code=transferHTTP("UNSUBSCRIBE",request,strlen(request), &response,sub_copy.EventURL); free(request); if (return_code==HTTP_SUCCESS) free(response); } freeClientSubList(handle_info->ClientSubList); HandleUnlock(); return return_code;}//********************************************************//* Name: genaNotifyReceived//* Description: Function called from genaCallback to handle reception of events (client).//* Function validates that the headers of the request confrom to the Upnp v 1.0 spec.//* Function parses the content of the request as XML. (only checks if it is valid XML)//* Function then tries to find and lock the client handle which corrsponds to the incoming SID//* If the SID is valid, respond OK, increment callback reference count, unlock client handle//* make client callback with Upnp_Event struct.//* Note: The values passed in the Upnp_event struct are only valid during the callback.//* In: http_message request (parsed http_message)//* int sockfd (socket)//* Out: None//* Return Codes: None//* Error Codes: None//* //********************************************************void genaNotifyReceived(http_message request, int sockfd){ struct Upnp_Event event_struct; token temp_buff; token NT; token NTS; int eventKey; token sid; client_subscription * subscription; Upnp_Document ChangedVars; struct Handle_Info *handle_info; void * cookie; Upnp_FunPtr callback; UpnpClient_Handle client_handle; //get SID if ( !search_for_header(&request,"SID",&sid)) { respond(sockfd, MISSING_SID); return; } //get Event Key if ( (!search_for_header(&request,"SEQ",&temp_buff) || (sscanf(temp_buff.buff,"%d",&eventKey)!=1))) { respond(sockfd,BAD_REQUEST); return; } //get NT and NTS header if ( (!search_for_header(&request,"NT",&NT)) || (!search_for_header(&request,"NTS",&NTS))) { respond(sockfd,BAD_REQUEST); return; } //verify NT and NTS headers if ( ( (NT.size== (int)strlen("upnp:event")) && (strncmp(NT.buff,"upnp:event",NT.size))) || ( (NT.size== (int)strlen("upnp:propchange")) && (strncmp(NTS.buff,"upnp:propchange",NTS.size))) ) { respond(sockfd,INVALID_NT); return; } //parse the content (should be XML) if ( (request.content.size==0) || ( (ChangedVars=UpnpParse_Buffer(request.content.buff))==NULL)) { respond(sockfd,BAD_REQUEST); return; } //Lock handle HandleLock(); if ( (GetClientHandleInfo(&client_handle, &handle_info)!=HND_CLIENT)) { respond(sockfd,INVALID_SID); HandleUnlock(); UpnpDocument_free(ChangedVars); return; } if ( ( (subscription= GetClientSubActualSID(handle_info->ClientSubList, &sid))==NULL)) { if (eventKey==0) { //wait until we've finished processing a subscription (if we are in the middle) //this is to avoid mistakenly rejecting the first event if we receive it before the subscription response HandleUnlock(); //try and get Subscription Lock (in case we are in the process of subscribing) SubscribeLock(); //get HandleLock again; HandleLock(); if ( (GetClientHandleInfo(&client_handle, &handle_info)!=HND_CLIENT)) { respond(sockfd,INVALID_SID); SubscribeUnlock(); HandleUnlock(); UpnpDocument_free(ChangedVars); return; } if ( ( (subscription= GetClientSubActualSID(handle_info->ClientSubList, &sid))==NULL)) { respond(sockfd,INVALID_SID); SubscribeUnlock(); HandleUnlock(); UpnpDocument_free(ChangedVars); return; } SubscribeUnlock(); } else { respond(sockfd,INVALID_SID); HandleUnlock(); UpnpDocument_free(ChangedVars); return; } } respond(sockfd,HTTP_OK_CRLF); // fill event struct strcpy((char *)event_struct.Sid,subscription->sid); event_struct.EventKey=eventKey; event_struct.ChangedVariables=ChangedVars; //copy callback callback=handle_info->Callback; cookie=handle_info->Cookie; HandleUnlock(); //make call back with event struct //in the future should find a way of mainting //that the handle is not unregistered in the middle of a //callback callback(UPNP_EVENT_RECEIVED,&event_struct,cookie); UpnpDocument_free(ChangedVars); }//********************************************************//* Name: genaUnSubscribe//* Description: Unsubscribes a SID//* First Validates the SID and client_handle//* Locks the Handle//* copies the subscription//* removes the subscription//* UnLocks the Handle//* Sends UNSUBSCRIBE http request to service//* processes request//* In: UpnpClient_Handle client_handle//* SID in_sid//* Out: None//* Return Codes: UPNP_E_SUCCESS : if service responds OK//* Error Codes: UPNP_E_OUTOF_MEMORY: subscription may or may not be removed from client side.//* UPNP_E_UNSUBSCRIBE_UNACCEPTED : if service responds with other than OK (Note: subscription is still//* removed from client side)//* UPNP_E_NETWORK_ERROR: see upnp.h//* //* //********************************************************int genaUnSubscribe(UpnpClient_Handle client_handle, const Upnp_SID in_sid){ client_subscription * sub; char * request; int request_size=0; int return_code =GENA_SUCCESS; char * response; http_message parsed_response; struct Handle_Info *handle_info; client_subscription sub_copy; HandleLock(); //validate handle and sid if ( GetHandleInfo(client_handle,&handle_info)!=HND_CLIENT) { HandleUnlock(); return GENA_E_BAD_HANDLE; } if ( ( ( sub=GetClientSubClientSID(handle_info->ClientSubList,in_sid))==NULL)) { HandleUnlock(); return GENA_E_BAD_SID; } return_code=copy_client_subscription(sub,&sub_copy); RemoveClientSubClientSID(&handle_info->ClientSubList,in_sid); HandleUnlock(); if (return_code!=HTTP_SUCCESS) return return_code; request_size=strlen("SID: \r\n\r\n")+ strlen(sub_copy.ActualSID)+1; request=(char *) malloc(request_size); if (request==NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -