📄 ssdp_server.c
字号:
if( textNode == NULL ) { continue; } // servType is of format Servicetype:ServiceVersion tmpStr = ixmlNode_getNodeValue( textNode ); if( tmpStr == NULL ) { continue; } strcpy( servType, tmpStr ); if( servType == NULL ) { continue; } UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "ServiceType = %s\n", servType ); if( AdFlag ) { if( AdFlag == 1 ) { ServiceAdvertisement( UDNstr, servType, SInfo->DescURL, Exp ); } else { // AdFlag == -1 ServiceShutdown( UDNstr, servType, SInfo->DescURL, Exp ); } } else { switch ( SearchType ) { case SSDP_ALL: ServiceReply( DestAddr, servType, UDNstr, SInfo->DescURL, defaultExp ); break; case SSDP_SERVICE: if( ServiceType != NULL ) { if( !strncasecmp( ServiceType, servType, strlen( ServiceType ) ) ) { ServiceReply( DestAddr, servType, UDNstr, SInfo->DescURL, defaultExp ); } } break; default: break; } // switch(SearchType) } } ixmlNodeList_free( tmpNodeList ); tmpNodeList = NULL; ixmlNodeList_free( nodeList ); nodeList = NULL; } UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Exiting AdvertiseAndReply : \n" ); HandleUnlock(); return UPNP_E_SUCCESS;} /****************** End of AdvertiseAndReply *********************/#endif /* EXCLUDE_SSDP == 0 */#endif /* INCLUDE_DEVICE_APIS *//************************************************************************ * Function : Make_Socket_NoBlocking * * Parameters: * IN int sock: socket * * Description: * This function makes socket non-blocking. * * Returns: int * 0 if successful else -1 ***************************************************************************/intMake_Socket_NoBlocking( int sock ){#ifdef WIN32 u_long val=1; return ioctlsocket(sock, FIONBIO, &val);#else int val; val = fcntl( sock, F_GETFL, 0 ); if( fcntl( sock, F_SETFL, val | O_NONBLOCK ) == -1 ) { return -1; }#endif return 0;}/************************************************************************ * Function : unique_service_name * * Parameters: * IN char *cmd: Service Name string * OUT SsdpEvent *Evt: The SSDP event structure partially filled * by all the function. * * Description: * This function fills the fields of the event structure like DeviceType, * Device UDN and Service Type * * Returns: int * 0 if successful else -1 ***************************************************************************/int unique_service_name(IN char *cmd, IN SsdpEvent *Evt){ char TempBuf[COMMAND_LEN]; char *TempPtr = NULL; char *Ptr = NULL; char *ptr1 = NULL; char *ptr2 = NULL; char *ptr3 = NULL; int CommandFound = 0; int length = 0; if( ( TempPtr = strstr( cmd, "uuid:schemas" ) ) != NULL ) { ptr1 = strstr( cmd, ":device" ); if( ptr1 != NULL ) { ptr2 = strstr( ptr1 + 1, ":" ); } else { return -1; } if( ptr2 != NULL ) { ptr3 = strstr( ptr2 + 1, ":" ); } else { return -1; } if( ptr3 != NULL ) { sprintf( Evt->UDN, "uuid:%s", ptr3 + 1 ); } else { return -1; } ptr1 = strstr( cmd, ":" ); if( ptr1 != NULL ) { strncpy( TempBuf, ptr1, ptr3 - ptr1 ); TempBuf[ptr3 - ptr1] = '\0'; sprintf( Evt->DeviceType, "urn%s", TempBuf ); } else { return -1; } return 0; } if( ( TempPtr = strstr( cmd, "uuid" ) ) != NULL ) { if( ( Ptr = strstr( cmd, "::" ) ) != NULL ) { strncpy( Evt->UDN, TempPtr, Ptr - TempPtr ); Evt->UDN[Ptr - TempPtr] = '\0'; } else { strcpy( Evt->UDN, TempPtr ); } CommandFound = 1; } if( strstr( cmd, "urn:" ) != NULL && strstr( cmd, ":service:" ) != NULL ) { if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) { strcpy( Evt->ServiceType, TempPtr ); CommandFound = 1; } } if( strstr( cmd, "urn:" ) != NULL && strstr( cmd, ":device:" ) != NULL ) { if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) { strcpy( Evt->DeviceType, TempPtr ); CommandFound = 1; } } if( ( TempPtr = strstr( cmd, "::upnp:rootdevice" ) ) != NULL ) { /* Everything before "::upnp::rootdevice" is the UDN. */ if( TempPtr != cmd ) { length = TempPtr - cmd; strncpy(Evt->UDN, cmd, length); Evt->UDN[length] = 0; CommandFound = 1; } } if( CommandFound == 0 ) { return -1; } return 0;}/************************************************************************ * Function : ssdp_request_type1 * * Parameters: * IN char *cmd: command came in the ssdp request * * Description: * This function figures out the type of the SSDP search in the * in the request. * * Returns: enum SsdpSearchType * return appropriate search type else returns SSDP_ERROR ***************************************************************************/enum SsdpSearchTypessdp_request_type1( IN char *cmd ){ if( strstr( cmd, ":all" ) != NULL ) { return SSDP_ALL; } if( strstr( cmd, ":rootdevice" ) != NULL ) { return SSDP_ROOTDEVICE; } if( strstr( cmd, "uuid:" ) != NULL ) { return SSDP_DEVICEUDN; } if( ( strstr( cmd, "urn:" ) != NULL ) && ( strstr( cmd, ":device:" ) != NULL ) ) { return SSDP_DEVICETYPE; } if( ( strstr( cmd, "urn:" ) != NULL ) && ( strstr( cmd, ":service:" ) != NULL ) ) { return SSDP_SERVICE; } return SSDP_SERROR;}/************************************************************************ * Function : ssdp_request_type * * Parameters: * IN char *cmd: command came in the ssdp request * OUT SsdpEvent *Evt: The event structure partially filled by * this function. * * Description: * This function starts filling the SSDP event structure based upon the * request received. * * Returns: int * 0 on success; -1 on error ***************************************************************************/intssdp_request_type( IN char *cmd, OUT SsdpEvent * Evt ){ // clear event memset( Evt, 0, sizeof( SsdpEvent ) ); unique_service_name( cmd, Evt ); Evt->ErrCode = NO_ERROR_FOUND; if( ( Evt->RequestType = ssdp_request_type1( cmd ) ) == SSDP_SERROR ) { Evt->ErrCode = E_HTTP_SYNTEX; return -1; } return 0;}/************************************************************************ * Function : free_ssdp_event_handler_data * * Parameters: * IN void *the_data: ssdp_thread_data structure. This structure contains * SSDP request message. * * Description: * This function frees the ssdp request * * Returns: VOID * ***************************************************************************/static voidfree_ssdp_event_handler_data( void *the_data ){ ssdp_thread_data *data = ( ssdp_thread_data * ) the_data; if( data != NULL ) { http_message_t *hmsg = &data->parser.msg; // free data httpmsg_destroy( hmsg ); free( data ); }}/************************************************************************ * Function : valid_ssdp_msg * * Parameters: * IN void *the_data: ssdp_thread_data structure. This structure contains * SSDP request message. * * Description: * This function do some quick checking of the ssdp msg * * Returns: xboolean * returns TRUE if msg is valid else FALSE ***************************************************************************/static UPNP_INLINE xbooleanvalid_ssdp_msg( IN http_message_t * hmsg ){ memptr hdr_value; // check for valid methods - NOTIFY or M-SEARCH if( hmsg->method != HTTPMETHOD_NOTIFY && hmsg->method != HTTPMETHOD_MSEARCH && hmsg->request_method != HTTPMETHOD_MSEARCH ) { return FALSE; } if( hmsg->request_method != HTTPMETHOD_MSEARCH ) { // check PATH == * if( hmsg->uri.type != RELATIVE || strncmp( "*", hmsg->uri.pathquery.buff, hmsg->uri.pathquery.size ) != 0 ) { return FALSE; } // check HOST header if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) || ( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 ) ) { return FALSE; } } return TRUE; // passed quick check}/************************************************************************ * Function : start_event_handler * * Parameters: * IN void *the_data: ssdp_thread_data structure. This structure contains * SSDP request message. * * Description: * This function parses the message and dispatches it to a handler
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -