Compare commits

..

No commits in common. "feature/fix_bluetooth_kconfig_combination_issues" and "dev" have entirely different histories.

14 changed files with 14 additions and 586 deletions

View File

@ -721,7 +721,6 @@ endif # BLUETOOTH_GATT_SERVER
menuconfig BLUETOOTH_SPP
bool "Serial Port Profile (SPP)"
default n
select BT_RFCOMM
if BLUETOOTH_SPP
config BLUETOOTH_SPP_MAX_CONNECTIONS

View File

@ -237,12 +237,6 @@ ifneq ($(CONFIG_BLUETOOTH_STACK_BREDR_ZBLUE)$(CONFIG_BLUETOOTH_STACK_LE_ZBLUE),)
ifeq ($(CONFIG_BLUETOOTH_CONNECTION_MANAGER), y)
CSRCS += service/stacks/zephyr/sal_connection_manager.c
endif
ifeq ($(CONFIG_BLUETOOTH_SPP), y)
CSRCS += service/stacks/zephyr/sal_spp_interface.c
endif #CONFIG_BLUETOOTH_SPP
ifeq ($(CONFIG_BLUETOOTH_L2CAP), y)
CSRCS += service/stacks/zephyr/sal_l2cap_interface.c
endif #CONFIG_BLUETOOTH_L2CAP
ifeq ($(CONFIG_BLUETOOTH_A2DP), y)
CSRCS += service/stacks/zephyr/sal_a2dp_interface.c
endif #CONFIG_BLUETOOTH_A2DP
@ -250,20 +244,6 @@ ifneq ($(CONFIG_BLUETOOTH_AVRCP_CONTROL)$(CONFIG_BLUETOOTH_AVRCP_TARGET),)
CSRCS += service/stacks/zephyr/sal_avrcp_interface.c
endif #CONFIG_BLUETOOTH_AVRCP_CONTROL/CONFIG_BLUETOOTH_AVRCP_TARGET
ifeq ($(CONFIG_BLUETOOTH_HFP_HF), y)
CSRCS += service/stacks/zephyr/sal_hfp_hf_interface.c
endif #CONFIG_BLUETOOTH_HFP_HF
ifeq ($(CONFIG_BLUETOOTH_HFP_AG), y)
CSRCS += service/stacks/zephyr/sal_hfp_ag_interface.c
endif #CONFIG_BLUETOOTH_HFP_AG
ifeq ($(CONFIG_BLUETOOTH_HID_DEVICE), y)
CSRCS += service/stacks/zephyr/sal_hid_device_interface.c
endif #CONFIG_BLUETOOTH_HID_DEVICE
ifeq ($(CONFIG_BLUETOOTH_PAN), y)
CSRCS += service/stacks/zephyr/sal_pan_interface.c
endif #CONFIG_BLUETOOTH_PAN
ifeq ($(CONFIG_BLUETOOTH_STACK_LE_ZBLUE), y)
CSRCS += service/stacks/zephyr/sal_adapter_le_interface.c
ifeq ($(CONFIG_BLUETOOTH_BLE_ADV), y)

View File

