636
686
if (session->dc_timer)
637
687
remove_disconnect_timer(session);
689
if (session->device_disconnect) {
690
g_idle_add(disconnect_timeout, session);
639
694
session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
640
695
disconnect_timeout,
644
void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id)
699
void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
648
case AVDTP_ERROR_ERRNO:
701
err->category = category;
703
if (category == AVDTP_ERRNO)
649
704
err->err.posix_errno = id;
651
case AVDTP_ERROR_ERROR_CODE:
652
706
err->err.error_code = id;
657
avdtp_error_type_t avdtp_error_type(struct avdtp_error *err)
709
uint8_t avdtp_error_category(struct avdtp_error *err)
711
return err->category;
662
714
int avdtp_error_error_code(struct avdtp_error *err)
664
assert(err->type == AVDTP_ERROR_ERROR_CODE);
716
assert(err->category != AVDTP_ERRNO);
665
717
return err->err.error_code;
668
720
int avdtp_error_posix_errno(struct avdtp_error *err)
670
assert(err->type == AVDTP_ERROR_ERRNO);
722
assert(err->category == AVDTP_ERRNO);
671
723
return err->err.posix_errno;
908
static void handle_unanswered_req(struct avdtp *session,
909
struct avdtp_stream *stream)
911
struct pending_req *req;
912
struct avdtp_local_sep *lsep;
913
struct avdtp_error err;
915
if (session->req->signal_id == AVDTP_ABORT) {
916
/* Avoid freeing the Abort request here */
917
DBG("handle_unanswered_req: Abort req, returning");
918
session->req->stream = NULL;
925
avdtp_error_init(&err, AVDTP_ERRNO, EIO);
929
switch (req->signal_id) {
930
case AVDTP_RECONFIGURE:
931
error("No reply to Reconfigure request");
932
if (lsep && lsep->cfm && lsep->cfm->reconfigure)
933
lsep->cfm->reconfigure(session, lsep, stream, &err,
937
error("No reply to Open request");
938
if (lsep && lsep->cfm && lsep->cfm->open)
939
lsep->cfm->open(session, lsep, stream, &err,
943
error("No reply to Start request");
944
if (lsep && lsep->cfm && lsep->cfm->start)
945
lsep->cfm->start(session, lsep, stream, &err,
949
error("No reply to Suspend request");
950
if (lsep && lsep->cfm && lsep->cfm->suspend)
951
lsep->cfm->suspend(session, lsep, stream, &err,
955
error("No reply to Close request");
956
if (lsep && lsep->cfm && lsep->cfm->close)
957
lsep->cfm->close(session, lsep, stream, &err,
960
case AVDTP_SET_CONFIGURATION:
961
error("No reply to SetConfiguration request");
962
if (lsep && lsep->cfm && lsep->cfm->set_configuration)
963
lsep->cfm->set_configuration(session, lsep, stream,
964
&err, lsep->user_data);
967
pending_req_free(req);
852
970
static void avdtp_sep_set_state(struct avdtp *session,
853
971
struct avdtp_local_sep *sep,
854
972
avdtp_state_t state)
984
1117
void avdtp_unref(struct avdtp *session)
1119
struct avdtp_server *server;
989
if (!g_slist_find(sessions, session)) {
990
error("avdtp_unref: trying to unref a unknown session");
996
debug("avdtp_unref(%p): ref=%d", session, session->ref);
1126
DBG("%p: ref=%d", session, session->ref);
998
1128
if (session->ref == 1) {
999
1129
if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
1131
struct audio_device *dev;
1132
dev = manager_get_device(&session->server->src,
1133
&session->dst, FALSE);
1134
audio_device_cancel_authorization(dev, auth_cb,
1001
1136
g_io_channel_shutdown(session->io, TRUE, NULL);
1002
1137
g_io_channel_unref(session->io);
1003
1138
session->io = NULL;
1139
avdtp_set_state(session,
1140
AVDTP_SESSION_STATE_DISCONNECTED);
1006
1143
if (session->io)
1059
static struct avdtp_local_sep *find_local_sep(struct avdtp_server *server,
1197
struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
1198
struct avdtp_local_sep *lsep)
1066
for (l = server->seps; l != NULL; l = g_slist_next(l)) {
1067
struct avdtp_local_sep *sep = l->data;
1069
if (sep->info.inuse)
1072
if (sep->info.type == type &&
1073
sep->info.media_type == media_type &&
1074
sep->codec == codec)
1202
if (lsep->info.inuse)
1205
for (l = session->seps; l != NULL; l = g_slist_next(l)) {
1206
struct avdtp_remote_sep *sep = l->data;
1207
struct avdtp_service_capability *cap;
1208
struct avdtp_media_codec_capability *codec_data;
1210
/* Type must be different: source <-> sink */
1211
if (sep->type == lsep->info.type)
1214
if (sep->media_type != lsep->info.media_type)
1221
codec_data = (void *) cap->data;
1223
if (codec_data->media_codec_type != lsep->codec)
1226
if (sep->stream == NULL)
1186
1358
g_slist_free(caps);
1188
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1189
AVDTP_GET_CAPABILITIES, buf, rsp_size);
1360
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, cmd,
1192
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
1193
AVDTP_GET_CAPABILITIES, &err, sizeof(err));
1364
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, cmd,
1368
static void setconf_cb(struct avdtp *session, struct avdtp_stream *stream,
1369
struct avdtp_error *err)
1371
struct conf_rej rej;
1372
struct avdtp_local_sep *sep;
1375
rej.error = AVDTP_UNSUPPORTED_CONFIGURATION;
1376
rej.category = err->err.error_code;
1377
avdtp_send(session, session->in.transaction,
1378
AVDTP_MSG_TYPE_REJECT, AVDTP_SET_CONFIGURATION,
1383
if (!avdtp_send(session, session->in.transaction, AVDTP_MSG_TYPE_ACCEPT,
1384
AVDTP_SET_CONFIGURATION, NULL, 0)) {
1385
stream_free(stream);
1390
sep->stream = stream;
1391
sep->info.inuse = 1;
1392
session->streams = g_slist_append(session->streams, stream);
1394
avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
1196
1397
static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
1257
1468
if (cap->category == AVDTP_MEDIA_TRANSPORT && cap->length != 0) {
1258
1469
err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
1474
if (stream->delay_reporting && session->version < 0x0103)
1475
session->version = 0x0103;
1263
1477
if (sep->ind && sep->ind->set_configuration) {
1264
1478
if (!sep->ind->set_configuration(session, sep, stream,
1267
1481
sep->user_data)) {
1482
err = AVDTP_UNSUPPORTED_CONFIGURATION;
1487
if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1488
AVDTP_SET_CONFIGURATION, NULL, 0)) {
1268
1489
stream_free(stream);
1273
if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1274
AVDTP_SET_CONFIGURATION, NULL, 0)) {
1275
stream_free(stream);
1279
sep->stream = stream;
1280
session->streams = g_slist_append(session->streams, stream);
1282
avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
1493
sep->stream = stream;
1494
sep->info.inuse = 1;
1495
session->streams = g_slist_append(session->streams, stream);
1497
avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
1503
stream_free(stream);
1287
1505
rej.error = err;
1288
1506
rej.category = category;
1590
1808
static gboolean avdtp_secctl_cmd(struct avdtp *session, uint8_t transaction,
1591
1809
struct seid_req *req, int size)
1593
return avdtp_unknown_cmd(session, transaction, (void *) req, size);
1811
return avdtp_unknown_cmd(session, transaction, AVDTP_SECURITY_CONTROL);
1814
static gboolean avdtp_delayreport_cmd(struct avdtp *session,
1815
uint8_t transaction,
1816
struct delay_req *req,
1819
struct avdtp_local_sep *sep;
1820
struct avdtp_stream *stream;
1823
if (size < sizeof(struct delay_req)) {
1824
error("Too short delay report request");
1828
sep = find_local_sep_by_seid(session->server, req->acp_seid);
1829
if (!sep || !sep->stream) {
1830
err = AVDTP_BAD_ACP_SEID;
1834
stream = sep->stream;
1836
if (sep->state != AVDTP_STATE_CONFIGURED &&
1837
sep->state != AVDTP_STATE_STREAMING) {
1838
err = AVDTP_BAD_STATE;
1842
stream->delay = ntohs(req->delay);
1844
if (sep->ind && sep->ind->delayreport) {
1845
if (!sep->ind->delayreport(session, sep, stream->rseid,
1846
stream->delay, &err,
1851
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1852
AVDTP_DELAY_REPORT, NULL, 0);
1855
return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
1856
AVDTP_DELAY_REPORT, &err, sizeof(err));
1596
1859
static gboolean avdtp_parse_cmd(struct avdtp *session, uint8_t transaction,
1599
1862
switch (signal_id) {
1600
1863
case AVDTP_DISCOVER:
1601
debug("Received DISCOVER_CMD");
1864
DBG("Received DISCOVER_CMD");
1602
1865
return avdtp_discover_cmd(session, transaction, buf, size);
1603
1866
case AVDTP_GET_CAPABILITIES:
1604
debug("Received GET_CAPABILITIES_CMD");
1605
return avdtp_getcap_cmd(session, transaction, buf, size);
1867
DBG("Received GET_CAPABILITIES_CMD");
1868
return avdtp_getcap_cmd(session, transaction, buf, size,
1870
case AVDTP_GET_ALL_CAPABILITIES:
1871
DBG("Received GET_ALL_CAPABILITIES_CMD");
1872
return avdtp_getcap_cmd(session, transaction, buf, size, TRUE);
1606
1873
case AVDTP_SET_CONFIGURATION:
1607
debug("Received SET_CONFIGURATION_CMD");
1874
DBG("Received SET_CONFIGURATION_CMD");
1608
1875
return avdtp_setconf_cmd(session, transaction, buf, size);
1609
1876
case AVDTP_GET_CONFIGURATION:
1610
debug("Received GET_CONFIGURATION_CMD");
1877
DBG("Received GET_CONFIGURATION_CMD");
1611
1878
return avdtp_getconf_cmd(session, transaction, buf, size);
1612
1879
case AVDTP_RECONFIGURE:
1613
debug("Received RECONFIGURE_CMD");
1880
DBG("Received RECONFIGURE_CMD");
1614
1881
return avdtp_reconf_cmd(session, transaction, buf, size);
1615
1882
case AVDTP_OPEN:
1616
debug("Received OPEN_CMD");
1883
DBG("Received OPEN_CMD");
1617
1884
return avdtp_open_cmd(session, transaction, buf, size);
1618
1885
case AVDTP_START:
1619
debug("Received START_CMD");
1886
DBG("Received START_CMD");
1620
1887
return avdtp_start_cmd(session, transaction, buf, size);
1621
1888
case AVDTP_CLOSE:
1622
debug("Received CLOSE_CMD");
1889
DBG("Received CLOSE_CMD");
1623
1890
return avdtp_close_cmd(session, transaction, buf, size);
1624
1891
case AVDTP_SUSPEND:
1625
debug("Received SUSPEND_CMD");
1892
DBG("Received SUSPEND_CMD");
1626
1893
return avdtp_suspend_cmd(session, transaction, buf, size);
1627
1894
case AVDTP_ABORT:
1628
debug("Received ABORT_CMD");
1895
DBG("Received ABORT_CMD");
1629
1896
return avdtp_abort_cmd(session, transaction, buf, size);
1630
1897
case AVDTP_SECURITY_CONTROL:
1631
debug("Received SECURITY_CONTROL_CMD");
1898
DBG("Received SECURITY_CONTROL_CMD");
1632
1899
return avdtp_secctl_cmd(session, transaction, buf, size);
1900
case AVDTP_DELAY_REPORT:
1901
DBG("Received DELAY_REPORT_CMD");
1902
return avdtp_delayreport_cmd(session, transaction, buf, size);
1634
debug("Received unknown request id %u", signal_id);
1635
return avdtp_unknown_cmd(session, transaction, buf, size);
1904
DBG("Received unknown request id %u", signal_id);
1905
return avdtp_unknown_cmd(session, transaction, signal_id);
2165
static uint16_t get_version(struct avdtp *session)
2167
struct btd_adapter *adapter;
2168
struct btd_device *device;
2169
const sdp_record_t *rec;
2171
sdp_data_t *proto_desc;
2173
uint16_t ver = 0x0100;
2175
adapter = manager_find_adapter(&session->server->src);
2179
ba2str(&session->dst, addr);
2180
device = adapter_find_device(adapter, addr);
2184
rec = btd_device_get_record(device, A2DP_SINK_UUID);
2186
rec = btd_device_get_record(device, A2DP_SOURCE_UUID);
2191
if (sdp_get_access_protos(rec, &protos) < 0)
2194
proto_desc = sdp_get_proto_desc(protos, AVDTP_UUID);
2195
if (proto_desc && proto_desc->dtd == SDP_UINT16)
2196
ver = proto_desc->val.uint16;
2198
sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
2199
sdp_list_free(protos, NULL);
1892
2205
static struct avdtp *avdtp_get_internal(const bdaddr_t *src, const bdaddr_t *dst)
2207
struct avdtp_server *server;
1894
2208
struct avdtp *session;
1896
2210
assert(src != NULL);
1897
2211
assert(dst != NULL);
1899
session = find_session(src, dst);
2213
server = find_server(servers, src);
2217
session = find_session(server->sessions, dst);
1901
2219
if (session->pending_auth)
2065
debug("AVDTP: incoming connect from %s", address);
2377
DBG("AVDTP: incoming connect from %s", address);
2067
2379
session = avdtp_get_internal(&src, &dst);
2069
sk = g_io_channel_unix_get_fd(chan);
2383
/* This state (ie, session is already *connecting*) happens when the
2384
* device initiates a connect (really a config'd L2CAP channel) even
2385
* though there is a connect we initiated in progress. In sink.c &
2386
* source.c, this state is referred to as XCASE connect:connect.
2387
* Abort the device's channel in favor of our own.
2389
if (session->state == AVDTP_SESSION_STATE_CONNECTING) {
2390
DBG("connect already in progress (XCASE connect:connect)");
2071
2394
if (session->pending_open && session->pending_open->open_acp) {
2072
2395
if (!bt_io_accept(chan, avdtp_connect_cb, session, NULL, NULL))
2136
2463
session->req_queue = g_slist_append(session->req_queue, req);
2139
static gboolean request_timeout(gpointer user_data)
2141
struct avdtp *session = user_data;
2466
static uint8_t req_get_seid(struct pending_req *req)
2468
if (req->signal_id == AVDTP_DISCOVER)
2471
return ((struct seid_req *) (req->data))->acp_seid;
2474
static int cancel_request(struct avdtp *session, int err)
2142
2476
struct pending_req *req;
2143
2477
struct seid_req sreq;
2144
2478
struct avdtp_local_sep *lsep;
2145
2479
struct avdtp_stream *stream;
2147
struct avdtp_error err;
2481
struct avdtp_error averr;
2149
2483
req = session->req;
2150
2484
session->req = NULL;
2152
avdtp_error_init(&err, AVDTP_ERROR_ERRNO, ETIMEDOUT);
2154
seid = ((struct seid_req *) (req->data))->acp_seid;
2156
stream = find_stream_by_rseid(session, seid);
2486
avdtp_error_init(&averr, AVDTP_ERRNO, err);
2488
seid = req_get_seid(req);
2490
stream = find_stream_by_rseid(session, seid);
2495
stream->abort_int = TRUE;
2159
2496
lsep = stream->lsep;
2163
2500
switch (req->signal_id) {
2164
2501
case AVDTP_RECONFIGURE:
2165
error("Reconfigure request timed out");
2502
error("Reconfigure: %s (%d)", strerror(err), err);
2166
2503
if (lsep && lsep->cfm && lsep->cfm->reconfigure)
2167
lsep->cfm->reconfigure(session, lsep, stream, &err,
2504
lsep->cfm->reconfigure(session, lsep, stream, &averr,
2168
2505
lsep->user_data);
2170
2507
case AVDTP_OPEN:
2171
error("Open request timed out");
2508
error("Open: %s (%d)", strerror(err), err);
2172
2509
if (lsep && lsep->cfm && lsep->cfm->open)
2173
lsep->cfm->open(session, lsep, stream, &err,
2510
lsep->cfm->open(session, lsep, stream, &averr,
2174
2511
lsep->user_data);
2176
2513
case AVDTP_START:
2177
error("Start request timed out");
2514
error("Start: %s (%d)", strerror(err), err);
2178
2515
if (lsep && lsep->cfm && lsep->cfm->start)
2179
lsep->cfm->start(session, lsep, stream, &err,
2516
lsep->cfm->start(session, lsep, stream, &averr,
2180
2517
lsep->user_data);
2182
2519
case AVDTP_SUSPEND:
2183
error("Suspend request timed out");
2520
error("Suspend: %s (%d)", strerror(err), err);
2184
2521
if (lsep && lsep->cfm && lsep->cfm->suspend)
2185
lsep->cfm->suspend(session, lsep, stream, &err,
2522
lsep->cfm->suspend(session, lsep, stream, &averr,
2186
2523
lsep->user_data);
2188
2525
case AVDTP_CLOSE:
2189
error("Close request timed out");
2190
if (lsep && lsep->cfm && lsep->cfm->close)
2191
lsep->cfm->close(session, lsep, stream, &err,
2526
error("Close: %s (%d)", strerror(err), err);
2527
if (lsep && lsep->cfm && lsep->cfm->close) {
2528
lsep->cfm->close(session, lsep, stream, &averr,
2192
2529
lsep->user_data);
2531
stream->close_int = FALSE;
2194
2534
case AVDTP_SET_CONFIGURATION:
2195
error("SetConfiguration request timed out");
2535
error("SetConfiguration: %s (%d)", strerror(err), err);
2196
2536
if (lsep && lsep->cfm && lsep->cfm->set_configuration)
2197
2537
lsep->cfm->set_configuration(session, lsep, stream,
2198
&err, lsep->user_data);
2538
&averr, lsep->user_data);
2200
2540
case AVDTP_DISCOVER:
2201
error("Discover request timed out");
2541
error("Discover: %s (%d)", strerror(err), err);
2203
2543
case AVDTP_GET_CAPABILITIES:
2204
error("GetCapabilities request timed out");
2544
error("GetCapabilities: %s (%d)", strerror(err), err);
2206
2546
case AVDTP_ABORT:
2207
error("Abort request timed out");
2547
error("Abort: %s (%d)", strerror(err), err);
2211
2554
memset(&sreq, 0, sizeof(sreq));
2212
2555
sreq.acp_seid = seid;
2214
if (send_request(session, TRUE, stream, AVDTP_ABORT,
2215
&sreq, sizeof(sreq)) < 0) {
2557
err = send_request(session, TRUE, stream, AVDTP_ABORT, &sreq,
2216
2560
error("Unable to send abort request");
2485
2866
switch (signal_id) {
2486
2867
case AVDTP_DISCOVER:
2487
debug("DISCOVER request succeeded");
2868
DBG("DISCOVER request succeeded");
2488
2869
return avdtp_discover_resp(session, buf, size);
2870
case AVDTP_GET_ALL_CAPABILITIES:
2489
2872
case AVDTP_GET_CAPABILITIES:
2490
debug("GET_CAPABILITIES request succeeded");
2873
DBG("GET_%sCAPABILITIES request succeeded", get_all);
2491
2874
if (!avdtp_get_capabilities_resp(session, buf, size))
2493
if (!(next && next->signal_id == AVDTP_GET_CAPABILITIES))
2876
if (!(next && (next->signal_id == AVDTP_GET_CAPABILITIES ||
2877
next->signal_id == AVDTP_GET_ALL_CAPABILITIES)))
2494
2878
finalize_discovery(session, 0);
2882
/* The remaining commands require an existing stream so bail out
2883
* here if the stream got unexpectedly disconnected */
2885
DBG("AVDTP: stream was closed while waiting for reply");
2889
switch (signal_id) {
2496
2890
case AVDTP_SET_CONFIGURATION:
2497
debug("SET_CONFIGURATION request succeeded");
2891
DBG("SET_CONFIGURATION request succeeded");
2498
2892
return avdtp_set_configuration_resp(session, stream,
2500
2894
case AVDTP_RECONFIGURE:
2501
debug("RECONFIGURE request succeeded");
2895
DBG("RECONFIGURE request succeeded");
2502
2896
return avdtp_reconfigure_resp(session, stream, buf, size);
2503
2897
case AVDTP_OPEN:
2504
debug("OPEN request succeeded");
2898
DBG("OPEN request succeeded");
2505
2899
return avdtp_open_resp(session, stream, buf, size);
2506
2900
case AVDTP_SUSPEND:
2507
debug("SUSPEND request succeeded");
2901
DBG("SUSPEND request succeeded");
2508
2902
return avdtp_suspend_resp(session, stream, buf, size);
2509
2903
case AVDTP_START:
2510
debug("START request succeeded");
2904
DBG("START request succeeded");
2511
2905
return avdtp_start_resp(session, stream, buf, size);
2512
2906
case AVDTP_CLOSE:
2513
debug("CLOSE request succeeded");
2907
DBG("CLOSE request succeeded");
2514
2908
return avdtp_close_resp(session, stream, buf, size);
2515
2909
case AVDTP_ABORT:
2516
debug("ABORT request succeeded");
2910
DBG("ABORT request succeeded");
2517
2911
return avdtp_abort_resp(session, stream, buf, size);
2912
case AVDTP_DELAY_REPORT:
2913
DBG("DELAY_REPORT request succeeded");
2914
return avdtp_delay_report_resp(session, stream, buf, size);
2520
2917
error("Unknown signal id in accept response: %u", signal_id);
2847
ret = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0);
3262
err = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0);
2849
3264
session->discov_cb = cb;
2850
3265
session->user_data = user_data;
2856
int avdtp_get_seps(struct avdtp *session, uint8_t acp_type, uint8_t media_type,
2857
uint8_t codec, struct avdtp_local_sep **lsep,
2858
struct avdtp_remote_sep **rsep)
2863
int_type = acp_type == AVDTP_SEP_TYPE_SINK ?
2864
AVDTP_SEP_TYPE_SOURCE : AVDTP_SEP_TYPE_SINK;
2866
*lsep = find_local_sep(session->server, int_type, media_type, codec);
2870
for (l = session->seps; l != NULL; l = g_slist_next(l)) {
2871
struct avdtp_remote_sep *sep = l->data;
2872
struct avdtp_service_capability *cap;
2873
struct avdtp_media_codec_capability *codec_data;
2875
if (sep->type != acp_type)
2878
if (sep->media_type != media_type)
2885
codec_data = (void *) cap->data;
2887
if (codec_data->media_codec_type != codec)
2899
3271
gboolean avdtp_stream_remove_cb(struct avdtp *session,
2985
3357
if (!(lsep && rsep))
2986
3358
return -EINVAL;
2988
debug("avdtp_set_configuration(%p): int_seid=%u, acp_seid=%u",
2989
session, lsep->info.seid, rsep->seid);
3360
DBG("%p: int_seid=%u, acp_seid=%u", session,
3361
lsep->info.seid, rsep->seid);
2991
3363
new_stream = g_new0(struct avdtp_stream, 1);
2992
3364
new_stream->session = session;
2993
3365
new_stream->lsep = lsep;
2994
3366
new_stream->rseid = rsep->seid;
3368
if (rsep->delay_reporting && lsep->delay_reporting) {
3369
struct avdtp_service_capability *delay_reporting;
3371
delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
3373
caps = g_slist_append(caps, delay_reporting);
3374
new_stream->delay_reporting = TRUE;
2996
3377
g_slist_foreach(caps, copy_capabilities, &new_stream->caps);
2998
3379
/* Calculate total size of request */
3152
3547
if (!g_slist_find(session->streams, stream))
3153
3548
return -EINVAL;
3155
if (stream->lsep->state <= AVDTP_STATE_OPEN)
3550
if (stream->lsep->state == AVDTP_STATE_ABORTING)
3156
3551
return -EINVAL;
3553
if (session->req && stream == session->req->stream)
3554
return cancel_request(session, ECANCELED);
3158
3556
memset(&req, 0, sizeof(req));
3159
3557
req.acp_seid = stream->rseid;
3161
3559
ret = send_request(session, TRUE, stream, AVDTP_ABORT,
3162
3560
&req, sizeof(req));
3164
avdtp_sep_set_state(session, stream->lsep,
3165
AVDTP_STATE_ABORTING);
3562
stream->abort_int = TRUE;
3567
int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
3570
struct delay_req req;
3572
if (!g_slist_find(session->streams, stream))
3575
if (stream->lsep->state != AVDTP_STATE_CONFIGURED &&
3576
stream->lsep->state != AVDTP_STATE_STREAMING)
3579
if (!stream->delay_reporting || session->version < 0x0103 ||
3580
session->server->version < 0x0103)
3583
stream->delay = delay;
3585
memset(&req, 0, sizeof(req));
3586
req.acp_seid = stream->rseid;
3587
req.delay = htons(delay);
3589
return send_request(session, TRUE, stream, AVDTP_DELAY_REPORT,
3170
3593
struct avdtp_local_sep *avdtp_register_sep(const bdaddr_t *src, uint8_t type,
3171
3594
uint8_t media_type,
3172
3595
uint8_t codec_type,
3596
gboolean delay_reporting,
3173
3597
struct avdtp_sep_ind *ind,
3174
3598
struct avdtp_sep_cfm *cfm,
3175
3599
void *user_data)
3303
3727
bacpy(dst, &session->dst);
3306
int avdtp_init(const bdaddr_t *src, GKeyFile *config)
3730
int avdtp_init(const bdaddr_t *src, GKeyFile *config, uint16_t *version)
3308
3732
GError *err = NULL;
3309
3733
gboolean tmp, master = TRUE;
3310
3734
struct avdtp_server *server;
3313
tmp = g_key_file_get_boolean(config, "General",
3316
debug("audio.conf: %s", err->message);
3317
g_clear_error(&err);
3321
tmp = g_key_file_get_boolean(config, "General", "AutoConnect",
3324
g_clear_error(&err);
3735
uint16_t ver = 0x0102;
3740
tmp = g_key_file_get_boolean(config, "General",
3743
DBG("audio.conf: %s", err->message);
3744
g_clear_error(&err);
3748
tmp = g_key_file_get_boolean(config, "General", "AutoConnect",
3751
g_clear_error(&err);
3755
if (g_key_file_get_boolean(config, "A2DP", "DelayReporting", NULL))
3329
3759
server = g_new0(struct avdtp_server, 1);
3331
3761
return -ENOMEM;
3763
server->version = ver;
3766
*version = server->version;
3333
3768
server->io = avdtp_server_socket(src, master);
3334
3769
if (!server->io) {
3335
3770
g_free(server);