static int handle_var_request(struct upnp_device *priv, struct Upnp_State_Var_Request *var_event) { struct service *srv = find_service(priv->upnp_device_descriptor, var_event->ServiceID); if (srv == NULL) { var_event->ErrCode = UPNP_SOAP_E_INVALID_ARGS; return -1; } ithread_mutex_lock(srv->service_mutex); char *result = NULL; const int var_count = VariableContainer_get_num_vars(srv->variable_container); for (int i = 0; i < var_count; ++i) { const char *name; const char *value = VariableContainer_get(srv->variable_container, i, &name); if (value && strcmp(var_event->StateVarName, name) == 0) { result = strdup(value); break; } } ithread_mutex_unlock(srv->service_mutex); var_event->CurrentVal = result; var_event->ErrCode = (result == NULL) ? UPNP_SOAP_E_INVALID_VAR : UPNP_E_SUCCESS; Log_info("upnp", "Variable request %s -> %s (%s)", var_event->StateVarName, result, var_event->ServiceID); return 0; }
void upnp_append_variable(struct action_event *event, int varnum, const char *paramname) { const char *value; struct service *service = event->service; assert(event != NULL); assert(paramname != NULL); ithread_mutex_lock(service->service_mutex); value = VariableContainer_get(service->variable_container, varnum, NULL); assert(value != NULL); // triggers on invalid variable. upnp_add_response(event, paramname, value); ithread_mutex_unlock(service->service_mutex); }
static const char *get_var(transport_variable_t varnum) { return VariableContainer_get(state_variables_, varnum, NULL, NULL); }
static int handle_subscription_request(struct upnp_device *priv, struct Upnp_Subscription_Request *sr_event) { struct service *srv; int rc; assert(priv != NULL); Log_info("upnp", "Subscription request for %s (%s)", sr_event->ServiceId, sr_event->UDN); srv = find_service(priv->upnp_device_descriptor, sr_event->ServiceId); if (srv == NULL) { Log_error("upnp", "%s: Unknown service '%s'", __FUNCTION__, sr_event->ServiceId); return -1; } int result = -1; ithread_mutex_lock(&(priv->device_mutex)); // There is really only one variable evented: LastChange const char *eventvar_names[] = { "LastChange", NULL }; const char *eventvar_values[] = { NULL, NULL }; // Build the current state of the variables as one gigantic initial // LastChange update. ithread_mutex_lock(srv->service_mutex); const int var_count = VariableContainer_get_num_vars(srv->variable_container); // TODO(hzeller): maybe use srv->last_change directly ? upnp_last_change_builder_t *builder = UPnPLastChangeBuilder_new(srv->event_xml_ns); for (int i = 0; i < var_count; ++i) { const char *name; const char *value = VariableContainer_get(srv->variable_container, i, &name); // Send over all variables except "LastChange" itself. Also all // A_ARG_TYPE variables are not evented. if (value && strcmp("LastChange", name) != 0 && strncmp("A_ARG_TYPE_", name, strlen("A_ARG_TYPE_")) != 0) { UPnPLastChangeBuilder_add(builder, name, value); } } ithread_mutex_unlock(srv->service_mutex); char *xml_value = UPnPLastChangeBuilder_to_xml(builder); Log_info("upnp", "Initial variable sync: %s", xml_value); eventvar_values[0] = xmlescape(xml_value, 0); free(xml_value); UPnPLastChangeBuilder_delete(builder); rc = UpnpAcceptSubscription(priv->device_handle, sr_event->UDN, sr_event->ServiceId, eventvar_names, eventvar_values, 1, sr_event->Sid); if (rc == UPNP_E_SUCCESS) { result = 0; } else { Log_error("upnp", "Accept Subscription Error: %s (%d)", UpnpGetErrorMessage(rc), rc); } ithread_mutex_unlock(&(priv->device_mutex)); free((char*)eventvar_values[0]); return result; }