@ -42,7 +42,7 @@ bool BTSYMBOLS(bt_cs_unregister_callbacks)(bt_instance_t* ins, void* cookie)
return profile->unregister_callbacks(NULL, cookie);
}
bt_status_t BTSYMBOLS(bt_cs_start_distance_measurement)(bt_instance_t* ins, const bt_distance_measurement_params_t* params)
bt_status_t BTSYMBOLS(bt_cs_start_distance_measurement)(bt_instance_t* ins, bt_distance_measurement_params_t* params)
{
bt_cs_interface_t* profile = get_profile_service();

View File

@ -488,6 +488,12 @@ typedef struct bt_instance {
callbacks_list_t* avrcp_target_callbacks;
callbacks_list_t* avrcp_control_callbacks;
callbacks_list_t* cs_callbacks;
void* adapter_cookie;
void* a2dp_sink_cookie;
void* a2dp_source_cookie;
void* avrcp_target_cookie;
void* avrcp_control_cookie;
void* cs_cookie;
callbacks_list_t* hfp_ag_callbacks;
callbacks_list_t* hfp_hf_callbacks;
@ -495,24 +501,17 @@ typedef struct bt_instance {
callbacks_list_t* spp_callbacks;
callbacks_list_t* hidd_callbacks;
callbacks_list_t* l2cap_callbacks;
bt_list_t* gattc_remote_list;
bt_list_t* gatts_remote_list;
void* priv;
#endif
void* adapter_cookie;
void* a2dp_sink_cookie;
void* a2dp_source_cookie;
void* avrcp_target_cookie;
void* avrcp_control_cookie;
void* cs_cookie;
void* hfp_ag_cookie;
void* hfp_hf_cookie;
void* panu_cookie;
void* spp_cookie;
void* hidd_cookie;
void* l2cap_cookie;
bt_list_t* gattc_remote_list;
bt_list_t* gatts_remote_list;
void* priv;
#endif
} bt_instance_t;
/**

View File

@ -232,7 +232,7 @@ static bool cs_unregister_callbacks(void** remote, void* cookie)
return bt_remote_callbacks_unregister(g_cs_service.callbacks, remote, cookie);
}
static bt_status_t cs_start_distance_measurement(const bt_distance_measurement_params_t* params)
static bt_status_t cs_start_distance_measurement(bt_distance_measurement_params_t* params)
{
BT_LOGD("cs_start_distance_measurement");
switch (params->method) {

View File

@ -665,7 +665,7 @@ typedef struct {
* @brief Unregister the cs event callback
*/
bool (*unregister_callbacks)(void** remote, void* cookie);
bt_status_t (*start_distance_measurement)(const bt_distance_measurement_params_t* params);
bt_status_t (*start_distance_measurement)(bt_distance_measurement_params_t* params);
bt_status_t (*stop_distance_measurement)(bt_address_t* addr, int method, bool timeout);

View File

@ -29,7 +29,6 @@
#include "bt_list.h"
#include "callbacks_list.h"
#include "netutils/netlib.h"
#include "pan_service.h"
#include "power_manager.h"
#include "sal_pan_interface.h"
#include "service_loop.h"

View File

@ -25,9 +25,7 @@
#include "bt_hash.h"
#include "bt_le_scan.h"
#include "bt_list.h"
#ifdef CONFIG_BLUETOOTH_FRAMEWORK_SOCKET_IPC
#include "bt_socket.h"
#endif
#include "bt_time.h"
#include "sal_interface.h"
#include "scan_filter.h"
@ -251,12 +249,10 @@ static void notify_scanners_scan_result(void* data)
scanner_device_t* device;
uint32_t timestamp_ms;
#ifdef CONFIG_BLUETOOTH_FRAMEWORK_SOCKET_IPC
if (bt_socket_server_is_busy()) {
do_in_service_loop_deffered(notify_scanners_scan_result, data, true);
return;
}
#endif
timestamp_ms = bt_get_os_timestamp_ms();
list_for_every(&scanner_manager.scanning_list, node)

View File

@ -1,34 +0,0 @@
/****************************************************************************
* Copyright (C) 2026 Xiaomi Corporation
*
* Licensed 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 __SAL_L2CAP_INTERFACE_H__
#define __SAL_L2CAP_INTERFACE_H__
#include <stdint.h>
#include "bt_addr.h"
#include "bt_l2cap.h"
#include "bt_status.h"
bt_status_t bt_sal_l2cap_init(void);
void bt_sal_l2cap_cleanup(void);
bt_status_t bt_sal_l2cap_listen_channel(l2cap_config_option_t* option);
bt_status_t bt_sal_l2cap_stop_listen_channel(uint16_t psm);
bt_status_t bt_sal_l2cap_connect_channel(bt_address_t* addr, l2cap_config_option_t* option);
bt_status_t bt_sal_l2cap_disconnect_channel(uint16_t local_cid);
bt_status_t bt_sal_l2cap_send_packet(uint16_t local_cid, const uint8_t* data, uint16_t size);
bt_status_t bt_sal_l2cap_give_incoming_credits(bt_address_t* addr, uint16_t local_cid, uint16_t credits);
#endif /* __SAL_L2CAP_INTERFACE_H__ */

View File

@ -1,33 +0,0 @@
/****************************************************************************
* Copyright (C) 2026 Xiaomi Corporation
*
* Licensed 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 __SAL_PAN_INTERFACE_H__
#define __SAL_PAN_INTERFACE_H__
#include <stdint.h>
#include "bt_addr.h"
#include "bt_pan.h"
#include "bt_status.h"
bt_status_t bt_sal_pan_init(uint8_t max_connections, pan_role_t role);
void bt_sal_pan_cleanup(void);
bt_status_t bt_sal_pan_connect(bt_address_t* addr, pan_role_t dst_role, pan_role_t src_role);
bt_status_t bt_sal_pan_disconnect(bt_address_t* addr);
bt_status_t bt_sal_pan_write(bt_address_t* addr, uint16_t protocol,
const uint8_t* dst_addr, const uint8_t* src_addr,
const uint8_t* data, uint16_t length);
#endif /* __SAL_PAN_INTERFACE_H__ */

View File

@ -149,9 +149,7 @@ static struct bt_conn_cb g_conn_cbs = {
};
static struct bt_conn_auth_info_cb g_conn_auth_info_cbs = {
#ifdef CONFIG_BT_SMP
.pairing_complete_ctkd = zblue_on_pairing_complete_ctkd,
#endif
.pairing_complete = zblue_on_pairing_complete,
.pairing_failed = zblue_on_pairing_failed,
.bond_deleted = zblue_on_bond_deleted,
@ -327,9 +325,7 @@ static int zblue_on_ltk_notify(uint8_t dev_id, uint8_t id, bt_addr_le_t* addr, c
/* smp[38 ~ 53] IRK */
memcpy(&prop->smp_key[38], keys->irk.val, 16);
/* smp[54 ~ 69] CSRK(remote) */
#ifdef CONFIG_BT_SIGNING
memcpy(&prop->smp_key[54], keys->remote_csrk.val, 16);
#endif
// smp[70 ~ 77] addr { addr[6], type[1], cap[1]/id_num[1] };
memcpy(&prop->smp_key[70], prop->addr.addr, sizeof(prop->addr.addr));
@ -338,9 +334,7 @@ static int zblue_on_ltk_notify(uint8_t dev_id, uint8_t id, bt_addr_le_t* addr, c
/* smp[78 ~ 79] RFU/keys; */
memcpy(&prop->smp_key[78], &keys->keys, 2);
#ifdef CONFIG_BT_SIGNING
memcpy(prop->local_csrk, keys->local_csrk.val, 16);
#endif
adapter_on_le_bonded_device_update(prop, 1);
free(prop);
@ -393,12 +387,10 @@ static int zblue_on_ltk_load(bt_addr_le_t* addr, uint8_t* key_value, uint8_t val
memcpy(keys->irk.rpa.val, remote_addr->addr, sizeof(remote_addr->addr));
#ifdef CONFIG_BT_SIGNING
memcpy(keys->remote_csrk.val, &smp_data[54], 16);
if (local_csrk)
memcpy(keys->local_csrk.val, local_csrk, 16);
#endif
memcpy(key_value, keys->storage_start, value_len);

View File

@ -35,16 +35,6 @@
#ifdef CONFIG_BLUETOOTH_GATT_CLIENT
#define STACK_CALL(func) zblue_##func
#ifndef CONFIG_GATT_CLIENT_SERVICE_MAX
#define CONFIG_GATT_CLIENT_SERVICE_MAX 20
#endif
#ifndef CONFIG_GATT_CLIENT_ELEMENT_MAX
#define CONFIG_GATT_CLIENT_ELEMENT_MAX 200
#endif
#ifndef CONFIG_GATT_CLIENT_CHAR_PER_SERVICE_MAX
#define CONFIG_GATT_CLIENT_CHAR_PER_SERVICE_MAX 100
#endif
typedef void (*sal_func_t)(void* args);
typedef struct {

View File

@ -1,407 +0,0 @@
/****************************************************************************
* Copyright (C) 2026 Xiaomi Corporation
*
* Licensed 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 <debug.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/l2cap.h>
#include "bt_addr.h"
#include "l2cap_service.h"
#include "sal_interface.h"
#include "sal_l2cap_interface.h"
#include "sal_zblue.h"
#include "service_loop.h"
#include "utils/log.h"
#define L2CAP_MAX_CHANNELS 20
#define L2CAP_MAX_SERVERS 8
#define L2CAP_SDU_BUF_SIZE CONFIG_BLUETOOTH_L2CAP_OUTGOING_MTU
#define L2CAP_TX_BUF_COUNT 8
NET_BUF_POOL_FIXED_DEFINE(l2cap_tx_pool, L2CAP_TX_BUF_COUNT,
BT_L2CAP_SDU_BUF_SIZE(L2CAP_SDU_BUF_SIZE), 0, NULL);
typedef struct {
struct bt_l2cap_le_chan le_chan;
bt_address_t addr;
uint16_t local_cid;
uint16_t psm;
uint16_t id;
bool is_server;
} sal_l2cap_channel_t;
typedef struct {
struct bt_l2cap_server server;
uint16_t psm;
uint16_t mtu;
uint16_t mps;
uint16_t credits;
bool in_use;
} sal_l2cap_server_t;
static sal_l2cap_channel_t* g_channels[L2CAP_MAX_CHANNELS];
static sal_l2cap_server_t* g_servers[L2CAP_MAX_SERVERS];
static sal_l2cap_channel_t* find_channel_by_cid(uint16_t local_cid)
{
for (int i = 0; i < L2CAP_MAX_CHANNELS; i++) {
if (g_channels[i] && g_channels[i]->local_cid == local_cid) {
return g_channels[i];
}
}
return NULL;
}
static sal_l2cap_channel_t* find_channel_by_le_chan(struct bt_l2cap_le_chan* le_chan)
{
for (int i = 0; i < L2CAP_MAX_CHANNELS; i++) {
if (g_channels[i] && &g_channels[i]->le_chan == le_chan) {
return g_channels[i];
}
}
return NULL;
}
static sal_l2cap_channel_t* alloc_channel(void)
{
for (int i = 0; i < L2CAP_MAX_CHANNELS; i++) {
if (!g_channels[i]) {
g_channels[i] = calloc(1, sizeof(sal_l2cap_channel_t));
return g_channels[i];
}
}
return NULL;
}
static void free_channel(sal_l2cap_channel_t* ch)
{
if (!ch) {
return;
}
for (int i = 0; i < L2CAP_MAX_CHANNELS; i++) {
if (g_channels[i] == ch) {
free(g_channels[i]);
g_channels[i] = NULL;
return;
}
}
}
static sal_l2cap_server_t* find_server_by_psm(uint16_t psm)
{
for (int i = 0; i < L2CAP_MAX_SERVERS; i++) {
if (g_servers[i] && g_servers[i]->psm == psm) {
return g_servers[i];
}
}
return NULL;
}
static sal_l2cap_server_t* alloc_server(void)
{
for (int i = 0; i < L2CAP_MAX_SERVERS; i++) {
if (!g_servers[i]) {
g_servers[i] = calloc(1, sizeof(sal_l2cap_server_t));
if (!g_servers[i]) {
return NULL;
}
g_servers[i]->in_use = true;
return g_servers[i];
}
}
return NULL;
}
static void get_addr_from_conn(struct bt_conn* conn, bt_address_t* addr)
{
const bt_addr_le_t* peer = bt_conn_get_dst(conn);
memcpy(addr->addr, peer->a.val, sizeof(addr->addr));
}
static int l2cap_recv_cb(struct bt_l2cap_chan* chan, struct net_buf* buf)
{
sal_l2cap_channel_t* ch = find_channel_by_le_chan(BT_L2CAP_LE_CHAN(chan));
if (!ch) {
return -ENOENT;
}
l2cap_on_packet_received(&ch->addr, ch->local_cid, buf->data, buf->len);
return 0;
}
static void l2cap_connected_cb(struct bt_l2cap_chan* chan)
{
struct bt_l2cap_le_chan* le_chan = BT_L2CAP_LE_CHAN(chan);
sal_l2cap_channel_t* ch = find_channel_by_le_chan(le_chan);
if (!ch) {
return;
}
ch->local_cid = le_chan->tx.cid;
get_addr_from_conn(chan->conn, &ch->addr);
l2cap_channel_param_t param = {
.local_cid = le_chan->tx.cid,
.remote_cid = le_chan->rx.cid,
.psm = ch->psm,
.is_client = !ch->is_server,
.transport = BT_TRANSPORT_BLE,
.incoming = {
.mtu = le_chan->rx.mtu,
.le_mps = le_chan->rx.mps,
.credits = atomic_get(&le_chan->rx.credits),
},
.outgoing = {
.mtu = le_chan->tx.mtu,
.le_mps = le_chan->tx.mps,
.credits = atomic_get(&le_chan->tx.credits),
},
};
l2cap_on_channel_connected(&ch->addr, &param);
}
static void l2cap_disconnected_cb(struct bt_l2cap_chan* chan)
{
sal_l2cap_channel_t* ch = find_channel_by_le_chan(BT_L2CAP_LE_CHAN(chan));
if (!ch) {
return;
}
l2cap_on_channel_disconnected(&ch->addr, ch->local_cid, 0);
free_channel(ch);
}
static void l2cap_sent_cb(struct bt_l2cap_chan* chan)
{
sal_l2cap_channel_t* ch = find_channel_by_le_chan(BT_L2CAP_LE_CHAN(chan));
if (!ch) {
return;
}
l2cap_on_packet_sent(&ch->addr, ch->local_cid);
}
static const struct bt_l2cap_chan_ops l2cap_chan_ops = {
.recv = l2cap_recv_cb,
.connected = l2cap_connected_cb,
.disconnected = l2cap_disconnected_cb,
.sent = l2cap_sent_cb,
};
static int l2cap_accept_cb(struct bt_conn* conn, struct bt_l2cap_server* server,
struct bt_l2cap_chan** chan)
{
sal_l2cap_channel_t* ch = alloc_channel();
if (!ch) {
return -ENOMEM;
}
sal_l2cap_server_t* srv = find_server_by_psm(server->psm);
ch->is_server = true;
ch->psm = server->psm;
get_addr_from_conn(conn, &ch->addr);
ch->le_chan.chan.ops = &l2cap_chan_ops;
if (srv) {
ch->le_chan.rx.mtu = srv->mtu;
ch->le_chan.rx.mps = srv->mps;
}
*chan = &ch->le_chan.chan;
return 0;
}
bt_status_t bt_sal_l2cap_init(void)
{
memset(g_channels, 0, sizeof(g_channels));
memset(g_servers, 0, sizeof(g_servers));
return BT_STATUS_SUCCESS;
}
void bt_sal_l2cap_cleanup(void)
{
for (int i = 0; i < L2CAP_MAX_CHANNELS; i++) {
if (g_channels[i]) {
bt_l2cap_chan_disconnect(&g_channels[i]->le_chan.chan);
free(g_channels[i]);
g_channels[i] = NULL;
}
}
for (int i = 0; i < L2CAP_MAX_SERVERS; i++) {
if (g_servers[i]) {
free(g_servers[i]);
g_servers[i] = NULL;
}
}
}
bt_status_t bt_sal_l2cap_listen_channel(l2cap_config_option_t* option)
{
if (!option) {
return BT_STATUS_PARM_INVALID;
}
sal_l2cap_server_t* srv = find_server_by_psm(option->psm);
if (srv) {
/* Server already registered in zblue, reuse it */
srv->mtu = option->mtu;
srv->mps = option->le_mps;
srv->credits = option->init_credits;
return BT_STATUS_SUCCESS;
}
srv = alloc_server();
if (!srv) {
return BT_STATUS_NOMEM;
}
srv->psm = option->psm;
srv->mtu = option->mtu;
srv->mps = option->le_mps;
srv->credits = option->init_credits;
srv->server.psm = option->psm;
srv->server.accept = l2cap_accept_cb;
int err = bt_l2cap_server_register(&srv->server);
if (err) {
for (int i = 0; i < L2CAP_MAX_SERVERS; i++) {
if (g_servers[i] == srv) {
free(g_servers[i]);
g_servers[i] = NULL;
break;
}
}
BT_LOGE("L2CAP server register failed: %d", err);
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
bt_status_t bt_sal_l2cap_stop_listen_channel(uint16_t psm)
{
sal_l2cap_server_t* srv = find_server_by_psm(psm);
if (!srv) {
return BT_STATUS_NOT_FOUND;
}
/* Keep the server struct allocated since zblue has no unregister API.
* Mark as inactive so it can be reused on re-listen. */
srv->in_use = false;
return BT_STATUS_SUCCESS;
}
bt_status_t bt_sal_l2cap_connect_channel(bt_address_t* addr, l2cap_config_option_t* option)
{
if (!addr || !option) {
return BT_STATUS_PARM_INVALID;
}
sal_l2cap_channel_t* ch = alloc_channel();
if (!ch) {
return BT_STATUS_NOMEM;
}
ch->is_server = false;
ch->psm = option->psm;
ch->id = option->id;
memcpy(&ch->addr, addr, sizeof(bt_address_t));
ch->le_chan.chan.ops = &l2cap_chan_ops;
ch->le_chan.rx.mtu = option->mtu;
ch->le_chan.rx.mps = option->le_mps;
bt_addr_le_t le_addr;
le_addr.type = BT_ADDR_LE_PUBLIC;
memcpy(le_addr.a.val, addr->addr, sizeof(le_addr.a.val));
struct bt_conn* conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &le_addr);
if (!conn) {
free_channel(ch);
return BT_STATUS_NOT_FOUND;
}
int err = bt_l2cap_chan_connect(conn, &ch->le_chan.chan, option->psm);
bt_conn_unref(conn);
if (err) {
free_channel(ch);
BT_LOGE("L2CAP connect failed: %d", err);
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
bt_status_t bt_sal_l2cap_disconnect_channel(uint16_t local_cid)
{
sal_l2cap_channel_t* ch = find_channel_by_cid(local_cid);
if (!ch) {
return BT_STATUS_NOT_FOUND;
}
int err = bt_l2cap_chan_disconnect(&ch->le_chan.chan);
if (err) {
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
bt_status_t bt_sal_l2cap_send_packet(uint16_t local_cid, const uint8_t* data, uint16_t size)
{
sal_l2cap_channel_t* ch = find_channel_by_cid(local_cid);
if (!ch) {
return BT_STATUS_NOT_FOUND;
}
struct net_buf* buf = net_buf_alloc_len(&l2cap_tx_pool, size, K_NO_WAIT);
if (!buf) {
return BT_STATUS_NOMEM;
}
net_buf_add_mem(buf, data, size);
int err = bt_l2cap_chan_send(&ch->le_chan.chan, buf);
if (err < 0) {
net_buf_unref(buf);
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
bt_status_t bt_sal_l2cap_give_incoming_credits(bt_address_t* addr, uint16_t local_cid, uint16_t credits)
{
sal_l2cap_channel_t* ch = find_channel_by_cid(local_cid);
if (!ch) {
return BT_STATUS_NOT_FOUND;
}
/* Credits are managed automatically by the zblue stack when using
* the standard recv callback. Manual credit management via
* bt_l2cap_chan_give_credits is only needed with seg_recv. */
return BT_STATUS_SUCCESS;
}

View File

@ -1,53 +0,0 @@
/****************************************************************************
* Copyright (C) 2026 Xiaomi Corporation
*
* Licensed 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 <stdint.h>
#include "bt_addr.h"
#include "bt_pan.h"
#include "bt_status.h"
#include "sal_pan_interface.h"
#include "utils/log.h"
/* PAN profile requires BNEP which is not yet implemented in zblue stack.
* These stubs allow compilation but return NOT_SUPPORTED at runtime. */
bt_status_t bt_sal_pan_init(uint8_t max_connections, pan_role_t role)
{
BT_LOGW("PAN SAL: not implemented (BNEP not available in zblue)");
return BT_STATUS_NOT_SUPPORTED;
}
void bt_sal_pan_cleanup(void)
{
}
bt_status_t bt_sal_pan_connect(bt_address_t* addr, pan_role_t dst_role, pan_role_t src_role)
{
return BT_STATUS_NOT_SUPPORTED;
}
bt_status_t bt_sal_pan_disconnect(bt_address_t* addr)
{
return BT_STATUS_NOT_SUPPORTED;
}
bt_status_t bt_sal_pan_write(bt_address_t* addr, uint16_t protocol,
const uint8_t* dst_addr, const uint8_t* src_addr,
const uint8_t* data, uint16_t length)
{
return BT_STATUS_NOT_SUPPORTED;
}