MariuszSkamra commented on code in PR #1691:
URL: https://github.com/apache/mynewt-nimble/pull/1691#discussion_r1504290188


##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:

Review Comment:
   typo?
   ```suggestion
       case BLE_SVC_AUDIO_BASS_CHR_UUID16_BASS_CONTROL_POINT:
   ```
   or just
   ```suggestion
       case BLE_SVC_AUDIO_BASS_CHR_UUID16_CONTROL_POINT:
   ```



##########
nimble/host/services/audio/bass/include/services/bass/ble_audio_svc_bass.h:
##########
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_AUDIO_SVC_BASS_
+#define H_BLE_AUDIO_SVC_BASS_
+
+#include <stdint.h>
+#include "host/audio/ble_audio_bsnk.h"
+#include "syscfg/syscfg.h"
+
+#define BLE_SVC_AUDIO_BASS_UUID16                                           
0x184F
+#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT                     
0x2BC7
+#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE               
0x2BC8
+
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STOPPED             
0x00
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STARTED             
0x01
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_ADD_SOURCE                      
0x02
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_MODIFY_SOURCE                   
0x03
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_SET_BROADCAST_CODE              
0x04
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOVE_SOURCE                   
0x05
+
+enum ble_svc_audio_bass_big_enc {
+    BLE_SVC_AUDIO_BASS_BIG_ENC_NOT_ENCRYPTED,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_BROADCAST_CODE_REQ,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_DECRYPTING,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE
+};
+
+enum ble_svc_audio_bass_pa_sync {
+    BLE_SVC_AUDIO_BASS_PA_SYNC_DO_NOT_SYNC,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_AVAILABLE,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_NOT_AVAILABLE
+};
+
+enum ble_svc_audio_bass_pa_sync_state {
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NOT_SYNCED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNC_INFO_REQ,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED_FAILED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NO_PAST
+};
+
+struct ble_svc_audio_bass_subgroup {
+    uint32_t bis_sync_state;
+    uint8_t metadata_length;
+    uint8_t *metadata;
+};
+
+struct ble_svc_audio_bass_receiver_state_params {
+    ble_addr_t source_addr;
+    uint8_t source_adv_sid;
+    uint32_t broadcast_id;
+    uint8_t pa_sync_state;
+    uint8_t big_encryption;
+    uint8_t bad_code[BLE_AUDIO_BROADCAST_CODE_SIZE];
+    uint8_t num_subgroups;
+    struct ble_svc_audio_bass_subgroup
+        subgroups[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE)];
+};
+
+struct ble_svc_audio_bass_receiver_state {
+    uint8_t source_id;
+    struct ble_audio_bsnk *bsnk;
+    struct ble_svc_audio_bass_receiver_state_params params;
+};
+
+struct ble_svc_audio_bass_ctrl_point_event {
+    /**
+     * Indicates the type of BASS event that occurred.  This is one of the
+     * BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT codes.
+     */
+    uint8_t op;
+
+    /**
+     * A discriminated union containing additional details concerning the BASS 
Control Point
+     * event.  The 'type' field indicates which member of the union is valid.
+     */
+    union {
+        /**
+         * Represents Add Source operation.  Valid for the following event
+         * types:
+         *     o BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_ADD_SOURCE
+         * Application can accept or reject Add Source operation. If no 
application callback is set
+         * and free Receive State characteristic exists operation is 
automatically accepted.
+         * If application callback exists and returns 0 accepted. Otherwise, 
Operation is rejected.
+         * If operation is accepted by application callback, this callback may 
select receiver
+         * state to be filled. If application doesnt select characteristic, 
BASS Server falls back
+         * to searching free one. If none is found, operation is rejected.
+         */
+        struct {
+            /**
+             * Advertiser Address
+             */
+            ble_addr_t adv_addr;
+            uint8_t adv_sid;
+            uint32_t broadcast_id : 24;
+            uint8_t pa_sync;
+            uint16_t pa_interval;
+            uint16_t num_subgroups;
+            struct ble_svc_audio_bass_subgroup
+                
subgroups[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE)];
+            uint8_t *source_id;
+        } add_source;
+
+        /**newt
+         * Represents Modify Source operation. Valid for the following event
+         * types:
+         *     o BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_MODIFY_SOURCE
+         * Application can accept or reject Add Source operation. If no 
application callback is set
+         * or application callback returns 0 operation is automatically 
accepted.
+         * If application callback returns non-zero value operation is 
rejected.
+         */
+        struct {
+            uint8_t source_id;

Review Comment:
   As discussed offline, this could be `struct 
ble_svc_audio_bass_receiver_state` instead, to use a common, single interface 
object in all functions and events



##########
nimble/host/services/audio/bass/include/services/bass/ble_audio_svc_bass.h:
##########
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_AUDIO_SVC_BASS_
+#define H_BLE_AUDIO_SVC_BASS_
+
+#include <stdint.h>
+#include "host/audio/ble_audio_bsnk.h"
+#include "syscfg/syscfg.h"
+
+#define BLE_SVC_AUDIO_BASS_UUID16                                           
0x184F
+#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT                     
0x2BC7
+#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE               
0x2BC8
+
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STOPPED             
0x00
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STARTED             
0x01
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_ADD_SOURCE                      
0x02
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_MODIFY_SOURCE                   
0x03
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_SET_BROADCAST_CODE              
0x04
+#define BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOVE_SOURCE                   
0x05
+
+enum ble_svc_audio_bass_big_enc {
+    BLE_SVC_AUDIO_BASS_BIG_ENC_NOT_ENCRYPTED,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_BROADCAST_CODE_REQ,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_DECRYPTING,
+    BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE
+};
+
+enum ble_svc_audio_bass_pa_sync {
+    BLE_SVC_AUDIO_BASS_PA_SYNC_DO_NOT_SYNC,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_AVAILABLE,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_NOT_AVAILABLE
+};
+
+enum ble_svc_audio_bass_pa_sync_state {
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NOT_SYNCED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNC_INFO_REQ,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED_FAILED,
+    BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NO_PAST
+};
+
+struct ble_svc_audio_bass_subgroup {
+    uint32_t bis_sync_state;
+    uint8_t metadata_length;
+    uint8_t *metadata;
+};
+
+struct ble_svc_audio_bass_receiver_state_params {
+    ble_addr_t source_addr;
+    uint8_t source_adv_sid;
+    uint32_t broadcast_id;
+    uint8_t pa_sync_state;
+    uint8_t big_encryption;
+    uint8_t bad_code[BLE_AUDIO_BROADCAST_CODE_SIZE];
+    uint8_t num_subgroups;
+    struct ble_svc_audio_bass_subgroup
+        subgroups[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE)];
+};
+
+struct ble_svc_audio_bass_receiver_state {
+    uint8_t source_id;
+    struct ble_audio_bsnk *bsnk;
+    struct ble_svc_audio_bass_receiver_state_params params;
+};
+
+struct ble_svc_audio_bass_ctrl_point_event {
+    /**
+     * Indicates the type of BASS event that occurred.  This is one of the
+     * BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT codes.
+     */
+    uint8_t op;
+
+    /**
+     * A discriminated union containing additional details concerning the BASS 
Control Point
+     * event.  The 'type' field indicates which member of the union is valid.
+     */
+    union {
+        /**
+         * Represents Add Source operation.  Valid for the following event
+         * types:
+         *     o BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_ADD_SOURCE
+         * Application can accept or reject Add Source operation. If no 
application callback is set
+         * and free Receive State characteristic exists operation is 
automatically accepted.
+         * If application callback exists and returns 0 accepted. Otherwise, 
Operation is rejected.
+         * If operation is accepted by application callback, this callback may 
select receiver
+         * state to be filled. If application doesnt select characteristic, 
BASS Server falls back
+         * to searching free one. If none is found, operation is rejected.
+         */

Review Comment:
   Once the Add Source operation is accepted, the additional event shall be 
generated to notify all subscribers that Broadcast Source has been added.
   As discussed offline, the ble_audio_event should be extended with events 
that inform that:
   * Broadcast Source has been added
   * Broadcast Source has been removed
   * Broadcast Source has been modified
   * Broadcast Code has been provided



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);

Review Comment:
   No need to declare this function as it's not referenced before it's 
definition.



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+            rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt);
+        } else {
+            assert(0);
+        }
+        return rc;
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
+            rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg);
+        } else {
+            assert(0);
+        }
+        return rc;
+    default:
+        assert(0);
+    }
+}
+
+static uint8_t
+ble_svc_audio_bass_get_new_source_id()
+{
+    struct ble_svc_audio_bass_receiver_state *rcv_state;
+    struct ble_svc_audio_bass_receiver_state *next_rcv_state;
+    uint8_t free_source_id;
+    uint8_t highest_source_id = 0;
+    uint8_t lowest_source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE;
+
+    int i;
+
+    /* First characteristic is 
BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT, iterate from 2nd */
+    for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) {
+        rcv_state = ble_svc_audio_bass_chrs[i].arg;
+        if (highest_source_id < rcv_state->source_id &&
+            rcv_state->source_id != 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE)
+        {
+            highest_source_id = rcv_state->source_id;
+        }
+
+        if (lowest_source_id > rcv_state->source_id) {
+            lowest_source_id = rcv_state->source_id;
+        }
+    }
+
+    if ((highest_source_id + 1) < 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) {
+        return highest_source_id + 1;
+    }
+
+    return min(lowest_source_id + 1, 0);

