int discovery_search_result(struct Upnp_Discovery *event) { if (event->ErrCode != UPNP_E_SUCCESS) { fprintf(stderr, "Error in discovering device\n"); exit(-1); } IXML_Document *desc = NULL; int ret = UpnpDownloadXmlDoc(event->Location, &desc); if (ret != UPNP_E_SUCCESS) { fprintf(stderr, "Error in obtaining device description\n"); exit(-1); } const char *UUID = get_device_property(desc, "UDN"); if (!list_contains(&devices, UUID, chromecast_matches_UUID)) { struct chromecast_device *device = malloc(sizeof(struct chromecast_device)); device->addr = ((struct sockaddr_in *)&event->DestAddr)->sin_addr; device->device_name = create_string_copy(get_device_property(desc, "friendlyName")); device->device_type = create_string_copy(get_device_property(desc, "deviceType")); device->device_UUID = create_string_copy(UUID); device->device_OS = create_string_copy(event->Os); device->device_manufacturer = create_string_copy(get_device_property(desc, "manufacturer")); device->device_model_name = create_string_copy(get_device_property(desc, "modelName")); device->service_type = create_string_copy(get_device_property(desc, "serviceType")); device->service_version = create_string_copy(event->ServiceVer); device->service_id = create_string_copy(get_device_property(desc, "serviceId")); list_add_sync(&devices, device); print_device(device); } ixmlDocument_free(desc); return 0; }
/* * Handles servers listing UPnP events */ int MediaServerList::Callback( Upnp_EventType event_type, void* p_event, void* p_user_data ) { MediaServerList* self = static_cast<MediaServerList*>( p_user_data ); services_discovery_t* p_sd = self->p_sd_; switch( event_type ) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { struct Upnp_Discovery* p_discovery = ( struct Upnp_Discovery* )p_event; IXML_Document *p_description_doc = NULL; int i_res; i_res = UpnpDownloadXmlDoc( p_discovery->Location, &p_description_doc ); if ( i_res != UPNP_E_SUCCESS ) { msg_Warn( p_sd, "Could not download device description! " "Fetching data from %s failed: %s", p_discovery->Location, UpnpGetErrorMessage( i_res ) ); return i_res; } self->parseNewServer( p_description_doc, p_discovery->Location ); ixmlDocument_free( p_description_doc ); } break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery* p_discovery = ( struct Upnp_Discovery* )p_event; self->removeServer( p_discovery->DeviceId ); } break; case UPNP_EVENT_SUBSCRIBE_COMPLETE: msg_Warn( p_sd, "subscription complete" ); break; case UPNP_DISCOVERY_SEARCH_TIMEOUT: msg_Warn( p_sd, "search timeout" ); break; case UPNP_EVENT_RECEIVED: case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: // Those are for the access part break; default: msg_Err( p_sd, "Unhandled event, please report ( type=%d )", event_type ); break; } return UPNP_E_SUCCESS; }
int TvDeviceStateTableInit(char *DescDocURL) { IXML_Document *DescDoc = NULL; int ret = UPNP_E_SUCCESS; char *servid_ctrl = NULL; char *evnturl_ctrl = NULL; char *ctrlurl_ctrl = NULL; char *servid_pict = NULL; char *evnturl_pict = NULL; char *ctrlurl_pict = NULL; char *udn = NULL; /*Download description document */ if (UpnpDownloadXmlDoc(DescDocURL, &DescDoc) != UPNP_E_SUCCESS) { SampleUtil_Print("TvDeviceStateTableInit -- Error Parsing %s\n", DescDocURL); ret = UPNP_E_INVALID_DESC; goto error_handler; } udn = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN"); /* Find the Tv Control Service identifiers */ if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL, TvServiceType[TV_SERVICE_CONTROL], &servid_ctrl, &evnturl_ctrl, &ctrlurl_ctrl)) { SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n", TvServiceType[TV_SERVICE_CONTROL]); ret = UPNP_E_INVALID_DESC; goto error_handler; } /* set control service table */ SetServiceTable(TV_SERVICE_CONTROL, udn, servid_ctrl, TvServiceType[TV_SERVICE_CONTROL], &tv_service_table[TV_SERVICE_CONTROL]); /* Find the Tv Picture Service identifiers */ if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL, TvServiceType[TV_SERVICE_PICTURE], &servid_pict, &evnturl_pict, &ctrlurl_pict)) { SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n", TvServiceType[TV_SERVICE_PICTURE]); ret = UPNP_E_INVALID_DESC; goto error_handler; } /* set picture service table */ SetServiceTable(TV_SERVICE_PICTURE, udn, servid_pict, TvServiceType[TV_SERVICE_PICTURE], &tv_service_table[TV_SERVICE_PICTURE]); error_handler: /* clean up */ if (udn) free(udn); if (servid_ctrl) free(servid_ctrl); if (evnturl_ctrl) free(evnturl_ctrl); if (ctrlurl_ctrl) free(ctrlurl_ctrl); if (servid_pict) free(servid_pict); if (evnturl_pict) free(evnturl_pict); if (ctrlurl_pict) free(ctrlurl_pict); if (DescDoc) ixmlDocument_free(DescDoc); return (ret); }
/******************************************************************************** * upnp_igd_callback * * Description: * The callback handler registered with the SDK while registering * the control point. Detects the type of callback, and passes the * request on to the appropriate function. * * Parameters: * event_type -- The type of callback event * event -- Data structure containing event data * cookie -- Optional data specified during callback registration * ********************************************************************************/ int upnp_igd_callback(Upnp_EventType event_type, void* event, void *cookie) { int ret = 1; upnp_igd_context *igd_ctxt = (upnp_igd_context*)cookie; upnp_context_add_client(igd_ctxt); upnp_igd_print_event(igd_ctxt, UPNP_IGD_DEBUG, event_type, event); switch(event_type) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)event; IXML_Document *desc_doc = NULL; int ret; if (d_event->ErrCode != UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in Discovery Callback -- %d", d_event->ErrCode); } ret = UpnpDownloadXmlDoc(d_event->Location, &desc_doc); if (ret != UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error obtaining device description from %s -- error = %d", d_event->Location, ret); } else { upnp_igd_add_device(igd_ctxt, desc_doc, d_event); } if (desc_doc) { ixmlDocument_free(desc_doc); } } break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)event; if (d_event->ErrCode != UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in Discovery ByeBye Callback -- %d", d_event->ErrCode); } upnp_igd_remove_device(igd_ctxt, d_event->DeviceId); } 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) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in Action Complete Callback -- %d", a_event->ErrCode); } else { upnp_igd_handle_send_action(igd_ctxt, UPNP_STRING(a_event->CtrlUrl), a_event->ActionRequest, a_event->ActionResult); } } 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) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in Get Var Complete Callback -- %d", sv_event->ErrCode); } else { upnp_igd_handle_get_var(igd_ctxt, UPNP_STRING(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; upnp_igd_handle_event(igd_ctxt, 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) { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error in Event Subscribe Callback -- %d", es_event->ErrCode); } else { upnp_igd_handle_subscribe_update(igd_ctxt, UPNP_STRING(es_event->PublisherUrl), es_event->Sid, es_event->TimeOut); } } break; case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { struct Upnp_Event_Subscribe *es_event = (struct Upnp_Event_Subscribe *)event; int TimeOut = 1801; Upnp_SID newSID; int ret; ret = UpnpSubscribe(igd_ctxt->upnp_handle, UPNP_STRING(es_event->PublisherUrl), &TimeOut, newSID); if (ret == UPNP_E_SUCCESS) { upnp_igd_print(igd_ctxt, UPNP_IGD_DEBUG, "Subscribed to EventURL with SID=%s", newSID); upnp_igd_handle_subscribe_update(igd_ctxt, UPNP_STRING(es_event->PublisherUrl), newSID, TimeOut); } else { upnp_igd_print(igd_ctxt, UPNP_IGD_ERROR, "Error Subscribing to EventURL -- %d", ret); } } break; default: break; } upnp_context_handle_callbacks(igd_ctxt); upnp_context_remove_client(igd_ctxt); return ret; }
// Handles all UPnP events static int Callback( Upnp_EventType eventType, void* event, void* user_data ) { services_discovery_t *p_sd = ( services_discovery_t* ) user_data; services_discovery_sys_t* p_sys = p_sd->p_sys; vlc_mutex_locker locker( &p_sys->callbackLock ); switch( eventType ) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { struct Upnp_Discovery* discovery = ( struct Upnp_Discovery* )event; IXML_Document *descriptionDoc = 0; int res; res = UpnpDownloadXmlDoc( discovery->Location, &descriptionDoc ); if ( res != UPNP_E_SUCCESS ) { msg_Dbg( p_sd, "%s:%d: Could not download device description!", __FILE__, __LINE__ ); return res; } MediaServer::parseDeviceDescription( descriptionDoc, discovery->Location, p_sd ); ixmlDocument_free( descriptionDoc ); } break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery* discovery = ( struct Upnp_Discovery* )event; p_sys->serverList->removeServer( discovery->DeviceId ); } break; case UPNP_EVENT_RECEIVED: { Upnp_Event* e = ( Upnp_Event* )event; MediaServer* server = p_sys->serverList->getServerBySID( e->Sid ); if ( server ) server->fetchContents(); } break; case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { // Re-subscribe... Upnp_Event_Subscribe* s = ( Upnp_Event_Subscribe* )event; MediaServer* server = p_sys->serverList->getServerBySID( s->Sid ); if ( server ) server->subscribeToContentDirectory(); } break; case UPNP_EVENT_SUBSCRIBE_COMPLETE: msg_Warn( p_sd, "subscription complete" ); break; case UPNP_DISCOVERY_SEARCH_TIMEOUT: msg_Warn( p_sd, "search timeout" ); break; default: msg_Dbg( p_sd, "%s:%d: DEBUG: UNHANDLED EVENT ( TYPE=%d )", __FILE__, __LINE__, eventType ); break; } return UPNP_E_SUCCESS; }
/******************************************************************************** * TvCtrlPointCallbackEventHandler * * Description: * The callback handler registered with the SDK while registering * the control point. Detects the type of callback, and passes the * request on to the appropriate function. * * Parameters: * EventType -- The type of callback event * Event -- Data structure containing event data * Cookie -- Optional data specified during callback registration * ********************************************************************************/ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, const void *Event, void *Cookie) { int errCode = 0; SampleUtil_PrintEvent(EventType, Event); switch ( EventType ) { /* SSDP Stuff */ case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { const UpnpDiscovery *d_event = (UpnpDiscovery *)Event; IXML_Document *DescDoc = NULL; const char *location = NULL; int errCode = UpnpDiscovery_get_ErrCode(d_event); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print( "Error in Discovery Callback -- %d\n", errCode); } location = UpnpString_get_String(UpnpDiscovery_get_Location(d_event)); errCode = UpnpDownloadXmlDoc(location, &DescDoc); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print( "Error obtaining device description from %s -- error = %d\n", location, errCode); } else { TvCtrlPointAddDevice( DescDoc, location, UpnpDiscovery_get_Expires(d_event)); } if (DescDoc) { ixmlDocument_free(DescDoc); } TvCtrlPointPrintList(); break; } case UPNP_DISCOVERY_SEARCH_TIMEOUT: /* Nothing to do here... */ break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { UpnpDiscovery *d_event = (UpnpDiscovery *)Event; int errCode = UpnpDiscovery_get_ErrCode(d_event); const char *deviceId = UpnpString_get_String( UpnpDiscovery_get_DeviceID(d_event)); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print( "Error in Discovery ByeBye Callback -- %d\n", errCode); } SampleUtil_Print("Received ByeBye for Device: %s\n", deviceId); TvCtrlPointRemoveDevice(deviceId); SampleUtil_Print("After byebye:\n"); TvCtrlPointPrintList(); break; } /* SOAP Stuff */ case UPNP_CONTROL_ACTION_COMPLETE: { UpnpActionComplete *a_event = (UpnpActionComplete *)Event; int errCode = UpnpActionComplete_get_ErrCode(a_event); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print("Error in Action Complete Callback -- %d\n", 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: { UpnpStateVarComplete *sv_event = (UpnpStateVarComplete *)Event; int errCode = UpnpStateVarComplete_get_ErrCode(sv_event); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print( "Error in Get Var Complete Callback -- %d\n", errCode); } else { TvCtrlPointHandleGetVar( UpnpString_get_String(UpnpStateVarComplete_get_CtrlUrl(sv_event)), UpnpString_get_String(UpnpStateVarComplete_get_StateVarName(sv_event)), UpnpStateVarComplete_get_CurrentVal(sv_event)); } break; } /* GENA Stuff */ case UPNP_EVENT_RECEIVED: { UpnpEvent *e_event = (UpnpEvent *)Event; TvCtrlPointHandleEvent( UpnpEvent_get_SID_cstr(e_event), UpnpEvent_get_EventKey(e_event), UpnpEvent_get_ChangedVariables(e_event)); break; } case UPNP_EVENT_SUBSCRIBE_COMPLETE: case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: case UPNP_EVENT_RENEWAL_COMPLETE: { UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; errCode = UpnpEventSubscribe_get_ErrCode(es_event); if (errCode != UPNP_E_SUCCESS) { SampleUtil_Print( "Error in Event Subscribe Callback -- %d\n", errCode); } else { TvCtrlPointHandleSubscribeUpdate( UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)), UpnpString_get_String(UpnpEventSubscribe_get_SID(es_event)), UpnpEventSubscribe_get_TimeOut(es_event)); } break; } case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; int TimeOut = default_timeout; Upnp_SID newSID; errCode = UpnpSubscribe( ctrlpt_handle, UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)), &TimeOut, newSID); if (errCode == UPNP_E_SUCCESS) { SampleUtil_Print("Subscribed to EventURL with SID=%s\n", newSID); TvCtrlPointHandleSubscribeUpdate( UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)), newSID, TimeOut); } else { SampleUtil_Print("Error Subscribing to EventURL -- %d\n", errCode); } 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; Cookie = Cookie; }
int CtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie) { /*int errCode = 0;*/ Util_PrintEventType(EventType); 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) { g_print("Error in Discovery Callback -- %d\n", d_event->ErrCode); } ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc); if (ret != UPNP_E_SUCCESS) { g_print("Error obtaining device description from %s -- error = %d\n", d_event->Location, ret); } else { CtrlPointAddDevice( 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: { break; } /* SOAP Stuff */ case UPNP_CONTROL_ACTION_COMPLETE: { break; } case UPNP_CONTROL_GET_VAR_COMPLETE: { break; } /* GENA Stuff */ case UPNP_EVENT_RECEIVED: { break; } case UPNP_EVENT_SUBSCRIBE_COMPLETE: case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: case UPNP_EVENT_RENEWAL_COMPLETE: { } case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { 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; }
/* * Handles all UPnP events */ static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data ) { services_discovery_t* p_sd = ( services_discovery_t* ) p_user_data; services_discovery_sys_t* p_sys = p_sd->p_sys; vlc_mutex_locker locker( &p_sys->callback_lock ); switch( event_type ) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_SEARCH_RESULT: { struct Upnp_Discovery* p_discovery = ( struct Upnp_Discovery* )p_event; IXML_Document *p_description_doc = 0; int i_res; i_res = UpnpDownloadXmlDoc( p_discovery->Location, &p_description_doc ); if ( i_res != UPNP_E_SUCCESS ) { msg_Warn( p_sd, "Could not download device description! " "Fetching data from %s failed: %s", p_discovery->Location, UpnpGetErrorMessage( i_res ) ); return i_res; } MediaServer::parseDeviceDescription( p_description_doc, p_discovery->Location, p_sd ); ixmlDocument_free( p_description_doc ); } break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery* p_discovery = ( struct Upnp_Discovery* )p_event; p_sys->p_server_list->removeServer( p_discovery->DeviceId ); } break; case UPNP_EVENT_RECEIVED: { Upnp_Event* p_e = ( Upnp_Event* )p_event; MediaServer* p_server = p_sys->p_server_list->getServerBySID( p_e->Sid ); if ( p_server ) p_server->fetchContents(); } break; case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { /* Re-subscribe. */ Upnp_Event_Subscribe* p_s = ( Upnp_Event_Subscribe* )p_event; MediaServer* p_server = p_sys->p_server_list->getServerBySID( p_s->Sid ); if ( p_server ) p_server->subscribeToContentDirectory(); } break; case UPNP_EVENT_SUBSCRIBE_COMPLETE: msg_Warn( p_sd, "subscription complete" ); break; case UPNP_DISCOVERY_SEARCH_TIMEOUT: msg_Warn( p_sd, "search timeout" ); break; default: msg_Err( p_sd, "Unhandled event, please report ( type=%d )", event_type ); break; } return UPNP_E_SUCCESS; }
/******************************************************************************** * TvCtrlPointCallbackEventHandler * * Description: * The callback handler registered with the SDK while registering * the control point. Detects the type of callback, and passes the * request on to the appropriate function. * * Parameters: * EventType -- The type of callback event * Event -- Data structure containing event data * Cookie -- Optional data specified during callback registration * ********************************************************************************/ int TvCtrlPointCallbackEventHandler( 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; }
/* Function:Link Server CallBack; INPUT: Upnp_EventType -- EventType; Event -- void*; Cookie -- void*; SUCCESS:1; ERROR:0; */ int SA_CallbackEventHandler( Upnp_EventType EventType, void *Event, void *Cookie ) { PrintEvent( EventType, Event ); switch ( EventType ) { case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: break; 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 ) { SA_Print( "Error in Discovery Callback -- %d", d_event->ErrCode ); } if( ( ret = UpnpDownloadXmlDoc( d_event->Location, &DescDoc ) ) != UPNP_E_SUCCESS ) { SA_Print ( "Error obtaining device description from %s -- error = %d", d_event->Location, ret ); } else { DevCtrlPoint_AddDevice( DescDoc, d_event->Location, d_event->Expires ); } if( DescDoc ) ixmlDocument_free( DescDoc ); DevCtrlPoint_PrintList(); break; } case UPNP_DISCOVERY_SEARCH_TIMEOUT: break; case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { struct Upnp_Discovery *d_event = ( struct Upnp_Discovery * )Event; if( d_event->ErrCode != UPNP_E_SUCCESS ) { SA_Print ( "Error in Discovery ByeBye Callback -- %d", d_event->ErrCode ); } SA_Print( "Received ByeBye for Device: %s", d_event->DeviceId ); DevCtrlPoint_RemoveDevice( d_event->DeviceId ); SA_Print( "After byebye:" ); DevCtrlPoint_PrintList(); break; } case UPNP_CONTROL_ACTION_COMPLETE: { struct Upnp_Action_Complete *a_event = ( struct Upnp_Action_Complete * )Event; if( a_event->ErrCode != UPNP_E_SUCCESS ) { SA_Print ( "Error in Action Complete Callback -- %d", a_event->ErrCode ); } break; } case UPNP_EVENT_RECEIVED: { 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 ) { SA_Print ( "Error in Event Subscribe Callback -- %d", es_event->ErrCode ); } else { DevCtrlPoint_HandleSubscribeUpdate( 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 ) { SA_Print( "Subscribed to EventURL with SID=%s", newSID ); DevCtrlPoint_HandleSubscribeUpdate( es_event-> PublisherUrl, newSID, TimeOut ); } else { SA_Print ( "Error Subscribing to EventURL -- %d", ret ); } break; } case UPNP_EVENT_SUBSCRIPTION_REQUEST: case UPNP_CONTROL_ACTION_REQUEST: break; default: break; } return 0; }
ERROR_TYPE IUpnp::DownloadXmlDoc(IN const char *url,OUT IXML_Document **xmlDoc) { return (ERROR_TYPE)UpnpDownloadXmlDoc(url,xmlDoc); }
/******************************************************************************** * WscUPnPCPAddDevice * * Description: * Add a new Wsc device into the wsc device list or just update its advertisement * expiration timeout if it alreay exists in the list. * * Parameters: * deviceType -- The device type want to add to the Device List * d_event -- The "Upnp_Discovery" data * * Return: * WSC_SYS_SUCCESS - if success * other value - if failure ********************************************************************************/ int WscUPnPCPAddDevice( IN char *deviceType, IN struct Upnp_Discovery *d_event, OUT unsigned int *outIPAddr) { IXML_Document *DescDoc = NULL, *scpdDescDoc = NULL; char *deviceTypeStr = NULL, *friendlyName = NULL, *baseURL = NULL, *relURL = NULL, *UDN = NULL; char presURL[200] = {0}; char *serviceId = NULL, *SCPDURL = NULL, *eventURL = NULL, *controlURL = NULL; Upnp_SID eventSID; struct upnpDeviceNode *newDeviceNode, *devNodePtr; int ret = WSC_SYS_ERROR; int found = 0; int TimeOut = DEF_SUBSCRIPTION_TIMEOUT; unsigned int ipAddr = 0; unsigned short port = 0; if(d_event->DestAddr != NULL) { ipAddr = (unsigned int)d_event->DestAddr->sin_addr.s_addr; port = (unsigned short)d_event->DestAddr->sin_port; *outIPAddr = ipAddr; } printf("%s():outIPAddr=0x%x!\n", __FUNCTION__, *outIPAddr); if( !(strcmp(&HostDescURL[0], &d_event->Location[0]))) { // DBGPRINTF(RT_DBG_INFO, "%s():Adver from LocalDev, ignore it!\n", __FUNCTION__); goto done; } // Check if this device is already in the list devNodePtr = WscDeviceList; while (devNodePtr) { if((strcmp(devNodePtr->device.UDN, d_event->DeviceId) == 0) && (strcmp(devNodePtr->device.DescDocURL, d_event->Location) == 0)) { found = 1; break; } devNodePtr = devNodePtr->next; } if (found) { // Update the advertisement timeout field // DBGPRINTF(RT_DBG_INFO, "Old device, just update the expires!\n"); devNodePtr->device.AdvrTimeOut = d_event->Expires; devNodePtr->device.timeCount = 0; } else { DBGPRINTF(RT_DBG_INFO, "Adver from a new device!\n"); if((ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc)) != UPNP_E_SUCCESS){ DBGPRINTF(RT_DBG_ERROR, "Get device description failed from %s -- err=%d\n", d_event->Location, ret); goto done; } /* Read key elements from description document */ UDN = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN"); deviceTypeStr = SampleUtil_GetFirstDocumentItem(DescDoc, "deviceType"); friendlyName = SampleUtil_GetFirstDocumentItem(DescDoc, "friendlyName"); baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase"); relURL = SampleUtil_GetFirstDocumentItem(DescDoc, "presentationURL"); if((UDN == NULL) || (deviceTypeStr == NULL) || (friendlyName == NULL)) { DBGPRINTF(RT_DBG_ERROR, "%s(): Get UDN failed!\n", __FUNCTION__); goto done; } UpnpResolveURL((baseURL ? baseURL : d_event->Location), relURL, presURL); if (SampleUtil_FindAndParseService(DescDoc, d_event->Location, WscServiceTypeStr, &serviceId, &SCPDURL, &eventURL,&controlURL)) { if (SCPDURL != NULL) { if ((ret = UpnpDownloadXmlDoc(SCPDURL, &scpdDescDoc)) != UPNP_E_SUCCESS) { DBGPRINTF(RT_DBG_ERROR, "Get service description failed from %s -- err=%d\n", SCPDURL, ret); } else { WscUPnPCPCheckService(scpdDescDoc); free(scpdDescDoc); } } if ((ret = UpnpSubscribe(WscCPHandle, eventURL, &TimeOut, eventSID)) != UPNP_E_SUCCESS) { DBGPRINTF(RT_DBG_ERROR, "Error Subscribing to EventURL(%s) -- %d\n", eventURL, ret); goto done; } /* Create a new device node */ newDeviceNode = (struct upnpDeviceNode *)malloc(sizeof(struct upnpDeviceNode)); if (newDeviceNode == NULL) { DBGPRINTF(RT_DBG_ERROR, "%s: create new wsc Device Node failed!\n", __FUNCTION__); goto done; } memset(newDeviceNode, 0, sizeof(newDeviceNode)); newDeviceNode->device.services.StateVarVal[WSC_EVENT_WLANEVENT] = NULL; newDeviceNode->device.services.StateVarVal[WSC_EVENT_APSTATUS] = NULL; newDeviceNode->device.services.StateVarVal[WSC_EVENT_STASTATUS] = NULL; strncpy(newDeviceNode->device.UDN, UDN, NAME_SIZE-1); strncpy(newDeviceNode->device.DescDocURL, d_event->Location, NAME_SIZE-1); strncpy(newDeviceNode->device.FriendlyName, friendlyName, NAME_SIZE-1); strncpy(newDeviceNode->device.PresURL, presURL, NAME_SIZE-1); newDeviceNode->device.AdvrTimeOut = d_event->Expires; newDeviceNode->device.timeCount = 0; newDeviceNode->device.ipAddr = ipAddr; strncpy(newDeviceNode->device.services.ServiceType, WscServiceTypeStr, NAME_SIZE-1); if (serviceId) strncpy(newDeviceNode->device.services.ServiceId, serviceId, NAME_SIZE-1); if (SCPDURL) strncpy(newDeviceNode->device.services.SCPDURL, SCPDURL, NAME_SIZE-1); if (eventURL) strncpy(newDeviceNode->device.services.EventURL, eventURL, NAME_SIZE-1); if (controlURL) strncpy(newDeviceNode->device.services.ControlURL, controlURL, NAME_SIZE-1); if (eventSID) strncpy(newDeviceNode->device.services.SID, eventSID, NAME_SIZE-1); newDeviceNode->next = NULL; #if 0 for (var = 0; var < WSC_STATE_VAR_COUNT; var++) { deviceNode->device.services.serviceList.stateVarVals[var] = (char *)malloc(WSC_STATE_VAR_MAX_STR_LEN); strcpy(deviceNode->device.services.serviceList.stateVarVals[var], ""); } #endif // Insert the new device node in the list if(WscDeviceList) { newDeviceNode->next = WscDeviceList->next; WscDeviceList->next = newDeviceNode; } else { WscDeviceList = newDeviceNode; } ret = WSC_SYS_SUCCESS; // TODO:Notify New Device Added //WscCPDevUpdate(NULL, NULL, deviceNode->device.UDN, DEVICE_ADDED); } else { DBGPRINTF(RT_DBG_ERROR, "Error: Could not find Service: %s\n", WscServiceTypeStr); } } done: if (DescDoc) ixmlDocument_free(DescDoc); if (UDN) free(UDN); if (deviceTypeStr) free(deviceTypeStr); if (friendlyName) free(friendlyName); if (baseURL) free(baseURL); if (relURL) free(relURL); if (serviceId) free(serviceId); if (controlURL) free(controlURL); if (eventURL) free(eventURL); return ret; }