static void set_volume(const GDBusPropertyTable *property, DBusMessageIter *iter, GDBusPendingPropertySet id, void *data) { struct media_transport *transport = data; struct a2dp_transport *a2dp = transport->data; uint16_t volume; if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16) { g_dbus_pending_property_error(id, ERROR_INTERFACE ".InvalidArguments", "Invalid arguments in method call"); return; } dbus_message_iter_get_basic(iter, &volume); if (volume > 127) { g_dbus_pending_property_error(id, ERROR_INTERFACE ".InvalidArguments", "Invalid arguments in method call"); return; } if (a2dp->volume != volume) avrcp_set_volume(transport->device, volume); a2dp->volume = volume; g_dbus_pending_property_success(id); }
static int set_property_a2dp(struct media_transport *transport, const char *property, DBusMessageIter *value) { struct a2dp_transport *a2dp = transport->data; if (g_strcmp0(property, "Delay") == 0) { if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16) return -EINVAL; dbus_message_iter_get_basic(value, &a2dp->delay); /* FIXME: send new delay */ return 0; } else if (g_strcmp0(property, "Volume") == 0) { uint16_t volume; if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16) return -EINVAL; dbus_message_iter_get_basic(value, &volume); if (volume > 127) return -EINVAL; if (a2dp->volume == volume) return 0; return avrcp_set_volume(transport->device, volume); } return -EINVAL; }
static void handle_set_volume(const void *buf, uint16_t len) { struct hal_cmd_avrcp_set_volume *cmd = (void *) buf; struct avrcp_device *dev; uint8_t status; int ret; DBG(""); if (!devices) { error("AVRCP: No device found to set volume"); status = HAL_STATUS_FAILED; goto done; } /* Peek the first device since the HAL cannot really address a specific * device it might mean there could only be one connected. */ dev = devices->data; ret = avrcp_set_volume(dev->session, cmd->value & 0x7f, set_volume_rsp, dev); if (ret < 0) { status = HAL_STATUS_FAILED; goto done; } status = HAL_STATUS_SUCCESS; done: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME, status); }
static int media_transport_init_sink(struct media_transport *transport) { struct btd_service *service; struct a2dp_transport *a2dp; service = btd_device_get_service(transport->device, A2DP_SOURCE_UUID); if (service == NULL) return -EINVAL; a2dp = g_new0(struct a2dp_transport, 1); transport->resume = resume_a2dp; transport->suspend = suspend_a2dp; transport->cancel = cancel_a2dp; transport->data = a2dp; transport->destroy = destroy_a2dp; a2dp->volume = 127; avrcp_set_volume(transport->device, a2dp->volume); transport->source_watch = source_add_state_cb(service, source_state_changed, transport); return 0; }
struct media_transport *media_transport_create(struct audio_device *device, uint8_t *configuration, size_t size, void *data) { struct media_endpoint *endpoint = data; struct media_transport *transport; const char *uuid; static int fd = 0; transport = g_new0(struct media_transport, 1); transport->device = device; transport->endpoint = endpoint; transport->configuration = g_new(uint8_t, size); memcpy(transport->configuration, configuration, size); transport->size = size; transport->path = g_strdup_printf("%s/fd%d", device_get_path(device->btd_dev), fd++); transport->fd = -1; uuid = media_endpoint_get_uuid(endpoint); if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0 || strcasecmp(uuid, A2DP_SINK_UUID) == 0) { struct a2dp_transport *a2dp; a2dp = g_new0(struct a2dp_transport, 1); transport->resume = resume_a2dp; transport->suspend = suspend_a2dp; transport->cancel = cancel_a2dp; transport->data = a2dp; transport->destroy = destroy_a2dp; if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) { a2dp->volume = -1; transport->sink_watch = sink_add_state_cb(device, sink_state_changed, transport); } else { a2dp->volume = 127; avrcp_set_volume(device, a2dp->volume); transport->source_watch = source_add_state_cb(device, source_state_changed, transport); } } else goto fail;