Review Comment:
   This does not seem right to me. Consider having 3 Receiver states with 
sources added, let say 1, 2, 3.
   1. Client removes source 3.
   2. Client adds new source.
   3. The source ID assigned will be 3.
   
   I think the better approach would be to assign source ID 4. It's because it 
will be clear for e.g. a second Broadcast Assistent that will connect and read 
the Receiver States that this Source is new, and the old one has been removed.
   
   Consider having a static variable with last or first free source ID, so that 
you won't need to loop over the registered sources.



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+            rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt);
+        } else {
+            assert(0);
+        }
+        return rc;
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
+            rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg);
+        } else {
+            assert(0);
+        }
+        return rc;
+    default:
+        assert(0);
+    }
+}
+
+static uint8_t
+ble_svc_audio_bass_get_new_source_id()
+{
+    struct ble_svc_audio_bass_receiver_state *rcv_state;
+    struct ble_svc_audio_bass_receiver_state *next_rcv_state;
+    uint8_t free_source_id;
+    uint8_t highest_source_id = 0;
+    uint8_t lowest_source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE;
+
+    int i;
+
+    /* First characteristic is 
BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT, iterate from 2nd */
+    for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) {
+        rcv_state = ble_svc_audio_bass_chrs[i].arg;
+        if (highest_source_id < rcv_state->source_id &&
+            rcv_state->source_id != 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE)
+        {
+            highest_source_id = rcv_state->source_id;
+        }
+
+        if (lowest_source_id > rcv_state->source_id) {
+            lowest_source_id = rcv_state->source_id;
+        }
+    }
+
+    if ((highest_source_id + 1) < 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) {
+        return highest_source_id + 1;
+    }
+
+    return min(lowest_source_id + 1, 0);
+}
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev = {
+        .op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STOPPED
+    };

