char *xmldoc_tostring(struct xmldoc *doc) { char *result = NULL; assert(doc != NULL); result = ixmlDocumenttoString(to_idoc(doc)); return result; }
char *xmldoc_tostring(struct xmldoc *doc) { char *result = NULL; assert(doc != NULL); #ifdef HAVE_LIBUPNP result = ixmlDocumenttoString(doc->doc); #else #ifdef HAVE_LIBXML int buffersize; xmlDocDumpFormatMemory(doc->doc, (xmlChar **)&result, &buffersize, 1); #endif #endif return result; }
} while (i < MAX_PROTO && n < size); // remove trailing "*" as we WILL add DLNA-related info, so some options to come for (i = 0; (p = Device->ProtocolCap[i]); i++) if (p[strlen(p) - 1] == '*') p[strlen(p) - 1] = '\0'; } /*----------------------------------------------------------------------------*/ void SaveConfig(char *name) { struct sMR *p; IXML_Document *doc = ixmlDocument_createDocument(); IXML_Node *root, *common; char *s; FILE *file; int i; root = XMLAddNode(doc, NULL, "squeeze2upnp", NULL); XMLAddNode(doc, root, "server", glSQServer); XMLAddNode(doc, root, "upnp_socket", gluPNPSocket); XMLAddNode(doc, root, "slimproto_stream_port", "%d", gl_slimproto_stream_port); XMLAddNode(doc, root, "base_mac", "%02x:%02x:%02x:%02x:%02x:%02x", glMac[0], glMac[1], glMac[2], glMac[3], glMac[4], glMac[5]); XMLAddNode(doc, root, "slimproto_log", level2debug(glLog.slimproto)); XMLAddNode(doc, root, "stream_log", level2debug(glLog.stream)); XMLAddNode(doc, root, "output_log", level2debug(glLog.output)); XMLAddNode(doc, root, "decode_log", level2debug(glLog.decode)); XMLAddNode(doc, root, "web_log", level2debug(glLog.web)); XMLAddNode(doc, root, "upnp_log", level2debug(glLog.upnp)); XMLAddNode(doc, root, "main_log",level2debug(glLog.main)); XMLAddNode(doc, root, "sq2mr_log", level2debug(glLog.sq2mr)); XMLAddNode(doc, root, "upnp_scan_interval", "%d", (u32_t) gluPNPScanInterval); XMLAddNode(doc, root, "upnp_scan_timeout", "%d", (u32_t) gluPNPScanTimeout); common = XMLAddNode(doc, root, "common", NULL); XMLAddNode(doc, common, "streambuf_size", "%d", (u32_t) glDeviceParam.stream_buf_size); XMLAddNode(doc, common, "output_size", "%d", (u32_t) glDeviceParam.output_buf_size); XMLAddNode(doc, common, "buffer_dir", glDeviceParam.buffer_dir); XMLAddNode(doc, common, "buffer_limit", "%d", (u32_t) glDeviceParam.buffer_limit); XMLAddNode(doc, common, "stream_length", "%d", (s32_t) glMRConfig.StreamLength); XMLAddNode(doc, common, "max_read_wait", "%d", (int) glDeviceParam.max_read_wait); XMLAddNode(doc, common, "max_GET_bytes", "%d", (s32_t) glDeviceParam.max_get_bytes); XMLAddNode(doc, common, "enabled", "%d", (int) glMRConfig.Enabled); XMLAddNode(doc, common, "process_mode", "%d", (int) glMRConfig.ProcessMode); XMLAddNode(doc, common, "codecs", glDeviceParam.codecs); XMLAddNode(doc, common, "sample_rate", "%d", (int) glDeviceParam.sample_rate); XMLAddNode(doc, common, "L24_format", "%d", (int) glDeviceParam.L24_format); XMLAddNode(doc, common, "flac_header", "%d", (int) glDeviceParam.flac_header); XMLAddNode(doc, common, "seek_after_pause", "%d", (int) glMRConfig.SeekAfterPause); XMLAddNode(doc, common, "force_volume", "%d", (int) glMRConfig.ForceVolume); XMLAddNode(doc, common, "volume_on_play", "%d", (int) glMRConfig.VolumeOnPlay); XMLAddNode(doc, common, "send_metadata", "%d", (int) glMRConfig.SendMetaData); XMLAddNode(doc, common, "volume_curve", glMRConfig.VolumeCurve); XMLAddNode(doc, common, "accept_nexturi", "%d", (int) glMRConfig.AcceptNextURI); s = ixmlDocumenttoString(doc); for (i = 0; i < MAX_RENDERERS; i++) { IXML_Node *dev_node; if (!glMRDevices[i].InUse) continue; else p = &glMRDevices[i]; dev_node = XMLAddNode(doc, root, "device", NULL); XMLAddNode(doc, dev_node, "udn", p->UDN); XMLAddNode(doc, dev_node, "name", p->FriendlyName); XMLAddNode(doc, dev_node, "mac", "%02x:%02x:%02x:%02x:%02x:%02x", p->sq_config.mac[0], p->sq_config.mac[1], p->sq_config.mac[2], p->sq_config.mac[3], p->sq_config.mac[4], p->sq_config.mac[5]); XMLAddNode(doc, dev_node, "enabled", "%d", (int) p->Config.Enabled); if (p->sq_config.stream_buf_size != glDeviceParam.stream_buf_size) XMLAddNode(doc, dev_node, "streambuf_size", "%d", (u32_t) p->sq_config.stream_buf_size); if (p->sq_config.output_buf_size != glDeviceParam.output_buf_size) XMLAddNode(doc, dev_node, "output_size", "%d", (u32_t) p->sq_config.output_buf_size); if (strcmp(p->sq_config.buffer_dir, glDeviceParam.buffer_dir)) XMLAddNode(doc, dev_node, "buffer_dir", p->sq_config.buffer_dir); if (p->sq_config.buffer_limit != glDeviceParam.buffer_limit) XMLAddNode(doc, dev_node, "buffer_limit", "%d", (u32_t) p->sq_config.buffer_limit); if (p->Config.StreamLength != glMRConfig.StreamLength) XMLAddNode(doc, dev_node, "stream_length", "%d", (s32_t) p->Config.StreamLength); if (p->sq_config.max_read_wait != glDeviceParam.max_read_wait) XMLAddNode(doc, dev_node, "max_read_wait", "%d", (int) p->sq_config.max_read_wait); if (p->sq_config.max_get_bytes != glDeviceParam.max_get_bytes) XMLAddNode(doc, dev_node, "max_GET_size", "%d", (s32_t) p->sq_config.max_get_bytes); if (p->Config.ProcessMode != glMRConfig.ProcessMode) XMLAddNode(doc, dev_node, "process_mode", "%d", (int) p->Config.ProcessMode); if (p->Config.SeekAfterPause != glMRConfig.SeekAfterPause) XMLAddNode(doc, dev_node, "seek_after_pause", "%d", (int) p->Config.SeekAfterPause); if (p->Config.ForceVolume != glMRConfig.ForceVolume) XMLAddNode(doc, dev_node, "force_volume", "%d", (int) p->Config.ForceVolume); if (p->Config.VolumeOnPlay != glMRConfig.VolumeOnPlay) XMLAddNode(doc, dev_node, "volume_on_play", "%d", (int) p->Config.VolumeOnPlay); if (p->Config.SendMetaData != glMRConfig.SendMetaData) XMLAddNode(doc, dev_node, "send_metadata", "%d", (int) p->Config.SendMetaData); if (strcmp(p->Config.VolumeCurve, glMRConfig.VolumeCurve)) XMLAddNode(doc, dev_node, "volume_curve", p->Config.VolumeCurve); if (p->Config.AcceptNextURI != glMRConfig.AcceptNextURI) XMLAddNode(doc, dev_node, "accept_nexturi", "%d", (int) p->Config.AcceptNextURI); if (strcmp(p->sq_config.codecs, glDeviceParam.codecs)) XMLAddNode(doc, dev_node, "codecs", p->sq_config.codecs); if (p->sq_config.sample_rate != glDeviceParam.sample_rate) XMLAddNode(doc, dev_node, "sample_rate", "%d", (int) p->sq_config.sample_rate); if (p->sq_config.L24_format != glDeviceParam.L24_format) XMLAddNode(doc, dev_node, "L24_format", "%d", (int) p->sq_config.L24_format); if (p->sq_config.flac_header != glDeviceParam.flac_header) XMLAddNode(doc, dev_node, "flac_header", "%d", (int) p->sq_config.flac_header); p = p->Next;
static int handle_action_request(struct upnp_device *priv, struct Upnp_Action_Request *ar_event) { struct service *event_service; struct action *event_action; event_service = find_service(priv->upnp_device_descriptor, ar_event->ServiceID); event_action = find_action(event_service, ar_event->ActionName); if (event_action == NULL) { Log_error("upnp", "Unknown action '%s' for service '%s'", ar_event->ActionName, ar_event->ServiceID); ar_event->ActionResult = NULL; ar_event->ErrCode = 401; return -1; } // We want to send the LastChange event only after the action is // finished - just to be conservative, we don't know how clients // react to get LastChange notifictions while in the middle of // issuing an action. // // So we nest the change collector level here, so that we only send the // LastChange after the action is finished (). // // Note, this is, in fact, only a preparation and not yet working as // described above: we are still in the middle // of executing the event-callback while sending the last change // event implicitly when calling UPnPLastChangeCollector_finish() below. // It would be good to enqueue the upnp_device_notify() after // the action event is finished. if (event_service->last_change) { ithread_mutex_lock(event_service->service_mutex); UPnPLastChangeCollector_start(event_service->last_change); ithread_mutex_unlock(event_service->service_mutex); } #ifdef ENABLE_ACTION_LOGGING { char *action_request_xml = NULL; if (ar_event->ActionRequest) { action_request_xml = ixmlDocumenttoString( ar_event->ActionRequest); } Log_info("upnp", "Action '%s'; Request: %s", ar_event->ActionName, action_request_xml); free(action_request_xml); } #endif if (event_action->callback) { struct action_event event; int rc; event.request = ar_event; event.status = 0; event.service = event_service; event.device = priv; rc = (event_action->callback) (&event); if (rc == 0) { ar_event->ErrCode = UPNP_E_SUCCESS; #ifdef ENABLE_ACTION_LOGGING if (ar_event->ActionResult) { char *action_result_xml = NULL; action_result_xml = ixmlDocumenttoString( ar_event->ActionResult); Log_info("upnp", "Action '%s' OK; Response %s", ar_event->ActionName, action_result_xml); free(action_result_xml); } else { Log_info("upnp", "Action '%s' OK", ar_event->ActionName); } #endif } if (ar_event->ActionResult == NULL) { ar_event->ActionResult = UpnpMakeActionResponse(ar_event->ActionName, event_service->service_type, 0, NULL); } } else { Log_error("upnp", "Got a valid action, but no handler defined (!)\n" " ErrCode: %d\n" " Socket: %d\n" " ErrStr: '%s'\n" " ActionName: '%s'\n" " DevUDN: '%s'\n" " ServiceID: '%s'\n", ar_event->ErrCode, ar_event->Socket, ar_event->ErrStr, ar_event->ActionName, ar_event->DevUDN, ar_event->ServiceID); ar_event->ErrCode = UPNP_E_SUCCESS; } if (event_service->last_change) { // See comment above. ithread_mutex_lock(event_service->service_mutex); UPnPLastChangeCollector_finish(event_service->last_change); ithread_mutex_unlock(event_service->service_mutex); } return 0; }