/* | |
* 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 |