UpnpInstanceWrapper *UpnpInstanceWrapper::get(vlc_object_t *p_obj, Upnp_FunPtr callback, SD::MediaServerList *opaque) { vlc_mutex_locker lock( &s_lock ); if ( s_instance == NULL ) { UpnpInstanceWrapper* instance = new(std::nothrow) UpnpInstanceWrapper; if ( unlikely( !instance ) ) return NULL; #ifdef UPNP_ENABLE_IPV6 char* psz_miface = var_InheritString( p_obj, "miface" ); msg_Info( p_obj, "Initializing libupnp on '%s' interface", psz_miface ); int i_res = UpnpInit2( psz_miface, 0 ); free( psz_miface ); #else /* If UpnpInit2 isnt available, initialize on first IPv4-capable interface */ int i_res = UpnpInit( 0, 0 ); #endif if( i_res != UPNP_E_SUCCESS ) { msg_Err( p_obj, "Initialization failed: %s", UpnpGetErrorMessage( i_res ) ); delete instance; return NULL; } ixmlRelaxParser( 1 ); /* Register a control point */ i_res = UpnpRegisterClient( Callback, instance, &instance->handle_ ); if( i_res != UPNP_E_SUCCESS ) { msg_Err( p_obj, "Client registration failed: %s", UpnpGetErrorMessage( i_res ) ); delete instance; return NULL; } /* libupnp does not treat a maximum content length of 0 as unlimited * until 64dedf (~ pupnp v1.6.7) and provides no sane way to discriminate * between versions */ if( (i_res = UpnpSetMaxContentLength( INT_MAX )) != UPNP_E_SUCCESS ) { msg_Err( p_obj, "Failed to set maximum content length: %s", UpnpGetErrorMessage( i_res )); delete instance; return NULL; } s_instance = instance; } s_instance->refcount_++; // This assumes a single UPNP SD instance if (callback && opaque) { assert(!s_instance->callback_ && !s_instance->opaque_); s_instance->opaque_ = opaque; s_instance->callback_ = callback; } return s_instance; }
/*! * \brief 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. * * \return TV_SUCCESS if everything went well, else TV_ERROR. */ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr, int combo) { ithread_t timer_thread; int rc; unsigned short port = 0; char *ip_address = NULL; SampleUtil_Initialize(printFunctionPtr); SampleUtil_RegisterUpdateFunction(updateFunctionPtr); ithread_mutex_init(&DeviceListMutex, 0); SampleUtil_Print("Initializing UPnP Sdk with\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); rc = UpnpInit2(ip_address, port); if (rc != UPNP_E_SUCCESS) { SampleUtil_Print("WinCEStart: UpnpInit2() Error: %d\n", rc); if (!combo) { UpnpFinish(); return TV_ERROR; } } if (!ip_address) { ip_address = UpnpGetServerIpAddress(); } if (!port) { port = UpnpGetServerPort(); } SampleUtil_Print("UPnP Initialized\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); SampleUtil_Print("Registering Control Point\n"); rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler, &ctrlpt_handle, &ctrlpt_handle); if (rc != UPNP_E_SUCCESS) { SampleUtil_Print("Error registering CP: %d\n", rc); UpnpFinish(); return TV_ERROR; } SampleUtil_Print("Control Point Registered\n"); TvCtrlPointRefresh(); /* start a timer thread */ ithread_create(&timer_thread, NULL, TvCtrlPointTimerLoop, NULL); ithread_detach(timer_thread); return TV_SUCCESS; }
int TvDeviceStart(char *ip_address, unsigned short port, const char *desc_doc_name, const char *web_dir_path, print_string pfun, int combo) { int ret = UPNP_E_SUCCESS; char desc_doc_url[DESC_URL_SIZE]; ithread_mutex_init(&TVDevMutex, NULL); SampleUtil_Initialize(pfun); SampleUtil_Print("Initializing UPnP Sdk with\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); ret = UpnpInit2(ip_address, port); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error with UpnpInit2 -- %d\n", ret); UpnpFinish(); return ret; } ip_address = UpnpGetServerIpAddress(); port = UpnpGetServerPort(); SampleUtil_Print("UPnP Initialized\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); if (!desc_doc_name) { if (combo) { desc_doc_name = "tvcombodesc.xml"; } else { desc_doc_name = "tvdevicedesc.xml"; } } if (!web_dir_path) { web_dir_path = DEFAULT_WEB_DIR; } snprintf(desc_doc_url, DESC_URL_SIZE, "http://%s:%d/%s", ip_address, port, desc_doc_name); SampleUtil_Print("Specifying the webserver root directory -- %s\n", web_dir_path); ret = UpnpSetWebServerRootDir(web_dir_path); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print ("Error specifying webserver root directory -- %s: %d\n", web_dir_path, ret); UpnpFinish(); return ret; } SampleUtil_Print("Registering the RootDevice\n" "\t with desc_doc_url: %s\n", desc_doc_url); ret = UpnpRegisterRootDevice(desc_doc_url, TvDeviceCallbackEventHandler, &device_handle, &device_handle); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error registering the rootdevice : %d\n", ret); UpnpFinish(); return ret; } else { SampleUtil_Print("RootDevice Registered\n" "Initializing State Table\n"); TvDeviceStateTableInit(desc_doc_url); SampleUtil_Print("State Table Initialized\n"); ret = UpnpSendAdvertisement(device_handle, default_advr_expire); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error sending advertisements : %d\n", ret); UpnpFinish(); return ret; } SampleUtil_Print("Advertisements Sent\n"); } return UPNP_E_SUCCESS; }
int main(int argc, char *argv[]) { UpnpDevice_Handle upnp_handle; UpnpDevice_Handle upnp_device; char *device_desc = NULL; int rv = EXIT_FAILURE; struct sigaction sa; shutdown_flag = 0; /* init options, preset some defaults and parse command line arguments */ options = options_init(); options_parse_cli(argc, argv, options); memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_handler; sa.sa_flags = 0; sigfillset(&sa.sa_mask); if (sigaction(SIGINT, &sa, NULL) < 0) { perror("sigaction"); return EXIT_FAILURE; } if (sigaction(SIGTERM, &sa, NULL) < 0) { perror("sigaction"); return EXIT_FAILURE; } #ifdef UPNP_ENABLE_IPV6 rv = UpnpInit2(options->interface, 0); #else if (options->interface) fprintf(stderr, "Warning: ignoring interface argument, not supported by libupnp.\n"); rv = UpnpInit(NULL, 0); #endif if (rv != UPNP_E_SUCCESS) { fprintf(stderr, "UpnpInit failed: %d\n", rv); return EXIT_FAILURE; } rv = UpnpEnableWebserver(1); if (rv != UPNP_E_SUCCESS) { fprintf(stderr, "Could not enabled UPnP's internal HTTP server.\n"); goto upnp_finish; } device_desc = generate_device_desc(options); if (!device_desc) { fprintf(stderr, "Could not generated the UPnP device description.\n"); goto upnp_finish; } rv = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, device_desc, strlen(device_desc), 1, upnp_callback, &upnp_device, &upnp_device); if (rv != UPNP_E_SUCCESS) { fprintf(stderr, "Failed to register UPnP root device.\n"); goto free_out; } rv = UpnpSendAdvertisement(upnp_device, UPNP_ALIVE_INTERVAL); if (rv != UPNP_E_SUCCESS) { fprintf(stderr, "Failed to announce UPnP device.\n"); goto upnp_unregister; } while (!shutdown_flag) pause(); rv = EXIT_SUCCESS; upnp_unregister: UpnpUnRegisterRootDevice(upnp_device); free_out: if (device_desc) free(device_desc); upnp_finish: UpnpFinish(); err_out: options_free(options); return rv; }
/* * Initializes UPNP instance. */ static int Open( vlc_object_t *p_this ) { int i_res; services_discovery_t *p_sd = ( services_discovery_t* )p_this; services_discovery_sys_t *p_sys = ( services_discovery_sys_t * ) calloc( 1, sizeof( services_discovery_sys_t ) ); if( !( p_sd->p_sys = p_sys ) ) return VLC_ENOMEM; #ifdef UPNP_ENABLE_IPV6 char* psz_miface; psz_miface = var_InheritString( p_sd, "miface" ); msg_Info( p_sd, "Initializing libupnp on '%s' interface", psz_miface ); i_res = UpnpInit2( psz_miface, 0 ); free( psz_miface ); #else /* If UpnpInit2 isnt available, initialize on first IPv4-capable interface */ i_res = UpnpInit( 0, 0 ); #endif if( i_res != UPNP_E_SUCCESS ) { msg_Err( p_sd, "Initialization failed: %s", UpnpGetErrorMessage( i_res ) ); free( p_sys ); return VLC_EGENERIC; } ixmlRelaxParser( 1 ); p_sys->p_server_list = new MediaServerList( p_sd ); vlc_mutex_init( &p_sys->callback_lock ); /* Register a control point */ i_res = UpnpRegisterClient( Callback, p_sd, &p_sys->client_handle ); if( i_res != UPNP_E_SUCCESS ) { msg_Err( p_sd, "Client registration failed: %s", UpnpGetErrorMessage( i_res ) ); Close( (vlc_object_t*) p_sd ); return VLC_EGENERIC; } /* Search for media servers */ i_res = UpnpSearchAsync( p_sys->client_handle, 5, MEDIA_SERVER_DEVICE_TYPE, p_sd ); if( i_res != UPNP_E_SUCCESS ) { msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) ); Close( (vlc_object_t*) p_sd ); return VLC_EGENERIC; } /* libupnp does not treat a maximum content length of 0 as unlimited * until 64dedf (~ pupnp v1.6.7) and provides no sane way to discriminate * between versions */ if( (i_res = UpnpSetMaxContentLength( INT_MAX )) != UPNP_E_SUCCESS ) { msg_Err( p_sd, "Failed to set maximum content length: %s", UpnpGetErrorMessage( i_res )); Close( (vlc_object_t*) p_sd ); return VLC_EGENERIC; } return VLC_SUCCESS; }