Review Comment:
   Maybe it would be a good idea to provide in the callback an address or 
connection handle of Broadcast Assistant that is performing the Scan procedure 
for us



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+            rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt);
+        } else {
+            assert(0);
+        }
+        return rc;
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
+            rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg);
+        } else {
+            assert(0);
+        }
+        return rc;
+    default:
+        assert(0);
+    }
+}
+
+static uint8_t
+ble_svc_audio_bass_get_new_source_id()

Review Comment:
   ```suggestion
   ble_svc_audio_bass_get_new_source_id(void)
   ```



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);

Review Comment:
   Nitpick: Consider moving those up to place where you declare other functions



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+            rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt);
+        } else {
+            assert(0);
+        }
+        return rc;
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
+            rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg);
+        } else {
+            assert(0);
+        }
+        return rc;
+    default:
+        assert(0);
+    }
+}
+
+static uint8_t
+ble_svc_audio_bass_get_new_source_id()
+{
+    struct ble_svc_audio_bass_receiver_state *rcv_state;
+    struct ble_svc_audio_bass_receiver_state *next_rcv_state;
+    uint8_t free_source_id;
+    uint8_t highest_source_id = 0;
+    uint8_t lowest_source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE;
+
+    int i;
+
+    /* First characteristic is 
BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT, iterate from 2nd */
+    for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) {
+        rcv_state = ble_svc_audio_bass_chrs[i].arg;
+        if (highest_source_id < rcv_state->source_id &&
+            rcv_state->source_id != 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE)
+        {
+            highest_source_id = rcv_state->source_id;
+        }
+
+        if (lowest_source_id > rcv_state->source_id) {
+            lowest_source_id = rcv_state->source_id;
+        }
+    }
+
+    if ((highest_source_id + 1) < 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) {
+        return highest_source_id + 1;
+    }
+
+    return min(lowest_source_id + 1, 0);
+}
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev = {
+        .op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STOPPED
+    };
+
+    if (ctrl_point_ev.ctrl_point_ev_fn) {
+        ctrl_point_ev.ctrl_point_ev_fn(&ev, ctrl_point_ev.arg);
+    }
+
+    return 0;
+}
+
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev = {
+        .op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STARTED
+    };

