📄 gena_server.c
字号:
free(reference_count); return UPNP_E_OUTOF_MEMORY; } strcpy(UDN_copy,UDN); strcpy(servId_copy,servId); if ( (return_code=GeneratePropertySet(VarNames,VarValues, var_count,&propertySet))!=XML_SUCCESS) { free(UDN_copy); free(servId_copy); free(reference_count); return return_code; } headers_size=strlen("CONTENT-TYPE text/xml\r\n") + strlen("CONTENT-LENGTH: \r\n")+MAX_CONTENT_LENGTH + strlen("NT: upnp:event\r\n") + strlen("NTS: upnp:propchange\r\n")+1; headers=(char *) malloc(headers_size); if (headers==NULL) { free(UDN_copy); free(servId_copy); free(propertySet); free(reference_count); return UPNP_E_OUTOF_MEMORY; } //changed to add null terminator at end of content //content length = (length in bytes of property set) + null char sprintf(headers,"CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",strlen(propertySet)+1); HandleLock(); if ( GetHandleInfo(device_handle,&handle_info)!=HND_DEVICE) return_code=GENA_E_BAD_HANDLE; else { if ( (service = FindServiceId( &handle_info->ServiceTable, servId, UDN)) !=NULL) { finger=GetFirstSubscription(service); while (finger) { thread_struct=(notify_thread_struct *) malloc(sizeof(notify_thread_struct)); if (thread_struct==NULL) { break; return_code= UPNP_E_OUTOF_MEMORY; } (*reference_count)++; thread_struct->reference_count=reference_count; thread_struct->UDN=UDN_copy; thread_struct->servId=servId_copy; thread_struct->headers=headers; thread_struct->propertySet=propertySet; strcpy(thread_struct->sid,finger->sid); thread_struct->eventKey=finger->eventKey++; thread_struct->device_handle=device_handle; //if overflow, wrap to 1 if (finger->eventKey<0) finger->eventKey=1; if ( (return_code=tpool_Schedule( genaNotifyThread, thread_struct ))!=0) { if (return_code==-1) return_code= UPNP_E_OUTOF_MEMORY; break; } finger=GetNextSubscription(service,finger); } } else return_code=GENA_E_BAD_SERVICE; } if ((*reference_count)==0) { free(reference_count); free(headers); free(propertySet); free(UDN_copy); free(servId_copy); } HandleUnlock(); return return_code;}void genaUnsubscribeRequest(http_message request, int sockfd){ char * eventURLpath; token temp_buff; Upnp_SID sid; service_info * service; struct Handle_Info * handle_info; UpnpDevice_Handle device_handle; //if the callback or NT is present then there is an error if ( (search_for_header(&request,"CALLBACK",&temp_buff)) || (search_for_header(&request,"NT",&temp_buff) ) ) { respond(sockfd,BAD_REQUEST); return; } //get SID if ( ( !search_for_header(&request,"SID",&temp_buff)) || (temp_buff.size>SID_SIZE) ) { respond(sockfd, MISSING_SID); return; } memcpy(sid,temp_buff.buff,temp_buff.size); sid[SID_SIZE]=0; //look up service by eventURL eventURLpath=(char*) malloc(request.request.request_uri.pathquery.size+1); if (eventURLpath==NULL) { respond(sockfd,UNABLE_MEMORY); return; } memcpy(eventURLpath,request.request.request_uri.pathquery.buff,request.request.request_uri.pathquery.size); eventURLpath[request.request.request_uri.pathquery.size]=0; HandleLock(); //CURRENTLY ONLY SUPPORT ONE DEVICE if ( (GetDeviceHandleInfo(&device_handle,&handle_info)!=HND_DEVICE)) { respond(sockfd,INVALID_SID); HandleUnlock(); return; } service=FindServiceEventURLPath(&handle_info->ServiceTable, eventURLpath); free(eventURLpath); if ( (service==NULL) || (!service->active) || (GetSubscriptionSID(sid,service)==NULL)) { respond(sockfd,INVALID_SID); HandleUnlock(); return; } RemoveSubscriptionSID(sid,service); respond(sockfd,HTTP_OK_CRLF); HandleUnlock();}void genaRenewRequest(http_message request, int sockfd){ token temp_buff; Upnp_SID sid; char * eventURLpath; token timeout; subscription * sub; int time_out=1801; service_info *service; time_t current_time; struct Handle_Info * handle_info; UpnpDevice_Handle device_handle; //if the callback or NT is present then there is an error if ( (search_for_header(&request,"CALLBACK",&temp_buff)) || (search_for_header(&request,"NT",&temp_buff) ) ) { respond(sockfd,BAD_REQUEST); return; } //get SID if ( ( !search_for_header(&request,"SID",&temp_buff)) || (temp_buff.size>SID_SIZE) ) { respond(sockfd, MISSING_SID); return; } memcpy(sid,temp_buff.buff,temp_buff.size); sid[SID_SIZE]=0; //look up service by eventURL eventURLpath=(char*) malloc(request.request.request_uri.pathquery.size+1); if (eventURLpath==NULL) { respond(sockfd,UNABLE_MEMORY); return; } memcpy(eventURLpath,request.request.request_uri.pathquery.buff,request.request.request_uri.pathquery.size); eventURLpath[request.request.request_uri.pathquery.size]=0; HandleLock(); //CURRENTLY ONLY SUPPORT ONE DEVICE if ( (GetDeviceHandleInfo(&device_handle, &handle_info))!=HND_DEVICE) { respond(sockfd,INVALID_SID); HandleUnlock(); return; } service=FindServiceEventURLPath(&handle_info->ServiceTable, eventURLpath); free(eventURLpath); //get Subscription if ( (service==NULL) || (!service->active) || ( (sub=GetSubscriptionSID(sid,service))==NULL)) { respond(sockfd,INVALID_SID); HandleUnlock(); return; } DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Renew request: Number of subscriptions already: %d\n Max Subscriptions allowed:%d\n",service->TotalSubscriptions, handle_info->MaxSubscriptions)); if (handle_info->MaxSubscriptions!=-1) if (service->TotalSubscriptions>handle_info->MaxSubscriptions) { respond(sockfd,UNABLE_MEMORY); RemoveSubscriptionSID(sub->sid,service); HandleUnlock(); return; } //Set the timeout if (search_for_header(&request,"TIMEOUT",&timeout)) if (sscanf(timeout.buff,"Second-%d",&time_out)!=1) if (!strncmp(timeout.buff,"Second-infinite",strlen("Second-infinite"))) time_out=-1; else time_out=DEFAULT_TIMEOUT; //default is 1801 seconds if (handle_info->MaxSubscriptionTimeOut!=-1) if ( (time_out==-1) || (time_out>handle_info->MaxSubscriptionTimeOut)) time_out=handle_info->MaxSubscriptionTimeOut; time(¤t_time); if (time_out>0) sub->expireTime=current_time+time_out; else sub->expireTime=0; //respond if ( (respondOK(sockfd,time_out,sub)!=UPNP_E_SUCCESS)) { RemoveSubscriptionSID(sub->sid,service); } HandleUnlock(); }void genaSubscriptionRequest(http_message request, int sockfd){ char * eventURLpath; char temp_sid[SID_SIZE]; token timeout; token callback; int return_code=1; int time_out=1801; service_info * service; struct Upnp_Subscription_Request request_struct; subscription *sub; uuid_t uuid; time_t current_time; struct Handle_Info *handle_info; void * cookie; Upnp_FunPtr callback_fun; UpnpDevice_Handle device_handle; DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscription Request Received:\n")); DBGONLY(print_http_request(&request,UPNP_PACKET,GENA,__FILE__,__LINE__)); //Check NT header //Windows Millenium Interoperability: //we accept either upnp:event, or upnp:propchange for the NT header if ( (!search_for_header(&request,"NT",&callback)) || ( (strncasecmp(callback.buff,"upnp:event",callback.size)) && (strncasecmp(callback.buff,"upnp:propchange",callback.size))) ) { respond(sockfd,INVALID_NT); return; } //if a SID is present then the we have a bad request // "incompatible headers" if ( search_for_header(&request,"SID",&callback)) { respond(sockfd, BAD_REQUEST); return; } //look up service by eventURL eventURLpath=(char*) malloc(request.request.request_uri.pathquery.size+1); if (eventURLpath==NULL) { respond(sockfd,UNABLE_MEMORY); return; } memcpy(eventURLpath,request.request.request_uri.pathquery.buff,request.request.request_uri.pathquery.size); eventURLpath[request.request.request_uri.pathquery.size]=0; DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"SubscriptionRequest for event URL path: %s\n",eventURLpath);) HandleLock(); //CURRENTLY ONLY ONE DEVICE if ( (GetDeviceHandleInfo(&device_handle, &handle_info)!=HND_DEVICE)) { respond(sockfd,UNABLE_SERVICE_UNKNOWN); HandleUnlock(); return; } service=FindServiceEventURLPath(&handle_info->ServiceTable, eventURLpath); free(eventURLpath); if ( (service==NULL) || (!service->active) ) { respond(sockfd,UNABLE_SERVICE_UNKNOWN); HandleUnlock(); return; } DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscription Request: Number of Subscriptions already %d\n Max Subscriptions allowed: %d\n",service->TotalSubscriptions,handle_info->MaxSubscriptions)); if (handle_info->MaxSubscriptions!=-1) if ( (service->TotalSubscriptions>=handle_info->MaxSubscriptions)) { respond(sockfd,UNABLE_MEMORY); //return 500 series error code HandleUnlock(); return; } //generate new subscription sub=(subscription *) malloc(sizeof(subscription)); if (sub==NULL) { respond(sockfd, UNABLE_MEMORY); HandleUnlock(); return; } sub->eventKey=0; sub->ToSendEventKey=0; sub->active=0; sub->next=NULL; //check for valid callbacks if ( (!search_for_header(&request,"CALLBACK",&callback)) || ( (return_code=createURL_list(&callback,&sub->DeliveryURLs))==0 )) { respond(sockfd, BAD_CALLBACK); freeSubscriptionList(sub); HandleUnlock(); return; } else if (return_code==UPNP_E_OUTOF_MEMORY) { respond(sockfd,UNABLE_MEMORY); freeSubscriptionList(sub); HandleUnlock(); return; } //Set the timeout if (search_for_header(&request,"TIMEOUT",&timeout)) if (sscanf(timeout.buff,"Second-%d",&time_out)!=1) if (!strncmp(timeout.buff,"Second-infinite",strlen("Second-infinite"))) time_out=-1; else time_out=DEFAULT_TIMEOUT; //default is >1800 seconds if (handle_info->MaxSubscriptionTimeOut!=-1) if ( (time_out==-1) || (time_out>handle_info->MaxSubscriptionTimeOut)) time_out=handle_info->MaxSubscriptionTimeOut; time(¤t_time); if (time_out>0) sub->expireTime=current_time+time_out; else sub->expireTime=0; //generate SID uuid_generate(uuid); uuid_unparse(uuid,temp_sid); sprintf(sub->sid,"uuid:%s",temp_sid); //respond if (respondOK(sockfd,time_out,sub)!=UPNP_E_SUCCESS) { freeSubscriptionList(sub); HandleUnlock(); return; } //add to subscription list sub->next=service->subscriptionList; service->subscriptionList=sub; service->TotalSubscriptions++; //finally generate callback for init table dump request_struct.ServiceId=service->serviceId; request_struct.UDN=service->UDN; strcpy((char *) request_struct.Sid,sub->sid); //copy callback callback_fun=handle_info->Callback; cookie=handle_info->Cookie; HandleUnlock(); //make call back with request struct //in the future should find a way of mainting //that the handle is not unregistered in the middle of a //callback callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, &request_struct,cookie); }void genaSubscribeOrRenew(http_message request, int sockfd){ token NT; if ( search_for_header(&request,"NT",&NT)) { genaSubscriptionRequest(request, sockfd); } else { genaRenewRequest(request, sockfd); }})#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -