static gboolean cb_ss_control(int type, const char *sc, const char *sia, const char *sib, const char *sic, const char *dn, DBusMessage *msg, void *data) { struct ofono_call_barring *cb = data; DBusConnection *conn = ofono_dbus_get_connection(); int cls = BEARER_CLASS_DEFAULT; const char *fac; DBusMessage *reply; void *operation = NULL; int i; if (cb->pending) { reply = __ofono_error_busy(msg); g_dbus_send_message(conn, reply); return TRUE; } DBG("Received call barring ss control request"); DBG("type: %d, sc: %s, sia: %s, sib: %s, sic: %s, dn: %s", type, sc, sia, sib, sic, dn); fac = cb_ss_service_to_fac(sc); if (!fac) return FALSE; cb_set_query_bounds(cb, fac, type == SS_CONTROL_TYPE_QUERY); i = 0; while (cb_locks[i].name && strcmp(cb_locks[i].fac, fac)) i++; cb->ss_req_lock = i; if (strlen(sic) > 0) goto bad_format; if (strlen(dn) > 0) goto bad_format; if (type != SS_CONTROL_TYPE_QUERY && !is_valid_pin(sia, PIN_TYPE_NET)) goto bad_format; switch (type) { case SS_CONTROL_TYPE_ACTIVATION: case SS_CONTROL_TYPE_DEACTIVATION: case SS_CONTROL_TYPE_REGISTRATION: case SS_CONTROL_TYPE_ERASURE: operation = cb->driver->set; break; case SS_CONTROL_TYPE_QUERY: operation = cb->driver->query; break; default: break; } if (!operation) { reply = __ofono_error_not_implemented(msg); g_dbus_send_message(conn, reply); return TRUE; } /* According to 27.007, AG, AC and AB only work with mode = 0 * We support query by querying all relevant types, since we must * do this for the deactivation case anyway */ if ((!strcmp(fac, "AG") || !strcmp(fac, "AC") || !strcmp(fac, "AB")) && (type == SS_CONTROL_TYPE_ACTIVATION || type == SS_CONTROL_TYPE_REGISTRATION)) goto bad_format; if (strlen(sib) > 0) { long service_code; char *end; service_code = strtoul(sib, &end, 10); if (end == sib || *end != '\0') goto bad_format; cls = mmi_service_code_to_bearer_class(service_code); if (cls == 0) goto bad_format; } cb->ss_req_cls = cls; cb->pending = dbus_message_ref(msg); switch (type) { case SS_CONTROL_TYPE_ACTIVATION: case SS_CONTROL_TYPE_REGISTRATION: cb->ss_req_type = SS_CONTROL_TYPE_ACTIVATION; cb->driver->set(cb, fac, 1, sia, cls, cb_ss_set_lock_callback, cb); break; case SS_CONTROL_TYPE_ERASURE: case SS_CONTROL_TYPE_DEACTIVATION: cb->ss_req_type = SS_CONTROL_TYPE_DEACTIVATION; cb->driver->set(cb, fac, 0, sia, cls, cb_ss_set_lock_callback, cb); break; case SS_CONTROL_TYPE_QUERY: cb->ss_req_type = SS_CONTROL_TYPE_QUERY; cb_ss_query_next_lock(cb); break; } return TRUE; bad_format: reply = __ofono_error_invalid_format(msg); g_dbus_send_message(conn, reply); return TRUE; }
static gboolean cf_ss_control(int type, const char *sc, const char *sia, const char *sib, const char *sic, const char *dn, DBusMessage *msg, void *data) { struct ofono_call_forwarding *cf = data; DBusConnection *conn = ofono_dbus_get_connection(); int cls = BEARER_CLASS_SS_DEFAULT; int timeout = DEFAULT_NO_REPLY_TIMEOUT; int cf_type; DBusMessage *reply; struct ofono_phone_number ph; void *operation = NULL; /* Before we do anything, make sure we're actually initialized */ if (cf == NULL) return FALSE; if (__ofono_call_forwarding_is_busy(cf)) { reply = __ofono_error_busy(msg); g_dbus_send_message(conn, reply); return TRUE; } DBG("Received call forwarding ss control request"); DBG("type: %d, sc: %s, sia: %s, sib: %s, sic: %s, dn: %s", type, sc, sia, sib, sic, dn); if (!strcmp(sc, "21")) cf_type = CALL_FORWARDING_TYPE_UNCONDITIONAL; else if (!strcmp(sc, "67")) cf_type = CALL_FORWARDING_TYPE_BUSY; else if (!strcmp(sc, "61")) cf_type = CALL_FORWARDING_TYPE_NO_REPLY; else if (!strcmp(sc, "62")) cf_type = CALL_FORWARDING_TYPE_NOT_REACHABLE; else if (!strcmp(sc, "002")) cf_type = CALL_FORWARDING_TYPE_ALL; else if (!strcmp(sc, "004")) cf_type = CALL_FORWARDING_TYPE_ALL_CONDITIONAL; else return FALSE; if (strlen(sia) && (type == SS_CONTROL_TYPE_QUERY || type == SS_CONTROL_TYPE_ERASURE || type == SS_CONTROL_TYPE_DEACTIVATION)) goto error; /* * Activation / Registration is figured context specific according to * 22.030 Section 6.5.2 "The UE shall determine from the context * whether, an entry of a single *, activation or registration * was intended." */ if (type == SS_CONTROL_TYPE_ACTIVATION && strlen(sia) > 0) type = SS_CONTROL_TYPE_REGISTRATION; if (type == SS_CONTROL_TYPE_REGISTRATION && !valid_phone_number_format(sia)) goto error; if (strlen(sib) > 0) { long service_code; char *end; service_code = strtoul(sib, &end, 10); if (end == sib || *end != '\0') goto error; cls = mmi_service_code_to_bearer_class(service_code); if (cls == 0) goto error; } if (strlen(sic) > 0) { char *end; if (type != SS_CONTROL_TYPE_REGISTRATION) goto error; if (cf_type != CALL_FORWARDING_TYPE_ALL && cf_type != CALL_FORWARDING_TYPE_ALL_CONDITIONAL && cf_type != CALL_FORWARDING_TYPE_NO_REPLY) goto error; timeout = strtoul(sic, &end, 10); if (end == sic || *end != '\0') goto error; if (timeout < 1 || timeout > 30) goto error; } switch (type) { case SS_CONTROL_TYPE_REGISTRATION: operation = cf->driver->registration; break; case SS_CONTROL_TYPE_ACTIVATION: operation = cf->driver->activation; break; case SS_CONTROL_TYPE_DEACTIVATION: operation = cf->driver->deactivation; break; case SS_CONTROL_TYPE_ERASURE: operation = cf->driver->erasure; break; case SS_CONTROL_TYPE_QUERY: operation = cf->driver->query; break; } if (operation == NULL) { reply = __ofono_error_not_implemented(msg); g_dbus_send_message(conn, reply); return TRUE; } cf->ss_req = g_try_new0(struct cf_ss_request, 1); if (cf->ss_req == NULL) { reply = __ofono_error_failed(msg); g_dbus_send_message(conn, reply); return TRUE; } cf->ss_req->ss_type = type; cf->ss_req->cf_type = cf_type; cf->ss_req->cls = cls; cf->pending = dbus_message_ref(msg); switch (cf->ss_req->cf_type) { case CALL_FORWARDING_TYPE_ALL: cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL; cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; break; case CALL_FORWARDING_TYPE_ALL_CONDITIONAL: cf->query_next = CALL_FORWARDING_TYPE_BUSY; cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE; break; default: cf->query_next = cf->ss_req->cf_type; cf->query_end = cf->ss_req->cf_type; break; } /* * Some modems don't understand all classes very well, particularly * the older models. So if the bearer class is the default, we * just use the more commonly understood value of 7 since BEARER_SMS * is not applicable to CallForwarding conditions according to 22.004 * Annex A */ if (cls == BEARER_CLASS_SS_DEFAULT) cls = BEARER_CLASS_DEFAULT; switch (cf->ss_req->ss_type) { case SS_CONTROL_TYPE_REGISTRATION: string_to_phone_number(sia, &ph); cf->driver->registration(cf, cf_type, cls, &ph, timeout, cf_ss_control_callback, cf); break; case SS_CONTROL_TYPE_ACTIVATION: cf->driver->activation(cf, cf_type, cls, cf_ss_control_callback, cf); break; case SS_CONTROL_TYPE_DEACTIVATION: cf->driver->deactivation(cf, cf_type, cls, cf_ss_control_callback, cf); break; case SS_CONTROL_TYPE_ERASURE: cf->driver->erasure(cf, cf_type, cls, cf_ss_control_callback, cf); break; case SS_CONTROL_TYPE_QUERY: ss_set_query_next_cf_cond(cf); break; } return TRUE; error: reply = __ofono_error_invalid_format(msg); g_dbus_send_message(conn, reply); return TRUE; }