1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include "syscfg/syscfg.h"
21 #include "os/os.h"
22 #include "host/ble_hs_id.h"
23
24 #if MYNEWT_VAL(BLE_PERIODIC_ADV)
25 static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles;
26 static struct os_mempool ble_hs_periodic_sync_pool;
27
28 static os_membuf_t ble_hs_psync_elem_mem[
29 OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS),
30 sizeof(struct ble_hs_periodic_sync))
31 ];
32
ble_hs_periodic_sync_alloc(void)33 struct ble_hs_periodic_sync *ble_hs_periodic_sync_alloc(void)
34 {
35 struct ble_hs_periodic_sync *psync;
36 psync = os_memblock_get(&ble_hs_periodic_sync_pool);
37 if (psync) {
38 memset_s(psync, sizeof(*psync), 0, sizeof(*psync));
39 }
40
41 return psync;
42 }
43
ble_hs_periodic_sync_free(struct ble_hs_periodic_sync * psync)44 void ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync)
45 {
46 int rc;
47
48 if (psync == NULL) {
49 return;
50 }
51
52 #if MYNEWT_VAL(BLE_HS_DEBUG)
53 memset_s(psync, sizeof * psync, 0xff, sizeof * psync);
54 #endif
55 rc = os_memblock_put(&ble_hs_periodic_sync_pool, psync);
56 BLE_HS_DBG_ASSERT_EVAL(rc == 0);
57 }
58
ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync * psync)59 void ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync)
60 {
61 BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
62 BLE_HS_DBG_ASSERT_EVAL(ble_hs_periodic_sync_find_by_handle(psync->sync_handle) == NULL);
63 SLIST_INSERT_HEAD(&g_ble_hs_periodic_sync_handles, psync, next);
64 }
65
ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync * psync)66 void ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync *psync)
67 {
68 BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
69 SLIST_REMOVE(&g_ble_hs_periodic_sync_handles, psync, ble_hs_periodic_sync, next);
70 }
71
ble_hs_periodic_sync_find_by_handle(uint16_t sync_handle)72 struct ble_hs_periodic_sync *ble_hs_periodic_sync_find_by_handle(uint16_t sync_handle)
73 {
74 struct ble_hs_periodic_sync *psync;
75 BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
76 SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) {
77 if (psync->sync_handle == sync_handle) {
78 return psync;
79 }
80 }
81 return NULL;
82 }
83
ble_hs_periodic_sync_find(const ble_addr_t * addr,uint8_t sid)84 struct ble_hs_periodic_sync *ble_hs_periodic_sync_find(const ble_addr_t *addr, uint8_t sid)
85 {
86 struct ble_hs_periodic_sync *psync;
87 BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
88
89 if (!addr) {
90 return NULL;
91 }
92
93 SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) {
94 if ((ble_addr_cmp(&psync->advertiser_addr, addr) == 0) &&
95 (psync->adv_sid == sid)) {
96 return psync;
97 }
98 }
99 return NULL;
100 }
101
102 /**
103 * Retrieves the first periodic discovery handle in the list.
104 */
ble_hs_periodic_sync_first(void)105 struct ble_hs_periodic_sync *ble_hs_periodic_sync_first(void)
106 {
107 struct ble_hs_periodic_sync *psync;
108 ble_hs_lock();
109 psync = SLIST_FIRST(&g_ble_hs_periodic_sync_handles);
110 ble_hs_unlock();
111 return psync;
112 }
113
ble_hs_periodic_sync_init(void)114 int ble_hs_periodic_sync_init(void)
115 {
116 int rc;
117 rc = os_mempool_init(&ble_hs_periodic_sync_pool,
118 MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS),
119 sizeof(struct ble_hs_periodic_sync),
120 ble_hs_psync_elem_mem, "ble_hs_periodic_disc_pool");
121 if (rc != 0) {
122 return BLE_HS_EOS;
123 }
124
125 SLIST_INIT(&g_ble_hs_periodic_sync_handles);
126 return 0;
127 }
128 #endif