/******************** * fact_field_value ********************/ static char * fact_field_value(OhmFact *fact, char *field, char *buf, size_t size) { GValue *value, gstr = {0,}; if ((value = ohm_fact_get(fact, field)) == NULL) return NULL; if (G_VALUE_HOLDS_STRING(value)) { snprintf(buf, size, (char *)g_value_get_string(value)); return buf; } if (!g_value_type_transformable(G_VALUE_TYPE(value), G_TYPE_STRING)) return NULL; g_value_init(&gstr, G_TYPE_STRING); if (!g_value_transform(value, &gstr)) return NULL; snprintf(buf, size, "%s", g_value_get_string(&gstr)); g_value_unset(&gstr); return buf; }
static int profile_save_state(OhmFact *fact) { FILE *fp; GSList *l; GQuark q; const gchar *key; GValue *value; int err; if ((fp = fopen(PROFILE_SAVE_PATH, "w")) == NULL) return errno; for (l = ohm_fact_get_fields(fact); l != NULL; l = l->next) { q = (GQuark)GPOINTER_TO_INT(l->data); key = g_quark_to_string(q); value = ohm_fact_get(fact, key); if ((err = save_field(fp, key, value)) != 0) { fclose(fp); unlink(PROFILE_SAVE_PATH); return err; } } fflush(fp); /* fdatasync(fileno(fp)); */ fclose(fp); OHM_INFO("Profile state saved."); return 0; }
/* return TRUE if really disconnected, FALSE otherwise */ static gboolean disconnect_device(OhmFact *fact, const gchar *type) { GValue *gval; OHM_DEBUG(DBG_BT, "Disconnecting fact %p profile %s", fact, type); if (!fact) { return FALSE; } gval = ohm_fact_get(fact, type); if (gval && G_VALUE_TYPE(gval) == G_TYPE_STRING) { OHM_DEBUG(DBG_BT, "%s profile to be disconnected", type); dres_accessory_request(type, -1, 0); if (strcmp(type, BT_TYPE_HSP) == 0) { /* HSP device goes to disconnected state. We need to forget the * bluetooth override state. */ run_policy_hook("bthsp_disconnect", 0, NULL); } return TRUE; } OHM_DEBUG(DBG_BT, "Could not get type information from the fact"); return FALSE; }
static gboolean bt_any_to_disconnected(const gchar *type, const gchar *path, enum bt_state prev_state, enum bt_state new_state) { (void) new_state; OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *bt_connected = bt_get_connected(path); GValue *gval = NULL; OHM_DEBUG(DBG_BT, "running dres with type %s and setting device off", type); if (!bt_connected) return FALSE; if (prev_state == BT_STATE_NONE || prev_state == BT_STATE_CONNECTING || prev_state == BT_STATE_DISCONNECTED || !disconnect_device(bt_connected, type)) { OHM_DEBUG(DBG_BT, "there was nothing to disconnect"); } /* see if the other profiles are also disconnected: if yes, * remove the fact */ if (strcmp(type, BT_TYPE_A2DP) == 0) { gval = ohm_fact_get(bt_connected, BT_TYPE_HSP); } else { gval = ohm_fact_get(bt_connected, BT_TYPE_A2DP); } if ((gval == NULL || G_VALUE_TYPE(gval) != G_TYPE_STRING || strcmp(g_value_get_string(gval), BT_STATE_DISCONNECTED_S) == 0)) { ohm_fact_store_remove(fs, bt_connected); g_object_unref(bt_connected); bt_connected = NULL; } /* this is now ran in disconnect_device */ /* dres_accessory_request(type, -1, 0); */ return TRUE; }
static void profile_value_change(const char *profile, const char *key, const char *val, const char *type, void *dummy) { /* A value has changed in the currently active value */ OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *fact = NULL; /* get the previous fact with the profile name */ GSList *list = ohm_fact_store_get_facts_by_name(fs, FACTSTORE_PROFILE); (void) profile; (void) type; (void) dummy; OHM_DEBUG(DBG_PROFILE, "profile value change: '%s', '%s'", key, val); if (g_slist_length(list) != 1) { OHM_DEBUG(DBG_PROFILE, "Error: there isn't a unique profile fact"); return; } fact = list->data; if (fact && key) { GValue *gval = NULL; gval = ohm_fact_get(fact, key); if (gval && G_VALUE_TYPE(gval) == G_TYPE_STRING && strcmp(val, g_value_get_string(gval)) == 0) { /* the value is already there, no need to trigger an update */ return; } gval = NULL; /* change the value */ if (val) gval = ohm_value_from_string(val); OHM_DEBUG(DBG_PROFILE, "changing key %s with new value '%s'", key, val); ohm_fact_set(fact, key, gval); } else { OHM_DEBUG(DBG_PROFILE, "Error, no facts or empty key"); } return; }
static gboolean hsp_status_defined(OhmFact *fact) { GValue *gval; if (!fact) return FALSE; gval = ohm_fact_get(fact, "hsp"); if (gval == NULL) return FALSE; return TRUE; }
static gboolean get_status(OhmFact *fact, const gchar *hfp_or_hsp) { GValue *gval; if (!fact) return FALSE; gval = ohm_fact_get(fact, hfp_or_hsp); if (gval && G_VALUE_TYPE(gval) == G_TYPE_INT && g_value_get_int(gval) == 1) return TRUE; return FALSE; }
/******************** * fact_field_term ********************/ static int fact_field_term(OhmFact *fact, char *field, term_t term) { GValue *value; int i; double d; char *s; if ((value = ohm_fact_get(fact, field)) == NULL) return FALSE; switch (G_VALUE_TYPE(value)) { case G_TYPE_INT: i = g_value_get_int(value); PL_put_integer(term, i); break; case G_TYPE_UINT: i = g_value_get_uint(value); PL_put_integer(term, i); break; case G_TYPE_LONG: i = g_value_get_long(value); PL_put_integer(term, i); break; case G_TYPE_ULONG: i = g_value_get_ulong(value); PL_put_integer(term, i); break; case G_TYPE_DOUBLE: d = g_value_get_double(value); PL_put_float(term, d); break; case G_TYPE_FLOAT: d = 1.0 * g_value_get_float(value); PL_put_float(term, d); break; case G_TYPE_STRING: s = (char *)g_value_get_string(value); PL_put_atom_chars(term, s); break; default: return FALSE; } return TRUE; }
/* get the fact representing the connected device */ static OhmFact * bt_get_connected(const gchar *path) { OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *ret = NULL; GSList *e, *list = ohm_fact_store_get_facts_by_name(fs, BT_DEVICE); for (e = list; e != NULL; e = g_slist_next(e)) { OhmFact *tmp = (OhmFact *) e->data; GValue *gval = ohm_fact_get(tmp, "bt_path"); if (gval && G_VALUE_TYPE(gval) == G_TYPE_STRING && strcmp(path, g_value_get_string(gval)) == 0) { ret = e->data; break; } } return ret; }
static int get_args(OhmFact *fact, argdsc_t *argdsc, void *args) { argdsc_t *ad; GValue *gv; void *vptr; if (fact == NULL) return FALSE; for (ad = argdsc; ad->type != argtype_invalid; ad++) { vptr = args + ad->offs; if ((gv = ohm_fact_get(fact, ad->name)) == NULL) continue; #if 0 OHM_DEBUG(DBG_ACTION, "Got value type %d", G_VALUE_TYPE(gv)); #endif switch (ad->type) { case argtype_string: if (G_VALUE_TYPE(gv) == G_TYPE_STRING) *(const char **)vptr = g_value_get_string(gv); break; case argtype_integer: if (G_VALUE_TYPE(gv) == G_TYPE_INT) *(int *)vptr = g_value_get_int(gv); break; case argtype_unsigned: if (G_VALUE_TYPE(gv) == G_TYPE_ULONG) *(unsigned long *)vptr = g_value_get_ulong(gv); break; default: break; } } return TRUE; }
static void test_fact_store_transaction_push_and_commit (void) { OhmFactStore* fs; OhmFactStoreView* v; OhmFactStoreView* v2; OhmFactStoreView* tpv; OhmPattern* _tmp0; OhmPattern* _tmp1; OhmFact* fact; GValue* val; fs = ohm_fact_store_new (); v = ohm_fact_store_new_view (fs, NULL); v2 = ohm_fact_store_new_view (fs, NULL); tpv = ohm_fact_store_new_transparent_view (fs, NULL); _tmp0 = NULL; ohm_fact_store_view_add (v, OHM_STRUCTURE ((_tmp0 = ohm_pattern_new ("org.test.match")))); (_tmp0 == NULL ? NULL : (_tmp0 = (g_object_unref (_tmp0), NULL))); _tmp1 = NULL; ohm_fact_store_view_add (v2, OHM_STRUCTURE ((_tmp1 = ohm_pattern_new ("org.freedesktop.hello")))); (_tmp1 == NULL ? NULL : (_tmp1 = (g_object_unref (_tmp1), NULL))); _tmp1 = NULL; ohm_fact_store_view_add (tpv, OHM_STRUCTURE ((_tmp1 = ohm_pattern_new ("org.test.match")))); (_tmp1 == NULL ? NULL : (_tmp1 = (g_object_unref (_tmp1), NULL))); _tmp1 = NULL; /* insertion*/ ohm_fact_store_transaction_push (fs); { fact = ohm_fact_new ("org.test.match"); ohm_fact_set (fact, "field", ohm_value_from_int (42)); ohm_fact_store_insert (fs, fact); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 0); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 1); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 1); /* and from the fact store*/ g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); ohm_fact_set (fact, "field", ohm_value_from_int (43)); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 2); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 2); ohm_fact_store_transaction_push (fs); { ohm_fact_store_remove (fs, fact); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 0); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 2); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 3); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 3); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 3); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 0); /* update*/ fact = ohm_fact_new ("org.test.match"); ohm_fact_set (fact, "field", ohm_value_from_int (41)); ohm_fact_store_insert (fs, fact); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 4); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 4); ohm_fact_store_transaction_push (fs); { GValue* val; val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 41); ohm_fact_set (fact, "field", ohm_value_from_int (42)); val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 42); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 4); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 5); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 5); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 5); val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 42); (fs == NULL ? NULL : (fs = (g_object_unref (fs), NULL))); (v == NULL ? NULL : (v = (g_object_unref (v), NULL))); (v2 == NULL ? NULL : (v2 = (g_object_unref (v2), NULL))); (fact == NULL ? NULL : (fact = (g_object_unref (fact), NULL))); }
static int is_spurious_event(char *device, int driver, int connected) { /* * Filter out obviously spurious/duplicate events. Spurious events are * events that obviously do not represent any state change (eg. getting * a connected=0 event while already in disconnected state). */ GSList *list; OhmFact *fact; GValue *gval; int val, dmatch, cmatch, spurious = FALSE; OhmFactStore *store; store = ohm_fact_store_get_fact_store(); list = ohm_fact_store_get_facts_by_name(store, FACT_DEVICE_ACCESSIBLE); for ( ; list ; list = list->next) { fact = (OhmFact *)list->data; gval = ohm_fact_get(fact, "name"); if (!gval || G_VALUE_TYPE(gval) != G_TYPE_STRING) continue; if (strcmp(g_value_get_string(gval), device)) continue; if (driver != -1 && (gval = ohm_fact_get(fact, "driver")) != NULL) { switch (G_VALUE_TYPE(gval)) { case G_TYPE_INT: val = g_value_get_int(gval); break; case G_TYPE_UINT: val = g_value_get_uint(gval); break; case G_TYPE_LONG: val = g_value_get_long(gval); break; case G_TYPE_ULONG: val = g_value_get_ulong(gval); break; default: val = driver; /* ignored (ie. match) */ } dmatch = (val == driver); } else dmatch = TRUE; if (connected != -1 && (gval=ohm_fact_get(fact,"connected")) != NULL) { switch (G_VALUE_TYPE(gval)) { case G_TYPE_INT: val = g_value_get_int(gval); break; case G_TYPE_UINT: val = g_value_get_uint(gval); break; case G_TYPE_LONG: val = g_value_get_long(gval); break; case G_TYPE_ULONG: val = g_value_get_ulong(gval); break; default: val = connected; /* ignored (ie. match) */ } cmatch = (val == connected); } else cmatch = TRUE; spurious = dmatch && cmatch; /* no change is a spurious event */ break; } OHM_DEBUG(DBG_INFO, "%s, driver: %d, connected: %d is %sa spurious event", device, driver, connected, spurious ? "" : "not "); return spurious; }
static void get_properties_update_fact_cb (DBusPendingCall *pending, void *user_data) { DBusMessage *reply = NULL; DBusMessageIter iter, array_iter, dict_iter, variant_iter, uuid_iter; gchar **dbus_data = user_data; gchar *path = dbus_data[0]; gchar *interface = dbus_data[1]; gboolean is_hfp = FALSE, is_hsp = FALSE; OhmFact *bt_connected = NULL; g_free(dbus_data); if (pending == NULL) goto error; reply = dbus_pending_call_steal_reply(pending); dbus_pending_call_unref(pending); pending = NULL; if (reply == NULL) { goto error; } if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { goto error; } dbus_message_iter_init(reply, &iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { goto error; } dbus_message_iter_recurse(&iter, &array_iter); while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_DICT_ENTRY) { /* the arg type will be DBUS_TYPE_INVALID at the end of the * array */ gchar *key = NULL; int type; /* process the dicts */ dbus_message_iter_recurse(&array_iter, &dict_iter); /* key must be string */ if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { goto error; } dbus_message_iter_get_basic(&dict_iter, &key); /* go on to the value */ dbus_message_iter_next(&dict_iter); dbus_message_iter_recurse(&dict_iter, &variant_iter); type = dbus_message_iter_get_arg_type(&variant_iter); if (strcmp(key, "UUIDs") == 0) { if (type == DBUS_TYPE_ARRAY) { dbus_message_iter_recurse(&variant_iter, &uuid_iter); while (dbus_message_iter_get_arg_type(&uuid_iter) == DBUS_TYPE_STRING) { gchar *uuid = NULL; dbus_message_iter_get_basic(&uuid_iter, &uuid); if (!uuid) break; else if (strcmp(uuid, HFP_UUID) == 0) { is_hfp = TRUE; } else if (strcmp(uuid, HSP_UUID) == 0) { is_hsp = TRUE; } dbus_message_iter_next(&uuid_iter); } } else { OHM_DEBUG(DBG_BT, "Error: type '%u'\n", dbus_message_iter_get_arg_type(&dict_iter)); } } dbus_message_iter_next(&array_iter); } /* get the BT fact */ OHM_DEBUG(DBG_BT, "Device %s %s HFP support", path, is_hfp ? "has" : "has not"); OHM_DEBUG(DBG_BT, "Device %s %s HSP support", path, is_hsp ? "has" : "has not"); if ((bt_connected = bt_get_connected(path)) != NULL) { GValue *gval_state = ohm_fact_get(bt_connected, BT_TYPE_HSP); GValue *gval_prev_state = ohm_fact_get(bt_connected, "bthsp_prev_state"); const gchar *state = NULL, *prev_state = NULL; gboolean run_dres; define_hfp_status(bt_connected, is_hfp); define_hsp_status(bt_connected, is_hsp); if (gval_state != NULL && G_VALUE_TYPE(gval_state) == G_TYPE_STRING) { state = g_value_get_string(gval_state); } if (gval_prev_state != NULL && G_VALUE_TYPE(gval_prev_state) == G_TYPE_STRING) { prev_state = g_value_get_string(gval_prev_state); } OHM_DEBUG(DBG_BT, "running state transition from %s to %s from HFP/HSP status cb", prev_state ? prev_state : "NULL", state ? state : "NULL"); run_dres = bt_state_transition(BT_TYPE_HSP, path, map_to_state(prev_state), map_to_state(state)); dres_all(); } error: if (reply) dbus_message_unref (reply); g_free(path); g_free(interface); return; }
static gboolean bt_state_changed(const gchar *type, const gchar *path, const gchar *state) { OhmFactStore *fs = ohm_fact_store_get_fact_store(); gchar *prev_state = NULL; OhmFact *bt_connected = bt_get_connected(path); gboolean run_dres = FALSE; GValue *gval_state; gboolean bt_audio_connected = FALSE; //OHM_DEBUG(DBG_BT, "type: %s, state: %s", type, state); if (strcmp(type, BT_TYPE_AUDIO) == 0) { if (bt_connected) { gval_state = ohm_value_from_string(state); ohm_fact_set(bt_connected, type, gval_state); } if (strcmp(state, BT_STATE_CONNECTED_S) == 0) { /* Get a2dp and hsp status if AudioSink or Headset changed to * connected or playing before Audio state changed to connected. */ get_properties(path, BT_INTERFACE_A2DP, get_properties_cb); get_properties(path, BT_INTERFACE_HSP, get_properties_cb); } return TRUE; } if(bt_connected) { gval_state = ohm_fact_get(bt_connected, BT_TYPE_AUDIO); if (gval_state != NULL && G_VALUE_TYPE(gval_state) == G_TYPE_STRING) { bt_audio_connected = strcmp(g_value_get_string(gval_state), BT_STATE_CONNECTED_S) == 0 ? TRUE : FALSE; } } /* In pulseaudio module-bluetooth-device is loaded after BT Audio interface * gets connected. Need to wait until then to be able to route audio. */ if ((strcmp(state, BT_STATE_CONNECTED_S) == 0 || strcmp(state, BT_STATE_PLAYING_S) == 0) && !bt_audio_connected) { OHM_DEBUG(DBG_BT, "type: %s, state: %s transition not allowed.", type, state); return TRUE; } /* Type is either HSP or A2DP. HFP is distinguished from HSW by a * flag in the BT fact. */ if (!bt_connected) { GValue *gval = NULL; /* first time: create a new fact */ /* TODO: check that this doesn't leak memory! */ bt_connected = ohm_fact_new(BT_DEVICE); /* TODO: set the bthsp and bta2dp fields to "na" or "unknown" * values */ if (bt_connected == NULL) { OHM_DEBUG(DBG_BT, "could not create the BT fact!"); goto error; } else { /* add the object path to the bluetooth fact in order to * remember the device */ gval = ohm_value_from_string(path); ohm_fact_set(bt_connected, "bt_path", gval); ohm_fact_store_insert(fs, bt_connected); } } else { gval_state = ohm_fact_get(bt_connected, type); if (gval_state != NULL && G_VALUE_TYPE(gval_state) == G_TYPE_STRING) { /* copy the value so that we can overwrite the one in the * fact */ prev_state = g_strdup(g_value_get_string(gval_state)); } } OHM_DEBUG(DBG_BT, "type: %s, prev_state: %s, state: %s", type, prev_state ? prev_state : "NULL", state); gval_state = ohm_value_from_string(state); ohm_fact_set(bt_connected, type, gval_state); if (strcmp(type, BT_TYPE_HSP) == 0) { /* check if we already have the information about the accurate * mono profile status */ if (!hfp_status_defined(bt_connected) || !hsp_status_defined(bt_connected)) { /* We don't know the HFP or HSP status yet. Process the dres * only after we know the status. */ OHM_DEBUG(DBG_BT, "querying HFP/HSP state for device %s", path); if (prev_state) { GValue *gval_prev_state = ohm_value_from_string(prev_state); ohm_fact_set(bt_connected, "bthsp_prev_state", gval_prev_state); } if (get_properties(path, BT_INTERFACE_DEVICE, get_properties_update_fact_cb)) { /* continue processing in the callback */ goto end; } } } OHM_DEBUG(DBG_BT, "running state transition from %s to %s from BT status_changed cb", prev_state ? prev_state : "NULL", state ? state : "NULL"); if (prev_state && state && strcmp(prev_state, BT_STATE_CONNECTING_S) == 0 && strcmp(state, BT_STATE_PLAYING_S) == 0) { /* When state transition is not allowed state might change to playing. * In this case state change is from connecting to playing, and connected state * transition is not done. We need manually do it first */ run_dres = bt_state_transition(type, path, map_to_state(prev_state), map_to_state(BT_STATE_CONNECTED_S)); if (run_dres) dres_all(); } run_dres = bt_state_transition(type, path, map_to_state(prev_state), map_to_state(state)); if (run_dres) dres_all(); end: g_free(prev_state); return TRUE; error: return FALSE; }
static int get_field(OhmFact *fact, fsif_fldtype_t type,char *name,void *vptr) { GValue *gv; if (!fact || !name || !(gv = ohm_fact_get(fact, name))) { OHM_ERROR("resource: [%s] Cant find field %s", __FUNCTION__, name?name:"<null>"); goto return_empty_value; } switch (type) { case fldtype_string: if (G_VALUE_TYPE(gv) != G_TYPE_STRING) goto type_mismatch; else *(const char **)vptr = g_value_get_string(gv); break; case fldtype_integer: switch (G_VALUE_TYPE(gv)) { case G_TYPE_LONG: *(long *)vptr = g_value_get_long(gv); break; case G_TYPE_INT: *(long *)vptr = g_value_get_int(gv); break; default: goto type_mismatch; } break; case fldtype_unsignd: if (G_VALUE_TYPE(gv) != G_TYPE_ULONG) goto type_mismatch; else *(unsigned long *)vptr = g_value_get_ulong(gv); break; case fldtype_floating: if (G_VALUE_TYPE(gv) != G_TYPE_DOUBLE) goto type_mismatch; else *(double *)vptr = g_value_get_double(gv); break; case fldtype_time: if (G_VALUE_TYPE(gv) != G_TYPE_UINT64) goto type_mismatch; else *(time_t *)vptr = g_value_get_uint64(gv); break; default: break; } return TRUE; type_mismatch: OHM_ERROR("resource: [%s] Type mismatch when fetching field '%s'", __FUNCTION__,name); return_empty_value: switch (type) { case fldtype_string: *(char **)vptr = NULL; break; case fldtype_integer: *(long *)vptr = 0; break; case fldtype_unsignd: *(unsigned long *)vptr = 0; break; case fldtype_floating: *(double *)vptr = 0.0; break; case fldtype_time: *(unsigned long long *)vptr = 0ULL; break; default: break; } return FALSE; }