static mrp_json_t *alloc_reply(const char *type, int seq) { mrp_json_t *reply; reply = mrp_json_create(MRP_JSON_OBJECT); if (reply != NULL) { if (mrp_json_add_string (reply, "type", type) && mrp_json_add_integer(reply, "seq" , seq)) return reply; else mrp_json_unref(reply); } mrp_log_error("Failed to allocate WRT resource reply."); return NULL; }
static void error_reply(wrt_client_t *c, const char *type, int seq, int code, const char *fmt, ...) { mrp_json_t *reply; char errmsg[256]; va_list ap; reply = mrp_json_create(MRP_JSON_OBJECT); if (reply != NULL) { va_start(ap, fmt); vsnprintf(errmsg, sizeof(errmsg), fmt, ap); errmsg[sizeof(errmsg) - 1] = '\0'; va_end(ap); if (mrp_json_add_string (reply, "type" , type) && mrp_json_add_integer(reply, "seq" , seq ) && mrp_json_add_integer(reply, "error" , code) && mrp_json_add_string (reply, "message", errmsg)) send_message(c, reply); mrp_json_unref(reply); } }
static void query_resources(wrt_client_t *c, mrp_json_t *req) { const char *type = RESWRT_QUERY_RESOURCES; mrp_json_t *reply, *rarr, *r, *ao; const char **resources; int seq, cnt; mrp_attr_t *attrs, *a; mrp_attr_t buf[ATTRIBUTE_MAX]; uint32_t id; if (!mrp_json_get_integer(req, "seq", &seq)) { ignore_invalid_request(c, req, "missing 'seq' field"); return; } rarr = r = ao = NULL; resources = mrp_resource_definition_get_all_names(0, NULL); if (resources == NULL) { error_reply(c, type, seq, ENOMEM, "failed to query class names"); return; } reply = alloc_reply(type, seq); if (reply == NULL) return; rarr = mrp_json_create(MRP_JSON_ARRAY); if (rarr == NULL) goto fail; for (id = 0; resources[id]; id++) { r = mrp_json_create(MRP_JSON_OBJECT); if (r == NULL) goto fail; if (!mrp_json_add_string (r, "name", resources[id])) goto fail; attrs = mrp_resource_definition_read_all_attributes(id, ATTRIBUTE_MAX, buf); ao = mrp_json_create(MRP_JSON_OBJECT); if (ao == NULL) goto fail; for (a = attrs, cnt = 0; a->name; a++, cnt++) { switch (a->type) { case mqi_string: if (!mrp_json_add_string(ao, a->name, a->value.string)) goto fail; break; case mqi_integer: case mqi_unsignd: if (!mrp_json_add_integer(ao, a->name, a->value.integer)) goto fail; break; case mqi_floating: if (!mrp_json_add_double(ao, a->name, a->value.floating)) goto fail; break; default: mrp_log_error("attribute '%s' of resource '%s' " "has unknown type %d", a->name, resources[id], a->type); break; } } if (cnt > 0) mrp_json_add(r, "attributes", ao); else mrp_json_unref(ao); ao = NULL; if (!mrp_json_array_append(rarr, r)) goto fail; else r = NULL; } if (mrp_json_add_integer(reply, "status" , 0)) { mrp_json_add (reply, "resources", rarr); send_message(c, reply); } mrp_json_unref(reply); mrp_free(resources); return; fail: mrp_json_unref(reply); mrp_json_unref(rarr); mrp_json_unref(r); mrp_json_unref(ao); mrp_free(resources); }
mrp_json_t *mrp_json_add_array(mrp_json_t *o, const char *key, mrp_json_type_t type, ...) { va_list ap; void *arr; size_t cnt, i; mrp_json_t *a; va_start(ap, type); arr = va_arg(ap, void *); cnt = va_arg(ap, size_t); a = mrp_json_create(MRP_JSON_ARRAY); if (a == NULL) goto fail; switch (type) { case MRP_JSON_STRING: for (i = 0; i < cnt; i++) { if (!mrp_json_array_append_string(a, ((char **)arr)[i])) goto fail; } break; case MRP_JSON_INTEGER: for (i = 0; i < cnt; i++) { if (!mrp_json_array_append_integer(a, ((int *)arr)[i])) goto fail; } break; case MRP_JSON_DOUBLE: for (i = 0; i < cnt; i++) { if (!mrp_json_array_append_double(a, ((double *)arr)[i])) goto fail; } break; case MRP_JSON_BOOLEAN: for (i = 0; i < cnt; i++) { if (!mrp_json_array_append_boolean(a, ((bool *)arr)[i])) goto fail; } break; default: goto fail; } va_end(ap); mrp_json_add(o, key, a); return a; fail: va_end(ap); mrp_json_unref(a); return NULL; }