static gboolean initialize_device(struct upnp_device_descriptor *device_def, struct upnp_device *result_device, const char *ip_address, unsigned short port) { int rc; char *buf; rc = UpnpInit(ip_address, port); if (UPNP_E_SUCCESS != rc) { Log_error("upnp", "UpnpInit(ip=%s, port=%d) Error: %s (%d)", ip_address, port, UpnpGetErrorMessage(rc), rc); return FALSE; } Log_info("upnp", "Registered IP=%s port=%d\n", UpnpGetServerIpAddress(), UpnpGetServerPort()); rc = UpnpEnableWebserver(TRUE); if (UPNP_E_SUCCESS != rc) { Log_error("upnp", "UpnpEnableWebServer() Error: %s (%d)", UpnpGetErrorMessage(rc), rc); return FALSE; } if (!webserver_register_callbacks()) return FALSE; rc = UpnpAddVirtualDir("/upnp"); if (UPNP_E_SUCCESS != rc) { Log_error("upnp", "UpnpAddVirtualDir() Error: %s (%d)", UpnpGetErrorMessage(rc), rc); return FALSE; } buf = upnp_create_device_desc(device_def); rc = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, buf, strlen(buf), 1, &event_handler, result_device, &(result_device->device_handle)); free(buf); if (UPNP_E_SUCCESS != rc) { Log_error("upnp", "UpnpRegisterRootDevice2() Error: %s (%d)", UpnpGetErrorMessage(rc), rc); return FALSE; } rc = UpnpSendAdvertisement(result_device->device_handle, 100); if (UPNP_E_SUCCESS != rc) { Log_error("unpp", "Error sending advertisements: %s (%d)", UpnpGetErrorMessage(rc), rc); return FALSE; } return TRUE; }
int main(int argc, char **argv) { int rc; struct upnp_device_descriptor *upnp_renderer; if (!process_cmdline(argc, argv)) { return EXIT_FAILURE; } if (show_version) { do_show_version(); exit(EXIT_SUCCESS); } if (show_connmgr_scpd) { upnp_renderer_dump_connmgr_scpd(); exit(EXIT_SUCCESS); } if (show_control_scpd) { upnp_renderer_dump_control_scpd(); exit(EXIT_SUCCESS); } if (show_transport_scpd) { upnp_renderer_dump_transport_scpd(); exit(EXIT_SUCCESS); } if (show_outputs) { output_dump_modules(); exit(EXIT_SUCCESS); } init_logging(log_file); // Now we're going to start threads etc, which means we need // to become a daemon before that. // We need to open the pid-file now because relative filenames will // break if we're becoming a daemon and cwd changes. FILE *pid_file_stream = NULL; if (pid_file) { pid_file_stream = fopen(pid_file, "w"); } if (daemon_mode) { daemon(0, 0); // TODO: check for daemon() in configure. } if (pid_file_stream) { fprintf(pid_file_stream, "%d\n", getpid()); fclose(pid_file_stream); } #if !GLIB_CHECK_VERSION(2, 32, 0) // Only older version of glib require this. if (!g_thread_get_initialized()) { g_thread_init(NULL); } #endif upnp_renderer = upnp_renderer_descriptor(friendly_name, uuid); if (upnp_renderer == NULL) { return EXIT_FAILURE; } rc = output_init(output); if (rc != 0) { Log_error("main", "ERROR: Failed to initialize Output subsystem"); return EXIT_FAILURE; } struct upnp_device *device; if (listen_port != 0 && (listen_port < 49152 || listen_port > 65535)) { // Somewhere obscure internally in libupnp, they clamp the // port to be outside of the IANA range, so at least 49152. // Instead of surprising the user by ignoring lower port // numbers, complain loudly. Log_error("main", "Parameter error: --port needs to be in " "range [49152..65535] (but was set to %d)", listen_port); return EXIT_FAILURE; } device = upnp_device_init(upnp_renderer, ip_address, listen_port); if (device == NULL) { Log_error("main", "ERROR: Failed to initialize UPnP device"); return EXIT_FAILURE; } upnp_transport_init(device); upnp_control_init(device); if (show_devicedesc) { // This can only be run after all services have been // initialized. char *buf = upnp_create_device_desc(upnp_renderer); assert(buf != NULL); fputs(buf, stdout); exit(EXIT_SUCCESS); } if (Log_info_enabled()) { upnp_transport_register_variable_listener(log_variable_change, (void*) "transport"); upnp_control_register_variable_listener(log_variable_change, (void*) "control"); } // Write both to the log (which might be disabled) and console. Log_info("main", "Ready for rendering."); fprintf(stderr, "Ready for rendering.\n"); output_loop(); // We're here, because the loop exited. Probably due to catching // a signal. Log_info("main", "Exiting."); upnp_device_shutdown(device); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int rc; struct upnp_device_descriptor *upnp_renderer; #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init (NULL); // Was necessary < glib 2.32, deprecated since. #endif if (!process_cmdline(argc, argv)) { return EXIT_FAILURE; } if (show_version) { do_show_version(); exit(EXIT_SUCCESS); } if (show_connmgr_scpd) { upnp_renderer_dump_connmgr_scpd(); exit(EXIT_SUCCESS); } if (show_control_scpd) { upnp_renderer_dump_control_scpd(); exit(EXIT_SUCCESS); } if (show_transport_scpd) { upnp_renderer_dump_transport_scpd(); exit(EXIT_SUCCESS); } if (show_outputs) { output_dump_modules(); exit(EXIT_SUCCESS); } init_logging(log_file); // Now we're going to start threads etc, which means we need // to become a daemon before that. // We need to open the pid-file now because relative filenames will // break if we're becoming a daemon and cwd changes. FILE *pid_file_stream = NULL; if (pid_file) { pid_file_stream = fopen(pid_file, "w"); } if (daemon_mode) { daemon(0, 0); // TODO: check for daemon() in configure. } if (pid_file_stream) { fprintf(pid_file_stream, "%d\n", getpid()); fclose(pid_file_stream); } if (show_devicedesc) { // This can only be run after all services have been // initialized. char *buf = upnp_create_device_desc(upnp_renderer); assert(buf != NULL); fputs(buf, stdout); exit(EXIT_SUCCESS); } struct upnp *upnp = upnp_start(friendly_name, uuid, "1234", ip_address, listen_port, output); if (upnp == NULL) { Log_error("main", "ERROR: Failed to initialize UPnP device"); return EXIT_FAILURE; } // Write both to the log (which might be disabled) and console. Log_info("main", "Ready for rendering."); fprintf(stderr, "Ready for rendering.\n"); output_loop(); // We're here, because the loop exited. Probably due to catching // a signal. Log_info("main", "Exiting."); upnp_stop(upnp); return EXIT_SUCCESS; }