void prop_set_from_gvariant(GVariant *v, prop_t *p) { const GVariantType *T = g_variant_get_type(v); if(g_variant_type_equal(T, G_VARIANT_TYPE_BOOLEAN)) { prop_set_int(p, g_variant_get_boolean(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_BYTE)) { prop_set_int(p, g_variant_get_byte(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT16)) { prop_set_int(p, g_variant_get_int16(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT16)) { prop_set_int(p, g_variant_get_uint16(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT32)) { prop_set_int(p, g_variant_get_int32(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT32)) { prop_set_int(p, g_variant_get_uint32(v)); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_INT64)) { int64_t val = g_variant_get_int64(v); if(val <= INT_MAX) prop_set_int(p, val); else prop_set_float(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_UINT64)) { uint64_t val = g_variant_get_uint64(v); if(val <= INT_MAX) prop_set_int(p, val); else prop_set_float(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_STRING) || g_variant_type_equal(T, G_VARIANT_TYPE_OBJECT_PATH) || g_variant_type_equal(T, G_VARIANT_TYPE_SIGNATURE)) { const gchar *val = g_variant_get_string(v, NULL); prop_set_string(p, val); } else if(g_variant_type_equal(T, G_VARIANT_TYPE_VARDICT)) { prop_void_childs(p); prop_set_from_vardict(v, p); } else if(g_variant_type_is_array(T)) { int num = g_variant_n_children(v); prop_destroy_childs(p); for(int i = 0; i < num; i++) { prop_set_from_gvariant(g_variant_get_child_value(v, i), prop_create(p, NULL)); } } else { fprintf(stderr, "%s(): can't deal with type %s\n", __FUNCTION__, g_variant_get_type_string(v)); } }
static connman_service_t * update_service(GVariant *v, const char *path, connman_service_t *after) { connman_service_t *cs = connman_service_find(path); if(cs == NULL) { GError *err = NULL; GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START , NULL, "net.connman", path, "net.connman.Service", NULL, &err); if(proxy == NULL) { TRACE(TRACE_ERROR, "CONNMAN", "Unable to connect to service %s -- %s", path, err->message); g_error_free(err); return NULL; } cs = calloc(1, sizeof(connman_service_t)); cs->cs_refcount = 1; cs->cs_proxy = proxy; if(after == NULL) { TAILQ_INSERT_HEAD(&connman_services, cs, cs_link); } else { TAILQ_INSERT_AFTER(&connman_services, after, cs, cs_link); } connman_service_t *next = TAILQ_NEXT(cs, cs_link); cs->cs_prop = prop_create_root(path); cs->cs_path = strdup(path); cs->cs_sub = prop_subscribe(0, PROP_TAG_CALLBACK_EVENT, connman_service_event, cs, PROP_TAG_ROOT, cs->cs_prop, PROP_TAG_COURIER, connman_courier, NULL); g_signal_connect(G_OBJECT(cs->cs_proxy), "g-signal", G_CALLBACK(connman_svc_signal), cs); // Insert at correct position if(prop_set_parent_ex(cs->cs_prop, service_nodes, next ? next->cs_prop : NULL, NULL)) abort(); prop_t *m = prop_create(cs->cs_prop, "metadata"); prop_link(prop_create(m, "name"), prop_create(m, "title")); prop_set(cs->cs_prop, "type", PROP_SET_STRING, "network"); } else { // Possibly move TAILQ_REMOVE(&connman_services, cs, cs_link); if(after == NULL) { TAILQ_INSERT_HEAD(&connman_services, cs, cs_link); } else { TAILQ_INSERT_AFTER(&connman_services, after, cs, cs_link); } connman_service_t *next = TAILQ_NEXT(cs, cs_link); prop_move(cs->cs_prop, next ? next->cs_prop : NULL); } // Update metadata prop_set_from_vardict(v, prop_create(cs->cs_prop, "metadata")); GVariant *name = g_variant_lookup_value(v, "Name", NULL); const gchar *val = name ? g_variant_get_string(name, NULL) : NULL; if(val) mystrset(&cs->cs_name, val); return cs; }