📄 upnpapi.c
字号:
FreeHandle( Hnd ); UpnpSdkDeviceRegistered = 0; HandleUnlock(); UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpUnRegisterRootDevice \n" ); return retVal;} /****************** End of UpnpUnRegisterRootDevice *********************/#endif //INCLUDE_DEVICE_APIS// *************************************************************#ifdef INCLUDE_DEVICE_APIS#ifdef INTERNAL_WEB_SERVER/************************************************************************** * Function: GetNameForAlias * * Parameters: * IN char *name: name of the file * OUT char** alias: pointer to alias string * * Description: * This function determines alias for given name which is a file name * or URL. * * Return Values: * UPNP_E_SUCCESS on success, nonzero on failure. ***************************************************************************/static intGetNameForAlias( IN char *name, OUT char **alias ){ char *ext; char *al; ext = strrchr( name, '.' ); if( ext == NULL || strcasecmp( ext, ".xml" ) != 0 ) { return UPNP_E_EXT_NOT_XML; } al = strrchr( name, '/' ); if( al == NULL ) { *alias = name; } else { *alias = al; } return UPNP_E_SUCCESS;}/************************************************************************** * Function: get_server_addr * * Parameters: * OUT struct sockaddr_in* serverAddr: pointer to server address * structure * * Description: * This function fills the sockadr_in with miniserver information. * * Return Values: VOID * ***************************************************************************/static voidget_server_addr( OUT struct sockaddr_in *serverAddr ){ memset( serverAddr, 0, sizeof( struct sockaddr_in ) ); serverAddr->sin_family = AF_INET; serverAddr->sin_port = htons( LOCAL_PORT ); //inet_aton( LOCAL_HOST, &serverAddr->sin_addr ); serverAddr->sin_addr.s_addr = inet_addr( LOCAL_HOST );}/************************************************************************** * Function: GetDescDocumentAndURL ( In the case of device) * * Parameters: * IN Upnp_DescType descriptionType: pointer to server address * structure * IN char* description: * IN unsigned int bufferLen: * IN int config_baseURL: * OUT IXML_Document **xmlDoc: * OUT char descURL[LINE_SIZE]: * * Description: * This function fills the sockadr_in with miniserver information. * * Return Values: VOID * ***************************************************************************/static intGetDescDocumentAndURL( IN Upnp_DescType descriptionType, IN char *description, IN unsigned int bufferLen, IN int config_baseURL, OUT IXML_Document ** xmlDoc, OUT char descURL[LINE_SIZE] ){ int retVal = 0; char *membuf = NULL; char aliasStr[LINE_SIZE]; char *temp_str = NULL; FILE *fp = NULL; off_t fileLen; size_t num_read; time_t last_modified; struct stat file_info; struct sockaddr_in serverAddr; int rc = UPNP_E_SUCCESS; if( description == NULL ) { return UPNP_E_INVALID_PARAM; } // non-URL description must have configuration specified if( descriptionType != UPNPREG_URL_DESC && ( !config_baseURL ) ) { return UPNP_E_INVALID_PARAM; } // get XML doc and last modified time if( descriptionType == UPNPREG_URL_DESC ) { if( ( retVal = UpnpDownloadXmlDoc( description, xmlDoc ) ) != UPNP_E_SUCCESS ) { return retVal; } last_modified = time( NULL ); } else if( descriptionType == UPNPREG_FILENAME_DESC ) { retVal = stat( description, &file_info ); if( retVal == -1 ) { return UPNP_E_FILE_NOT_FOUND; } fileLen = file_info.st_size; last_modified = file_info.st_mtime; if( ( fp = fopen( description, "rb" ) ) == NULL ) { return UPNP_E_FILE_NOT_FOUND; } if( ( membuf = ( char * )malloc( fileLen + 1 ) ) == NULL ) { fclose( fp ); return UPNP_E_OUTOF_MEMORY; } num_read = fread( membuf, 1, fileLen, fp ); if( num_read != fileLen ) { fclose( fp ); free( membuf ); return UPNP_E_FILE_READ_ERROR; } membuf[fileLen] = 0; fclose( fp ); rc = ixmlParseBufferEx( membuf, xmlDoc ); free( membuf ); } else if( descriptionType == UPNPREG_BUF_DESC ) { last_modified = time( NULL ); rc = ixmlParseBufferEx( description, xmlDoc ); } else { return UPNP_E_INVALID_PARAM; } if( rc != IXML_SUCCESS && descriptionType != UPNPREG_URL_DESC ) { if( rc == IXML_INSUFFICIENT_MEMORY ) { return UPNP_E_OUTOF_MEMORY; } else { return UPNP_E_INVALID_DESC; } } // determine alias if( config_baseURL ) { if( descriptionType == UPNPREG_BUF_DESC ) { strcpy( aliasStr, "description.xml" ); } else // URL or filename { retVal = GetNameForAlias( description, &temp_str ); if( retVal != UPNP_E_SUCCESS ) { ixmlDocument_free( *xmlDoc ); return retVal; } if( strlen( temp_str ) > ( LINE_SIZE - 1 ) ) { ixmlDocument_free( *xmlDoc ); free( temp_str ); return UPNP_E_URL_TOO_BIG; } strcpy( aliasStr, temp_str ); } get_server_addr( &serverAddr ); // config retVal = configure_urlbase( *xmlDoc, &serverAddr, aliasStr, last_modified, descURL ); if( retVal != UPNP_E_SUCCESS ) { ixmlDocument_free( *xmlDoc ); return retVal; } } else // manual { if( strlen( description ) > ( LINE_SIZE - 1 ) ) { ixmlDocument_free( *xmlDoc ); return UPNP_E_URL_TOO_BIG; } strcpy( descURL, description ); } assert( *xmlDoc != NULL ); return UPNP_E_SUCCESS;}#else // no web server/************************************************************************** * Function: GetDescDocumentAndURL ( In the case of control point) * * Parameters: * IN Upnp_DescType descriptionType: pointer to server address * structure * IN char* description: * IN unsigned int bufferLen: * IN int config_baseURL: * OUT IXML_Document **xmlDoc: * OUT char *descURL: * * Description: * This function fills the sockadr_in with miniserver information. * * Return Values: VOID * ***************************************************************************/static intGetDescDocumentAndURL( IN Upnp_DescType descriptionType, IN char *description, IN unsigned int bufferLen, IN int config_baseURL, OUT IXML_Document ** xmlDoc, OUT char *descURL ){ int retVal; if( ( descriptionType != UPNPREG_URL_DESC ) || config_baseURL ) { return UPNP_E_NO_WEB_SERVER; } if( description == NULL ) { return UPNP_E_INVALID_PARAM; } if( strlen( description ) > ( LINE_SIZE - 1 ) ) { return UPNP_E_URL_TOO_BIG; } strcpy( descURL, description ); if( ( retVal = UpnpDownloadXmlDoc( description, xmlDoc ) ) != UPNP_E_SUCCESS ) { return retVal; } return UPNP_E_SUCCESS;}#endif // INTERNAL_WEB_SERVER// ********************************************************/**************************************************************************** * Function: UpnpRegisterRootDevice2 * * Parameters: * IN Upnp_DescType descriptionType: The type of description document. * IN const char* description: Treated as a URL, file name or * memory buffer depending on description type. * IN size_t bufferLen: Length of memory buffer if passing a description * in a buffer, otherwize ignored. * IN int config_baseURL: If nonzero, URLBase of description document is * configured and the description is served using the internal * web server. * IN Upnp_FunPtr Fun: Pointer to the callback function for * receiving asynchronous events. * IN const void* Cookie: Pointer to user data returned with the * callback function when invoked. * OUT UpnpDevice_Handle* Hnd: Pointer to a variable to store * the new device handle. * * Description: * This function is similar to UpnpRegisterRootDevice except that * it also allows the description document to be specified as a file or * a memory buffer. The description can also be configured to have the * correct IP and port address. * * Return Values: * UPNP_E_SUCCESS on success, nonzero on failure. *****************************************************************************/intUpnpRegisterRootDevice2( IN Upnp_DescType descriptionType, IN const char *description_const, IN size_t bufferLen, // ignored unless descType == UPNPREG_BUF_DESC IN int config_baseURL, IN Upnp_FunPtr Fun, IN const void *Cookie, OUT UpnpDevice_Handle * Hnd ){ struct Handle_Info *HInfo; int retVal = 0; char *description = ( char * )description_const; if( UpnpSdkInit != 1 ) { return UPNP_E_FINISH; } UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpRegisterRootDevice2\n" ); if( Hnd == NULL || Fun == NULL ) { return UPNP_E_INVALID_PARAM; } HandleLock(); if( UpnpSdkDeviceRegistered ) { HandleUnlock(); return UPNP_E_ALREADY_REGISTERED; } if( ( *Hnd = GetFreeHandle() ) == UPNP_E_OUTOF_HANDLE ) { HandleUnlock(); return UPNP_E_OUTOF_MEMORY; } HInfo = ( struct Handle_Info * )malloc( sizeof( struct Handle_Info ) ); if( HInfo == NULL ) { HandleUnlock(); return UPNP_E_OUTOF_MEMORY; } HandleTable[*Hnd] = HInfo; // prevent accidental removal of a non-existent alias HInfo->aliasInstalled = 0; retVal = GetDescDocumentAndURL( descriptionType, description, bufferLen, config_baseURL, &HInfo->DescDocument, HInfo->DescURL ); if( retVal != UPNP_E_SUCCESS ) { FreeHandle( *Hnd ); HandleUnlock(); return retVal; } HInfo->aliasInstalled = ( config_baseURL != 0 ); HInfo->HType = HND_DEVICE; HInfo->Callback = Fun; HInfo->Cookie = ( void * )Cookie; HInfo->MaxAge = DEFAULT_MAXAGE; HInfo->DeviceList = NULL; HInfo->ServiceList = NULL; CLIENTONLY( ListInit( &HInfo->SsdpSearchList, NULL, NULL ); ) CLIENTONLY( HInfo->ClientSubList = NULL; ) HInfo->MaxSubscriptions = UPNP_INFINITE; HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE; UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: Valid Description\n" ); UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: DescURL : %s\n", HInfo->DescURL ); HInfo->DeviceList = ixmlDocument_getElementsByTagName( HInfo->DescDocument, "device" ); if( !HInfo->DeviceList ) { CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ); ) ixmlDocument_free( HInfo->DescDocument ); FreeHandle( *Hnd ); HandleUnlock(); UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: No devices found for RootDevice\n" ); return UPNP_E_INVALID_DESC; } HInfo->ServiceList = ixmlDocument_getElementsByTagName( HInfo->DescDocument, "serviceList" ); if( !HInfo->ServiceList ) { UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: No services found for RootDevice\n" ); } UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: Gena Check\n" ); //******************************* // GENA SET UP //******************************* if( getServiceTable( ( IXML_Node * ) HInfo->DescDocument, &HInfo->ServiceTable, HInfo->DescURL ) ) { UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "UpnpRegisterRootDevice2: GENA Service Table\n" ); UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Here are the known services: \n" ); printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API ); } else { UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "\nUpnpRegisterRootDevice2: Empty service table\n" ); } UpnpSdkDeviceRegistered = 1; HandleUnlock(); UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Exiting RegisterRootDevice2 Successfully\n" ); return UPNP_E_SUCCESS;}#endif // INCLUDE_DEVICE_APIS#ifdef INCLUDE_CLIENT_APIS/************************************************************************** * Function: UpnpRegisterClient * * Parameters: * IN Upnp_FunPtr Fun: Pointer to a function for receiving * asynchronous events. * IN const void * Cookie: Pointer to user data returned with the * callback function when invoked. * OUT UpnpClient_Handle *Hnd: Pointer to a variable to store * the new control point handle. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -