static void auth_cb(DBusError *derr, void *user_data) { DBusConnection *conn = btd_get_dbus_connection(); struct service_adapter *serv_adapter = user_data; DBusMessage *reply; struct pending_auth *auth; auth = next_pending(serv_adapter); if (auth == NULL) { info("Authorization cancelled: Client exited"); return; } if (derr) { error("Access denied: %s", derr->message); reply = btd_error_not_authorized(auth->msg); g_dbus_send_message(conn, reply); goto done; } g_dbus_send_reply(conn, auth->msg, DBUS_TYPE_INVALID); done: serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, auth); dbus_message_unref(auth->msg); g_free(auth); auth = next_pending(serv_adapter); if (auth == NULL) return; auth->id = btd_request_authorization(get_address(serv_adapter), &auth->dst, auth->uuid, auth_cb, serv_adapter); }
static int send_cancel_request(struct connman_agent *agent, struct connman_agent_request *request) { DBusMessage *message; const char *interface = NULL; if (request && request->driver) interface = request->driver->interface; DBG("send cancel req to %s %s iface %s", agent->owner, agent->path, interface); message = dbus_message_new_method_call(agent->owner, agent->path, interface, "Cancel"); if (!message) { connman_error("Couldn't allocate D-Bus message"); return -ENOMEM; } g_dbus_send_message(connection, message); return 0; }
static void properties_changed(dbus_uint32_t state) { const char *key = "State"; DBusMessageIter iter, dict, dict_entry, dict_val; DBusMessage *signal; signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE, "PropertiesChanged"); if (signal == NULL) return; dbus_message_iter_init_append(signal, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry); dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key); dbus_message_iter_open_container(&dict_entry, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT32_AS_STRING, &dict_val); dbus_message_iter_append_basic(&dict_val, DBUS_TYPE_UINT32, &state); dbus_message_iter_close_container(&dict_entry, &dict_val); dbus_message_iter_close_container(&dict, &dict_entry); dbus_message_iter_close_container(&iter, &dict); g_dbus_send_message(connection, signal); }
static gboolean controlpoint_timeout(gpointer user_data) { struct controlpoint_req *req = user_data; if (req->opcode == UPDATE_SENSOR_LOC) { g_dbus_pending_property_error(req->reply_id, ERROR_INTERFACE ".Failed", "Operation failed (timeout)"); } else if (req->opcode == SET_CUMULATIVE_VALUE) { DBusMessage *reply; reply = btd_error_failed(req->msg, "Operation failed (timeout)"); g_dbus_send_message(btd_get_dbus_connection(), reply); dbus_message_unref(req->msg); } req->csc->pending_req = NULL; g_free(req); return FALSE; }
static int set_setting(const char *key, const char *value, void *user_data) { struct media_player *mp = user_data; const char *iface = MEDIA_PLAYER_INTERFACE; DBusMessage *msg; DBusMessageIter iter; const char *curval; DBG("%s = %s", key, value); curval = g_hash_table_lookup(mp->settings, key); if (!curval) return -EINVAL; if (strcasecmp(curval, value) == 0) return 0; msg = dbus_message_new_method_call(mp->sender, mp->path, DBUS_INTERFACE_PROPERTIES, "Set"); if (msg == NULL) { error("Couldn't allocate D-Bus message"); return -ENOMEM; } dbus_message_iter_init_append(msg, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface); if (strcasecmp(key, "Shuffle") == 0) set_shuffle_setting(&iter, value); else if (strcasecmp(key, "Repeat") == 0) set_repeat_setting(&iter, value); g_dbus_send_message(btd_get_dbus_connection(), msg); return 0; }
static void release_session(gpointer key, gpointer value, gpointer user_data) { struct connman_session *session = value; DBusMessage *message; DBG("owner %s path %s", session->owner, session->notify_path); if (session->notify_watch > 0) g_dbus_remove_watch(connection, session->notify_watch); g_dbus_unregister_interface(connection, session->session_path, CONNMAN_SESSION_INTERFACE); message = dbus_message_new_method_call(session->owner, session->notify_path, CONNMAN_NOTIFICATION_INTERFACE, "Release"); if (!message) return; dbus_message_set_no_reply(message, TRUE); g_dbus_send_message(connection, message); }
static int agent_ringer_set_ringer(const char *mode) { struct alert_data *alert; DBusMessage *msg; alert = get_alert_data_by_category("ringer"); if (!alert) { DBG("Category ringer is not registered"); return -EINVAL; } msg = dbus_message_new_method_call(alert->srv, alert->path, ALERT_AGENT_INTERFACE, "SetRinger"); if (!msg) return -ENOMEM; dbus_message_append_args(msg, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); dbus_message_set_no_reply(msg, TRUE); g_dbus_send_message(btd_get_dbus_connection(), msg); return 0; }
static void emit_interfaces_added(struct generic_data *data) { DBusMessage *signal; DBusMessageIter iter, array; if (root == NULL || data == root) return; signal = dbus_message_new_signal(root->path, DBUS_INTERFACE_OBJECT_MANAGER, "InterfacesAdded"); if (signal == NULL) return; dbus_message_iter_init_append(signal, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &data->path); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array); g_slist_foreach(data->added, append_interface, &array); g_slist_free(data->added); data->added = NULL; dbus_message_iter_close_container(&iter, &array); g_dbus_send_message(data->conn, signal); }
static void update_watchers_read_complete(gpointer data, gpointer user_data) { struct watcher *w = data; struct read_resp_op *op = user_data; struct characteristic *chr = op->chr; DBusConnection *conn = w->gatt->conn; DBusMessage *msg; uint8_t status = op->status; INFO("read_resp_watchers chr:%s data[0]:%02X len:%d",chr->path,op->data[0],op->len); msg = dbus_message_new_method_call(w->name, w->path, "org.bluez.Watcher", "ReadResponse"); if (msg == NULL) return; dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &chr->path, DBUS_TYPE_BYTE, &status, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &op->data, op->len, DBUS_TYPE_INVALID); dbus_message_set_no_reply(msg, TRUE); g_dbus_send_message(conn, msg); }
static void hfp_connect_reply(DBusPendingCall *call, gpointer user_data) { struct ofono_modem *modem = user_data; struct hfp_data *data = ofono_modem_get_data(modem); DBusError derr; DBusMessage *reply, *msg; reply = dbus_pending_call_steal_reply(call); if (ofono_modem_get_powered(modem)) goto done; dbus_error_init(&derr); if (!dbus_set_error_from_message(&derr, reply)) goto done; DBG("Connect reply: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { msg = dbus_message_new_method_call(BLUEZ_SERVICE, data->handsfree_path, BLUEZ_GATEWAY_INTERFACE, "Disconnect"); if (msg == NULL) ofono_error("Disconnect failed"); else g_dbus_send_message(connection, msg); } ofono_modem_set_powered(modem, FALSE); dbus_error_free(&derr); done: dbus_message_unref(reply); data->call = NULL; }
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path, const char *interface, const char *name, int type, void *value) { DBusMessage *signal; DBusMessageIter iter; signal = dbus_message_new_signal(path, interface, "PropertyChanged"); if (signal == NULL) { ofono_error("Unable to allocate new %s.PropertyChanged signal", interface); return -1; } dbus_message_iter_init_append(signal, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name); append_variant(&iter, type, value); return g_dbus_send_message(conn, signal); }
static void slc_failed(gpointer userdata) { struct ofono_modem *modem = userdata; struct hfp *hfp = ofono_modem_get_data(modem); struct hfp_slc_info *info = &hfp->info; DBusMessage *msg; msg = g_dbus_create_error(hfp->msg, BLUEZ_ERROR_INTERFACE ".Failed", "HFP Handshake failed"); g_dbus_send_message(ofono_dbus_get_connection(), msg); dbus_message_unref(hfp->msg); hfp->msg = NULL; ofono_error("Service level connection failed"); ofono_modem_set_powered(modem, FALSE); ofono_handsfree_card_remove(hfp->card); hfp->card = NULL; g_at_chat_unref(info->chat); info->chat = NULL; }
static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err, gpointer user_data) { struct serial_port *port = user_data; struct serial_device *device = port->device; struct rfcomm_dev_req req; int sk, fd; DBusMessage *reply; /* Owner exited? */ if (!port->listener_id) return; if (conn_err) { error("%s", conn_err->message); reply = btd_error_failed(port->msg, conn_err->message); goto fail; } sk = g_io_channel_unix_get_fd(chan); if (dbus_message_has_member(port->msg, "ConnectFD")) { reply = g_dbus_create_reply(port->msg, DBUS_TYPE_UNIX_FD, &sk, DBUS_TYPE_INVALID); g_dbus_send_message(device->conn, reply); close(sk); g_dbus_remove_watch(device->conn, port->listener_id); port->listener_id = 0; return; } memset(&req, 0, sizeof(req)); req.dev_id = -1; req.flags = (1 << RFCOMM_REUSE_DLC); bacpy(&req.src, &device->src); bacpy(&req.dst, &device->dst); req.channel = port->channel; g_io_channel_unref(port->io); port->io = NULL; port->id = ioctl(sk, RFCOMMCREATEDEV, &req); if (port->id < 0) { int err = -errno; error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(-err), -err); reply = btd_error_failed(port->msg, strerror(-err)); g_io_channel_shutdown(chan, TRUE, NULL); goto fail; } port->dev = g_strdup_printf("/dev/rfcomm%d", port->id); DBG("Serial port %s created", port->dev); g_io_channel_shutdown(chan, TRUE, NULL); /* Addressing connect port */ fd = port_open(port); if (fd < 0) /* Open in progress: Wait the callback */ return; open_notify(fd, 0, port); return; fail: g_dbus_send_message(device->conn, reply); g_dbus_remove_watch(device->conn, port->listener_id); port->listener_id = 0; }
int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg) { struct connman_technology *technology; GSList *list; int err = 0; int ret = -ENODEV; DBusMessage *reply; DBG("type %d enable", type); technology = technology_find(type); if (technology == NULL) { err = -ENXIO; goto done; } if (technology->pending_reply != NULL) { err = -EBUSY; goto done; } if (msg != NULL) { /* * This is a bit of a trick. When msg is not NULL it means * thats technology_enable was invoked from the manager API. Hence we save * the state here. */ technology->enable_persistent = TRUE; save_state(technology); } __connman_rfkill_block(technology->type, FALSE); /* * An empty device list means that devices in the technology * were rfkill blocked. The unblock above will enable the devs. */ if (technology->device_list == NULL) return 0; for (list = technology->device_list; list; list = list->next) { struct connman_device *device = list->data; err = __connman_device_enable(device); /* * err = 0 : Device was enabled right away. * If atleast one device gets enabled, we consider * the technology to be enabled. */ if (err == 0) ret = 0; } done: if (ret == 0) { if (msg != NULL) g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID); return ret; } if (msg != NULL) { if (err == -EINPROGRESS) { technology->pending_reply = dbus_message_ref(msg); technology->pending_timeout = g_timeout_add_seconds(10, technology_pending_reply, technology); } else { reply = __connman_error_failed(msg, -err); if (reply != NULL) g_dbus_send_message(connection, reply); } } return err; }
static void process_properties_from_interface(struct generic_data *data, struct interface_data *iface) { GSList *l; DBusMessage *signal; DBusMessageIter iter, dict, array; GSList *invalidated; if (iface->pending_prop == NULL) return; signal = dbus_message_new_signal(data->path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged"); if (signal == NULL) { error("Unable to allocate new " DBUS_INTERFACE_PROPERTIES ".PropertiesChanged signal"); return; } iface->pending_prop = g_slist_reverse(iface->pending_prop); dbus_message_iter_init_append(signal, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface->name); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); invalidated = NULL; for (l = iface->pending_prop; l != NULL; l = l->next) { GDBusPropertyTable *p = l->data; if (p->get == NULL) continue; if (p->exists != NULL && !p->exists(p, iface->user_data)) { invalidated = g_slist_prepend(invalidated, p); continue; } append_property(iface, p, &dict); } dbus_message_iter_close_container(&iter, &dict); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array); for (l = invalidated; l != NULL; l = g_slist_next(l)) { GDBusPropertyTable *p = l->data; dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &p->name); } g_slist_free(invalidated); dbus_message_iter_close_container(&iter, &array); g_dbus_send_message(data->conn, signal); g_slist_free(iface->pending_prop); iface->pending_prop = NULL; }
static void stream_state_changed(struct avdtp_stream *stream, avdtp_state_t old_state, avdtp_state_t new_state, struct avdtp_error *err, void *user_data) { struct audio_device *dev = user_data; struct sink *sink = dev->sink; gboolean value; if (err) return; switch (new_state) { case AVDTP_STATE_IDLE: if (sink->disconnect) { DBusMessage *reply; struct pending_request *p; p = sink->disconnect; sink->disconnect = NULL; reply = dbus_message_new_method_return(p->msg); g_dbus_send_message(p->conn, reply); pending_request_free(dev, p); } if (sink->session) { avdtp_unref(sink->session); sink->session = NULL; } sink->stream = NULL; sink->cb_id = 0; break; case AVDTP_STATE_OPEN: if (old_state == AVDTP_STATE_CONFIGURED && sink->state == SINK_STATE_CONNECTING) { value = TRUE; g_dbus_emit_signal(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Connected", DBUS_TYPE_INVALID); emit_property_changed(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Connected", DBUS_TYPE_BOOLEAN, &value); } else if (old_state == AVDTP_STATE_STREAMING) { value = FALSE; g_dbus_emit_signal(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Stopped", DBUS_TYPE_INVALID); emit_property_changed(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Playing", DBUS_TYPE_BOOLEAN, &value); } sink_set_state(dev, SINK_STATE_CONNECTED); break; case AVDTP_STATE_STREAMING: value = TRUE; g_dbus_emit_signal(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Playing", DBUS_TYPE_INVALID); emit_property_changed(dev->conn, dev->path, AUDIO_SINK_INTERFACE, "Playing", DBUS_TYPE_BOOLEAN, &value); sink_set_state(dev, SINK_STATE_PLAYING); break; case AVDTP_STATE_CONFIGURED: case AVDTP_STATE_CLOSING: case AVDTP_STATE_ABORTING: default: break; } sink->stream_state = new_state; }
static int session_policy_config_cb(struct connman_session *session, struct connman_session_config *config, void *user_data, int err) { struct creation_data *creation_data = user_data; struct session_info *info, *info_last; DBusMessage *reply; DBG("session %p config %p", session, config); if (err < 0) goto err; session->policy_config = config; session->mark = session_mark++; session->index = -1; err = init_firewall_session(session); if (err < 0) goto err; err = init_routing_table(session); if (err < 0) goto err; info = session->info; info_last = session->info_last; if (session->policy_config->ecall) ecall_session = session; info->state = CONNMAN_SESSION_STATE_DISCONNECTED; info->config.type = apply_policy_on_type( session->policy_config->type, creation_data->type); info->config.priority = session->policy_config->priority; info->config.roaming_policy = session->policy_config->roaming_policy; session->user_allowed_bearers = creation_data->allowed_bearers; creation_data->allowed_bearers = NULL; apply_policy_on_bearers( session->policy_config->allowed_bearers, session->user_allowed_bearers, &info->config.allowed_bearers); g_hash_table_replace(session_hash, session->session_path, session); DBG("add %s", session->session_path); if (!g_dbus_register_interface(connection, session->session_path, CONNMAN_SESSION_INTERFACE, session_methods, NULL, NULL, session, NULL)) { connman_error("Failed to register %s", session->session_path); g_hash_table_remove(session_hash, session->session_path); err = -EINVAL; goto err; } reply = g_dbus_create_reply(creation_data->pending, DBUS_TYPE_OBJECT_PATH, &session->session_path, DBUS_TYPE_INVALID); g_dbus_send_message(connection, reply); creation_data->pending = NULL; info_last->state = info->state; info_last->config.priority = info->config.priority; info_last->config.roaming_policy = info->config.roaming_policy; info_last->config.allowed_bearers = info->config.allowed_bearers; session->append_all = true; cleanup_creation_data(creation_data); session_activate(session); return 0; err: reply = __connman_error_failed(creation_data->pending, -err); g_dbus_send_message(connection, reply); creation_data->pending = NULL; cleanup_session(session); cleanup_creation_data(creation_data); return err; }
static int session_create_cb(struct connman_session *session, struct connman_session_config *config, void *user_data, int err) { DBusMessage *reply; struct user_config *user_config = user_data; struct session_info *info, *info_last; DBG("session %p config %p", session, config); if (err != 0) goto out; session->policy_config = config; info = session->info; info_last = session->info_last; if (session->policy_config->ecall == TRUE) ecall_session = session; info->state = CONNMAN_SESSION_STATE_DISCONNECTED; info->config.type = apply_policy_on_type( session->policy_config->type, user_config->type); info->config.priority = session->policy_config->priority; info->config.roaming_policy = session->policy_config->roaming_policy; info->entry = NULL; session->user_allowed_bearers = user_config->allowed_bearers; user_config->allowed_bearers = NULL; err = apply_policy_on_bearers( session->policy_config->allowed_bearers, session->user_allowed_bearers, &info->config.allowed_bearers); if (err < 0) goto out; g_hash_table_replace(session_hash, session->session_path, session); DBG("add %s", session->session_path); if (g_dbus_register_interface(connection, session->session_path, CONNMAN_SESSION_INTERFACE, session_methods, NULL, NULL, session, NULL) == FALSE) { connman_error("Failed to register %s", session->session_path); g_hash_table_remove(session_hash, session->session_path); err = -EINVAL; goto out; } reply = g_dbus_create_reply(user_config->pending, DBUS_TYPE_OBJECT_PATH, &session->session_path, DBUS_TYPE_INVALID); g_dbus_send_message(connection, reply); user_config->pending = NULL; populate_service_list(session); info_last->state = info->state; info_last->config.priority = info->config.priority; info_last->config.roaming_policy = info->config.roaming_policy; info_last->entry = info->entry; info_last->config.allowed_bearers = info->config.allowed_bearers; session->append_all = TRUE; session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING); out: if (err < 0) { reply = __connman_error_failed(user_config->pending, -err); g_dbus_send_message(connection, reply); free_session(session); } cleanup_user_config(user_config); return err; }
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; }
void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs, const unsigned char *data, int data_len) { DBusConnection *conn = ofono_dbus_get_connection(); const char *ussdstr = "USSD"; char *utf8_str = NULL; const char *str; const char sig[] = { DBUS_TYPE_STRING, 0 }; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter variant; DBG("status: %d %s, state: %d %s", status, ussd_status_name(status), ussd->state, ussd_state_name(ussd->state)); if (ussd->req && (status == OFONO_USSD_STATUS_NOTIFY || status == OFONO_USSD_STATUS_TERMINATED || status == OFONO_USSD_STATUS_TIMED_OUT || status == OFONO_USSD_STATUS_NOT_SUPPORTED)) { ussd_request_finish(ussd, ussd_status_to_failure_code(status), dcs, data, data_len); ussd_change_state(ussd, USSD_STATE_IDLE); return; } if (status == OFONO_USSD_STATUS_TERMINATED) { ussd_change_state(ussd, USSD_STATE_IDLE); if (ussd->pending == NULL) return; reply = __ofono_error_network_terminated(ussd->pending); goto out; } if (status == OFONO_USSD_STATUS_NOT_SUPPORTED) { ussd_change_state(ussd, USSD_STATE_IDLE); if (ussd->pending == NULL) return; reply = __ofono_error_not_supported(ussd->pending); goto out; } if (status == OFONO_USSD_STATUS_TIMED_OUT) { ussd_change_state(ussd, USSD_STATE_IDLE); if (ussd->pending == NULL) return; reply = __ofono_error_timed_out(ussd->pending); goto out; } if (data && data_len > 0) utf8_str = ussd_decode(dcs, data_len, data); str = utf8_str; /* TODO: Rework this in the Agent framework */ if (ussd->state == USSD_STATE_ACTIVE) { reply = dbus_message_new_method_return(ussd->pending); if (str == NULL) str = ""; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ussdstr); dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, sig, &variant); dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &str); dbus_message_iter_close_container(&iter, &variant); if (status == OFONO_USSD_STATUS_ACTION_REQUIRED) ussd_change_state(ussd, USSD_STATE_USER_ACTION); else ussd_change_state(ussd, USSD_STATE_IDLE); } else if (ussd->state == USSD_STATE_RESPONSE_SENT) { reply = dbus_message_new_method_return(ussd->pending); if (str == NULL) str = ""; dbus_message_append_args(reply, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); if (status == OFONO_USSD_STATUS_ACTION_REQUIRED) ussd_change_state(ussd, USSD_STATE_USER_ACTION); else ussd_change_state(ussd, USSD_STATE_IDLE); } else if (ussd->state == USSD_STATE_IDLE) { const char *signal_name; const char *path = __ofono_atom_get_path(ussd->atom); int new_state; if (status == OFONO_USSD_STATUS_ACTION_REQUIRED) { new_state = USSD_STATE_USER_ACTION; signal_name = "RequestReceived"; } else { new_state = USSD_STATE_IDLE; signal_name = "NotificationReceived"; } if (str == NULL) str = ""; g_dbus_emit_signal(conn, path, OFONO_SUPPLEMENTARY_SERVICES_INTERFACE, signal_name, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); ussd_change_state(ussd, new_state); goto free; } else { ofono_error("Received an unsolicited USSD but can't handle."); DBG("USSD is: status: %d, %s", status, str); goto free; } out: g_dbus_send_message(conn, reply); dbus_message_unref(ussd->pending); ussd->pending = NULL; free: g_free(utf8_str); }
static void sms_history_sms_send_status( struct ofono_history_context *context, const struct ofono_uuid *uuid, time_t when, enum ofono_history_sms_status s) { if ((s == OFONO_HISTORY_SMS_STATUS_DELIVERED) || (s == OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED)) { DBusMessage *signal; DBusMessageIter iter; DBusMessageIter dict; const char *uuid_str; char *msg_uuid_str; size_t msg_len; struct ofono_atom *atom; const char *path; DBusConnection *conn; int delivered; atom = __ofono_modem_find_atom(context->modem, OFONO_ATOM_TYPE_SMS); if (atom == NULL) return; path = __ofono_atom_get_path(atom); if (path == NULL) return; conn = ofono_dbus_get_connection(); if (conn == NULL) return; delivered = (s == OFONO_HISTORY_SMS_STATUS_DELIVERED); uuid_str = ofono_uuid_to_str(uuid); /* sizeof adds extra space for one '\0' */ msg_len = strlen(path) + sizeof(msg_prefix) + strlen(uuid_str); msg_uuid_str = g_try_malloc(msg_len); if (msg_uuid_str == NULL) return; /* modem path + msg_prefix + UUID as string */ snprintf(msg_uuid_str, msg_len, "%s%s%s", path, msg_prefix, uuid_str); DBG("SMS %s delivery success: %d", msg_uuid_str, delivered); signal = dbus_message_new_signal(path, OFONO_MESSAGE_MANAGER_INTERFACE, "StatusReport"); if (signal != NULL) { dbus_message_iter_init_append(signal, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &msg_uuid_str); dbus_message_iter_open_container( &iter, DBUS_TYPE_ARRAY, OFONO_PROPERTIES_ARRAY_SIGNATURE, &dict); ofono_dbus_dict_append(&dict, "Delivered", DBUS_TYPE_BOOLEAN, &delivered); dbus_message_iter_close_container(&iter, &dict); g_dbus_send_message(conn, signal); } g_free(msg_uuid_str); } }
static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data) { struct audio_device *dev = user_data; struct gateway *gw = dev->gateway; int ch; sdp_list_t *protos, *classes; uuid_t uuid; GIOChannel *io; GError *gerr = NULL; if (err < 0) { error("Unable to get service record: %s (%d)", strerror(-err), -err); goto fail; } if (!recs || !recs->data) { error("No records found"); err = -EIO; goto fail; } if (sdp_get_service_classes(recs->data, &classes) < 0) { error("Unable to get service classes from record"); err = -EINVAL; goto fail; } if (sdp_get_access_protos(recs->data, &protos) < 0) { error("Unable to get access protocols from record"); err = -ENODATA; goto fail; } gw->version = get_remote_profile_version(recs->data); if (gw->version == 0) { error("Unable to get profile version from record"); err = -EINVAL; goto fail; } memcpy(&uuid, classes->data, sizeof(uuid)); sdp_list_free(classes, free); if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 || uuid.value.uuid16 != HANDSFREE_AGW_SVCLASS_ID) { sdp_list_free(protos, NULL); error("Invalid service record or not HFP"); err = -EIO; goto fail; } ch = sdp_get_proto_port(protos, RFCOMM_UUID); sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); sdp_list_free(protos, NULL); if (ch <= 0) { error("Unable to extract RFCOMM channel from service record"); err = -EIO; goto fail; } io = bt_io_connect(rfcomm_connect_cb, dev, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, &dev->src, BT_IO_OPT_DEST_BDADDR, &dev->dst, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_CHANNEL, ch, BT_IO_OPT_INVALID); if (!io) { error("Unable to connect: %s", gerr->message); goto fail; } g_io_channel_unref(io); return; fail: if (gw->msg) { DBusMessage *reply = btd_error_failed(gw->msg, gerr ? gerr->message : strerror(-err)); g_dbus_send_message(btd_get_dbus_connection(), reply); } gateway_close(dev); if (gerr) g_error_free(gerr); }
static void setup_tun_interface(unsigned int flags, unsigned change, void *data) { struct connman_private_network *pn = data; unsigned char prefixlen; DBusMessageIter array, dict; int err; DBG("index %d flags %d change %d", pn->index, flags, change); if (flags & IFF_UP) return; prefixlen = __connman_ipconfig_netmask_prefix_len(PRIVATE_NETWORK_NETMASK); if ((__connman_inet_modify_address(RTM_NEWADDR, NLM_F_REPLACE | NLM_F_ACK, pn->index, AF_INET, pn->server_ip, pn->peer_ip, prefixlen, NULL)) < 0) { DBG("address setting failed"); return; } connman_inet_ifup(pn->index); err = enable_nat(default_interface); if (err < 0) { connman_error("failed to enable NAT on %s", default_interface); goto error; } dbus_message_iter_init_append(pn->reply, &array); dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH, &pn->path); connman_dbus_dict_open(&array, &dict); connman_dbus_dict_append_basic(&dict, "ServerIPv4", DBUS_TYPE_STRING, &pn->server_ip); connman_dbus_dict_append_basic(&dict, "PeerIPv4", DBUS_TYPE_STRING, &pn->peer_ip); connman_dbus_dict_append_basic(&dict, "PrimaryDNS", DBUS_TYPE_STRING, &pn->primary_dns); connman_dbus_dict_append_basic(&dict, "SecondaryDNS", DBUS_TYPE_STRING, &pn->secondary_dns); connman_dbus_dict_close(&array, &dict); dbus_message_iter_append_basic(&array, DBUS_TYPE_UNIX_FD, &pn->fd); g_dbus_send_message(connection, pn->reply); return; error: pn->reply = __connman_error_failed(pn->msg, -err); g_dbus_send_message(connection, pn->reply); g_hash_table_remove(pn_hash, pn->path); }
static void dispatch_text_message(struct ofono_sms *sms, const struct ofono_uuid *uuid, const char *message, enum sms_class cls, const struct sms_address *addr, const struct sms_scts *scts) { struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom); DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(sms->atom); DBusMessage *signal; DBusMessageIter iter; DBusMessageIter dict; char buf[128]; const char *signal_name; time_t ts; struct tm remote; struct tm local; const char *str = buf; ofono_sms_text_notify_cb_t notify; struct sms_handler *h; GSList *l; if (message == NULL) return; if (cls == SMS_CLASS_0) signal_name = "ImmediateMessage"; else signal_name = "IncomingMessage"; signal = dbus_message_new_signal(path, OFONO_MESSAGE_MANAGER_INTERFACE, signal_name); if (signal == NULL) return; dbus_message_iter_init_append(signal, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &message); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, OFONO_PROPERTIES_ARRAY_SIGNATURE, &dict); ts = sms_scts_to_time(scts, &remote); localtime_r(&ts, &local); strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", &local); buf[127] = '\0'; ofono_dbus_dict_append(&dict, "LocalSentTime", DBUS_TYPE_STRING, &str); strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", &remote); buf[127] = '\0'; ofono_dbus_dict_append(&dict, "SentTime", DBUS_TYPE_STRING, &str); str = sms_address_to_string(addr); ofono_dbus_dict_append(&dict, "Sender", DBUS_TYPE_STRING, &str); dbus_message_iter_close_container(&iter, &dict); g_dbus_send_message(conn, signal); if (cls == SMS_CLASS_0) return; for (l = sms->text_handlers->items; l; l = l->next) { h = l->data; notify = h->item.notify; notify(str, &remote, &local, message, h->item.notify_data); } __ofono_history_sms_received(modem, uuid, str, &remote, &local, message); }
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 void error_failed(DBusConnection *conn, DBusMessage *msg, const char *desc) { DBusMessage *reply = btd_error_failed(msg, desc); g_dbus_send_message(conn, reply); }
static void setup_tun_interface(unsigned int flags, unsigned change, void *data) { struct connman_private_network *pn = data; unsigned char prefixlen; DBusMessageIter array, dict; const char *server_ip; const char *peer_ip; const char *subnet_mask; int err; DBG("index %d flags %d change %d", pn->index, flags, change); if (flags & IFF_UP) return; subnet_mask = __connman_ippool_get_subnet_mask(pn->pool); server_ip = __connman_ippool_get_start_ip(pn->pool); peer_ip = __connman_ippool_get_end_ip(pn->pool); prefixlen = connman_ipaddress_calc_netmask_len(subnet_mask); if ((__connman_inet_modify_address(RTM_NEWADDR, NLM_F_REPLACE | NLM_F_ACK, pn->index, AF_INET, server_ip, peer_ip, prefixlen, NULL)) < 0) { DBG("address setting failed"); return; } connman_inet_ifup(pn->index); err = __connman_nat_enable(BRIDGE_NAME, server_ip, prefixlen); if (err < 0) { connman_error("failed to enable NAT"); goto error; } dbus_message_iter_init_append(pn->reply, &array); dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH, &pn->path); connman_dbus_dict_open(&array, &dict); connman_dbus_dict_append_basic(&dict, "ServerIPv4", DBUS_TYPE_STRING, &server_ip); connman_dbus_dict_append_basic(&dict, "PeerIPv4", DBUS_TYPE_STRING, &peer_ip); if (pn->primary_dns) connman_dbus_dict_append_basic(&dict, "PrimaryDNS", DBUS_TYPE_STRING, &pn->primary_dns); if (pn->secondary_dns) connman_dbus_dict_append_basic(&dict, "SecondaryDNS", DBUS_TYPE_STRING, &pn->secondary_dns); connman_dbus_dict_close(&array, &dict); dbus_message_iter_append_basic(&array, DBUS_TYPE_UNIX_FD, &pn->fd); g_dbus_send_message(connection, pn->reply); return; error: pn->reply = __connman_error_failed(pn->msg, -err); g_dbus_send_message(connection, pn->reply); g_hash_table_remove(pn_hash, pn->path); }