📄 upnp_tv_ctrlpt.c
字号:
* Cookie -- Optional data specified during callback registration * ********************************************************************************/intTvCtrlPointCallbackEventHandler( Upnp_EventType EventType, void *Event, void *Cookie ){ SampleUtil_PrintEvent( EventType, Event ); switch ( EventType ) { /* SSDP Stuff */ case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { struct Upnp_Discovery *d_event = ( struct Upnp_Discovery * )Event; IXML_Document *DescDoc = NULL; int ret; if( d_event->ErrCode != UPNP_E_SUCCESS ) { SampleUtil_Print( "Error in Discovery Callback -- %d", d_event->ErrCode ); } if( ( ret = UpnpDownloadXmlDoc( d_event->Location, &DescDoc ) ) != UPNP_E_SUCCESS ) { SampleUtil_Print ( "Error obtaining device description from %s -- error = %d", d_event->Location, ret ); } else { TvCtrlPointAddDevice( DescDoc, d_event->Location, d_event->Expires ); } if( DescDoc ) ixmlDocument_free( DescDoc ); TvCtrlPointPrintList( ); break; } case UPNP_DISCOVERY_SEARCH_TIMEOUT: /* Nothing to do here... */ break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery *d_event = ( struct Upnp_Discovery * )Event; if( d_event->ErrCode != UPNP_E_SUCCESS ) { SampleUtil_Print ( "Error in Discovery ByeBye Callback -- %d", d_event->ErrCode ); } SampleUtil_Print( "Received ByeBye for Device: %s", d_event->DeviceId ); TvCtrlPointRemoveDevice( d_event->DeviceId ); SampleUtil_Print( "After byebye:" ); TvCtrlPointPrintList( ); break; } /* SOAP Stuff */ case UPNP_CONTROL_ACTION_COMPLETE: { struct Upnp_Action_Complete *a_event = ( struct Upnp_Action_Complete * )Event; if( a_event->ErrCode != UPNP_E_SUCCESS ) { SampleUtil_Print ( "Error in Action Complete Callback -- %d", a_event->ErrCode ); } /* No need for any processing here, just print out results. Service state table updates are handled by events. */ break; } case UPNP_CONTROL_GET_VAR_COMPLETE: { struct Upnp_State_Var_Complete *sv_event = ( struct Upnp_State_Var_Complete * )Event; if( sv_event->ErrCode != UPNP_E_SUCCESS ) { SampleUtil_Print ( "Error in Get Var Complete Callback -- %d", sv_event->ErrCode ); } else { TvCtrlPointHandleGetVar( sv_event->CtrlUrl, sv_event->StateVarName, sv_event->CurrentVal ); } break; } /* GENA Stuff */ case UPNP_EVENT_RECEIVED: { struct Upnp_Event *e_event = ( struct Upnp_Event * )Event; TvCtrlPointHandleEvent( e_event->Sid, e_event->EventKey, e_event->ChangedVariables ); break; } case UPNP_EVENT_SUBSCRIBE_COMPLETE: case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: case UPNP_EVENT_RENEWAL_COMPLETE: { struct Upnp_Event_Subscribe *es_event = ( struct Upnp_Event_Subscribe * )Event; if( es_event->ErrCode != UPNP_E_SUCCESS ) { SampleUtil_Print ( "Error in Event Subscribe Callback -- %d", es_event->ErrCode ); } else { TvCtrlPointHandleSubscribeUpdate( es_event-> PublisherUrl, es_event->Sid, es_event->TimeOut ); } break; } case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { int TimeOut = default_timeout; Upnp_SID newSID; int ret; struct Upnp_Event_Subscribe *es_event = ( struct Upnp_Event_Subscribe * )Event; ret = UpnpSubscribe( ctrlpt_handle, es_event->PublisherUrl, &TimeOut, newSID ); if( ret == UPNP_E_SUCCESS ) { SampleUtil_Print( "Subscribed to EventURL with SID=%s", newSID ); TvCtrlPointHandleSubscribeUpdate( es_event-> PublisherUrl, newSID, TimeOut ); } else { SampleUtil_Print ( "Error Subscribing to EventURL -- %d", ret ); } break; } /* ignore these cases, since this is not a device */ case UPNP_EVENT_SUBSCRIPTION_REQUEST: case UPNP_CONTROL_GET_VAR_REQUEST: case UPNP_CONTROL_ACTION_REQUEST: break; } return 0;}/******************************************************************************** * TvCtrlPointVerifyTimeouts * * Description: * Checks the advertisement each device * in the global device list. If an advertisement expires, * the device is removed from the list. If an advertisement is about to * expire, a search request is sent for that device. * * Parameters: * incr -- The increment to subtract from the timeouts each time the * function is called. * ********************************************************************************/voidTvCtrlPointVerifyTimeouts( int incr ){ struct TvDeviceNode *prevdevnode, *curdevnode; int ret; ithread_mutex_lock( &DeviceListMutex ); prevdevnode = NULL; curdevnode = GlobalDeviceList; while( curdevnode ) { curdevnode->device.AdvrTimeOut -= incr; //SampleUtil_Print("Advertisement Timeout: %d\n", curdevnode->device.AdvrTimeOut); if( curdevnode->device.AdvrTimeOut <= 0 ) { /* This advertisement has expired, so we should remove the device from the list */ if( GlobalDeviceList == curdevnode ) GlobalDeviceList = curdevnode->next; else prevdevnode->next = curdevnode->next; TvCtrlPointDeleteNode( curdevnode ); if( prevdevnode ) curdevnode = prevdevnode->next; else curdevnode = GlobalDeviceList; } else { if( curdevnode->device.AdvrTimeOut < 2 * incr ) { /* This advertisement is about to expire, so send out a search request for this device UDN to try to renew */ ret = UpnpSearchAsync( ctrlpt_handle, incr, curdevnode->device.UDN, NULL ); if( ret != UPNP_E_SUCCESS ) SampleUtil_Print ( "Error sending search request for Device UDN: %s -- err = %d", curdevnode->device.UDN, ret ); } prevdevnode = curdevnode; curdevnode = curdevnode->next; } } ithread_mutex_unlock( &DeviceListMutex );}/******************************************************************************** * TvCtrlPointTimerLoop * * Description: * Function that runs in its own thread and monitors advertisement * and subscription timeouts for devices in the global device list. * * Parameters: * None * ********************************************************************************/void *TvCtrlPointTimerLoop( void *args ){ int incr = 30; // how often to verify the timeouts, in seconds while( 1 ) { isleep( incr ); TvCtrlPointVerifyTimeouts( incr ); }}/******************************************************************************** * TvCtrlPointStart * * Description: * Call this function to initialize the UPnP library and start the TV Control * Point. This function creates a timer thread and provides a callback * handler to process any UPnP events that are received. * * Parameters: * None * * Returns: * TV_SUCCESS if everything went well, else TV_ERROR * ********************************************************************************/intTvCtrlPointStart( print_string printFunctionPtr, state_update updateFunctionPtr ){ ithread_t timer_thread; int rc; short int port = 0; char *ip_address = NULL; SampleUtil_Initialize( printFunctionPtr ); SampleUtil_RegisterUpdateFunction( updateFunctionPtr ); ithread_mutex_init( &DeviceListMutex, 0 ); SampleUtil_Print( "Intializing UPnP with ipaddress=%s port=%d", ip_address, port ); rc = UpnpInit( ip_address, port ); if( UPNP_E_SUCCESS != rc ) { SampleUtil_Print( "WinCEStart: UpnpInit() Error: %d", rc ); UpnpFinish( ); return TV_ERROR; } if( NULL == ip_address ) ip_address = UpnpGetServerIpAddress( ); if( 0 == port ) port = UpnpGetServerPort( ); SampleUtil_Print( "UPnP Initialized (%s:%d)", ip_address, port ); SampleUtil_Print( "Registering Control Point" ); rc = UpnpRegisterClient( TvCtrlPointCallbackEventHandler, &ctrlpt_handle, &ctrlpt_handle ); if( UPNP_E_SUCCESS != rc ) { SampleUtil_Print( "Error registering CP: %d", rc ); UpnpFinish( ); return TV_ERROR; } SampleUtil_Print( "Control Point Registered" ); TvCtrlPointRefresh( ); // start a timer thread ithread_create( &timer_thread, NULL, TvCtrlPointTimerLoop, NULL ); return TV_SUCCESS;}intTvCtrlPointStop( void ){ TvCtrlPointRemoveAll( ); UpnpUnRegisterClient( ctrlpt_handle ); UpnpFinish( ); SampleUtil_Finish( ); return TV_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -