| /* |
| * 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 <string.h> |
| #include <errno.h> |
| #include "syscfg/syscfg.h" |
| #include "os/os.h" |
| #include "host/ble_hs_id.h" |
| #include "ble_hs_priv.h" |
| |
| #if MYNEWT_VAL(BLE_PERIODIC_ADV) |
| static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles; |
| static struct os_mempool ble_hs_periodic_sync_pool; |
| |
| static os_membuf_t ble_hs_psync_elem_mem[ |
| OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS), |
| sizeof (struct ble_hs_periodic_sync)) |
| ]; |
| |
| struct ble_hs_periodic_sync * |
| ble_hs_periodic_sync_alloc(void) |
| { |
| struct ble_hs_periodic_sync *psync; |
| |
| psync = os_memblock_get(&ble_hs_periodic_sync_pool); |
| if (psync) { |
| memset(psync, 0, sizeof(*psync)); |
| } |
| |
| return psync; |
| } |
| |
| void |
| ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync) |
| { |
| int rc; |
| |
| if (psync == NULL) { |
| return; |
| } |
| |
| #if MYNEWT_VAL(BLE_HS_DEBUG) |
| memset(psync, 0xff, sizeof *psync); |
| #endif |
| rc = os_memblock_put(&ble_hs_periodic_sync_pool, psync); |
| BLE_HS_DBG_ASSERT_EVAL(rc == 0); |
| } |
| |
| void |
| ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync) |
| { |
| BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); |
| |
| BLE_HS_DBG_ASSERT_EVAL( |
| ble_hs_periodic_sync_find_by_handle(psync->sync_handle) == NULL); |
| |
| SLIST_INSERT_HEAD(&g_ble_hs_periodic_sync_handles, psync, next); |
| } |
| |
| void |
| ble_hs_periodic_sync_remove(struct ble_hs_periodic_sync *psync) |
| { |
| BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); |
| |
| SLIST_REMOVE(&g_ble_hs_periodic_sync_handles, psync, ble_hs_periodic_sync, |
| next); |
| } |
| |
| struct ble_hs_periodic_sync * |
| ble_hs_periodic_sync_find_by_handle(uint16_t sync_handle) |
| { |
| struct ble_hs_periodic_sync *psync; |
| |
| BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); |
| |
| SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) { |
| if (psync->sync_handle == sync_handle) { |
| return psync; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| struct ble_hs_periodic_sync * |
| ble_hs_periodic_sync_find(const ble_addr_t *addr, uint8_t sid) |
| { |
| struct ble_hs_periodic_sync *psync; |
| |
| BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); |
| |
| if (!addr) { |
| return NULL; |
| } |
| |
| SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) { |
| if ((ble_addr_cmp(&psync->advertiser_addr, addr) == 0) && |
| (psync->adv_sid == sid)) { |
| return psync; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| /** |
| * Retrieves the first periodic discovery handle in the list. |
| */ |
| struct ble_hs_periodic_sync * |
| ble_hs_periodic_sync_first(void) |
| { |
| struct ble_hs_periodic_sync *psync; |
| |
| ble_hs_lock(); |
| psync = SLIST_FIRST(&g_ble_hs_periodic_sync_handles); |
| ble_hs_unlock(); |
| |
| return psync; |
| } |
| |
| int |
| ble_hs_periodic_sync_init(void) |
| { |
| int rc; |
| |
| rc = os_mempool_init(&ble_hs_periodic_sync_pool, |
| MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS), |
| sizeof (struct ble_hs_periodic_sync), |
| ble_hs_psync_elem_mem, "ble_hs_periodic_disc_pool"); |
| if (rc != 0) { |
| return BLE_HS_EOS; |
| } |
| |
| SLIST_INIT(&g_ble_hs_periodic_sync_handles); |
| |
| return 0; |
| } |
| #endif |