Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | /** @file * @brief Advance Audio Distribution Profile. */ /* * Copyright (c) 2015-2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <string.h> #include <errno.h> #include <atomic.h> #include <misc/byteorder.h> #include <misc/util.h> #include <misc/printk.h> #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_A2DP) #include <bluetooth/log.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h> #include <bluetooth/a2dp.h> #include "hci_core.h" #include "conn_internal.h" #include "avdtp_internal.h" #include "a2dp_internal.h" #define A2DP_NO_SPACE (-1) struct bt_a2dp { struct bt_avdtp session; }; /* Connections */ static struct bt_a2dp connection[CONFIG_BLUETOOTH_MAX_CONN]; void a2d_reset(struct bt_a2dp *a2dp_conn) { memset(a2dp_conn, 0, sizeof(struct bt_a2dp)); } struct bt_a2dp *get_new_connection(struct bt_conn *conn) { int8_t i, free; free = A2DP_NO_SPACE; if (!conn) { BT_ERR("Invalid Input (err: %d)", -EINVAL); return NULL; } /* Find a space */ for (i = 0; i < CONFIG_BLUETOOTH_MAX_CONN; i++) { if (connection[i].session.br_chan.chan.conn == conn) { BT_DBG("Conn already exists"); return NULL; } if (!connection[i].session.br_chan.chan.conn && free == A2DP_NO_SPACE) { free = i; } } if (free == A2DP_NO_SPACE) { BT_DBG("More connection cannot be supported"); return NULL; } /* Clean the memory area before returning */ a2d_reset(&connection[free]); return &connection[free]; } int a2dp_accept(struct bt_conn *conn, struct bt_avdtp **session) { struct bt_a2dp *a2dp_conn; a2dp_conn = get_new_connection(conn); if (!a2dp_conn) { return -ENOMEM; } *session = &(a2dp_conn->session); BT_DBG("session: %p", &(a2dp_conn->session)); return 0; } /* Callback for incoming requests */ static struct bt_avdtp_ind_cb cb_ind = { /*TODO*/ }; /* The above callback structures need to be packed and passed to AVDTP */ static struct bt_avdtp_event_cb avdtp_cb = { .ind = &cb_ind, .accept = a2dp_accept }; int bt_a2dp_init(void) { int err; /* Register event handlers with AVDTP */ err = bt_avdtp_register(&avdtp_cb); if (err < 0) { BT_ERR("A2DP registration failed"); return err; } BT_DBG("A2DP Initialized successfully."); return 0; } struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn) { struct bt_a2dp *a2dp_conn; int err; a2dp_conn = get_new_connection(conn); if (!a2dp_conn) { BT_ERR("Cannot allocate memory"); return NULL; } err = bt_avdtp_connect(conn, &(a2dp_conn->session)); if (err < 0) { /* If error occurs, undo the saving and return the error */ a2d_reset(a2dp_conn); BT_DBG("AVDTP Connect failed"); return NULL; } BT_DBG("Connect request sent"); return a2dp_conn; } |