static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep, struct avdtp_stream *stream, struct avdtp_error *err, void *user_data) { struct sink *sink = user_data; struct pending_request *pending; pending = sink->connect; if (stream) { DBusMessage *reply; sink->connect = NULL; reply = dbus_message_new_method_return(pending->msg); dbus_connection_send(pending->conn, reply, NULL); dbus_message_unref(reply); pending_request_free(pending); debug("Stream successfully created"); } else { avdtp_unref(sink->session); sink->session = NULL; if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO && avdtp_error_posix_errno(err) != EHOSTDOWN) { debug("connect:connect XCASE detected"); g_timeout_add(STREAM_SETUP_RETRY_TIMER, stream_setup_retry, sink); } else { sink->connect = NULL; error_failed(pending->conn, pending->msg, "Stream setup failed"); pending_request_free(pending); debug("Stream setup failed : %s", avdtp_strerror(err)); } } }
gboolean sink_shutdown(struct sink *sink) { if (!sink->session) return FALSE; avdtp_set_device_disconnect(sink->session, TRUE); /* cancel pending connect */ if (sink->connect) { struct pending_request *pending = sink->connect; if (pending->msg) error_failed(pending->conn, pending->msg, "Stream setup failed"); pending_request_free(sink->dev, pending); sink->connect = NULL; avdtp_unref(sink->session); sink->session = NULL; return TRUE; } /* disconnect already ongoing */ if (sink->disconnect) return TRUE; if (!sink->stream) return FALSE; if (avdtp_close(sink->session, sink->stream, FALSE) < 0) return FALSE; return TRUE; }
static void select_complete(struct avdtp *session, struct a2dp_sep *sep, GSList *caps, void *user_data) { struct sink *sink = user_data; struct pending_request *pending; int id; pending = sink->connect; pending->id = 0; id = a2dp_config(session, sep, stream_setup_complete, caps, sink); if (id == 0) goto failed; pending->id = id; return; failed: if (pending->msg) error_failed(pending->conn, pending->msg, "Stream setup failed"); pending_request_free(sink->dev, pending); sink->connect = NULL; avdtp_unref(sink->session); sink->session = NULL; }
static gboolean stream_setup_retry(gpointer user_data) { struct sink *sink = user_data; struct pending_request *pending = sink->connect; sink->retry_id = 0; if (sink->stream_state >= AVDTP_STATE_OPEN) { DBG("Stream successfully created, after XCASE connect:connect"); if (pending->msg) { DBusMessage *reply; reply = dbus_message_new_method_return(pending->msg); g_dbus_send_message(pending->conn, reply); } } else { DBG("Stream setup failed, after XCASE connect:connect"); if (pending->msg) error_failed(pending->conn, pending->msg, "Stream setup failed"); } sink->connect = NULL; pending_request_free(sink->dev, pending); return FALSE; }
static void records_cb(sdp_list_t *recs, int err, gpointer data) { struct pending_reply *pr = data; int len; sdp_data_t *d; sdp_record_t *rec = NULL; char name[MAX_NAME_SIZE], *desc = NULL; if (err < 0) { error_connection_attempt_failed(pr->conn, pr->msg, -err); goto fail; } if (!recs || !recs->data) { error_not_supported(pr->conn, pr->msg); error("Invalid PAN service record"); goto fail; } rec = recs->data; /* Concat remote name and service name */ memset(name, 0, MAX_NAME_SIZE); if (read_remote_name(&pr->src, &pr->dst, name, MAX_NAME_SIZE) < 0) len = 0; else len = strlen(name); d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) { snprintf(name + len, MAX_NAME_SIZE - len, len ? " (%.*s)" : "%.*s", d->unitSize, d->val.str); } /* Extract service description from record */ d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); if (d) { desc = g_new0(char, d->unitSize); snprintf(desc, d->unitSize, "%.*s", d->unitSize, d->val.str); } sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, desc) < 0) { error_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } connection_store(pr->path, FALSE); connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); fail: g_free(desc); pending_reply_free(pr); }
static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err, void *user_data) { struct sink *sink = user_data; struct pending_request *pending; struct avdtp_local_sep *lsep; struct avdtp_remote_sep *rsep; GSList *caps = NULL; int id; pending = sink->connect; if (err) { avdtp_unref(sink->session); sink->session = NULL; if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO && avdtp_error_posix_errno(err) != EHOSTDOWN) { debug("connect:connect XCASE detected"); g_timeout_add(STREAM_SETUP_RETRY_TIMER, stream_setup_retry, sink); } else goto failed; return; } debug("Discovery complete"); if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO, A2DP_CODEC_SBC, &lsep, &rsep) < 0) { error("No matching ACP and INT SEPs found"); goto failed; } if (!select_capabilities(session, rsep, &caps)) { error("Unable to select remote SEP capabilities"); goto failed; } id = a2dp_source_config(sink->session, stream_setup_complete, caps, sink); if (id == 0) goto failed; pending->id = id; return; failed: pending_request_free(pending); sink->connect = NULL; avdtp_unref(sink->session); sink->session = NULL; error_failed(pending->conn, pending->msg, "Stream setup failed"); }
static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err, void *user_data) { struct sink *sink = user_data; struct pending_request *pending; int id; if (!sink->connect) { avdtp_unref(sink->session); sink->session = NULL; return; } pending = sink->connect; if (err) { avdtp_unref(sink->session); sink->session = NULL; if (avdtp_error_category(err) == AVDTP_ERRNO && avdtp_error_posix_errno(err) != EHOSTDOWN) { DBG("connect:connect XCASE detected"); sink->retry_id = g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER, stream_setup_retry, sink); } else goto failed; return; } DBG("Discovery complete"); id = a2dp_select_capabilities(sink->session, AVDTP_SEP_TYPE_SINK, NULL, select_complete, sink); if (id == 0) goto failed; pending->id = id; return; failed: if (pending->msg) error_failed(pending->conn, pending->msg, "Stream setup failed"); pending_request_free(sink->dev, pending); sink->connect = NULL; avdtp_unref(sink->session); sink->session = NULL; }
static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep, struct avdtp_stream *stream, struct avdtp_error *err, void *user_data) { struct sink *sink = user_data; struct pending_request *pending; pending = sink->connect; pending->id = 0; if (stream) { DBG("Stream successfully created"); if (pending->msg) { DBusMessage *reply; reply = dbus_message_new_method_return(pending->msg); g_dbus_send_message(pending->conn, reply); } sink->connect = NULL; pending_request_free(sink->dev, pending); return; } avdtp_unref(sink->session); sink->session = NULL; if (avdtp_error_category(err) == AVDTP_ERRNO && avdtp_error_posix_errno(err) != EHOSTDOWN) { DBG("connect:connect XCASE detected"); sink->retry_id = g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER, stream_setup_retry, sink); } else { if (pending->msg) error_failed(pending->conn, pending->msg, "Stream setup failed"); sink->connect = NULL; pending_request_free(sink->dev, pending); DBG("Stream setup failed : %s", avdtp_strerror(err)); } }
static gboolean stream_setup_retry(gpointer user_data) { struct sink *sink = user_data; struct pending_request *pending = sink->connect; if (sink->state >= AVDTP_STATE_OPEN) { DBusMessage *reply; debug("Stream successfully created, after XCASE connect:connect"); reply = dbus_message_new_method_return(pending->msg); dbus_connection_send(pending->conn, reply, NULL); dbus_message_unref(reply); } else { debug("Stream setup failed, after XCASE connect:connect"); error_failed(pending->conn, pending->msg, "Stream setup failed"); } sink->connect = NULL; pending_request_free(pending); return FALSE; }
/* * A Phdc Manager requests to be added to the manager list. * - parse the parameters * * Initial version: the PHDC manager calls dbus_register_phdc_manager, * sending a simple path and a service name * TODO: check for DBUS_TYPE_UNIX_FD ((int) 'h') */ static DBusMessage *dbus_register_phdc_agent(DBusConnection *conn, DBusMessage *msg, void *data) { struct near_phdc_data *phdc_mgr; int err; DBG("conn %p", conn); /* Allocate the phdc_mgr struct */ phdc_mgr = g_try_malloc0(sizeof(struct near_phdc_data)); if (!phdc_mgr) { err = -ENOMEM; goto error; } /* Allocate a default p2p_driver */ phdc_mgr->p2p_driver = g_try_malloc0(sizeof(struct near_p2p_driver)); if (!phdc_mgr->p2p_driver) { err = -ENOMEM; goto error; } /* Get the the sender name */ phdc_mgr->sender = g_strdup(dbus_message_get_sender(msg)); DBG("%s", phdc_mgr->sender); /* default p2p values */ phdc_mgr->p2p_driver->fallback_service_name = NULL; phdc_mgr->p2p_driver->sock_type = SOCK_STREAM; phdc_mgr->p2p_driver->single_connection = FALSE; phdc_mgr->p2p_driver->new_client = phdc_p2p_newclient; phdc_mgr->p2p_driver->close = phdc_p2p_close; /* look for dict values and fill the struct */ err = parse_dictionary(msg, data, phdc_mgr, phdc_mgr->p2p_driver); if (err < 0) goto error; /* TODO: At this time, there's no support for Role == Agent */ if (phdc_mgr->role == ROLE_AGENT) { err = -ENOTSUP; goto error; } /* No correct role ? */ if (phdc_mgr->role == ROLE_UNKNOWN) { err = -EINVAL; goto error; } /* No path ? */ if (!phdc_mgr->path) { err = -EINVAL; goto error; } /* defaulting the p2p driver */ if (!phdc_mgr->p2p_driver->service_name) phdc_mgr->p2p_driver->service_name = g_strdup(DEFAULT_PHDC_SERVICE); /* p2p internal name */ phdc_mgr->p2p_driver->name = g_strdup_printf("{%s-%s}", (phdc_mgr->role == ROLE_MANAGER ? ROLE_MANAGER_TEXT : ROLE_AGENT_TEXT), phdc_mgr->p2p_driver->service_name); /* if one pointer is null, memory failed ! */ if ((!phdc_mgr->p2p_driver->name) || (!phdc_mgr->p2p_driver->service_name)) { err = -ENOMEM; goto error; } /* Watch the Phdc Manager */ phdc_mgr->watch = g_dbus_add_disconnect_watch(phdc_conn, phdc_mgr->sender, phdc_manager_disconnect, phdc_mgr, NULL); /* Add to the existing Manager list */ err = manager_add_to_list(phdc_mgr); if (err < 0) goto error; /* and register the p2p driver for the specified service */ err = near_p2p_register(phdc_mgr->p2p_driver); if (err < 0) goto error; return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); error: /* free memory */ free_mgr_data(phdc_mgr); return error_failed(msg, -err); }
int lock_ctl(struct gpio *gpio, int ctl, va_list args) { return error_failed(ERROR_CORE_INVAL); }