static gboolean cf_condition_enabled_property(struct ofono_call_forwarding *cf, const char *property, int *out_type, int *out_cls) { int i; int j; int len; const char *prefix; for (i = 1; i <= BEARER_CLASS_VOICE; i = i << 1) { prefix = bearer_class_to_string(i); len = strlen(prefix); if (strncmp(property, prefix, len)) continue; /* * We check the 4 call forwarding types, e.g. * unconditional, busy, no reply, not reachable */ for (j = 0; j < 4; j++) if (!strcmp(property+len, cf_type_lut[j])) { *out_type = j; *out_cls = i; return TRUE; } } return FALSE; }
static inline void emit_barring_changed(struct ofono_call_barring *cb, int start, int end, const char *type, int cls) { DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(cb->atom); char property_name[64]; const char *value; int i; int j; for (i = start; i <= end; i++) if (cb->cur_locks[i] & cls) break; for (j = start; j <= end; j++) if (cb->new_locks[j] & cls) break; if (i == j) return; if (j > end) value = "disabled"; else value = cb_locks[j].value; snprintf(property_name, sizeof(property_name), "%s%s", bearer_class_to_string(cls), type); ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_BARRING_INTERFACE, property_name, DBUS_TYPE_STRING, &value); }
static inline void property_append_cf_condition(DBusMessageIter *dict, int cls, const char *postfix, const char *value, dbus_uint16_t timeout) { char attr[64]; char tattr[64]; int addt = !strcmp(postfix, "NoReply"); snprintf(attr, sizeof(attr), "%s%s", bearer_class_to_string(cls), postfix); if (addt) snprintf(tattr, sizeof(tattr), "%s%sTimeout", bearer_class_to_string(cls), postfix); ofono_dbus_dict_append(dict, attr, DBUS_TYPE_STRING, &value); if (addt) ofono_dbus_dict_append(dict, tattr, DBUS_TYPE_UINT16, &timeout); }
static void cb_ss_property_append(struct ofono_call_barring *cb, DBusMessageIter *dict, int lock, int mask) { int i; char property_name[64]; const char *strvalue; for (i = 1; i <= BEARER_CLASS_PAD; i = i << 1) { if (!(mask & i)) continue; strvalue = (cb->new_locks[lock] & i) ? "enabled" : "disabled"; snprintf(property_name, sizeof(property_name), "%s%s", bearer_class_to_string(i), cb_locks[lock].name); ofono_dbus_dict_append(dict, property_name, DBUS_TYPE_STRING, &strvalue); } }
static gboolean cf_condition_timeout_property(const char *property, int *out_cls) { int i; int len; const char *prefix; for (i = 1; i <= BEARER_CLASS_VOICE; i = i << 1) { prefix = bearer_class_to_string(i); len = strlen(prefix); if (strncmp(property, prefix, len)) continue; if (!strcmp(property+len, "NoReplyTimeout")) { *out_cls = i; return TRUE; } } return FALSE; }
static void set_new_cond_list(struct ofono_call_forwarding *cf, int type, GSList *list) { GSList *old = cf->cf_conditions[type]; DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(cf->atom); GSList *l; GSList *o; struct ofono_call_forwarding_condition *lc; struct ofono_call_forwarding_condition *oc; const char *number; dbus_uint16_t timeout; char attr[64]; char tattr[64]; gboolean update_sim = FALSE; gboolean old_cfu; gboolean new_cfu; if ((cf->flags & CALL_FORWARDING_FLAG_CPHS_CFF) || cf->cfis_record_id > 0) old_cfu = is_cfu_enabled(cf, NULL); else old_cfu = FALSE; for (l = list; l; l = l->next) { lc = l->data; /* * New condition lists might have attributes we don't care about * triggered by e.g. ss control magic strings just skip them * here. For now we only support Voice, although Fax & all Data * basic services are applicable as well. */ if (lc->cls > BEARER_CLASS_VOICE) continue; timeout = lc->time; number = phone_number_to_string(&lc->phone_number); snprintf(attr, sizeof(attr), "%s%s", bearer_class_to_string(lc->cls), cf_type_lut[type]); if (type == CALL_FORWARDING_TYPE_NO_REPLY) snprintf(tattr, sizeof(tattr), "%sTimeout", attr); o = g_slist_find_custom(old, GINT_TO_POINTER(lc->cls), cf_condition_find_with_cls); if (o) { /* On the old list, must be active */ oc = o->data; if (oc->phone_number.type != lc->phone_number.type || strcmp(oc->phone_number.number, lc->phone_number.number)) { ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, attr, DBUS_TYPE_STRING, &number); if (type == CALL_FORWARDING_TYPE_UNCONDITIONAL) update_sim = TRUE; } if (type == CALL_FORWARDING_TYPE_NO_REPLY && oc->time != lc->time) ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, tattr, DBUS_TYPE_UINT16, &timeout); /* Remove from the old list */ g_free(o->data); old = g_slist_remove(old, o->data); } else { number = phone_number_to_string(&lc->phone_number); ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, attr, DBUS_TYPE_STRING, &number); if (type == CALL_FORWARDING_TYPE_UNCONDITIONAL) update_sim = TRUE; if (type == CALL_FORWARDING_TYPE_NO_REPLY && lc->time != DEFAULT_NO_REPLY_TIMEOUT) ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, tattr, DBUS_TYPE_UINT16, &timeout); } } timeout = DEFAULT_NO_REPLY_TIMEOUT; number = ""; for (o = old; o; o = o->next) { oc = o->data; /* * For now we only support Voice, although Fax & all Data * basic services are applicable as well. */ if (oc->cls > BEARER_CLASS_VOICE) continue; snprintf(attr, sizeof(attr), "%s%s", bearer_class_to_string(oc->cls), cf_type_lut[type]); if (type == CALL_FORWARDING_TYPE_NO_REPLY) snprintf(tattr, sizeof(tattr), "%sTimeout", attr); ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, attr, DBUS_TYPE_STRING, &number); if (type == CALL_FORWARDING_TYPE_UNCONDITIONAL) update_sim = TRUE; if (type == CALL_FORWARDING_TYPE_NO_REPLY && oc->time != DEFAULT_NO_REPLY_TIMEOUT) ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, tattr, DBUS_TYPE_UINT16, &timeout); } cf_list_clear(old); cf->cf_conditions[type] = list; if (update_sim == TRUE) sim_set_cf_indicator(cf); if ((cf->flags & CALL_FORWARDING_FLAG_CPHS_CFF) || cf->cfis_record_id > 0) new_cfu = is_cfu_enabled(cf, NULL); else new_cfu = FALSE; if (new_cfu != old_cfu) { ofono_bool_t status = new_cfu; ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, "ForwardingFlagOnSim", DBUS_TYPE_BOOLEAN, &status); } }
static void sim_cfis_read_cb(int ok, int total_length, int record, const unsigned char *data, int record_length, void *userdata) { struct ofono_call_forwarding *cf = userdata; DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(cf->atom); if (!ok || record_length < 16 || total_length < record_length) { cf->cfis_record_id = 0; return; } /* * Multiple Subscriber Profile number which can have values 1-4. * Profile id 1 is assumed as the current profile. */ if (data[0] != 1) return; cf->cfis_record_id = record; if (cf->flags & CALL_FORWARDING_FLAG_CACHED) return; /* * For now we only support Voice, although Fax & all Data * basic services are applicable as well. */ if (data[1] & 0x01) { int ton_npi; int number_len; const char *number; char attr[64]; struct ofono_call_forwarding_condition *cond; dbus_bool_t status; number_len = data[2]; ton_npi = data[3]; if (number_len > 11 || ton_npi == 0xff) return; cond = g_try_new0(struct ofono_call_forwarding_condition, 1); if (cond == NULL) return; status = TRUE; cond->status = TRUE; cond->cls = BEARER_CLASS_VOICE; cond->time = 0; cond->phone_number.type = ton_npi; sim_extract_bcd_number(data + 4, number_len - 1, cond->phone_number.number); number = phone_number_to_string(&cond->phone_number); snprintf(attr, sizeof(attr), "%s%s", bearer_class_to_string(BEARER_CLASS_VOICE), cf_type_lut[CALL_FORWARDING_TYPE_UNCONDITIONAL]); cf->cf_conditions[CALL_FORWARDING_TYPE_UNCONDITIONAL] = g_slist_append(NULL, cond); ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, attr, DBUS_TYPE_STRING, &number); ofono_dbus_signal_property_changed(conn, path, OFONO_CALL_FORWARDING_INTERFACE, "ForwardingFlagOnSim", DBUS_TYPE_BOOLEAN, &status); }