Review Comment:
   ditto



##########
nimble/host/services/audio/bass/src/ble_audio_svc_bass.c:
##########
@@ -0,0 +1,915 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "host/ble_hs.h"
+#include "host/ble_gatt.h"
+#include "../../host/src/ble_gatt_priv.h"
+#include "../../host/src/ble_att_priv.h"
+#include "services/bass/ble_audio_svc_bass.h"
+#include "../../host/audio/include/host/audio/ble_audio_bsnk.h"
+
+#define EXPECTED_LEN_VARIABLE                                   (-1)
+#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE            0xFF
+#define BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY          0xFFFFFFFF
+
+enum ble_svc_audio_bass_ctrl_point_op_code {
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+    BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+    BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+    BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+    BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+    BLE_AUDIO_SVC_BASS_REMOVE_SOURCE
+};
+
+typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_ev {
+    ble_svc_audio_bass_ctrl_point_ev_fn *ctrl_point_ev_fn;
+    void *arg;
+} ctrl_point_ev;
+
+static struct ble_svc_audio_bass_receiver_state
+    receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = {
+    [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = {
+        .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE
+    }
+};
+
+static struct ble_audio_event_listener ble_svc_audio_bass_audio_event_listener;
+
+static struct os_mempool ble_audio_svc_bass_metadata_pool;
+static os_membuf_t ble_audio_svc_bass_metadata_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) *
+                    
MYNEWT_VAL(BLE_SVC_AUDIO_BASS_MAX_SUBGROUPS_PER_RECV_STATE),
+                    MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))];
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_modify_source(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_set_broadcast_code(uint8_t *data, void *arg);
+static int
+ble_svc_audio_bass_remove_source(uint8_t *data, void *arg);
+
+static struct ble_svc_audio_bass_ctrl_point_handler {
+    uint8_t op_code;
+    int expected_len;
+    ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb;
+} ble_svc_audio_bass_ctrl_point_handlers[] = {
+    {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_stopped
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED,
+        .expected_len = 0,
+        .handler_cb = ble_svc_audio_bass_remote_scan_started
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_add_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE,
+        .expected_len = EXPECTED_LEN_VARIABLE,
+        .handler_cb = ble_svc_audio_bass_modify_source
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE,
+        .expected_len = 17,
+        .handler_cb = ble_svc_audio_bass_set_broadcast_code
+    }, {
+        .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE,
+        .expected_len = 1,
+        .handler_cb = ble_svc_audio_bass_remove_source
+    }
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static int
+ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt);
+static int
+ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, 
void *arg);
+
+static struct ble_gatt_chr_def 
ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2];
+
+static const struct ble_gatt_svc_def 
ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = 
{
+    { /*** Service: Published Audio Capabilities Service (bass) */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16),
+        .characteristics = ble_svc_audio_bass_chrs,
+    },
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle,
+                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid);
+    int rc;
+
+    switch (uuid16) {
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+            rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt);
+        } else {
+            assert(0);
+        }
+        return rc;
+    case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE:
+        if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
+            rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg);
+        } else {
+            assert(0);
+        }
+        return rc;
+    default:
+        assert(0);
+    }
+}
+
+static uint8_t
+ble_svc_audio_bass_get_new_source_id()
+{
+    struct ble_svc_audio_bass_receiver_state *rcv_state;
+    struct ble_svc_audio_bass_receiver_state *next_rcv_state;
+    uint8_t free_source_id;
+    uint8_t highest_source_id = 0;
+    uint8_t lowest_source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE;
+
+    int i;
+
+    /* First characteristic is 
BLE_SVC_AUDIO_BASS_CHR_UUID16_BAS_CONTROL_POINT, iterate from 2nd */
+    for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) {
+        rcv_state = ble_svc_audio_bass_chrs[i].arg;
+        if (highest_source_id < rcv_state->source_id &&
+            rcv_state->source_id != 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE)
+        {
+            highest_source_id = rcv_state->source_id;
+        }
+
+        if (lowest_source_id > rcv_state->source_id) {
+            lowest_source_id = rcv_state->source_id;
+        }
+    }
+
+    if ((highest_source_id + 1) < 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) {
+        return highest_source_id + 1;
+    }
+
+    return min(lowest_source_id + 1, 0);
+}
+
+static int
+ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev = {
+        .op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STOPPED
+    };
+
+    if (ctrl_point_ev.ctrl_point_ev_fn) {
+        ctrl_point_ev.ctrl_point_ev_fn(&ev, ctrl_point_ev.arg);
+    }
+
+    return 0;
+}
+
+static int
+ble_svc_audio_bass_remote_scan_started(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev = {
+        .op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_REMOTE_SCAN_STARTED
+    };
+
+    if (ctrl_point_ev.ctrl_point_ev_fn) {
+        ctrl_point_ev.ctrl_point_ev_fn(&ev, ctrl_point_ev.arg);
+    }
+
+    return 0;
+}
+
+static int
+ble_svc_audio_bass_create_bsnk(ble_addr_t *addr, uint8_t sid,
+                               uint32_t broadcast_id, uint16_t pa_itvl,
+                               struct ble_audio_bsnk **out_bsnk)
+{
+    struct ble_audio_bsnk_create_params bsnk_create_params;
+
+    bsnk_create_params.adv_addr = addr;
+    bsnk_create_params.adv_sid = sid;
+    bsnk_create_params.broadcast_id = broadcast_id;
+    bsnk_create_params.pa_interval = pa_itvl;
+
+    return ble_audio_bsnk_create(&bsnk_create_params, out_bsnk);
+}
+
+static int
+ble_svc_audio_bass_sync_pa(struct ble_audio_bsnk *bsnk)
+{
+    struct ble_audio_bsnk_pa_sync_params params = {
+        .conn_handle = BLE_HS_CONN_HANDLE_NONE,
+        .retry_count = 0,
+        .skip = 0
+    };
+
+    return ble_audio_bsnk_pa_sync(bsnk, &params);
+}
+
+static int
+ble_svc_audio_bass_receive_state_find_by_sink(struct 
ble_svc_audio_bass_receiver_state **out_state,
+                                              struct ble_audio_bsnk *snk)
+{
+    int i;
+
+    for (i = 0; i < sizeof(receiver_states); i++) {
+        if (receiver_states[i].bsnk == snk) {
+            *out_state = &receiver_states[i];
+            return 0;
+        }
+    }
+
+    return BLE_HS_ENOMEM;
+}
+
+static int
+ble_svc_audio_bass_receive_state_find_by_source_id(struct 
ble_svc_audio_bass_receiver_state **out_state,
+                                                   uint8_t source_id)
+{
+    int i;
+
+    for (i = 0; i < sizeof(receiver_states); i++) {
+        if (receiver_states[i].source_id == source_id) {
+            *out_state = &receiver_states[i];
+            return 0;
+        }
+    }
+
+    return BLE_HS_ENOMEM;
+}
+
+static int
+iso_event_handler(struct ble_iso_event *event, void *arg)
+{
+    struct ble_svc_audio_bass_receiver_state *state = arg;
+
+    switch (event->type) {
+    case BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED:
+
+        break;
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+static void
+ble_svc_audio_bass_sync_bises(struct ble_svc_audio_bass_receiver_state *state,
+                              uint32_t bis_sync_state)
+{
+    struct ble_audio_bsnk_bis_sync_params 
bis_sync_params[MYNEWT_VAL(BLE_MAX_BIS)] = { 0 };
+    struct ble_audio_bsnk_sync_params sync_params = {
+        .params = bis_sync_params,
+    };
+    uint8_t bis_index = 0x01;
+    int rc;
+    int i;
+
+    sync_params.num_bis = __builtin_popcount(bis_sync_state);
+
+    for (i = 0; i < sync_params.num_bis; i++) {
+        while (bis_sync_params[i].bis_index == 0) {
+            if (bis_sync_state & (1 << (bis_index - 1))) {
+                bis_sync_params[i].bis_index = bis_index;
+                bis_sync_params[i].cb = iso_event_handler;
+                bis_sync_params[i].cb_arg = state;
+            }
+
+            bis_index++;
+        }
+    }
+
+    rc = ble_audio_bsnk_sync(state->bsnk, &sync_params);
+    if (rc != 0) {
+        for (i = 0; i < state->params.num_subgroups; i++) {
+            state->params.subgroups[i].bis_sync_state =
+                BLE_SVC_AUDIO_BASS_RECEIVE_BIS_SYNC_STATE_ANY;
+        }
+    }
+}
+
+static int
+ble_svc_audio_bass_receive_state_notify(struct 
ble_svc_audio_bass_receiver_state *state)
+{
+    int i;
+
+    for (i = 0; i < sizeof(ble_svc_audio_bass_chrs); i++) {
+        if (ble_svc_audio_bass_chrs[i].arg == state) {
+            ble_gatts_chr_updated(*ble_svc_audio_bass_chrs[i].val_handle);
+            return 0;
+        }
+    }
+
+    return BLE_HS_ENOENT;
+}
+
+static int
+ble_svc_audio_bass_add_source(uint8_t *data, void *arg)
+{
+    struct ble_svc_audio_bass_ctrl_point_event ev;
+    struct ble_svc_audio_bass_receiver_state *rcv_state = NULL;
+    uint8_t source_id;
+    uint8_t offset = 0;
+    uint8_t *metadata_ptr;
+    int rc;
+    int i;
+
+    memset(&ev, 0, sizeof(ev));
+
+    ev.op = BLE_SVC_AUDIO_BASS_CTRL_POINT_EVENT_ADD_SOURCE;
+
+    ev.add_source.adv_addr.type = data[offset++];
+    memcpy(ev.add_source.adv_addr.val, &data[offset], 6);
+    offset += 6;
+    ev.add_source.adv_sid = data[offset++];
+    ev.add_source.broadcast_id = get_le24(&data[offset]);
+    offset += 3;
+    ev.add_source.pa_sync = data[offset++];
+    if (ev.add_source.pa_sync > 0x02) {
+        return BLE_HS_EINVAL;
+    }
+
+    ev.add_source.pa_interval = get_le16(&data[offset]);
+    offset += 2;
+    ev.add_source.num_subgroups = get_le16(&data[offset]);
+    offset += 2;
+
+    for (i = 0; i < ev.add_source.num_subgroups; i++) {
+        ev.add_source.subgroups[i].bis_sync_state = get_le32(&data[offset]);
+        offset += 4;
+        ev.add_source.subgroups[i].metadata_length = data[offset++];
+        ev.add_source.subgroups[i].metadata = &data[offset];
+        offset += ev.add_source.subgroups[i].metadata_length;
+    }
+
+    *ev.add_source.source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE;
+
+    if (ctrl_point_ev.ctrl_point_ev_fn) {
+        rc = ctrl_point_ev.ctrl_point_ev_fn(&ev, ctrl_point_ev.arg);
+        if (rc != 0) {
+            return BLE_HS_EREJECT;
+        }
+    }
+
+    if (*ev.add_source.source_id == 
BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) {
+        ble_svc_audio_bass_receive_state_find_free(&rcv_state);
+    }
+
+    if (!rcv_state) {
+        return BLE_HS_EREJECT;
+    }
+
+    source_id = ble_svc_audio_bass_get_new_source_id();
+
+    rcv_state->source_id = source_id;
+    rcv_state->params.source_addr.type = ev.add_source.adv_addr.type;
+    memcpy(&rcv_state->params.source_addr.type, ev.add_source.adv_addr.val, 6);
+    rcv_state->params.source_adv_sid = ev.add_source.adv_sid;
+    rcv_state->params.broadcast_id = ev.add_source.broadcast_id;
+
+    switch (ev.add_source.pa_sync) {
+    case 0x00:

Review Comment:
   Magic numbers



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to