bouffalolab_release_bl_iot_sdk_1.6.36-374-g8fefcfc75

This commit is contained in:
zrrong 2022-06-22 19:02:58 +08:00
parent b22e3fd94e
commit 1c9b62fb8f
1055 changed files with 44437 additions and 165360 deletions

View File

@ -22,7 +22,7 @@ COMPONENT_ADD_INCLUDEDIRS += ./
COMPONENT_PRIV_INCLUDEDIRS :=
## This component's src
COMPONENT_SRCS := ./syscalls.c ./assert.c ./stdatomic.c
COMPONENT_SRCS := ./syscalls.c ./assert.c
COMPONENT_OBJS := $(patsubst %.c,%.o, $(COMPONENT_SRCS))

View File

@ -68,6 +68,11 @@ malloc_table_info_t malloc_table_info;
#define SYS_TRACE_MEM_STATS_ENTRY_NUM 100
mem_stats_t mem_stats[SYS_TRACE_MEM_STATS_ENTRY_NUM];
bool set_monitor;
uint32_t callerAddr;
uint32_t mallocCnt = 0;
uint32_t freeCnt = 0;
void trace_malloc(void *ptr, size_t size, void *caller)
{
int i;
@ -82,6 +87,11 @@ void trace_malloc(void *ptr, size_t size, void *caller)
malloc_entry[i].ptr = ptr;
malloc_entry[i].size = size;
malloc_entry[i].caller = caller;
if(set_monitor && callerAddr == (uint32_t)caller)
{
mallocCnt++;
printf("trace_malloc, caller=%08lx, ptr=%08lx, mallocCnt=%lu\r\n", callerAddr, (uint32_t)malloc_entry[i].ptr, mallocCnt);
}
break;
}
}
@ -107,6 +117,11 @@ void trace_free(void *ptr, void *caller)
if(!malloc_table_info.table_full){
for(i = 0; i < SYS_TRACE_MEM_ENTRY_NUM; i++){
if(malloc_entry[i].ptr == ptr){
if(set_monitor && callerAddr == (uint32_t)malloc_entry[i].caller)
{
freeCnt++;
printf("trace_free, caller=%08lx, ptr=%08lx, freeCnt=%lu\r\n", callerAddr, (uint32_t)malloc_entry[i].ptr, freeCnt);
}
malloc_entry[i].ptr = NULL;
break;
}
@ -131,6 +146,10 @@ void trace_realloc(void *ptr_new, void *ptr_old, size_t size, void *caller)
malloc_entry[i].ptr = ptr_new;
malloc_entry[i].size = size;
malloc_entry[i].caller = caller;
if(set_monitor && callerAddr == (uint32_t)malloc_entry[i].caller)
{
printf("trace_realloc, caller=%08lx, ptr=%08lx\r\n", callerAddr, (uint32_t)malloc_entry[i].ptr);
}
break;
}
}
@ -192,6 +211,7 @@ void mem_trace_stats()
}
printf("Current left size is %d bytes\r\n", xPortGetFreeHeapSize());
}
#endif
/* Reentrant versions of system calls. */
@ -571,3 +591,7 @@ These functions are implemented and replaced by the 'common/time.c' file
int _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp);
_CLOCK_T_ _times_r(struct _reent *ptr, struct tms *ptms);
*/
void newlibc_init(void)
{
/*dummy functions*/
}

View File

@ -51,6 +51,9 @@ CONFIG_BT_OBSERVER := 0
CONFIG_BT_BROADCASTER := 0
CONFIG_DISABLE_BT_SMP := 1
CONFIG_DISABLE_BT_HOST_PRIVACY := 1
CONFIG_BT_GATT_CLIENT := 0
CONFIG_DISABLE_BLE_CONTROLLER_TEST_MODE := 1
CONFIG_BT_STACK_CLI := 0
endif
ifeq ($(PRIV_CONFIG_GEN_BLE),m0s0sp)
@ -82,10 +85,12 @@ CONFIG_SIMPLE_MASTER := 1
CONFIG_EM_16K := 1
endif
CONFIG_SLEEP ?= 1
ifndef CONFIG_FREERTOS_DISABLE
CFLAGS += -DCFG_FREERTOS
endif
CFLAGS += -DARCH_RISCV
ifeq ($(CONFIG_CHIP_NAME),BL602)
@ -130,7 +135,9 @@ CPPFLAGS += -DCFG_BLE_ENABLE
CFLAGS += -DBFLB_BLE
CFLAGS += -DCFG_BLE
ifeq ($(CONFIG_SLEEP),1)
CFLAGS += -DCFG_SLEEP
endif
CONFIG_BT_BREDR?=0
ifeq ($(CONFIG_BT_BREDR),1)
@ -166,6 +173,15 @@ ifeq ($(CONFIG_EM_16K),1)
CFLAGS += -DCONFIG_EM_16K
endif
ifeq ($(CONFIG_BLE_MFG),1)
CONFIG_BT := 0
CONFIG_SEC_CONN := 0
CONFIG_ADV_EXTENSION := 0
CONFIG_CIS := 0
CONFIG_BIS := 0
CONFIG_LE_PWR_CTRL ?= 0
endif
CONFIG_BT ?= 1
CONFIG_SCO_ESCO ?= 1
CONFIG_PCA ?= 1
@ -174,6 +190,7 @@ CONFIG_CSB ?= 1
CONFIG_SNIFF ?= 1
CONFIG_RSWITCH ?= 1
CONFIG_TEST_MODE ?= 1
CONFIG_BT_HCI_TEST_MODE ?= 1
CONFIG_SEC_CONN ?= 1
CONFIG_BT_DIRECT_TEST_MODE ?= 1
CONFIG_BLE ?= 1
@ -362,6 +379,9 @@ endif
ifeq ($(CONFIG_BT_BAS_SERVER),1)
CFLAGS += -DCONFIG_BT_BAS_SERVER
endif
ifeq ($(CONFIG_BT_SPP_SERVER),1)
CFLAGS += -DCONFIG_BT_SPP_SERVER
endif
ifeq ($(CONFIG_BT_SCPS_SERVER),1)
CFLAGS += -DCONFIG_BT_SCPS_SERVER
endif
@ -427,7 +447,13 @@ endif
ifeq ($(CONFIG_BT_MESH),1)
CFLAGS += -DCONFIG_BT_MESH -DBFLB_CRYPT_HARDWARE
CFLAGS += -DCONFIG_BT_MESH
ifeq ($(CONFIG_CHIP_NAME),BL602)
CFLAGS += -DBFLB_CRYPT_HARDWARE
else ifeq ($(CONFIG_CHIP_NAME),BL702)
CFLAGS += -DBFLB_CRYPT_HARDWARE
endif
CFLAGS += -DCONFIG_BT_MESH_PROV
CFLAGS += -DCONFIG_BT_MESH_RELAY
#CFLAGS += -DCONFIG_BT_SETTINGS
@ -509,4 +535,4 @@ endif
CFLAGS += -Wno-unused-const-variable \
-Wno-unused-but-set-variable \
-Wno-format
-Wno-format

View File

@ -35,7 +35,7 @@
void ble_controller_init(uint8_t task_priority);
void ble_controller_deinit(void);
#if !defined(CFG_FREERTOS) && !defined(CFG_AOS)
#if !defined(CFG_FREERTOS) && !defined(CFG_AOS) && !defined(CFG_NUTTX)
void blecontroller_main(void);
#endif
#if defined(CFG_BT_RESET)
@ -50,12 +50,12 @@ int8_t ble_controller_set_scan_filter_table_size(uint8_t size);
// return sleep duration, in unit of 1/32768s
// if 0, means not allow sleep
// if -1, means allow sleep, but there is no end of sleep interrupt (ble core deep sleep is not enabled)
int32_t ble_controller_sleep(void);
int32_t ble_controller_sleep(int32_t max_sleep_cycles);
void ble_controller_sleep_restore(void);
bool ble_controller_sleep_is_ongoing(void);
void ble_controller_set_tx_pwr(int ble_tx_power);
void ble_rf_set_tx_channel(uint16_t tx_channel);
void ble_controller_disable_adv_random_delay(bool disable);
#if defined(CONFIG_BLE_MFG)
enum

View File

@ -7,7 +7,7 @@
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_
#include <types.h>
#include <atomic.h>
#include <common/include/atomic.h>
#ifdef __cplusplus
extern "C" {

View File

@ -69,7 +69,7 @@ static struct {
.dst = BT_MESH_ADDR_UNASSIGNED,
};
#if defined(BL602) || defined(BL702)
#if defined(BL602) || defined(BL702) || defined(BL606P)
#define vOutputString(...) printf(__VA_ARGS__)
#else
#define vOutputString(...) bl_print(SYSTEM_UART_ID, PRINT_MODULE_CLI, __VA_ARGS__)
@ -479,7 +479,7 @@ static const struct bt_mesh_comp comp = {
.elem_count = ARRAY_SIZE(elements),
};
#if defined(BL602) || defined(BL702)
#if defined(BL602) || defined(BL702) || defined(BL606P)
const struct cli_command btMeshCmdSet[] STATIC_CLI_CMD_ATTRIBUTE = {
#else
const struct cli_command btMeshCmdSet[] = {

View File

@ -10,7 +10,7 @@
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <atomic.h>
#include <common/include/atomic.h>
#include <util.h>
#include <byteorder.h>

View File

@ -8,7 +8,7 @@
#include <zephyr.h>
#include <errno.h>
#include <atomic.h>
#include <common/include/atomic.h>
#include <util.h>
#include <byteorder.h>

View File

@ -28,7 +28,8 @@ ble_stack_srcs_dirs+= src/cli_cmds
endif
ble_stack_srcs_include_dirs += src/port/include \
src/common \
src \
src/common \
src/common/include \
src/common/include/zephyr \
src/common/include/misc \
@ -116,6 +117,11 @@ ble_stack_srcs += src/services/oad/oad_main.c \
src/services/oad/oad_service.c
endif
ifeq ($(CONFIG_BT_SPP_SERVER),1)
ble_stack_srcs += src/services/spp.c
endif
ifeq ($(CONFIG_BT_STACK_CLI),1)
ble_stack_srcs += src/cli_cmds/ble_cli_cmds.c \
src/cli_cmds/bredr_cli_cmds.c \
@ -134,10 +140,19 @@ ifeq ($(CONFIG_BT_DIS_SERVER),1)
ble_stack_srcs += src/services/dis.c
endif
ifeq ($(CONFIG_BT_IAS_SERVER),1)
ble_stack_srcs += src/services/ias.c
endif
ifeq ($(CONFIG_HOGP_SERVER),1)
ble_stack_srcs += src/services/hog.c
endif
ifeq ($(CONFIG_ATVV_SERVER),1)
ble_stack_srcs += src/services/atvv.c
endif
ifeq ($(CONFIG_BLE_TP_SERVER),1)
ble_stack_srcs += src/services/ble_tp_svc.c
endif

View File

@ -293,6 +293,7 @@ static void bl_onchiphci_rx_packet_handler(uint8_t pkt_type, uint16_t src_id, ui
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
}
#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_ALLROLES)
else if(pkt_type == BT_HCI_LE_EVT && param[0] == BT_HCI_EVT_LE_ADVERTISING_REPORT)
{
if(bt_buf_get_rx_avail_cnt() <= CONFIG_BT_RX_BUF_RSV_COUNT){
@ -307,6 +308,7 @@ static void bl_onchiphci_rx_packet_handler(uint8_t pkt_type, uint16_t src_id, ui
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
}
#endif /*(CONFIG_BT_OBSERVER || CONFIG_BT_CENTRAL || CONFIG_BT_ALLROLES)*/
else
{
if(pkt_type != BT_HCI_ACL_DATA){

View File

@ -17,6 +17,7 @@
#include "hog.h"
#endif
#define PASSKEY_MAX 0xF423F
#define NAME_LEN 30
#define CHAR_SIZE_MAX 512
@ -103,6 +104,17 @@ static void blecli_set_tx_pwr(char *pcWriteBuffer, int xWriteBufferLen, int argc
#if defined(CONFIG_HOGP_SERVER)
static void blecli_hog_srv_notify(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif
#if defined(BFLB_BLE_DYNAMIC_SERVICE)
#if defined(CONFIG_BT_PERIPHERAL)
#if defined(CONFIG_BT_SPP_SERVER)
static void blecli_add_spp_service(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void blecli_del_spp_service(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif
static void blecli_gatts_get_service_info(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void blecli_gatts_get_char(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void blecli_gatts_get_desp(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
#endif
#endif
const struct cli_command btStackCmdSet[] STATIC_CLI_CMD_ATTRIBUTE = {
#if 1
@ -218,7 +230,17 @@ const struct cli_command btStackCmdSet[] STATIC_CLI_CMD_ATTRIBUTE = {
#if defined(CONFIG_HOGP_SERVER)
{"ble_hog_srv_notify", "HOG srv notify\r\nParameter [hid usage] [press]\r\n", blecli_hog_srv_notify},
#endif
#if defined(BFLB_BLE_DYNAMIC_SERVICE)
#if defined(CONFIG_BT_PERIPHERAL)
#if defined(CONFIG_BT_SPP_SERVER)
{"ble_add_spp_svc", "", blecli_add_spp_service},
{"ble_del_spp_svc", "", blecli_del_spp_service},
#endif
{"ble_get_svc_info","",blecli_gatts_get_service_info},
{"ble_get_svc_char","",blecli_gatts_get_char},
{"ble_get_svc_desp","",blecli_gatts_get_desp},
#endif
#endif
#else
{"ble_init", "", blecli_init},
#if defined(CONFIG_BLE_TP_SERVER)
@ -352,6 +374,10 @@ static void disconnected(struct bt_conn *conn, u8_t reason)
#endif
if (default_conn == conn) {
#if defined(CONFIG_BT_CENTRAL)
if(conn->role == BT_HCI_ROLE_MASTER)
bt_conn_unref(conn);
#endif
default_conn = NULL;
}
}
@ -1714,7 +1740,85 @@ static void blecli_hog_srv_notify(char *pcWriteBuffer, int xWriteBufferLen, int
}
}
#endif
#if defined(BFLB_BLE_DYNAMIC_SERVICE)
#if defined(CONFIG_BT_PERIPHERAL)
#if defined(CONFIG_BT_SPP_SERVER)
static void blecli_add_spp_service(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
extern void bt_dyn_register_spp_srv(void);
bt_dyn_register_spp_srv();
}
static void blecli_del_spp_service(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
void bt_dyn_unregister_spp_srv(void);
bt_dyn_unregister_spp_srv();
}
#endif
static void blecli_gatts_get_service_info(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
struct simple_svc_info svc_info[2];
uint16_t svc_id;
if(argc != 2){
vOutputString("Number of Parameters is not correct\r\n");
return;
}
memset(svc_info,0,sizeof(svc_info));
get_uint16_from_string(&argv[1],&svc_id);
bt_gatts_get_service_simple_info(svc_id,&svc_info[0],sizeof(svc_info)/sizeof(struct simple_svc_info));
for(int i=0;i<sizeof(svc_info)/sizeof(struct simple_svc_info);i++){
vOutputString("svc_info : i(%d),idx(%d),state(%d),uuid(%s),type(%d)\r\n",i,svc_info[i].idx,svc_info[i].state,
svc_info[i].uuid,svc_info[i].type);
}
}
static void blecli_gatts_get_char(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
struct char_info cinfo[3];
uint16_t svc_id;
if(argc != 2){
vOutputString("Number of Parameters is not correct\r\n");
return;
}
memset(cinfo,0,sizeof(cinfo));
get_uint16_from_string(&argv[1],&svc_id);
bt_gatts_get_service_char(svc_id,cinfo,sizeof(cinfo)/sizeof(struct char_info));
for(int i=0;i<sizeof(cinfo)/sizeof(struct char_info);i++){
vOutputString("svc_info : i(%d),idx(%d),char_idx(0x%x),uuid(%s),prop(%d)\r\n",i,cinfo[i].svc_idx,cinfo[i].char_idx,
cinfo[i].uuid,cinfo[i].prop);
}
}
static void blecli_gatts_get_desp(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
{
struct descrip_info dinfo[4];
uint16_t svc_id;
memset(dinfo,0,sizeof(dinfo));
if(argc != 2){
vOutputString("Number of Parameters is not correct\r\n");
return;
}
get_uint16_from_string(&argv[1],&svc_id);
bt_gatts_get_service_desc(svc_id,dinfo,sizeof(dinfo)/sizeof(struct descrip_info));
for(int i=0;i<sizeof(dinfo)/sizeof(struct descrip_info);i++){
vOutputString("svc_info : i(%d),idx(%d),char_idx(0x%x),uuid(%s),desp_idx(0x%x)\r\n",i,dinfo[i].svc_idx,dinfo[i].char_idx,
dinfo[i].uuid,dinfo[i].desp_idx);
}
}
#endif
#endif
int ble_cli_register(void)
{
// static command(s) do NOT need to call aos_cli_register_command(s) to register.

View File

@ -9,6 +9,7 @@
#include <byteorder.h>
#include <bluetooth.h>
#include <hci_host.h>
#include <hci_core.h>
#include <conn.h>
#include <conn_internal.h>
#include <l2cap.h>
@ -18,7 +19,9 @@
#if CONFIG_BT_AVRCP
#include <avrcp.h>
#endif
#if CONFIG_BT_AVRCP
#include <rfcomm.h>
#endif
#include "cli.h"
#if PCM_PRINTF
@ -39,44 +42,88 @@ static struct bt_conn_cb conn_callbacks = {
.disconnected = bredr_disconnected,
};
#if CONFIG_BT_A2DP
static void a2dp_chain(struct bt_conn *conn, uint8_t state);
static void a2dp_stream(uint8_t state);
static struct a2dp_callback a2dp_callbacks =
{
.chain = a2dp_chain,
.stream = a2dp_stream,
};
#endif
#if CONFIG_BT_AVRCP
static void avrcp_chain(struct bt_conn *conn, uint8_t state);
static void avrcp_absvol(uint8_t vol);
static void avrcp_play_status(uint32_t song_len, uint32_t song_pos, uint8_t status);
static struct avrcp_callback avrcp_callbacks =
{
.chain = avrcp_chain,
.abs_vol = avrcp_absvol,
.play_status = avrcp_play_status,
};
#endif
#if PCM_PRINTF
static void pcm(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
#endif
static void bredr_init(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
static void bredr_write_local_name(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_write_eir(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_discoverable(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_connectable(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_disconnect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void bredr_remote_name(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
#if CONFIG_BT_A2DP
static void a2dp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
#endif
#if CONFIG_BT_AVRCP
static void avrcp_pasthr_key(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void avrcp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void avrcp_pth_key(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void avrcp_pth_key_act(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void avrcp_change_vol(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void avrcp_get_play_status(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
#endif
#if CONFIG_BT_HFP
static void hfp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
static void sco_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv);
#endif
const struct cli_command bredr_cmd_set[] STATIC_CLI_CMD_ATTRIBUTE = {
#if PCM_PRINTF
{"pcm", "", pcm},
#endif
{"bredr_init", "", bredr_init},
{"bredr_name", "", bredr_write_local_name},
{"bredr_eir", "", bredr_write_eir},
{"bredr_connectable", "", bredr_connectable},
{"bredr_discoverable", "", bredr_discoverable},
{"bredr_connect", "", bredr_connect},
{"bredr_disconnect", "", bredr_disconnect},
{"bredr_remote_name", "", bredr_remote_name},
#if CONFIG_BT_A2DP
{"a2dp_connect", "", a2dp_connect},
#endif
#if CONFIG_BT_AVRCP
{"avrcp_pasthr_key", "", avrcp_pasthr_key},
{"avrcp_connect", "", avrcp_connect},
{"avrcp_pth_key", "", avrcp_pth_key},
{"avrcp_pth_key_act", "", avrcp_pth_key_act},
{"avrcp_change_vol", "", avrcp_change_vol},
{"avrcp_play_status", "", avrcp_get_play_status},
#endif
#if CONFIG_BT_HFP
{"hfp_connect", "", hfp_connect},
{"sco_connect", "", sco_connect},
#endif
};
@ -119,6 +166,12 @@ static void bredr_init(char *pcWriteBuffer, int xWriteBufferLen, int argc, char
default_conn = NULL;
bt_conn_cb_register(&conn_callbacks);
#if CONFIG_BT_A2DP
a2dp_cb_register(&a2dp_callbacks);
#endif
#if CONFIG_BT_AVRCP
avrcp_cb_register(&avrcp_callbacks);
#endif
init = true;
printf("bredr init successfully\n");
@ -150,7 +203,7 @@ static void bredr_connected(struct bt_conn *conn, u8_t err)
}
bt_br_set_connectable(false);
bt_br_set_discoverable(false);
}
static void bredr_disconnected(struct bt_conn *conn, u8_t reason)
@ -173,11 +226,24 @@ static void bredr_disconnected(struct bt_conn *conn, u8_t reason)
}
}
static void bredr_write_local_name(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
char *name = "BL-BT";
err = bt_br_write_local_name(name);
if (err) {
printf("BR/EDR write local name failed, (err %d)\n", err);
} else {
printf("BR/EDR write local name done.\n");
}
}
static void bredr_write_eir(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
char *name = "Bouffalolab-classic-bluetooth";
uint8_t rec = 1;
uint8_t fec = 1;
uint8_t data[32] = {0};
data[0] = 30;
@ -190,7 +256,7 @@ static void bredr_write_eir(char *p_write_buffer, int write_buffer_len, int argc
}
printf("\n");
err = bt_br_write_eir(rec, data);
err = bt_br_write_eir(fec, data);
if (err) {
printf("BR/EDR write EIR failed, (err %d)\n", err);
} else {
@ -254,6 +320,30 @@ static void bredr_connectable(char *p_write_buffer, int write_buffer_len, int ar
}
}
static void bredr_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
struct bt_conn *conn;
u8_t addr_val[6];
bt_addr_t peer_addr;
struct bt_br_conn_param param;
char addr_str[18];
get_bytearray_from_string(&argv[1], addr_val, 6);
reverse_bytearray(addr_val, peer_addr.val, 6);
bt_addr_to_str(&peer_addr, addr_str, sizeof(addr_str));
printf("%s, create bredr connection with : %s \n", __func__, addr_str);
param.allow_role_switch = true;
conn = bt_conn_create_br(&peer_addr, &param);
if (conn) {
printf("Connect bredr ACL success.\n");
} else {
printf("Connect bredr ACL fail.\n");
}
}
static void bredr_disconnect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
if(!default_conn){
@ -261,16 +351,109 @@ static void bredr_disconnect(char *p_write_buffer, int write_buffer_len, int arg
return;
}
if(bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN)){
int err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
if (err) {
printf("Disconnection failed.\n");
}else{
} else {
printf("Disconnect successfully.\n");
}
}
void remote_name(const char *name)
{
if (name) {
printf("%s, remote name len: %d, : %s\n", __func__, strlen(name), name);
} else {
printf("%s, remote name request fail\n", __func__);
}
}
static void bredr_remote_name(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
struct bt_conn *conn;
u8_t addr_val[6];
bt_addr_t peer_addr;
char addr_str[18];
get_bytearray_from_string(&argv[1], addr_val, 6);
reverse_bytearray(addr_val, peer_addr.val, 6);
bt_addr_to_str(&peer_addr, addr_str, sizeof(addr_str));
printf("%s, create bredr connection with : %s \n", __func__, addr_str);
int err = remote_name_req(&peer_addr, remote_name);
if (!err) {
printf("remote name request pending.\n");
} else {
printf("remote name request fail.\n");
}
}
#if CONFIG_BT_A2DP
static void a2dp_chain(struct bt_conn *conn, uint8_t state)
{
printf("%s, conn: %p \n", __func__, conn);
if (state == BT_A2DP_CHAIN_CONNECTED) {
printf("a2dp connected. \n");
} else if (state == BT_A2DP_CHAIN_DISCONNECTED) {
printf("a2dp disconnected. \n");
}
}
static void a2dp_stream(uint8_t state)
{
printf("%s, state: %d \n", __func__, state);
if (state == BT_A2DP_STREAM_START) {
printf("a2dp play. \n");
} else if (state == BT_A2DP_STREAM_SUSPEND) {
printf("a2dp stop. \n");
}
}
static void a2dp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int ret;
if(!default_conn){
printf("Not connected.\n");
return;
}
ret = bt_a2dp_connect(default_conn);
if(ret) {
printf("a2dp connect successfully.\n");
} else {
printf("a2dp connect fail. \n");
}
}
#endif
#if CONFIG_BT_AVRCP
static void avrcp_chain(struct bt_conn *conn, uint8_t state)
{
printf("%s, conn: %p \n", __func__, conn);
if (state == BT_AVRCP_CHAIN_CONNECTED) {
printf("avrcp connected. \n");
} else if (state == BT_AVRCP_CHAIN_DISCONNECTED) {
printf("avrcp disconnected. \n");
}
}
static void avrcp_absvol(uint8_t vol)
{
printf("%s, vol: %d \n", __func__, vol);
}
static void avrcp_play_status(uint32_t song_len, uint32_t song_pos, uint8_t status)
{
printf("%s, song length: %d, song position: %d, play status: %d \n", __func__, song_len, song_pos, status);
}
static void avrcp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
@ -279,20 +462,19 @@ static void a2dp_connect(char *p_write_buffer, int write_buffer_len, int argc, c
return;
}
err = bt_a2dp_connect(default_conn);
err = bt_avrcp_connect(default_conn);
if(err) {
printf("a2dp connect failed, err: %d\n", err);
printf("avrcp connect failed, err: %d\n", err);
} else {
printf("a2dp connect successfully.\n");
printf("avrcp connect successfully.\n");
}
}
#endif
#if CONFIG_BT_AVRCP
static void avrcp_pasthr_key(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
static void avrcp_pth_key(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
uint8_t key;
if(!default_conn){
printf("Not connected.\n");
return;
@ -302,18 +484,45 @@ static void avrcp_pasthr_key(char *p_write_buffer, int write_buffer_len, int arg
err = avrcp_pasthr_cmd(NULL, PASTHR_STATE_PRESSED, key);
if(err) {
printf("avrcp pass through play pressed failed, err: %d\n", err);
printf("avrcp key pressed failed, err: %d\n", err);
} else {
printf("avrcp pass through play pressed successfully.\n");
printf("avrcp key pressed successfully.\n");
}
err = avrcp_pasthr_cmd(NULL, PASTHR_STATE_RELEASED, key);
if(err) {
printf("avrcp pass through play released failed, err: %d\n", err);
printf("avrcp key released failed, err: %d\n", err);
} else {
printf("avrcp pass through play released successfully.\n");
printf("avrcp key play released successfully.\n");
}
}
static void avrcp_pth_key_act(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
uint8_t key;
uint8_t action;
if(!default_conn){
printf("Not connected.\n");
return;
}
get_uint8_from_string(&argv[1], &key);
get_uint8_from_string(&argv[2], &action);
if (action != PASTHR_STATE_PRESSED && action != PASTHR_STATE_RELEASED)
{
printf("invalid key action.\n");
return;
}
err = avrcp_pasthr_cmd(NULL, action, key);
if(err) {
printf("avrcp key action failed, err: %d\n", err);
} else {
printf("avrcp %s key %d successfully.\n", action ? "released":"pressed", key);
}
}
static void avrcp_change_vol(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
@ -327,10 +536,100 @@ static void avrcp_change_vol(char *p_write_buffer, int write_buffer_len, int arg
get_uint8_from_string(&argv[1], &vol);
err = avrcp_change_volume(vol);
if(err) {
if (err) {
printf("avrcp change volume fail\n");
} else {
printf("avrcp change volume success\n");
}
}
static void avrcp_get_play_status(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
if(!default_conn){
printf("Not connected.\n");
return;
}
err = avrcp_get_play_status_cmd(NULL);
if(err) {
printf("avrcp get play status fail\n");
} else {
printf("avrcp get play status success\n");
}
}
#endif
#if CONFIG_BT_HFP
static void rfcomm_recv(struct bt_rfcomm_dlc *dlci, struct net_buf *buf)
{
printf("hfp incoming data dlc %p len %u \n", dlci, buf->len);
}
static void rfcomm_connected(struct bt_rfcomm_dlc *dlci)
{
printf("hfp dlc %p connected \n", dlci);
}
static void rfcomm_disconnected(struct bt_rfcomm_dlc *dlci)
{
printf("hfp dlc %p disconnected \n", dlci);
}
static struct bt_rfcomm_dlc_ops rfcomm_ops = {
.recv = rfcomm_recv,
.connected = rfcomm_connected,
.disconnected = rfcomm_disconnected,
};
static struct bt_rfcomm_dlc rfcomm_dlc = {
.ops = &rfcomm_ops,
.mtu = 30,
};
static void hfp_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
int err;
if(!default_conn){
printf("Not connected.\n");
return;
}
err = bt_rfcomm_dlc_connect(default_conn, &rfcomm_dlc, 0x01);
if (err) {
printf("hfp connect fail.\n");
} else {
printf("hfp connect pending.\n");
}
}
static void sco_connect(char *p_write_buffer, int write_buffer_len, int argc, char **argv)
{
struct bt_conn *conn;
u8_t addr_val[6];
bt_addr_t peer_addr;
char addr_str[18];
get_bytearray_from_string(&argv[1], addr_val, 6);
reverse_bytearray(addr_val, peer_addr.val, 6);
bt_addr_to_str(&peer_addr, addr_str, sizeof(addr_str));
printf("%s, create sco connection with : %s \n", __func__, addr_str);
if(!default_conn){
printf("Not connected.\n");
return;
}
conn = bt_conn_create_sco(&peer_addr);
if (!conn) {
printf("sco connect fail.\n");
} else {
printf("sco connect success.\n");
}
}
#endif

View File

@ -164,8 +164,8 @@ void net_buf_init(struct net_buf_pool *buf_pool, u16_t buf_count, size_t data_si
#endif
{
struct net_buf_pool_fixed *buf_fixed;
buf_pool->alloc = (struct net_buf_data_alloc *)k_malloc(sizeof(void *));
buf_pool->alloc->alloc_data = (struct net_buf_pool_fixed *)k_malloc(sizeof(void *));
buf_pool->alloc = (struct net_buf_data_alloc *)k_malloc(sizeof(struct net_buf_data_alloc));
buf_pool->alloc->alloc_data = (struct net_buf_pool_fixed *)k_malloc(sizeof(struct net_buf_pool_fixed));
buf_fixed = (struct net_buf_pool_fixed *)buf_pool->alloc->alloc_data;
@ -453,6 +453,12 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size,
NET_BUF_DBG("%s():%d: pool %p size %zu timeout %d", func, line, pool,
size, timeout);
#if (BFLB_BT_CO_THREAD)
extern struct k_thread co_thread_data;
if(k_is_current_thread(&co_thread_data))
timeout = K_NO_WAIT;
#endif
/* We need to lock interrupts temporarily to prevent race conditions
* when accessing pool->uninit_count.
*/

View File

@ -1,133 +0,0 @@
/* errno.h - errno numbers */
/*
* Copyright (c) 1984-1999, 2012 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)errno.h 7.1 (Berkeley) 6/4/86
*/
#ifndef __INCerrnoh
#define __INCerrnoh
#ifdef __cplusplus
extern "C" {
#endif
extern int *__errno(void);
#define errno (*__errno())
/*
* POSIX Error codes
*/
#define EPERM 1 /* Not owner */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such context */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No children */
#define EAGAIN 11 /* No more contexts */
#define ENOMEM 12 /* Not enough core */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTEMPTY 15 /* Directory not empty */
#define EBUSY 16 /* Mount device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ENAMETOOLONG 26 /* File name too long */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDEADLK 33 /* Resource deadlock avoided */
#define ENOLCK 34 /* No locks available */
#define ENOTSUP 35 /* Unsupported value */
#define EMSGSIZE 36 /* Message size */
/* ANSI math software */
#define EDOM 37 /* Argument too large */
#define ERANGE 38 /* Result too large */
/* ipc/network software */
/* argument errors */
#define EDESTADDRREQ 40 /* Destination address required */
#define EPROTOTYPE 41 /* Protocol wrong type for socket */
#define ENOPROTOOPT 42 /* Protocol not available */
#define EPROTONOSUPPORT 43 /* Protocol not supported */
#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
#define EOPNOTSUPP 45 /* Operation not supported on socket */
#define EPFNOSUPPORT 46 /* Protocol family not supported */
#define EAFNOSUPPORT 47 /* Addr family not supported */
#define EADDRINUSE 48 /* Address already in use */
#define EADDRNOTAVAIL 49 /* Can't assign requested address */
#define ENOTSOCK 50 /* Socket operation on non-socket */
/* operational errors */
#define ENETUNREACH 51 /* Network is unreachable */
#define ENETRESET 52 /* Network dropped connection on reset */
#define ECONNABORTED 53 /* Software caused connection abort */
#define ECONNRESET 54 /* Connection reset by peer */
#define ENOBUFS 55 /* No buffer space available */
#define EISCONN 56 /* Socket is already connected */
#define ENOTCONN 57 /* Socket is not connected */
#define ESHUTDOWN 58 /* Can't send after socket shutdown */
#define ETOOMANYREFS 59 /* Too many references: can't splice */
#define ETIMEDOUT 60 /* Connection timed out */
#define ECONNREFUSED 61 /* Connection refused */
#define ENETDOWN 62 /* Network is down */
#define ETXTBSY 63 /* Text file busy */
#define ELOOP 64 /* Too many levels of symbolic links */
#define EHOSTUNREACH 65 /* No route to host */
#define ENOTBLK 66 /* Block device required */
#define EHOSTDOWN 67 /* Host is down */
/* non-blocking and interrupt i/o */
#define EINPROGRESS 68 /* Operation now in progress */
#define EALREADY 69 /* Operation already in progress */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOSYS 71 /* Function not implemented */
/* aio errors (should be under posix) */
#define ECANCELED 72 /* Operation canceled */
#define ERRMAX 81
/* specific STREAMS errno values */
#define ENOSR 74 /* Insufficient memory */
#define ENOSTR 75 /* STREAMS device required */
#define EPROTO 76 /* Generic STREAMS error */
#define EBADMSG 77 /* Invalid STREAMS message */
#define ENODATA 78 /* Missing expected message data */
#define ETIME 79 /* STREAMS timeout occurred */
#define ENOMSG 80 /* Unexpected message type */
#ifdef __cplusplus
}
#endif
#endif /* __INCerrnoh */

View File

@ -154,14 +154,26 @@ static inline void set_event_ready(struct k_poll_event *event, u32_t state)
event->state |= state;
}
#if (BFLB_BT_CO_THREAD)
static bool polling_events(struct k_poll_event *events, int num_events, int total_evt_array_cnt,
s32_t timeout, int *last_registered)
#else
static bool polling_events(struct k_poll_event *events, int num_events,
s32_t timeout, int *last_registered)
#endif
{
int rc;
bool polling = true;
unsigned int key;
#if (BFLB_BT_CO_THREAD)
for (int ii = 0; ii < total_evt_array_cnt; ii++)
{
if(ii >= num_events && ii != total_evt_array_cnt-1)
continue;
#else
for (int ii = 0; ii < num_events; ii++) {
#endif
u32_t state;
key = irq_lock();
if (is_condition_met(&events[ii], &state)) {
@ -180,7 +192,11 @@ static bool polling_events(struct k_poll_event *events, int num_events,
return polling;
}
#if (BFLB_BT_CO_THREAD)
int k_poll(struct k_poll_event *events, int num_events, int total_evt_array_cnt, s32_t timeout, u8_t *to_process)
#else
int k_poll(struct k_poll_event *events, int num_events, s32_t timeout)
#endif
{
__ASSERT(events, "NULL events\n");
__ASSERT(num_events > 0, "zero events\n");
@ -190,16 +206,32 @@ int k_poll(struct k_poll_event *events, int num_events, s32_t timeout)
bool polling = true;
/* find events whose condition is already fulfilled */
#if (BFLB_BT_CO_THREAD)
polling = polling_events(events, num_events, total_evt_array_cnt, timeout, &last_registered);
#else
polling = polling_events(events, num_events, timeout, &last_registered);
if (polling == false) {
#endif
if (polling == false) {
goto exit;
}
#if (BFLB_BT_CO_THREAD)
if(timeout != K_NO_WAIT)
#endif
{
k_sem_take(&g_poll_sem, timeout);
last_registered = -1;
#if (BFLB_BT_CO_THREAD)
polling = polling_events(events, num_events, total_evt_array_cnt, timeout, &last_registered);
#else
polling_events(events, num_events, timeout, &last_registered);
#endif
}
k_sem_take(&g_poll_sem, timeout);
last_registered = -1;
polling_events(events, num_events, timeout, &last_registered);
#if (BFLB_BT_CO_THREAD)
if(to_process)
*to_process = polling?0:1;
#endif
exit:
key = irq_lock();
clear_event_registrations(events, last_registered, key);

View File

@ -28,10 +28,25 @@ static void k_work_submit_to_queue(struct k_work_q *work_q,
{
if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) {
k_fifo_put(&work_q->fifo, work);
#if (BFLB_BT_CO_THREAD)
extern struct k_sem g_poll_sem;
k_sem_give(&g_poll_sem);
#endif
}
}
#if defined(BFLB_BLE)
#if (BFLB_BT_CO_THREAD)
void handle_work_queue(void)
{
struct k_work *work;
work = k_fifo_get(&g_work_queue_main.fifo, K_NO_WAIT);
if (atomic_test_and_clear_bit(work->flags, K_WORK_STATE_PENDING)) {
work->handler(work);
}
}
#else
static void work_queue_main(void *p1)
{
struct k_work *work;
@ -55,6 +70,7 @@ int k_work_q_start(void)
CONFIG_BT_WORK_QUEUE_STACK_SIZE,
work_queue_main, CONFIG_BT_WORK_QUEUE_PRIO);
}
#endif
int k_work_init(struct k_work *work, k_work_handler_t handler)
{

View File

@ -51,11 +51,6 @@ static K_SEM_DEFINE(sem_prio_recv, 0, BT_UINT_MAX);
#endif
K_FIFO_DEFINE(recv_fifo);
#if (BFLB_BLE_CO_THREAD)
extern struct k_sem g_poll_sem;
static int recv_fifo_count = 0;
#endif
#if !defined(BFLB_BLE)
struct k_thread prio_recv_thread_data;
static BT_STACK_NOINIT(prio_recv_thread_stack,
@ -292,37 +287,6 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
#endif
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
void co_rx_thread()
{
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_NO_WAIT);
if(buf){
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
}
void co_tx_rx_thread(void *p1)
{
UNUSED(p1);
BT_DBG("using %s\n", __func__);
while (1) {
if (k_sem_count_get(&g_poll_sem) > 0) {
co_tx_thread();
}
if (recv_fifo_count > 0) {
recv_fifo_count--;
co_rx_thread();
}
k_sleep(portTICK_PERIOD_MS);
k_yield();
}
}
#else
static void recv_thread(void *p1)
{
UNUSED(p1);
@ -400,7 +364,6 @@ static void recv_thread(void *p1)
}
}
#endif
#endif
#if !defined(BFLB_BLE)
static int cmd_handle(struct net_buf *buf)
@ -502,15 +465,11 @@ static int hci_driver_open(void)
hci_init(NULL);
#endif
#endif
#if (!BFLB_BT_CO_THREAD)
k_fifo_init(&recv_fifo, 20);
#endif
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
k_thread_create(&recv_thread_data, "co_tx_rx_thread",
CONFIG_BT_RX_STACK_SIZE,
co_tx_rx_thread,
K_PRIO_COOP(CONFIG_BT_RX_PRIO));
#else
#if (!BFLB_BT_CO_THREAD)
k_thread_create(&recv_thread_data, "recv_thread",
CONFIG_BT_RX_STACK_SIZE/*K_THREAD_STACK_SIZEOF(recv_thread_stack)*/,
recv_thread,
@ -531,9 +490,10 @@ k_thread_create(&recv_thread_data, "co_tx_rx_thread",
void hci_driver_enque_recvq(struct net_buf *buf)
{
net_buf_put(&recv_fifo, buf);
#if (BFLB_BLE_CO_THREAD)
recv_fifo_count++;
#endif
#if (BFLB_BT_CO_THREAD)
extern struct k_sem g_poll_sem;
k_sem_give(&g_poll_sem);
#endif
}
static const struct bt_hci_driver drv = {

View File

@ -2271,7 +2271,14 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,
return;
}
k_sem_take(&att->tx_sem, K_FOREVER);
#if (BFLB_BT_CO_THREAD)
if (k_sem_take(&att->tx_sem, K_NO_WAIT) < 0) {
k_fifo_put(&att->tx_queue, att->req->buf);
return;
}
#else
k_sem_take(&att->tx_sem, K_FOREVER);
#endif
if (!att_is_connected(att)) {
BT_WARN("Disconnected");
k_sem_give(&att->tx_sem);

View File

@ -561,6 +561,7 @@ struct bt_conn *bt_conn_create_br(const bt_addr_t *peer,
bt_conn_set_state(conn, BT_CONN_CONNECT);
conn->role = BT_CONN_ROLE_MASTER;
bt_conn_unref(conn);
return conn;
}
@ -1384,10 +1385,21 @@ int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf,
tx_data(buf)->tx = NULL;
}
#if (BFLB_BT_CO_THREAD)
if(k_is_current_thread(bt_get_co_thread()))
bt_conn_process_tx(conn, buf);
else
net_buf_put(&conn->tx_queue, buf);
#if defined(BFLB_BLE)
k_sem_give(&g_poll_sem);
#endif
#else//BFLB_BT_CO_THREAD
net_buf_put(&conn->tx_queue, buf);
#if defined(BFLB_BLE)
k_sem_give(&g_poll_sem);
#endif
#endif //BFLB_BT_CO_THREAD
return 0;
}
@ -1613,7 +1625,11 @@ int bt_conn_prepare_events(struct k_poll_event events[])
return ev_count;
}
#if (BFLB_BT_CO_THREAD)
void bt_conn_process_tx(struct bt_conn *conn, struct net_buf *tx_buf)
#else
void bt_conn_process_tx(struct bt_conn *conn)
#endif
{
struct net_buf *buf;
@ -1625,9 +1641,15 @@ void bt_conn_process_tx(struct bt_conn *conn)
conn_cleanup(conn);
return;
}
#if (BFLB_BT_CO_THREAD)
if(tx_buf)
buf = tx_buf;
else
buf = net_buf_get(&conn->tx_queue, K_NO_WAIT);
#else
/* Get next ACL packet for connection */
buf = net_buf_get(&conn->tx_queue, K_NO_WAIT);
#endif
BT_ASSERT(buf);
if (!send_buf(conn, buf)) {
net_buf_unref(buf);

View File

@ -332,7 +332,12 @@ struct k_sem *bt_conn_get_pkts(struct bt_conn *conn);
/* k_poll related helpers for the TX thread */
int bt_conn_prepare_events(struct k_poll_event events[]);
#if (BFLB_BT_CO_THREAD)
void bt_conn_process_tx(struct bt_conn *conn, struct net_buf *tx_buf);
#else
void bt_conn_process_tx(struct bt_conn *conn);
#endif
#if defined(BFLB_BLE)
/** @brief Get connection handle for a connection.

View File

@ -774,7 +774,7 @@ static u8_t found_attr(const struct bt_gatt_attr *attr, void *user_data)
return BT_GATT_ITER_STOP;
}
static const struct bt_gatt_attr *find_attr(uint16_t handle)
const struct bt_gatt_attr *find_attr(uint16_t handle)
{
const struct bt_gatt_attr *attr = NULL;
@ -1085,7 +1085,12 @@ static void sc_indicate(u16_t start, u16_t end)
#endif
if (!update_range(&gatt_sc.start, &gatt_sc.end, start, end)) {
return;
#if defined (BFLB_BLE_PATCH_SET_SCRANGE_CHAGD_ONLY_IN_CONNECTED_STATE)
if(conn){
bt_conn_unref(conn);
}
#endif
return;
}
submit:
@ -1336,6 +1341,9 @@ uint16_t bt_gatt_attr_value_handle(const struct bt_gatt_attr *attr)
/* Fall back to Zephyr value handle policy */
handle = (attr->handle ? : find_static_attr(attr)) + 1U;
}
#else
if(handle == 0)
handle = attr->handle+1;
#endif
}
@ -1922,6 +1930,8 @@ int bt_gatt_notify_cb(struct bt_conn *conn,
}
#if !defined(BFLB_BLE_DISABLE_STATIC_ATTR)
handle = attr->handle ? : find_static_attr(attr);
#else
handle = attr->handle;
#endif
if (!handle) {
return -ENOENT;
@ -1986,6 +1996,8 @@ int bt_gatt_indicate(struct bt_conn *conn,
}
#if !defined(BFLB_BLE_DISABLE_STATIC_ATTR)
handle = attr->handle ? : find_static_attr(attr);
#else
handle = attr->handle;
#endif
if (!handle) {
return -ENOENT;
@ -4759,4 +4771,536 @@ last:
return last_handle;
}
#endif
#if defined(BFLB_BLE_DYNAMIC_SERVICE)
#if defined(CONFIG_BT_PERIPHERAL)
static sys_slist_t custom_services_db;
static sys_slist_t custom_desp_db;
static uint16_t service_idx = 0;
static uint16_t attr_idx = 0;
static struct bt_uuid *primary = BT_UUID_GATT_PRIMARY;
static struct bt_uuid *include = BT_UUID_GATT_INCLUDE;
static struct bt_uuid *chrc = BT_UUID_GATT_CHRC;
int bt_gatts_add_serv_attr(const struct bt_uuid *uuid, uint8_t is_primary,uint32_t number_attrs)
{
const struct bt_uuid *srv_uuid = NULL;
struct bt_gatt_attr attr_info;
struct bt_gatt_service *serv_info = NULL;
struct customer_svc_list *list;
srv_uuid = uuid;
if(!srv_uuid){
return -ENOBUFS;
}
if(!serv_info){
serv_info = (struct bt_gatt_service *)k_malloc(sizeof(struct bt_gatt_service));
if(!serv_info){
return -ENOBUFS;
}
}
memset(serv_info,0,sizeof(struct bt_gatt_service));
if(!serv_info->attrs){
serv_info->attrs = (struct bt_gatt_attr *)k_malloc(sizeof(struct bt_gatt_attr) * number_attrs);
if(!serv_info->attrs){
return -ENOBUFS;
}
}
memset(serv_info->attrs,0,sizeof(struct bt_gatt_attr)*number_attrs);
serv_info->attr_count = number_attrs;
if(is_primary){
attr_info.uuid = primary;
}else{
attr_info.uuid = include;
}
attr_info.read = bt_gatt_attr_read_service;
attr_info.write = NULL;
attr_info.user_data = (void *)srv_uuid;
attr_info.handle = 0;
attr_info.perm = BT_GATT_PERM_READ;
memcpy(serv_info->attrs,&attr_info,sizeof(struct bt_gatt_attr));
attr_idx++;
list = (struct customer_svc_list *)k_malloc(sizeof(struct customer_svc_list));
list->svc = serv_info;
sys_slist_append(&custom_services_db, &list->node);
return 0;
}
int bt_gatts_add_char(const struct bt_gatt_attr *char_attr,uint32_t val_prop)
{
struct bt_gatt_chrc char_dec_val;
struct bt_gatt_attr char_dec;
struct bt_uuid *char_uuid = NULL;
struct bt_gatt_attr char_val;
struct bt_gatt_service *last;
struct customer_svc_list *last_list;
last_list = SYS_SLIST_PEEK_TAIL_CONTAINER(&custom_services_db, last_list, node);
if(!last_list){
BT_ERR("Not found svc list");
return -ENOBUFS;
}
last = last_list->svc;
if(!last){
BT_ERR("Not found service");
return -ENOBUFS;
}
if(!char_attr){
BT_ERR("Attr is NULL");
return -EINVAL;
}
char_uuid = char_attr->uuid;
memset(&char_dec, 0, sizeof(struct bt_gatt_attr));
char_dec.uuid = chrc;
char_dec.read = bt_gatt_attr_read_chrc;
char_dec.write = NULL;
char_dec_val.uuid = char_uuid;
char_dec_val.value_handle = 0;
char_dec_val.properties = val_prop;
char_dec.user_data = (struct bt_gatt_chrc *)k_malloc(sizeof(struct bt_gatt_chrc));
if(!char_dec.user_data){
k_free(char_uuid);
return -ENOBUFS;
}
memcpy(char_dec.user_data, &char_dec_val, sizeof(struct bt_gatt_chrc));
char_dec.handle = 0;
char_dec.perm = BT_GATT_PERM_READ;
memcpy(last->attrs+attr_idx,&char_dec,sizeof(struct bt_gatt_attr));
attr_idx++;
memset(&char_val, 0, sizeof(struct bt_gatt_attr));
char_val.uuid = char_uuid;
char_val.read = char_attr->read;
char_val.write = char_attr->write;
char_val.user_data = char_attr->user_data;
char_val.handle = 0;
char_val.perm = char_attr->perm;
memcpy(last->attrs+attr_idx,&char_val,sizeof(struct bt_gatt_attr));
attr_idx++;
return 0;
}
int bt_gatts_add_desc(const struct bt_gatt_attr *desp_attr)
{
struct bt_uuid *desc_uuid = NULL;
struct _bt_gatt_ccc *ccc = NULL;
struct bt_gatt_attr desc_attr;
struct bt_gatt_service *last;
struct add_gatts_attr *d;
struct customer_svc_list *list;
list = SYS_SLIST_PEEK_TAIL_CONTAINER(&custom_services_db, list, node);
if(!list){
BT_ERR("Not found service list");
return -ENOBUFS;
}
last = list->svc;
if(!last){
BT_ERR("Not found service");
return -ENOBUFS;
}
if(!desp_attr){
return -EINVAL;
}
desc_uuid = desp_attr->uuid;
if(!desc_uuid)
return -ENOBUFS;
desc_attr.uuid = desc_uuid;
if(!bt_uuid_cmp(desc_uuid, BT_UUID_GATT_CCC)){
ccc = (struct _bt_gatt_ccc *)k_malloc(sizeof(struct _bt_gatt_ccc));
if(!ccc){
k_free(desc_uuid);
return -ENOBUFS;
}
memset(ccc,0,sizeof(struct _bt_gatt_ccc));
ccc->cfg_changed = NULL;
ccc->cfg_write = NULL;
ccc->cfg_match = NULL;
desc_attr.read = bt_gatt_attr_read_ccc;
desc_attr.write = bt_gatt_attr_write_ccc;
desc_attr.user_data = (void *)ccc;
}else{
desc_attr.read = desp_attr->read;
desc_attr.write = desp_attr->write;
desc_attr.user_data = desp_attr->user_data;
}
desc_attr.handle = 0;
desc_attr.perm = desp_attr->perm;
memcpy(last->attrs+attr_idx,&desc_attr,sizeof(struct bt_gatt_attr));
d = (struct add_gatts_attr*)k_malloc(sizeof(struct add_gatts_attr));
d->attr = last->attrs+attr_idx;
attr_idx++;
sys_slist_append(&custom_desp_db, &d->node);
return 0;
}
static int bt_gatts_free_service_list(struct bt_gatt_service *svc)
{
struct customer_svc_list *tmp_svc_list;
uint16_t id = 0;
if(sys_slist_is_empty(&custom_services_db)){
BT_ERR("Regsitered service list is empty");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_services_db, tmp_svc_list, node){
if(tmp_svc_list && tmp_svc_list->svc == svc){
sys_slist_find_and_remove(&custom_services_db,&tmp_svc_list->node);
k_free(tmp_svc_list);
}
}
return id;
}
int bt_gatts_get_service_simple_info(uint16_t svc_id,struct simple_svc_info *info,uint16_t info_num)
{
struct simple_svc_info *sinfo = info;
struct customer_svc_list *tmp;
struct bt_gatt_service *dtmp;
struct bt_gatt_attr *attr = NULL;
int svc_idx = 0;
int state = 0;
if(sys_slist_is_empty(&custom_services_db)){
BT_ERR("No service registered yet");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_services_db, tmp, node){
if(tmp){
SYS_SLIST_FOR_EACH_CONTAINER(&db, dtmp, node){
if(dtmp == tmp->svc){
state = 1;
}
}
svc_idx = tmp->svc_idx;
if(svc_idx == svc_id){
attr = tmp->svc->attrs;
for(int i = 1,info_idx=1; i < tmp->svc->attr_count && info_idx <= info_num; i++){
if(attr && attr->uuid && sinfo){
if(!bt_uuid_cmp(attr->uuid,BT_UUID_GATT_PRIMARY)){
sinfo->type = 1;
sinfo->idx = svc_idx;
sinfo->state = state;
struct bt_uuid *srv_uuid = (struct bt_uuid *)(attr->user_data);
bt_uuid_to_str(srv_uuid,sinfo->uuid,sizeof(sinfo->uuid));
info_idx++;
sinfo += info_idx;
}else if(!bt_uuid_cmp(attr->uuid,BT_UUID_GATT_SECONDARY) ||
!bt_uuid_cmp(attr->uuid,BT_UUID_GATT_INCLUDE)){
sinfo->type = 0;
sinfo->idx = svc_idx;
sinfo->state = state;
struct bt_uuid *srv_uuid = (struct bt_uuid *)(attr->user_data);
bt_uuid_to_str(srv_uuid,sinfo->uuid,sizeof(sinfo->uuid));
info_idx++;
sinfo += info_idx;
}
attr += i;
}
}
}else{
state = 0;
}
}
}
return 0;
}
int bt_gatts_get_service_char(uint16_t svc_id,struct char_info *info,uint16_t char_num)
{
struct char_info *cinfo = info;
struct customer_svc_list *tmp;
struct bt_gatt_attr *attr = NULL;
int svc_idx = 0;
int info_idx = 0;
if(sys_slist_is_empty(&custom_services_db)){
BT_ERR("No service registered yet");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_services_db, tmp, node){
if(tmp && tmp->svc && cinfo){
svc_idx = tmp->svc_idx;
if(svc_idx == svc_id){
attr = tmp->svc->attrs;
for(int i = 1; i < tmp->svc->attr_count && info_idx < char_num; i++){
if(cinfo && attr && attr->uuid &&
!bt_uuid_cmp(attr->uuid,BT_UUID_GATT_CHRC)){
struct bt_gatt_chrc *gatt_chrc = (struct bt_gatt_chrc *)attr->user_data;
cinfo->prop = gatt_chrc->properties;
cinfo->char_idx = bt_gatt_attr_value_handle(attr);
if(++attr){
bt_uuid_to_str(attr->uuid,cinfo->uuid,sizeof(cinfo->uuid));
cinfo->svc_idx = svc_idx;
}
info_idx++;
cinfo = info + info_idx;
}
attr = tmp->svc->attrs + i;
}
}
}
}
return 0;
}
static int attr_is_descptor(struct bt_gatt_attr *desp_attr)
{
struct add_gatts_attr *tmp_attr;
int ret = -1;
if(sys_slist_is_empty(&custom_desp_db)){
BT_ERR("No descriptor registered yet");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_desp_db, tmp_attr, node){
if(tmp_attr){
if(tmp_attr->attr == desp_attr){
ret = 0;
}
}
}
return ret;
}
static int free_attr_descptor(struct bt_gatt_attr *desp_attr)
{
struct add_gatts_attr *tmp_attr;
if(sys_slist_is_empty(&custom_desp_db)){
BT_ERR("No descriptor registered yet");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_desp_db, tmp_attr, node){
if(tmp_attr){
if(tmp_attr->attr == desp_attr){
//sys_slist_find_and_remove(&custom_desp_db,&tmp_attr->node);
k_free(tmp_attr);
}
}
}
return 0;
}
static int bt_gatts_get_service_desp(struct bt_gatt_service *svc,
struct descrip_info *info,uint16_t desp_num)
{
uint16_t phdl = 0;
uint16_t nhdl = 0;
int num_desp = 0;
int hdl = 0;
int idx = 0;
for(idx=0;idx<desp_num;idx++){
if(info[idx].char_idx){
phdl = info[idx].char_idx;
if(idx+1 > desp_num)
goto last;
nhdl = info[idx+1].char_idx;
const struct bt_gatt_attr *s = find_attr(phdl);
const struct bt_gatt_attr *p = find_attr(nhdl);
for(const struct bt_gatt_attr *d = s;d<p;d++){
if(d && !attr_is_descptor(d)){
bt_uuid_to_str(d->uuid,info[idx].uuid,sizeof(info[idx].uuid));
info[idx].desp_idx = info[idx].char_idx + d - s;
}
}
}
}
last:
if(svc){
struct bt_gatt_attr * a = find_attr(phdl);
num_desp = svc->attrs + svc->attr_count - a - 2;
for(int id=0;id<desp_num;id++){
if(phdl==info[id].char_idx){
info[id].desp_idx = phdl + 2;
while(num_desp>0){
info[id].desp_idx += hdl;
const struct bt_gatt_attr *temp_attr = find_attr(info[id].desp_idx);
if(temp_attr){
bt_uuid_to_str(temp_attr->uuid,info[id].uuid,sizeof(info[id].uuid));
}
num_desp--;
hdl++;
}
}
}
}
return 0;
}
static int bt_gatts_get_service_char_hdl(struct bt_gatt_service *svc,uint16_t svc_id,
struct descrip_info *info,uint16_t desp_num)
{
int idx = 0;
struct descrip_info *dinfo = info;
if(!svc){
return -EINVAL;
}
struct bt_gatt_attr *attr = svc->attrs;
for(int i = 1; i < (svc->attr_count - 1); i++){
if(dinfo && attr && attr->uuid){
if(!bt_uuid_cmp(attr->uuid,BT_UUID_GATT_CHRC)){
if(idx<=desp_num){
dinfo->svc_idx = svc_id;
dinfo->char_idx = bt_gatt_attr_value_handle(attr) - 1;
idx++;
dinfo = info + idx;
}else{
BT_WARN("number (%d),idx (%d)",desp_num,idx);
return -1;
}
}
attr = svc->attrs + i;
}
}
return 0;
}
int bt_gatts_get_service_desc(uint16_t svc_id,struct descrip_info *info,uint16_t desp_num)
{
struct descrip_info *dinfo = info;
struct customer_svc_list *tmp;
int svc_idx = 0;
uint8_t uuid[37] = {0};
if(sys_slist_is_empty(&custom_services_db)){
BT_ERR("No service registered yet");
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&custom_services_db, tmp, node){
if(tmp && dinfo){
svc_idx = tmp->svc_idx;
if(svc_id == svc_idx){
bt_gatts_get_service_char_hdl(tmp->svc,svc_idx,dinfo,desp_num);
bt_gatts_get_service_desp(tmp->svc,dinfo,desp_num);
}
}
}
for(int i=0;i<desp_num;i++){
if(!memcmp(info[i].uuid,uuid,sizeof(info[i].uuid))){
if(i+1 < desp_num){
memcpy(&info[i],&info[i+1],sizeof(struct descrip_info));
memset(&info[i+1],0,sizeof(struct descrip_info));
}
}
}
return 0;
}
uint16_t bt_gatts_add_service(void)
{
int ret;
struct bt_gatt_service *serv_info;
struct customer_svc_list *list;
list = SYS_SLIST_PEEK_TAIL_CONTAINER(&custom_services_db, list, node);
if(!list){
BT_ERR("list is NULL");
return -ENOBUFS;
}
serv_info = list->svc;
if(serv_info->attr_count != attr_idx){
BT_ERR("Invalid attribution count (%d) attr_idx(%d)",serv_info->attr_count,attr_idx);
return -EINVAL;
}
ret = gatt_register(serv_info);
if(!ret){
service_idx++;
attr_idx = 0;
}
list->svc_idx = service_idx;
return service_idx;
}
int bt_gatts_del_service(uint16_t svc_id)
{
int ret = 0;
int svc_idx = 0;
struct bt_gatt_attr *pattr = NULL;
struct customer_svc_list *svc_list;
struct bt_gatt_service *serv_info;
SYS_SLIST_FOR_EACH_CONTAINER(&custom_services_db, svc_list, node){
if(svc_list && svc_list->svc){
svc_idx = svc_list->svc_idx;
serv_info = svc_list->svc;
if(svc_id == svc_idx){
ret = bt_gatt_service_unregister(serv_info);
bt_gatts_free_service_list(serv_info);
for(int i = 0; i < serv_info->attr_count; i++){
pattr = serv_info->attrs + i;
if(pattr && pattr->user_data &&
(!bt_uuid_cmp(pattr->uuid,BT_UUID_GATT_CHRC) || !bt_uuid_cmp(pattr->uuid,BT_UUID_GATT_CCC))){
k_free(pattr->user_data);
}
if(pattr && !attr_is_descptor(pattr)){
free_attr_descptor(pattr);
}
}
if(serv_info && serv_info->attrs){
k_free(serv_info->attrs);
serv_info->attrs = NULL;
}
if(serv_info){
k_free(serv_info);
serv_info = NULL;
}
}
}
}
return ret;
}
#endif
#endif

View File

@ -67,12 +67,18 @@
#define HCI_CMD_TIMEOUT K_SECONDS(10)
extern struct k_fifo recv_fifo;
extern struct k_work_q g_work_queue_main;
/* Stacks for the threads */
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
static struct k_thread rx_thread_data;
static K_THREAD_STACK_DEFINE(rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
#endif
#if (!BFLB_BLE_CO_THREAD)
#if (BFLB_BT_CO_THREAD)
struct k_thread co_thread_data;
static void process_events(struct k_poll_event *ev, int count, int total_evt_array_cnt);
static void send_cmd(struct net_buf *tx_buf);
#else
static struct k_thread tx_thread_data;
#endif
#if !defined(BFLB_BLE)
@ -142,6 +148,24 @@ volatile u8_t event_flag = 0;
struct blhast_cb *host_assist_cb;
#endif
#if (BFLB_BT_CO_THREAD)
#if defined(CONFIG_BT_CONN)
/* command FIFO + conn_change signal + rxqueue + workQueue + MAX_CONN */
#define EV_COUNT (4 + CONFIG_BT_MAX_CONN)
#else
/* command FIFO + rxqueue + workQueue + MAX_CONN */
#define EV_COUNT 3
#endif
#else
#if defined(CONFIG_BT_CONN)
/* command FIFO + conn_change signal + MAX_CONN */
#define EV_COUNT (2 + CONFIG_BT_MAX_CONN)
#else
/* command FIFO */
#define EV_COUNT 1
#endif
#endif //BFLB_BT_CO_THREAD
struct cmd_state_set {
atomic_t *target;
int bit;
@ -169,7 +193,9 @@ struct cmd_data {
/** The state to update when command completes with success. */
struct cmd_state_set *state;
#if (BFLB_BT_CO_THREAD)
uint8_t sync_state;
#endif
/** Used by bt_hci_cmd_send_sync. */
struct k_sem *sync;
};
@ -228,7 +254,9 @@ struct net_buf_pool discardable_pool;
#endif
#endif /*!defined(BFLB_DYNAMIC_ALLOC_MEM)*/
#if defined CONFIG_BT_HFP
extern bool hfp_codec_msbc;
#endif
struct event_handler {
u8_t event;
@ -398,6 +426,61 @@ int bt_hci_cmd_send(u16_t opcode, struct net_buf *buf)
return 0;
}
#if (BFLB_BT_CO_THREAD)
struct k_thread *bt_get_co_thread(void)
{
return &co_thread_data;
}
static void bt_hci_sync_check(struct net_buf *buf)
{
static struct k_poll_event events[EV_COUNT] = {
[0] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&g_work_queue_main.fifo,
BT_EVENT_WORK_QUEUE),
[1] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&bt_dev.cmd_tx_queue,
BT_EVENT_CMD_TX),
#if defined(CONFIG_BT_CONN)
[EV_COUNT -1] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&recv_fifo,
BT_EVENT_RX_QUEUE),
#endif
};
uint32_t time_start = k_uptime_get_32();
send_cmd(buf);
while (1)
{
int ev_count, err;
u8_t to_process = 0;
events[0].state = K_POLL_STATE_NOT_READY;
events[1].state = K_POLL_STATE_NOT_READY;
events[EV_COUNT -1].state = K_POLL_STATE_NOT_READY;
ev_count = 2;
if (IS_ENABLED(CONFIG_BT_CONN)) {
ev_count += bt_conn_prepare_events(&events[2]);
}
err = k_poll(events, ev_count, EV_COUNT, K_NO_WAIT, &to_process);
BT_ASSERT(err == 0);
if(to_process)
process_events(events, ev_count, EV_COUNT);
if ((cmd(buf)->sync_state == BT_CMD_SYNC_TX_DONE) ||
(k_uptime_get_32() - time_start) >= HCI_CMD_TIMEOUT)
{
break;
}
}
}
#endif
#if defined(BFLB_HOST_ASSISTANT)
extern void blhast_bt_reset(void);
uint16_t hci_cmd_to_cnt = 0;
@ -407,6 +490,9 @@ int bt_hci_cmd_send_sync(u16_t opcode, struct net_buf *buf,
{
struct k_sem sync_sem;
int err;
#if (BFLB_BT_CO_THREAD)
bool is_bt_co_thread = k_is_current_thread(&co_thread_data);
#endif
if (!buf) {
buf = bt_hci_cmd_create(opcode, 0);
@ -416,9 +502,21 @@ int bt_hci_cmd_send_sync(u16_t opcode, struct net_buf *buf,
}
BT_DBG("buf %p opcode 0x%04x len %u", buf, opcode, buf->len);
#if (BFLB_BT_CO_THREAD)
if(is_bt_co_thread)
{
cmd(buf)->sync_state = BT_CMD_SYNC_TX;
cmd(buf)->sync = NULL;
}else{
k_sem_init(&sync_sem, 0, 1);
cmd(buf)->sync = &sync_sem;
cmd(buf)->sync_state = BT_CMD_SYNC_NONE;
}
#else
k_sem_init(&sync_sem, 0, 1);
cmd(buf)->sync = &sync_sem;
#endif
#if defined(BFLB_BLE)
/*Assign a initial value to status in order to check if hci cmd timeout*/
@ -428,16 +526,32 @@ int bt_hci_cmd_send_sync(u16_t opcode, struct net_buf *buf,
/* Make sure the buffer stays around until the command completes */
net_buf_ref(buf);
net_buf_put(&bt_dev.cmd_tx_queue, buf);
#if defined(BFLB_BLE)
#if (BFLB_BT_CO_THREAD)
if(is_bt_co_thread)
bt_hci_sync_check(buf);
else{
net_buf_put(&bt_dev.cmd_tx_queue, buf);
#if defined(BFLB_BLE)
k_sem_give(&g_poll_sem);
#endif
err = k_sem_take(&sync_sem, HCI_CMD_TIMEOUT);
#ifdef BFLB_BLE_PATCH_FREE_ALLOCATED_BUFFER_IN_OS
k_sem_delete(&sync_sem);
#endif
__ASSERT(err == 0, "k_sem_take failed with err %d", err);
}
#else
net_buf_put(&bt_dev.cmd_tx_queue, buf);
#if defined(BFLB_BLE)
k_sem_give(&g_poll_sem);
#endif
#endif
err = k_sem_take(&sync_sem, HCI_CMD_TIMEOUT);
#ifdef BFLB_BLE_PATCH_FREE_ALLOCATED_BUFFER_IN_OS
#ifdef BFLB_BLE_PATCH_FREE_ALLOCATED_BUFFER_IN_OS
k_sem_delete(&sync_sem);
#endif
#endif
__ASSERT(err == 0, "k_sem_take failed with err %d", err);
#endif//#if (BFLB_BT_CO_THREAD)
BT_DBG("opcode 0x%04x status 0x%02x", opcode, cmd(buf)->status);
if (cmd(buf)->status) {
@ -2131,18 +2245,17 @@ static int accept_sco_conn(const bt_addr_t *bdaddr, struct bt_conn *sco_conn)
cp->tx_bandwidth = 0x00001f40;
cp->rx_bandwidth = 0x00001f40;
if (!hfp_codec_msbc) {
cp->max_latency = 0x0007;
cp->retrans_effort = 0x01;
cp->content_format = BT_VOICE_CVSD_16BIT;
BT_DBG("eSCO air coding CVSD!");
} else {
cp->max_latency = 0x0007;
cp->retrans_effort = 0x01;
cp->content_format = BT_VOICE_CVSD_16BIT;
#if defined CONFIG_BT_HFP
if (!hfp_codec_msbc) {
cp->max_latency = 0x000d;
cp->retrans_effort = 0x02;
cp->content_format = BT_VOICE_MSBC_16BIT;
BT_DBG("eSCO air coding mSBC!");
}
}
#endif
err = bt_hci_cmd_send_sync(BT_HCI_OP_ACCEPT_SYNC_CONN_REQ, buf, NULL);
if (err) {
return err;
@ -2744,6 +2857,25 @@ static int request_name(const bt_addr_t *addr, u8_t pscan, u16_t offset)
return bt_hci_cmd_send_sync(BT_HCI_OP_REMOTE_NAME_REQUEST, buf, NULL);
}
bredr_name_callback name_callback = NULL;
int remote_name_req(const bt_addr_t *addr, bredr_name_callback cb)
{
u8_t pscan = 0x01;
u16_t clock_offset = 0x00;
name_callback = cb;
return request_name(addr, pscan, clock_offset);
}
void remote_name_complete(u8_t *name)
{
if (name_callback)
{
name_callback((const char *)name);
}
}
#define EIR_SHORT_NAME 0x08
#define EIR_COMPLETE_NAME 0x09
@ -2956,6 +3088,11 @@ static void remote_name_request_complete(struct net_buf *buf)
int eir_len = 240;
u8_t *eir;
int i;
BT_DBG("remote name:%s", evt->name);
if (evt->name) {
remote_name_complete(evt->name);
}
result = get_result_slot(&evt->bdaddr, 0xff);
if (!result) {
@ -3738,11 +3875,21 @@ static void hci_cmd_done(u16_t opcode, u8_t status, struct net_buf *buf)
atomic_set_bit_to(update->target, update->bit, update->val);
}
#if (BFLB_BT_CO_THREAD)
/* If the command was synchronous wake up bt_hci_cmd_send_sync() */
if (cmd(buf)->sync) {
if (cmd(buf)->sync || cmd(buf)->sync_state) {
cmd(buf)->status = status;
if(cmd(buf)->sync_state)
cmd(buf)->sync_state = BT_CMD_SYNC_TX_DONE;
else
k_sem_give(cmd(buf)->sync);
}
#else
if (cmd(buf)->sync) {
cmd(buf)->status = status;
k_sem_give(cmd(buf)->sync);
}
#endif//BFLB_BT_CO_THREAD
}
static void hci_cmd_complete(struct net_buf *buf)
@ -4254,14 +4401,29 @@ static void hci_event(struct net_buf *buf)
net_buf_unref(buf);
}
#if (BFLB_BT_CO_THREAD)
static void send_cmd(struct net_buf *tx_buf)
#else
static void send_cmd(void)
#endif
{
struct net_buf *buf;
int err;
#if (BFLB_BT_CO_THREAD)
if(tx_buf)
{
buf = tx_buf;
}
else
{
buf = net_buf_get(&bt_dev.cmd_tx_queue, K_NO_WAIT);
}
#else
/* Get next command */
BT_DBG("calling net_buf_get");
buf = net_buf_get(&bt_dev.cmd_tx_queue, K_NO_WAIT);
#endif
BT_ASSERT(buf);
/* Wait until ncmd > 0 */
@ -4291,27 +4453,64 @@ static void send_cmd(void)
}
}
#if (BFLB_BT_CO_THREAD)
static void handle_rx_queue(void)
{
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_NO_WAIT);
if(buf){
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
}
#endif
#if (BFLB_BT_CO_THREAD)
static void process_events(struct k_poll_event *ev, int count, int total_evt_array_cnt)
#else
static void process_events(struct k_poll_event *ev, int count)
#endif
{
BT_DBG("count %d", count);
#if (BFLB_BT_CO_THREAD)
for (int ii = 0; ii < total_evt_array_cnt; ev++,ii++) {
if(ii >= count && ii != total_evt_array_cnt-1)
continue;
#else
for (; count; ev++, count--) {
BT_DBG("ev->state %u", ev->state);
#endif
BT_DBG("ev->state %u", ev->state);
switch (ev->state) {
case K_POLL_STATE_SIGNALED:
break;
case K_POLL_STATE_FIFO_DATA_AVAILABLE:
if (ev->tag == BT_EVENT_CMD_TX) {
#if (BFLB_BT_CO_THREAD)
send_cmd(NULL);
#else
send_cmd();
} else if (IS_ENABLED(CONFIG_BT_CONN)) {
#endif
}
#if (BFLB_BT_CO_THREAD)
else if(ev->tag == BT_EVENT_RX_QUEUE ){
handle_rx_queue();
}else if(ev->tag == BT_EVENT_WORK_QUEUE ){
extern void handle_work_queue(void);
handle_work_queue();
}
#endif
else if (IS_ENABLED(CONFIG_BT_CONN)) {
struct bt_conn *conn;
if (ev->tag == BT_EVENT_CONN_TX_QUEUE) {
conn = CONTAINER_OF(ev->fifo,
struct bt_conn,
tx_queue);
#if (BFLB_BT_CO_THREAD)
bt_conn_process_tx(conn, NULL);
#else
bt_conn_process_tx(conn);
#endif
}
}
break;
@ -4324,40 +4523,58 @@ static void process_events(struct k_poll_event *ev, int count)
}
}
#if defined(CONFIG_BT_CONN)
/* command FIFO + conn_change signal + MAX_CONN */
#define EV_COUNT (2 + CONFIG_BT_MAX_CONN)
#else
/* command FIFO */
#define EV_COUNT 1
#endif
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
void co_tx_thread()
#if (BFLB_BT_CO_THREAD)
static void bt_co_thread(void *p1, void *p2, void *p3)
{
static struct k_poll_event events[EV_COUNT] = {
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
[0] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&g_work_queue_main.fifo,
BT_EVENT_WORK_QUEUE),
[1] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&bt_dev.cmd_tx_queue,
BT_EVENT_CMD_TX),
[EV_COUNT -1] = K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&recv_fifo,
BT_EVENT_RX_QUEUE),
};
if (k_sem_count_get(&g_poll_sem) > 0) {
BT_DBG("Started");
while (1) {
int ev_count, err;
events[0].state = K_POLL_STATE_NOT_READY;
ev_count = 1;
events[1].state = K_POLL_STATE_NOT_READY;
events[EV_COUNT -1].state = K_POLL_STATE_NOT_READY;
ev_count = 2;
if (IS_ENABLED(CONFIG_BT_CONN)) {
ev_count += bt_conn_prepare_events(&events[1]);
ev_count += bt_conn_prepare_events(&events[2]);
}
err = k_poll(events, ev_count, K_NO_WAIT);
process_events(events, ev_count);
BT_DBG("Calling k_poll with %d events", ev_count);
err = k_poll(events, ev_count, EV_COUNT, K_FOREVER, NULL);
BT_ASSERT(err == 0);
process_events(events, ev_count, EV_COUNT);
/* Make sure we don't hog the CPU if there's all the time
* some ready events.
*/
k_yield();
}
}
#endif
#else
#if defined(BFLB_BLE)
static void hci_tx_thread(void *p1)
#else
static void hci_tx_thread(void *p1, void *p2, void *p3)
@ -4395,7 +4612,7 @@ static void hci_tx_thread(void *p1, void *p2, void *p3)
k_yield();
}
}
#endif //BFLB_BT_CO_THREAD
static void read_local_ver_complete(struct net_buf *buf)
{
@ -5710,7 +5927,11 @@ int bt_enable(bt_ready_cb_t cb)
#endif
k_work_init(&bt_dev.init, init_work);
#if (BFLB_BT_CO_THREAD)
k_fifo_init(&g_work_queue_main.fifo, 20);
#else
k_work_q_start();
#endif
#if !defined(CONFIG_BT_WAIT_NOP)
k_sem_init(&bt_dev.ncmd_sem, 1, 1);
#else
@ -5722,6 +5943,10 @@ int bt_enable(bt_ready_cb_t cb)
#endif
k_sem_init(&g_poll_sem, 0, 1);
#if (BFLB_BT_CO_THREAD)
//need to initialize recv_fifo before create bt_co_thread
k_fifo_init(&recv_fifo, 20);
#endif
#endif
#if defined(BFLB_BLE_PATCH_SETTINGS_LOAD)
@ -5748,7 +5973,12 @@ int bt_enable(bt_ready_cb_t cb)
/* TX thread */
#if defined(BFLB_BLE)
#if (!BFLB_BLE_CO_THREAD)
#if (BFLB_BT_CO_THREAD)
k_thread_create(&co_thread_data, "bt_co_thread",
CONFIG_BT_CO_STACK_SIZE,
bt_co_thread,
CONFIG_BT_CO_TASK_PRIO);
#else
k_thread_create(&tx_thread_data, "hci_tx_thread",
CONFIG_BT_HCI_TX_STACK_SIZE,
hci_tx_thread,
@ -5820,9 +6050,7 @@ bool le_check_valid_scan(void)
#if defined(BFLB_DISABLE_BT)
extern struct k_thread recv_thread_data;
extern struct k_thread work_q_thread;
extern struct k_fifo recv_fifo;
extern struct k_fifo free_tx;
extern struct k_work_q g_work_queue_main;
#if defined(CONFIG_BT_SMP)
extern struct k_sem sc_local_pkey_ready;
#endif
@ -5845,10 +6073,12 @@ extern struct net_buf_pool prep_pool;
#if defined(CONFIG_BT_BREDR)
extern struct net_buf_pool br_sig_pool;
extern struct net_buf_pool sdp_pool;
#if defined CONFIG_BT_HFP
extern struct net_buf_pool hf_pool;
extern struct net_buf_pool dummy_pool;
#endif
#endif
#endif
int bt_disable_action(void)
{
@ -5895,9 +6125,11 @@ int bt_disable_action(void)
#if defined(CONFIG_BT_BREDR)
net_buf_deinit(&br_sig_pool);
net_buf_deinit(&sdp_pool);
#if defined CONFIG_BT_HFP
net_buf_deinit(&hf_pool);
net_buf_deinit(&dummy_pool);
#endif
#endif
#endif//defined(CONFIG_BT_CONN)
#if defined(CONFIG_BT_DISCARDABLE_BUF_COUNT)
net_buf_deinit(&discardable_pool);
@ -5908,9 +6140,13 @@ int bt_disable_action(void)
//delete task
ble_controller_deinit();
#if (BFLB_BT_CO_THREAD)
k_thread_delete(&co_thread_data);
#else
k_thread_delete(&tx_thread_data);
k_thread_delete(&work_q_thread);
k_thread_delete(&recv_thread_data);
#endif
return 0;
}
@ -6677,6 +6913,14 @@ int bt_le_read_rssi(u16_t handle,int8_t *rssi)
int set_adv_enable(bool enable)
{
int err;
if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
return -EAGAIN;
}
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
return -EALREADY;
}
err = set_advertise_enable(enable);
if (err) {
return err;
@ -7381,6 +7625,34 @@ int bt_set_tx_pwr(int8_t power)
}
#endif
int bt_set_bd_addr(const bt_addr_t *addr)
{
struct bt_hci_cp_vs_set_bd_addr set_param;
struct net_buf *buf;
int err;
memset(&set_param, 0, sizeof(set_param));
memcpy(&set_param.bdaddr,addr,sizeof(*addr));
buf = bt_hci_cmd_create(BT_HCI_OP_VS_SET_BD_ADDR, sizeof(set_param));
if (!buf) {
return -ENOBUFS;
}
net_buf_add_mem(buf, &set_param, sizeof(set_param));
err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_SET_BD_ADDR, buf, NULL);
if (err) {
return err;
}
return 0;
}
int bt_buf_get_rx_avail_cnt(void)
{
return (k_queue_get_cnt(&hci_rx_pool.free._queue) \
@ -7660,7 +7932,24 @@ int bt_br_set_discoverable(bool enable)
}
}
int bt_br_write_eir(u8_t rec, u8_t *data)
int bt_br_write_local_name(char *name)
{
struct bt_hci_write_local_name *local_name;
struct net_buf *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_LOCAL_NAME, sizeof(*local_name));
if (!buf) {
return -ENOBUFS;
}
local_name = net_buf_add(buf, sizeof(*local_name));
memset(local_name, 0, sizeof(*local_name));
memcpy(local_name->local_name, name, strlen(name));
return bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_LOCAL_NAME, buf, NULL);
}
int bt_br_write_eir(u8_t fec, u8_t *data)
{
struct bt_hci_cp_write_ext_inquiry_resp *ext_ir;
struct net_buf *buf;
@ -7673,7 +7962,7 @@ int bt_br_write_eir(u8_t rec, u8_t *data)
ext_ir = net_buf_add(buf, sizeof(*ext_ir));
memset(ext_ir, 0, sizeof(*ext_ir));
ext_ir->rec= rec;
ext_ir->fec= fec;
memcpy(ext_ir->eir, data, strlen((char *)data));
return bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_EXT_INQUIRY_RESP, buf, NULL);

View File

@ -20,10 +20,22 @@
#define BT_VOICE_CVSD_16BIT 0x0060
#define BT_VOICE_MSBC_16BIT 0x0063
#if (BFLB_BT_CO_THREAD)
enum{
BT_CMD_SYNC_NONE =0,
BT_CMD_SYNC_TX = 1,
BT_CMD_SYNC_TX_DONE = 2
};
#endif
/* k_poll event tags */
enum {
BT_EVENT_CMD_TX,
BT_EVENT_CONN_TX_QUEUE,
#if (BFLB_BT_CO_THREAD)
BT_EVENT_RX_QUEUE,
BT_EVENT_WORK_QUEUE,
#endif
};
/* bt_dev flags: the flags defined here represent BT controller state */
@ -270,6 +282,10 @@ int bt_le_set_data_len(struct bt_conn *conn, u16_t tx_octets, u16_t tx_time);
int hci_le_set_phy(struct bt_conn *conn, uint8_t all_phys,
uint8_t pref_tx_phy, uint8_t pref_rx_phy, uint8_t phy_opts);
int hci_le_set_default_phy(u8_t default_phy);
/* Notice: Use of this API will lead to mismatch between chip mac address
and address set by this API.
In some condition, BD address may be reset to chip mac address.*/
int bt_set_bd_addr(const bt_addr_t *addr);
#if defined(CONFIG_SET_TX_PWR)
@ -289,4 +305,7 @@ void bt_hci_reset_complete(struct net_buf *buf);
void bt_register_host_assist_cb(struct blhast_cb *cb);
#endif
typedef void (*bredr_name_callback)(const char *name);
int remote_name_req(const bt_addr_t *addr, bredr_name_callback cb);
#endif

View File

@ -852,10 +852,15 @@ struct bt_bond_info {
void bt_foreach_bond(u8_t id, void (*func)(const struct bt_bond_info *info, void *user_data),
void *user_data);
/**
* write local name.
*/
int bt_br_write_local_name(char *name);
/**
* write extern inquiry response.
*/
int bt_br_write_eir(u8_t rec, u8_t *data);
int bt_br_write_eir(u8_t fec, u8_t *data);
/**
* @}
*/

View File

@ -1391,7 +1391,106 @@ void bt_gatt_register_notification_callback(bt_notification_all_cb_t cb);
*/
void bt_gatt_ccc_load(void);
#endif
#if defined(BFLB_BLE_DYNAMIC_SERVICE)
#if defined(CONFIG_BT_PERIPHERAL)
struct simple_svc_info{
/*service index*/
uint16_t idx;
/*service state*/
uint8_t state;
/*service type*/
uint8_t type;
/*service uuid*/
char uuid[37];
};
struct char_info{
/*service index*/
uint16_t svc_idx;
/*characteristics index*/
uint16_t char_idx;
/*characteristics value's uuid*/
char uuid[37];
/*characteristics value's properties*/
uint8_t prop;
};
struct descrip_info{
/*service index*/
uint16_t svc_idx;
/*characteristics index*/
uint16_t char_idx;
/*descriptor index*/
uint16_t desp_idx;
/*descriptor's uuid*/
char uuid[37];
};
struct add_gatts_attr{
struct bt_gatt_attr *attr;
sys_snode_t node;
};
struct customer_svc_list{
struct bt_gatt_service *svc;
uint16_t svc_idx;
sys_snode_t node;
};
/** @brief Add service
*
* @param service_uuid UUID of the service.
* @param is_primary 1 indicates the primary service, 0 indicates other services.
* @param number_attrs Number of attributes in the service.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_add_serv_attr(const struct bt_uuid *uuid, uint8_t is_primary,uint32_t number_attrs);
/** @brief Add characteristics and characteristic value
*
* @param char_attr characteristics attribution.
* @param val_prop characteristic value .
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_add_char(const struct bt_gatt_attr *char_attr,uint32_t val_prop);
/** @brief Add descriptor
*
* @param desp_attr characteristics attribution.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_add_desc(const struct bt_gatt_attr *desp_attr);
/** @brief Get simple service information.
* @param svc_id ID of the service.
* @param info Pointer to a simple service information structure.
* @param info_num Number of Simple Service Information Structures.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_get_service_simple_info(uint16_t svc_id,struct simple_svc_info *info,uint16_t info_num);
/** @brief Get service characteristics.
* @param svc_id ID of the service.
* @param info Pointer to service characteristics information structure.
* @param info_num Number of service characteristics.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_get_service_char(uint16_t svc_id,struct char_info *info,uint16_t char_num);
/** @brief Get service characteristics descriptor.
* @param svc_id ID of the service.
* @param info Pointer to service characteristics descriptor information structure.
* @param info_num Number of service characteristics descriptor.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_get_service_desc(uint16_t svc_id,struct descrip_info *info,uint16_t desp_num);
/** @brief Register service.
* @return service id(>0) in case of success.
*/
uint16_t bt_gatts_add_service(void);
/** @brief Add Unregister service.
* @param svc_id ID of the service.
* @param desp_attr characteristics attribution.
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatts_del_service(uint16_t svc_id);
#endif
#endif
#ifdef __cplusplus
}
#endif

View File

@ -546,7 +546,7 @@ struct bt_hci_cp_write_page_scan_type {
#define BT_HCI_OP_WRITE_EXT_INQUIRY_RESP BT_OP(BT_OGF_BASEBAND, 0x0052)
struct bt_hci_cp_write_ext_inquiry_resp {
u8_t rec;
u8_t fec;
u8_t eir[240];
} __packed;
@ -2641,6 +2641,10 @@ typedef bool bt_hci_vnd_evt_cb_t(struct net_buf_simple *buf);
*/
int bt_hci_register_vnd_evt_cb(bt_hci_vnd_evt_cb_t cb);
#if (BFLB_BT_CO_THREAD)
struct k_thread *bt_get_co_thread(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -140,6 +140,12 @@ struct bt_hci_cp_vs_set_tx_pwr {
}__packed;
#endif
#define BT_HCI_OP_VS_SET_BD_ADDR BT_OP(BT_OGF_VS, 0x0062)
struct bt_hci_cp_vs_set_bd_addr {
bt_addr_t bdaddr;
}__packed;
/* Events */
struct bt_hci_evt_vs {

View File

@ -137,6 +137,10 @@ struct bt_uuid_128 {
* @brief Generic Attribute
*/
#define BT_UUID_GATT BT_UUID_DECLARE_16(0x1801)
/** @def BT_UUID_IAS
* @brief Immediate Alert Service
*/
#define BT_UUID_IAS BT_UUID_DECLARE_16(0x1802)
/** @def BT_UUID_CTS
* @brief Current Time Service
*/
@ -257,6 +261,10 @@ struct bt_uuid_128 {
* @brief GATT Characteristic Service Changed
*/
#define BT_UUID_GATT_SC BT_UUID_DECLARE_16(0x2a05)
/** @def BT_UUID_IAS_ALERT_LEVEL
* @brief IAS Characteristic Alert Level
*/
#define BT_UUID_IAS_ALERT_LEVEL BT_UUID_DECLARE_16(0x2a06)
/** @def BT_UUID_BAS_BATTERY_LEVEL
* @brief BAS Characteristic Battery Level
*/

View File

@ -194,10 +194,6 @@ void hci_driver_enque_recvq(struct net_buf *buf);
int hci_driver_init(void);
#if (BFLB_BLE_CO_THREAD)
void co_tx_thread();
#endif
#endif //#if (BFLB_BLE)
#ifdef __cplusplus

View File

@ -253,19 +253,28 @@ int k_thread_create(struct k_thread *new_thread, const char *name,
return new_thread->task? 0 : -1;
}
void k_thread_delete(struct k_thread *new_thread)
void k_thread_delete(struct k_thread *thread)
{
if(NULL == new_thread || 0 == new_thread->task)
if(NULL == thread || 0 == thread->task)
{
BT_ERR("task is NULL\n");
return;
}
vTaskDelete((void *)(new_thread->task));
new_thread->task = 0;
vTaskDelete((void *)(thread->task));
thread->task = 0;
return;
}
bool k_is_current_thread(struct k_thread *thread)
{
eTaskState thread_state = eTaskGetState((void *)(thread->task));
if(thread_state == eRunning)
return true;
else
return false;
}
int k_yield(void)
{
taskYIELD();
@ -381,10 +390,18 @@ void k_get_random_byte_array(uint8_t *buf, size_t len)
void *k_malloc(size_t size)
{
#if defined(CFG_USE_PSRAM)
return pvPortMallocPsram(size);
#else
return pvPortMalloc(size);
#endif /* CFG_USE_PSRAM */
}
void k_free(void *buf)
{
#if defined(CFG_USE_PSRAM)
return vPortFreePsram(buf);
#else
return vPortFree(buf);
#endif
}

View File

@ -8,6 +8,7 @@
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "types.h"
#include "bl_port.h"
@ -237,6 +238,8 @@ int k_thread_create(struct k_thread *new_thread, const char *name,
void k_thread_delete(struct k_thread *new_thread);
bool k_is_current_thread(struct k_thread *thread);
/**
* @brief Yield the current thread.
*/

View File

@ -53,6 +53,20 @@
#define CONFIG_BT_HCI_RX_STACK_SIZE 512
#endif
/**
* BL_BLE_CO_THREAD: combine tx rx thread
*/
#define BFLB_BT_CO_THREAD 1
#if (BFLB_BT_CO_THREAD)
#define CONFIG_BT_CO_TASK_PRIO (configMAX_PRIORITIES - 3)
#if defined(CONFIG_BT_MESH)
#define CONFIG_BT_CO_STACK_SIZE 3072//2048//1536//1024
#else
#define CONFIG_BT_CO_STACK_SIZE 2048//2048//1536//1024
#endif
#endif
#ifndef CONFIG_BT_RX_STACK_SIZE
#if defined(CONFIG_BT_MESH)
#define CONFIG_BT_RX_STACK_SIZE 3072//2048//1536//1024
@ -97,14 +111,6 @@
#define CONFIG_BT_CTLR_RX_PRIO (configMAX_PRIORITIES - 4)
#endif
/**
* BL_BLE_CO_THREAD: combine tx rx thread
*/
#ifndef BFLB_BLE_CO_THREAD
#define BFLB_BLE_CO_THREAD 0
#endif
/**
* CONFIG_BT_HCI_CMD_COUNT: hci cmd buffer count,range 2 to 64
*/
@ -298,9 +304,13 @@
* range 1 to 65535,seconds
*/
#ifndef CONFIG_BT_RPA_TIMEOUT
#if defined(CONFIG_AUTO_PTS)
#define CONFIG_BT_RPA_TIMEOUT 60
#else
#define CONFIG_BT_RPA_TIMEOUT 900
#endif
#endif
#endif
/**
* CONFIG_BT_GATT_DYNAMIC_DB:enables GATT services to be added dynamically to database
@ -612,8 +622,9 @@ happens, which cause memory leak issue.*/
#define BFLB_BLE_PATCH_FREE_ALLOCATED_BUFFER_IN_OS
/*To avoid duplicated pubkey callback.*/
#define BFLB_BLE_PATCH_AVOID_DUPLI_PUBKEY_CB
#define BFLB_BLE_DYNAMIC_SERVICE
/*The flag @conn_ref is not clean up after disconnect*/
#define BFLB_BLE_PATCH_CLEAN_UP_CONNECT_REF
//#define BFLB_BLE_PATCH_CLEAN_UP_CONNECT_REF
#if !defined(CONFIG_AUTO_PTS)
/*To avoid sevice changed indication sent at the very beginning, without any new service added.*/
#define BFLB_BLE_PATCH_SET_SCRANGE_CHAGD_ONLY_IN_CONNECTED_STATE

View File

@ -134,7 +134,11 @@ struct k_poll_signal {
}
extern int k_poll_signal_raise(struct k_poll_signal *signal, int result);
#if (BFLB_BT_CO_THREAD)
extern int k_poll(struct k_poll_event *events, int num_events, int total_evt_array_cnt, s32_t timeout, u8_t *to_process);
#else
extern int k_poll(struct k_poll_event *events, int num_events, s32_t timeout);
#endif
extern void k_poll_event_init(struct k_poll_event *event, u32_t type, int mode, void *obj);
/* public - polling modes */

View File

@ -0,0 +1,402 @@
/****************************************************************************
FILE NAME
atvv.c
DESCRIPTION
google voice over ble service.
<<Google Voice over BLE spec 1.0>>
****************************************************************************/
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include "bluetooth.h"
#include "conn.h"
#include "conn_internal.h"
#include "gatt.h"
#include "hci_core.h"
#include "uuid.h"
#include "atvv.h"
#include "log.h"
#define AUDIO_TRANSFER_TIMEOUT K_SECONDS(30)
struct k_delayed_work audio_timeout_work;
static struct bt_conn *atvv_conn;
static struct bt_gatt_exchange_params exchg_mtu;
static uint8_t tx_mtu_size = 20;
static void atvv_connected(struct bt_conn *conn, u8_t err);
static void atvv_disconnected(struct bt_conn *conn, u8_t reason);
static int atvv_notify(struct bt_conn *conn, uint8_t attr_index, uint8_t *buf, uint16_t len);
static struct bt_gatt_attr *get_attr(u8_t index);
static struct bt_conn_cb atvv_conn_callbacks = {
.connected = atvv_connected,
.disconnected = atvv_disconnected,
};
static uint8_t audio_notify_enable = 0;
static uint8_t ctl_notify_enable = 0;
/*
0x01: ADPCM 8khz/16bit;
0x02: ADPCM 16khz/16bit;
*/
static uint8_t codecs_used = 0x01;
/*
0x00: On-request model (should be supported by all remotes);
0x01: Press-to-Talk model enabled;
0x03: Hold-to-Talk model enabled.
*/
static uint8_t assis_mode = 0x00;
/*************************************************************************
* NAME: set_codecs_mode
*/
void set_codecs_mode(uint8_t used)
{
codecs_used = used;
}
/*************************************************************************
* NAME: set_assis_mode
*/
void set_assis_mode(uint8_t mode)
{
assis_mode = mode;
}
/*************************************************************************
* NAME: audio_search
*/
int audio_search()
{
int err = -1;
uint8_t audio_cmd[1] = {START_SEARCH};
if (ctl_notify_enable)
{
err = atvv_notify(atvv_conn, ATVV_CHAR_CTL_ATTR_VAL_INDEX, audio_cmd, sizeof(audio_cmd));
}
return err;
}
/*************************************************************************
* NAME: audio_stop
*/
int audio_start(uint8_t reason, uint8_t stream)
{
int err = -1;
uint8_t audio_cmd[4] = {
AUDIO_START,
reason,
codecs_used,
stream
};
if (ctl_notify_enable)
{
err = atvv_notify(atvv_conn, ATVV_CHAR_CTL_ATTR_VAL_INDEX, audio_cmd, sizeof(audio_cmd));
if (!err)
{
k_delayed_work_submit(&audio_timeout_work, AUDIO_TRANSFER_TIMEOUT);
}
}
return err;
}
/*************************************************************************
* NAME: audio_stop
*/
int audio_stop(uint8_t reason)
{
int err = -1;
uint8_t audio_cmd[2] = {
AUDIO_STOP,
reason
};
if (ctl_notify_enable)
{
err = atvv_notify(atvv_conn, ATVV_CHAR_CTL_ATTR_VAL_INDEX, audio_cmd, sizeof(audio_cmd));
k_delayed_work_cancel(&audio_timeout_work);
}
return err;
}
/*************************************************************************
* NAME: audio_transfer
*/
int audio_transfer(uint8_t *buf, uint16_t len)
{
int err = -1;
if (audio_notify_enable)
{
err = atvv_notify(atvv_conn, ATVV_CHAR_AUDIO_ATTR_VAL_INDEX, buf, len);
}
return err;
}
/*************************************************************************
* NAME: audio_timeout
*/
static void audio_timeout(struct k_work *work)
{
BT_WARN("audio transfer timeout");
audio_stop(STOP_REASON_TIME_OUT);
}
/*************************************************************************
* NAME: atvv_tx_mtu_size
*/
static void atvv_tx_mtu_size(struct bt_conn *conn, u8_t err, struct bt_gatt_exchange_params *params)
{
if(!err)
{
tx_mtu_size = bt_gatt_get_mtu(atvv_conn);
BT_INFO("atvv echange mtu size success, mtu size: %d", tx_mtu_size);
}
else
{
BT_WARN("atvv echange mtu size failure, err: %d", err);
}
}
/*************************************************************************
* NAME: atvv_connected
*/
static void atvv_connected(struct bt_conn *conn, u8_t err)
{
if(err || conn->type != BT_CONN_TYPE_LE)
{
return;
}
int tx_octets = 0x00fb;
int tx_time = 0x0848;
int ret = -1;
BT_INFO("%s", __func__);
atvv_conn = conn;
/*set data length after connected.*/
ret = bt_le_set_data_len(atvv_conn, tx_octets, tx_time);
if(!ret)
{
BT_WARN("atvv set data length success.");
}
else
{
BT_WARN("atvv set data length failure, err: %d", ret);
}
/*exchange mtu size after connected.*/
exchg_mtu.func = atvv_tx_mtu_size;
ret = bt_gatt_exchange_mtu(atvv_conn, &exchg_mtu);
if (!ret) {
BT_INFO("atvv exchange mtu size pending.");
} else {
BT_WARN("atvv exchange mtu size failure, err: %d", ret);
}
k_delayed_work_init(&audio_timeout_work, audio_timeout);
}
/*************************************************************************
NAME: atvv_disconnected
*/
static void atvv_disconnected(struct bt_conn *conn, u8_t reason)
{
if(conn->type != BT_CONN_TYPE_LE)
{
return;
}
BT_INFO("%s", __func__);
atvv_conn = NULL;
k_delayed_work_del_timer(&audio_timeout_work);
}
/*************************************************************************
* NAME: atvv_notify
*/
static int atvv_notify(struct bt_conn *conn, uint8_t attr_index, uint8_t *buf, uint16_t len)
{
int err = -1;
err = bt_gatt_notify(conn, get_attr(attr_index), buf, len);
if (!err)
{
BT_INFO("atvv send notify success.");
} else
{
BT_WARN("atvv send notify : %d", err);
}
return err;
}
/*************************************************************************
* NAME: atvv_tx
*/
static int atvv_tx(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, u16_t len, u16_t offset, u8_t flags)
{
BT_INFO("recv data len=%d, offset=%d, flag=%d", len, offset, flags);
uint8_t command = ((uint8_t *)buf)[0];
switch(command)
{
case GET_CAPS:
{
uint8_t caps_rsp[9] = {
CAPS_RESP,
0x01, 0x00,
0x03,
assis_mode,
0x00, (tx_mtu_size - 3),
0x01,
0x00
};
if (ctl_notify_enable)
{
atvv_notify(conn, ATVV_CHAR_CTL_ATTR_VAL_INDEX, caps_rsp, sizeof(caps_rsp));
}
}
break;
case MIC_OPEN:
{
audio_start(START_REASON_MIC_OPEN, 0);
}
break;
case MIC_CLOSE:
{
audio_stop(STOP_REASON_MIC_CLOSE);
}
break;
case MIC_EXTEND:
{
k_delayed_work_cancel(&audio_timeout_work);
k_delayed_work_submit(&audio_timeout_work, AUDIO_TRANSFER_TIMEOUT);
}
break;
default:
break;
}
return len;
}
/*************************************************************************
* NAME: atvv_audio_ccc_changed
*/
static void atvv_audio_ccc_changed(const struct bt_gatt_attr *attr, u16_t value)
{
BT_INFO("ccc:value=[%d]", value);
if (value == BT_GATT_CCC_NOTIFY)
{
audio_notify_enable = 1;
}
else
{
audio_notify_enable = 0;
}
}
/*************************************************************************
* NAME: atvv_ctl_ccc_changed
*/
static void atvv_ctl_ccc_changed(const struct bt_gatt_attr *attr, u16_t value)
{
BT_INFO("ccc:value=[%d]", value);
if (value == BT_GATT_CCC_NOTIFY)
{
ctl_notify_enable = 1;
}
else
{
ctl_notify_enable = 0;
}
}
/*************************************************************************
* DEFINE : attrs
*/
static struct bt_gatt_attr attrs[]= {
BT_GATT_PRIMARY_SERVICE(ATVV_SERVICE_UUID),
BT_GATT_CHARACTERISTIC(ATVV_CHAR_TX,
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE,
NULL,
atvv_tx,
NULL),
BT_GATT_CHARACTERISTIC(ATVV_CHAR_AUDIO,
BT_GATT_CHRC_NOTIFY,
NULL,
NULL,
NULL,
NULL),
BT_GATT_CCC(atvv_audio_ccc_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
BT_GATT_CHARACTERISTIC(ATVV_CHAR_CTL,
BT_GATT_CHRC_NOTIFY,
NULL,
NULL,
NULL,
NULL),
BT_GATT_CCC(atvv_ctl_ccc_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
};
/*************************************************************************
* NAME: get_attr
*/
struct bt_gatt_attr *get_attr(u8_t index)
{
return &attrs[index];
}
/*************************************************************************
* NAME: atvv_server
*/
struct bt_gatt_service atvv_server = BT_GATT_SERVICE(attrs);
/*************************************************************************
* NAME: atvv_init
*/
void atvv_init()
{
bt_conn_cb_register(&atvv_conn_callbacks);
bt_gatt_service_register(&atvv_server);
}

View File

@ -0,0 +1,57 @@
/****************************************************************************
FILE NAME
atvv.h
DESCRIPTION
google voice over ble service.
<<Google Voice over BLE spec 1.0>>
****************************************************************************/
#ifndef _BLE_GVOB_H_
#define _BLE_GVOB_H_
#define ATVV_SERVICE_UUID BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xAB5E0001, 0x5A21, 0x4F05, 0xBC7D, 0xAF01F617B664))
#define ATVV_CHAR_TX BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xAB5E0002, 0x5A21, 0x4F05, 0xBC7D, 0xAF01F617B664))
#define ATVV_CHAR_AUDIO BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xAB5E0003, 0x5A21, 0x4F05, 0xBC7D, 0xAF01F617B664))
#define ATVV_CHAR_CTL BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xAB5E0004, 0x5A21, 0x4F05, 0xBC7D, 0xAF01F617B664))
#define ATVV_CHAR_TX_ATTR_VAL_INDEX (2)
#define ATVV_CHAR_AUDIO_ATTR_VAL_INDEX (4)
#define ATVV_CHAR_CTL_ATTR_VAL_INDEX (7)
//ATV ---> Remote
#define GET_CAPS 0x0A
#define MIC_OPEN 0x0C
#define MIC_CLOSE 0x0D
#define MIC_EXTEND 0x0E
//Remote ---> ATV
#define AUDIO_STOP 0x00
#define AUDIO_START 0x04
#define START_SEARCH 0x08
#define AUDIO_SYNC 0x0A
#define CAPS_RESP 0x0B
#define MIC_OPEN_ERROR 0x0C
#define START_REASON_MIC_OPEN 0x00
#define START_REASON_PTT 0x01
#define START_REASON_HTT 0x03
#define STOP_REASON_MIC_CLOSE 0x00
#define STOP_REASON_HTT 0x02
#define STOP_REASON_AUDIO_START 0x04
#define STOP_REASON_TIME_OUT 0x08
#define STOP_REASON_DIS_NOTIFY 0x10
void atvv_init(void);
void set_codecs_mode(uint8_t used);
void set_assis_mode(uint8_t mode);
int audio_search(void);
int audio_start(uint8_t reason, uint8_t stream);
int audio_stop(uint8_t reason);
int audio_transfer(uint8_t *buf, uint16_t len);
#endif

View File

@ -0,0 +1,66 @@
/****************************************************************************
FILE NAME
ias.c
DESCRIPTION
Immediate Alert Service
****************************************************************************/
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include "bluetooth.h"
#include "gatt.h"
#include "uuid.h"
#include "ias.h"
#include "log.h"
/*************************************************************************
* NAME: ias_recv_wr
*/
static int ias_recv_wr(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, u16_t len, u16_t offset, u8_t flags)
{
BT_INFO("recv data len=%d, offset=%d, flag=%d", len, offset, flags);
if(flags & BT_GATT_WRITE_FLAG_CMD)
{
BT_INFO("rcv write command");
//handle alert level.
}
return len;
}
/*************************************************************************
* DEFINE : attrs
*/
static struct bt_gatt_attr attrs[]= {
BT_GATT_PRIMARY_SERVICE(BT_UUID_IAS),
BT_GATT_CHARACTERISTIC(BT_UUID_IAS_ALERT_LEVEL,
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE,
NULL,
ias_recv_wr,
NULL)
};
struct bt_gatt_service ias_server = BT_GATT_SERVICE(attrs);
/*************************************************************************
* NAME: ias_init
*/
void ias_init()
{
bt_gatt_service_register(&ias_server);
}

View File

@ -0,0 +1,17 @@
/****************************************************************************
FILE NAME
ias.h
DESCRIPTION
Immediate Alert Service
****************************************************************************/
#ifndef _BLE_IA_SVC_H_
#define _BLE_IA_SVC_H_
/**
@brief register immediate alert service.
*/
void ias_init();
#endif

View File

@ -0,0 +1,217 @@
#include "bluetooth.h"
#include "conn.h"
#include "conn_internal.h"
#include "gatt.h"
#include "hci_core.h"
#include "uuid.h"
#include "spp.h"
uint16_t svc1_index = 0;
uint16_t svc2_index = 0;
static uint8_t short_val_1[1] = {0x30};
static uint8_t short_val_2[1] = {0x30};
static uint8_t short_val_3[512] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
static uint8_t short_val_4[512] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
static uint8_t short_val_5[1] = {0x30};
static uint8_t short_val_6[1] = {0x01};
static uint8_t short_val_7[1] = {0x30};
static uint8_t short_val_8[1] = {0x30};
static uint8_t short_val_9[512] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
static uint8_t short_val_10[1] = {0x30};
static uint8_t short_val_11[1] = {0x30};
static uint8_t short_val_12[1] = {0x30};
static uint8_t short_val_13[1] = {0x30};
static uint8_t short_val_14[1] = {0x30};
static uint8_t short_val_15[1] = {0x30};
static uint8_t short_val_16[1] = {0x30};
static uint8_t short_val_17[1] = {0x30};
static int spp_read_data(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, u16_t len, u16_t offset)
{
struct attr_val *attrval = attr->user_data;
return bt_gatt_attr_read(conn, attr, buf, len, offset, attrval->data,attrval->len);
}
static int spp_write_data(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, u16_t len, u16_t offset,u8_t flags)
{
struct attr_val *attrval = attr->user_data;
if (offset + len > attrval->len) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
memcpy(attrval->data + offset, buf, len);
return len;
}
/**
*@Dynamic spp service attribution list
*/
static struct bt_gatt_attr svc1_attr[] = {
BT_GATT_ATTRIBUTE(SPP_UUID_0,
BT_GATT_PERM_READ,
spp_read_data,
0,
(void*)val_convert(short_val_1,sizeof(short_val_1))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_2,sizeof(short_val_2))),
BT_GATT_ATTRIBUTE(SPP_UUID_1,
BT_GATT_PERM_READ,
spp_read_data,
0,
(void*)val_convert(short_val_3,sizeof(short_val_3))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_4,sizeof(short_val_4))),
BT_GATT_ATTRIBUTE(SPP_UUID_2,
BT_GATT_PERM_READ,
0,
spp_write_data,
(void*)val_convert(short_val_5,sizeof(short_val_5))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_6,sizeof(short_val_6))),
BT_GATT_ATTRIBUTE(SPP_UUID_3,
BT_GATT_PERM_WRITE,
0,
spp_write_data,
(void*)val_convert(short_val_7,sizeof(short_val_7))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_8,sizeof(short_val_8))),
BT_GATT_ATTRIBUTE(SPP_UUID_4,
BT_GATT_PERM_WRITE,
0,
spp_write_data,
(void*)val_convert(short_val_9,sizeof(short_val_9))),
BT_GATT_ATTRIBUTE(SPP_UUID_5,
0,
0,
spp_write_data,
(void*)val_convert(short_val_10,sizeof(short_val_10))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CCC,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
0,
0,
0),
BT_GATT_ATTRIBUTE(SPP_UUID_6,
0,
0,
spp_write_data,
(void*)val_convert(short_val_11,sizeof(short_val_11))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CCC,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
0,
0,
0),
BT_GATT_ATTRIBUTE(SPP_UUID_7,
BT_GATT_PERM_READ,
spp_read_data,
0,
(void*)val_convert(short_val_12,sizeof(short_val_12))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_13,sizeof(short_val_13))),
};
static struct bt_gatt_attr svc2_attr[] = {
BT_GATT_ATTRIBUTE(SPP_UUID_8,
BT_GATT_PERM_READ,
spp_read_data,
0,
(void*)val_convert(short_val_14,sizeof(short_val_14))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
(BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_15,sizeof(short_val_15))),
BT_GATT_ATTRIBUTE(SPP_UUID_9,
BT_GATT_PERM_READ,
spp_read_data,
0,
(void*)val_convert(short_val_16,sizeof(short_val_16))),
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CUD,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
spp_read_data,
spp_write_data,
(void*)val_convert(short_val_17,sizeof(short_val_17))),
};
void bt_dyn_register_spp_srv(void)
{
struct bt_gatt_attr *attr = svc1_attr;
bt_gatts_add_serv_attr(spp_svc_1_uuid,1,24);
bt_gatts_add_char(attr,BT_GATT_CHRC_READ);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_READ);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_WRITE);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_WRITE_WITHOUT_RESP);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_WRITE);
bt_gatts_add_char(++attr,BT_GATT_CHRC_NOTIFY);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_INDICATE);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_READ);
bt_gatts_add_desc(++attr);
svc1_index = bt_gatts_add_service();
attr = svc2_attr;
bt_gatts_add_serv_attr(spp_svc_2_uuid,1,7);
bt_gatts_add_char(attr,BT_GATT_CHRC_READ);
bt_gatts_add_desc(++attr);
bt_gatts_add_char(++attr,BT_GATT_CHRC_READ);
bt_gatts_add_desc(++attr);
svc2_index = bt_gatts_add_service();
}
void bt_dyn_unregister_spp_srv(void)
{
bt_gatts_del_service(svc1_index);
bt_gatts_del_service(svc2_index);
}

View File

@ -0,0 +1,44 @@
#ifndef __SPP_H_
#define __SPP_H_
#include <stdio.h>
#include "uuid.h"
struct attr_val {
uint16_t len;
uint8_t *data;
};
#define set_attr_val(val,size) \
{ \
.len = size, \
.data = val, \
}
#define val_convert(val,size){ \
(& (struct attr_val) \
set_attr_val(val,size) \
) \
}
#define SPP_UUID_0 BT_UUID_DECLARE_16(0xc300)
#define SPP_UUID_1 BT_UUID_DECLARE_16(0xc301)
#define SPP_UUID_2 BT_UUID_DECLARE_16(0xc302)
#define SPP_UUID_3 BT_UUID_DECLARE_16(0xc303)
#define SPP_UUID_4 BT_UUID_DECLARE_16(0xc304)
#define SPP_UUID_5 BT_UUID_DECLARE_16(0xc305)
#define SPP_UUID_6 BT_UUID_DECLARE_16(0xc306)
#define SPP_UUID_7 BT_UUID_DECLARE_16(0xc307)
#define SPP_UUID_8 BT_UUID_DECLARE_16(0xc400)
#define SPP_UUID_9 BT_UUID_DECLARE_16(0xc401)
static const struct bt_uuid *spp_svc_1_uuid = BT_UUID_DECLARE_16(0xa002);
static const struct bt_uuid *spp_svc_2_uuid = BT_UUID_DECLARE_16(0xa003);
void bt_dyn_register_spp_srv(void);
void bt_dyn_unregister_spp_srv(void);
#endif

View File

@ -7,17 +7,24 @@ endif
#
## These include paths would be exported to project level
COMPONENT_ADD_INCLUDEDIRS += src/include lwip-port lwip-port/config lwip-port/FreeRTOS lwip-port/arch
## not be exported to project level
COMPONENT_PRIV_INCLUDEDIRS :=
COMPONENT_ADD_INCLUDEDIRS += src/include src/include/compat/posix lwip-port lwip-port/config lwip-port/FreeRTOS lwip-port/arch bugkiller/include
## This component's src
## not be exported to project level
COMPONENT_PRIV_INCLUDEDIRS :=
## This component's src
#COMPONENT_SRCS :=
#COMPONENT_OBJS := $(patsubst %.c,%.o, $(COMPONENT_SRCS))
COMPONENT_SRCDIRS := src/api src/core src/core/ipv4 src/netif lwip-port/FreeRTOS lwip-port src/apps/altcp_tls
ifeq ($(CONFIG_COMPONENT_BUGKILLER_ENABLE),1)
COMPONENT_SRCDIRS += bugkiller
CFLAGS += -DBUGKILLER
endif
ifeq ($(CONFIG_IPV6), 1)
COMPONENT_SRCDIRS += src/core/ipv6
endif
##
#CPPFLAGS +=
#CPPFLAGS +=

View File

@ -0,0 +1,29 @@
unsigned long __attribute__((section(".bugkiller_code"))) bugkiller_mbox_peek_unrecved(sys_mbox_t recvmbox)
{
unsigned long sum = 0;
struct pbuf *msg[TCPIP_MBOX_SIZE] = {0};
int i = 0, j = 0;
while(sys_arch_mbox_tryfetch(&recvmbox, (void **)&msg[i++]) != SYS_MBOX_EMPTY) {
sum += msg[i-1]->tot_len;
}
while(--i) {
sys_mbox_trypost(&recvmbox, (void *)msg[j++]);
}
return sum;
}
unsigned long __attribute__((section(".bugkiller_code"))) bugkiller_mbox_peek_accepted(sys_mbox_t acceptmbox)
{
unsigned long sum = 0;
struct pbuf *msg[TCPIP_MBOX_SIZE] = {0};
int i = 0, j = 0;
while(sys_arch_mbox_tryfetch(&acceptmbox, (void **)&msg[i++]) != SYS_MBOX_EMPTY) {
sum++;
}
while(--i) {
sys_mbox_trypost(&acceptmbox, (void *)msg[j++]);
}
return sum;
}

View File

@ -0,0 +1,82 @@
#include "lwip_bugkiller_inner.h"
/*
iperf server(recv) dump socket inner,
SocketId: 0 Type: TCP Status: 192.168.1.116:5001 -> 0.0.0.0:49466 (LISTEN)
SocketId: 1 Type: TCP Status: 192.168.1.116:5001 -> 192.168.1.143:44312 (ESTABLISHED)
recv wnd : -1460 ~ 827230504 ~ +33580
recv_ann wnd : -33580 ~ 827264084
snd wnd : -0 ~ 6511 ~ +64240
unsend len: 0, unacked len: 0, ooseq len: 0
iperf client(send) dump socket inner,
SocketId: 0 Type: TCP Status: 192.168.1.116:61738 -> 192.168.1.143:5001 (ESTABLISHED)
recv wnd : -0 ~ 76303226 ~ +43800
recv_ann wnd : -43800 ~ 76347026
snd wnd : -17520 ~ 7173790 ~ +48015
unsend len: 0, unacked len: 17520, ooseq len: 0
*/
extern unsigned long bugkiller_mbox_peek_unrecved(sys_mbox_t recvmbox);
extern unsigned long bugkiller_mbox_peek_accepted(sys_mbox_t acceptbox);
void __attribute__((section(".bugkiller_code"))) bugkiller_socket_inner_dump(int id)
{
switch(sockets[id].conn->type) {
case NETCONN_UDP:
break;
case NETCONN_TCP:
if(sockets[id].conn->pcb.tcp->state == LISTEN) {
bugkiller_tcp_listen_dump(bugkiller_mbox_peek_accepted(sockets[id].conn->acceptmbox), \
sockets[id].conn->pcb.tcp);
} else {
bugkiller_tcp_wnd_dump(bugkiller_mbox_peek_unrecved(sockets[id].conn->recvmbox) + \
(sockets[id].lastdata.pbuf ? sockets[id].lastdata.pbuf->tot_len : 0), \
sockets[id].conn->pcb.tcp);
bugkiller_tcp_seg_dump(sockets[id].conn->pcb.tcp);
}
break;
default:
printf(lwip_bugkiller_format[4]);
break;
}
}
/* sockets_dump():
SocketId: 6 Type: TCP Status: localhost:33783 -> baidu.com:8000
SocketId: 7 Type: UDP Status: localhost:33784 -> baidu.com:8001
SocketId: 8 Type: TCP Status: localhost:8000 (Listen)
....
*/
void __attribute__((section(".bugkiller_code"))) bugkiller_sockets_dump()
{
for(int i = 0; i < NUM_SOCKETS && sockets[i].conn; i++) {
if(sockets[i].conn == NULL)
continue;
switch(sockets[i].conn->type) {
case NETCONN_UDP:
printf(lwip_bugkiller_format[0], i);
printf(lwip_bugkiller_format[1],
ip4addr_ntoa((const ip4_addr_t *) &sockets[i].conn->pcb.udp->local_ip.addr),
sockets[i].conn->pcb.udp->local_port);
printf(lwip_bugkiller_format[6],
ip4addr_ntoa((const ip4_addr_t *) &sockets[i].conn->pcb.udp->remote_ip.addr),
sockets[i].conn->pcb.udp->remote_port);
break;
case NETCONN_TCP:
printf(lwip_bugkiller_format[3], i);
printf(lwip_bugkiller_format[1],
ip4addr_ntoa((const ip4_addr_t *) &sockets[i].conn->pcb.udp->local_ip.addr),
sockets[i].conn->pcb.tcp->local_port);
if(sockets[i].conn->pcb.tcp->state != LISTEN) {
printf(lwip_bugkiller_format[2],
ip4addr_ntoa((const ip4_addr_t *) &sockets[i].conn->pcb.tcp->remote_ip.addr),
sockets[i].conn->pcb.tcp->remote_port);
}
puts(lwip_bugkiller_tcp_state[sockets[i].conn->pcb.tcp->state]);
bugkiller_socket_inner_dump(i);
break;
default:
printf(lwip_bugkiller_format[5]);
break;
}
}
}

View File

@ -0,0 +1,45 @@
#include "lwip_bugkiller_inner.h"
/* bugkiller_tcp_wnd_dump()
recv wnd : -2345 ~ 327584 ~ +5466
recv_ann wnd : -5466 ~ 330084
snd wnd : -1245 ~ 133458 ~ +244
*/
void __attribute__((section(".bugkiller_code"))) bugkiller_tcp_wnd_dump(unsigned long unrecv_len, void *s)
{
struct tcp_pcb *pcb = (struct tcp_pcb *)s;
/* receiver */
printf(lwip_bugkiller_tcp_format[0], unrecv_len, pcb->rcv_nxt, pcb->rcv_wnd);
/* receiver ann */
printf(lwip_bugkiller_tcp_format[1], pcb->rcv_ann_wnd, pcb->rcv_ann_right_edge);
/* sender */
printf(lwip_bugkiller_tcp_format[2], pcb->snd_nxt - pcb->lastack, pcb->snd_nxt, pcb->snd_wnd + pcb->lastack - pcb->snd_nxt);
}
/* bugkiller_tcp_seg_dump()
unsend len: 1000, unakced len: 885
*/
void __attribute__((section(".bugkiller_code"))) bugkiller_tcp_seg_dump(void *s)
{
struct tcp_pcb *pcb = (struct tcp_pcb *)s;
unsigned long unsend_len = 0, unacked_len = 0, ooseq_len = 0;
for(struct tcp_seg *seg = pcb->unsent; seg; seg = seg->next) {
unsend_len += seg->len;
}
for(struct tcp_seg *seg = pcb->unacked; seg; seg = seg->next) {
unacked_len += seg->len;
}
#if TCP_QUEUE_OOSEQ
for(struct tcp_seg *seg = pcb->ooseq; seg; seg = seg->next) {
ooseq_len += seg->len;
}
#endif /* TCP_QUEUE_OOSEQ */
printf(lwip_bugkiller_tcp_format[3], unsend_len, unacked_len, ooseq_len);
}
void __attribute__((section(".bugkiller_code"))) bugkiller_tcp_listen_dump(unsigned long accept_num,void *s)
{
struct tcp_pcb_listen *listen_pcb = (struct tcp_pcb_listen *)s;
printf(lwip_bugkiller_tcp_listen_format[0], accept_num);
}

View File

@ -0,0 +1,34 @@
char *lwip_bugkiller_format[]={
"SocketId: %d\tType: UDP\t",
"Status: %s:%d",
" -> %s:%d",
"SocketId: %d\tType: TCP\t",
" (Listen)\r\n",
"type not support\r\n",
" -> %s:%d\r\n"
};
char *lwip_bugkiller_tcp_state[]={
" (CLOSED) \r\n",
" (LISTEN) \r\n",
" (SYN_SENT) \r\n",
" (SYN_RCVD) \r\n",
" (ESTABLISHED)\r\n",
" (FIN_WAIT_1) \r\n",
" (FIN_WAIT_2) \r\n",
" (CLOSE_WAIT) \r\n",
" (CLOSING) \r\n",
" (LAST_ACK) \r\n",
" (TIME_WAIT) \r\n"
};
char *lwip_bugkiller_tcp_format[]={
"recv wnd : -%lu ~ %lu ~ +%lu\r\r\n",
"recv_ann wnd : -%lu ~ %lu\r\r\n",
"snd wnd : -%lu ~ %lu ~ +%lu\r\r\n",
"unsend len: %lu, unacked len: %lu, ooseq len: %lu\r\r\n"
};
char *lwip_bugkiller_tcp_listen_format[]={
"wait_accept_num: %lu\r\r\n"
};

View File

@ -0,0 +1,8 @@
void bugkiller_tcp_wnd_dump(unsigned long unrecv_len, void *pcb);
void bugkiller_tcp_seg_dump(void *pcb);
void bugkiller_tcp_listen_dump(unsigned long accept_num, void *pcb);
extern char *lwip_bugkiller_format[7];
extern char *lwip_bugkiller_tcp_state[11];
extern char *lwip_bugkiller_tcp_format[4];
extern char *lwip_bugkiller_tcp_listen_format[1];

View File

@ -195,25 +195,3 @@ err_t ethernetif_init(struct netif *netif)
return ERR_OK;
}
void set_if(struct netif *netif, char* ip_addr, char* gw_addr, char* nm_addr)
{
ip4_addr_t *ip;
ip4_addr_t addr;
ip = (ip4_addr_t *)&addr;
/* set ip address */
if ((ip_addr != NULL) && ip4addr_aton(ip_addr, &addr)) {
netif_set_ipaddr(netif, ip);
}
/* set gateway address */
if ((gw_addr != NULL) && ip4addr_aton(gw_addr, &addr)) {
netif_set_gw(netif, ip);
}
/* set netmask address */
if ((nm_addr != NULL) && ip4addr_aton(nm_addr, &addr)) {
netif_set_netmask(netif, ip);
}
}

View File

@ -41,7 +41,11 @@
* ATTENTION: this does not work when tcpip_input() is called from
* interrupt context!
*/
#if defined(CFG_CHIP_BL808)
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
#else
#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
#endif
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
@ -51,7 +55,14 @@
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#if defined(CFG_CHIP_BL808)
#define MEM_SIZE (60*1024)
#elif defined(CFG_SDIOWIFI)
#define MEM_SIZE (24*1024)
#else
#define MEM_SIZE (8*1024)
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
@ -68,7 +79,11 @@ a lot of data that needs to be copied, this should be set high. */
#define MEMP_NUM_TCP_PCB_LISTEN 5
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#if defined(CFG_CHIP_BL808)
#define MEMP_NUM_TCP_SEG 100
#else
#define MEMP_NUM_TCP_SEG 32
#endif
/* NUM of sys_timeout pool*/
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 8 + 3)
@ -78,15 +93,19 @@ a lot of data that needs to be copied, this should be set high. */
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#if !defined PBUF_POOL_SIZE
#if defined(CFG_CHIP_BL808)
#define PBUF_POOL_SIZE 200
#else
#ifdef CFG_ETHERNET_ENABLE
#define PBUF_POOL_SIZE 12
#else
#define PBUF_POOL_SIZE 0
#endif
#endif /*CFG_ETHERNET_ENABLE*/
#endif
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#ifdef CFG_ETHERNET_ENABLE
#if defined(CFG_CHIP_BL808)||defined(CFG_ETHERNET_ENABLE)
#define PBUF_POOL_BUFSIZE 1600
#else
#define PBUF_POOL_BUFSIZE 760
@ -106,12 +125,17 @@ a lot of data that needs to be copied, this should be set high. */
//#define TCP_MSS (1500 - 80) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
//#define TCP_MSS (800 - 40 - 80 + 8) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
/* TCP sender buffer space (bytes). */
#if defined(CFG_CHIP_BL808)
#define TCP_SND_BUF (12*TCP_MSS)
#else
#ifdef CFG_ETHERNET_ENABLE
#define TCP_SND_BUF (11*TCP_MSS)
#else
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (3*TCP_MSS)
#endif
#endif
/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
@ -128,17 +152,29 @@ a lot of data that needs to be copied, this should be set high. */
#define TCP_SNDQUEUELOWAT ((TCP_SND_QUEUELEN)/2)
/* TCP receive window. */
#if defined(CFG_CHIP_BL808)
#define TCP_WND (30*TCP_MSS)
#else
#ifdef CFG_ETHERNET_ENABLE
#define TCP_WND (6*TCP_MSS)
#else
#define TCP_WND (3*TCP_MSS)
#endif
#endif
#if defined(CFG_CHIP_BL808)
#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]
#endif
/**
* TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an
* explicit window update
*/
#if defined(CFG_CHIP_BL808)
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 2), (TCP_MSS * 16))
#else
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 2), (TCP_MSS * 6))
#endif
/**
* By default, TCP socket/netconn close waits 20 seconds max to send the FIN
@ -268,6 +304,8 @@ a lot of data that needs to be copied, this should be set high. */
#define TCPIP_THREAD_NAME "TCP/IP"
#ifdef CFG_ETHERNET_ENABLE
#define TCPIP_THREAD_STACKSIZE 1536
#elif defined(CFG_SDIOWIFI)
#define TCPIP_THREAD_STACKSIZE 512
#else
#define TCPIP_THREAD_STACKSIZE 4000
#endif /* CFG_ETHERNET_ENABLE */
@ -279,7 +317,11 @@ a lot of data that needs to be copied, this should be set high. */
#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2)
#define LWIP_COMPAT_MUTEX 0
#if defined(CFG_CHIP_BL808)
#define LWIP_TCPIP_CORE_LOCKING 1
#else
#define LWIP_TCPIP_CORE_LOCKING 0
#endif
#define LWIP_SOCKET_SET_ERRNO 1
#define SO_REUSE 1
#define LWIP_TCP_KEEPALIVE 1

View File

@ -4156,4 +4156,9 @@ lwip_socket_drop_registered_mld6_memberships(int s)
}
#endif /* LWIP_IPV6_MLD */
#ifdef BUGKILLER
#include <bugkiller/bugkiller_socket_dump.inc>
#include <bugkiller/bugkiller_mbox_dump.inc>
#endif
#endif /* LWIP_SOCKET */

View File

@ -122,7 +122,14 @@ icmp6_input(struct pbuf *p, struct netif *inp)
return;
case ICMP6_TYPE_RS:
#if LWIP_IPV6_FORWARD
#ifdef LWIP_IPV6_FOR_BORDER_ROUTER
{
/* @todo implement router functionality */
extern void ot_recv_icmp_6nd(struct netif *inp, ip6_addr_t* src, const uint8_t* data, uint16_t len);
ot_recv_icmp_6nd(inp,ip6_current_src_addr(),p->payload,
p->len);
}
#endif /* LWIP_IPV6_FOR_BORDER_ROUTER */
#endif
break;
#if LWIP_IPV6_MLD

View File

@ -553,6 +553,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
case ICMP6_TYPE_RA: /* Router Advertisement. */
{
#ifdef LWIP_IPV6_FOR_BORDER_ROUTER
extern void ot_recv_icmp_6nd(struct netif *inp, ip6_addr_t* src, const uint8_t* data, uint16_t len);
ot_recv_icmp_6nd(inp,ip6_current_src_addr(),p->payload, p->len);
#endif /* LWIP_IPV6_FOR_BORDER_ROUTER */
struct ra_header *ra_hdr;
u8_t *buffer; /* Used to copy options. */
u16_t offset;
@ -1388,6 +1392,42 @@ nd6_send_rs(struct netif *netif)
return err;
}
#ifdef LWIP_IPV6_FOR_BORDER_ROUTER
err_t
nd6_send(struct netif *netif, const ip6_addr_t *dest,
const uint8_t *abuf, uint16_t alen)
{
//printf("nd6_send\r\n");
struct rs_header *rs_hdr;
struct pbuf *p;
const ip6_addr_t *src_addr;
err_t err;
/* Link-local source address, or unspecified address? */
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) {
src_addr = netif_ip6_addr(netif, 0);
} else {
src_addr = IP6_ADDR_ANY6;
}
p = pbuf_alloc(PBUF_IP, alen, PBUF_RAM);
if (p == NULL) {
ND6_STATS_INC(nd6.memerr);
return ERR_BUF;
}
SMEMCPY(p->payload, abuf, alen);
rs_hdr = (struct rs_header *)p->payload;
#if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
dest);
}
#endif /* CHECKSUM_GEN_ICMP6 */
ND6_STATS_INC(nd6.xmit);
err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, dest,
ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
pbuf_free(p);
return err;
}
#endif /* LWIP_IPV6_FOR_BORDER_ROUTER */
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
/**

View File

@ -2701,4 +2701,8 @@ int tcp_get_pcbs(struct tcp_pcb **const**list)
}
#endif
#ifdef BUGKILLER
#include <bugkiller/bugkiller_tcp_dump.inc>
#endif
#endif /* LWIP_TCP */

View File

@ -2528,7 +2528,11 @@
* applicable, plus any number of groups to be joined on UDP sockets.
*/
#if !defined MEMP_NUM_MLD6_GROUP || defined __DOXYGEN__
#ifdef LWIP_IPV6_FOR_BORDER_ROUTER
#define MEMP_NUM_MLD6_GROUP (4+10)
#else
#define MEMP_NUM_MLD6_GROUP 4
#endif /* LWIP_IPV6_FOR_BORDER_ROUTER */
#endif
/**
* @}

View File

@ -18,7 +18,6 @@
#include <lwip/sockets.h>
#include <lwip/inet_chksum.h>
#include <netif/etharp.h>
#include <ethernetif.h>
#include <lwip/ip.h>
#include <lwip/init.h>
@ -184,6 +183,7 @@ dhcp_client_find(struct dhcp_server *dhcpserver, struct dhcp_msg *msg,
return node;
} else {
puts("IP Found, but MAC address is NOT the same\r\n");
return node; //FIXME use hostname instead of mac address
}
}
}
@ -682,6 +682,29 @@ err_t dhcp_server_stop(struct netif *netif)
return ERR_OK;
}
static void set_if(struct netif *netif, char* ip_addr, char* gw_addr, char* nm_addr)
{
ip4_addr_t *ip;
ip4_addr_t addr;
ip = (ip4_addr_t *)&addr;
/* set ip address */
if ((ip_addr != NULL) && ip4addr_aton(ip_addr, &addr)) {
netif_set_ipaddr(netif, ip);
}
/* set gateway address */
if ((gw_addr != NULL) && ip4addr_aton(gw_addr, &addr)) {
netif_set_gw(netif, ip);
}
/* set netmask address */
if ((nm_addr != NULL) && ip4addr_aton(nm_addr, &addr)) {
netif_set_netmask(netif, ip);
}
}
//TODO better dhcpd_stop flow?
void dhcpd_start(struct netif *netif)
{
@ -689,8 +712,6 @@ void dhcpd_start(struct netif *netif)
if (1)
{
extern void set_if(struct netif *netif, char* ip_addr, char* gw_addr, char* nm_addr);
dhcp_stop(netif);
set_if(netif, DHCPD_SERVER_IP, "0.0.0.0", "255.255.255.0");

View File

@ -50,7 +50,11 @@
#define IPERF_PORT_LOCAL 5002
#define IPERF_PORT 5001
#if defined(CFG_CHIP_BL808)
#define IPERF_BUFSZ (16 * 1300)
#else
#define IPERF_BUFSZ (4 * 1300)
#endif
#define IPERF_BUFSZ_UDP (1 * 1300)
#define DEBUG_HEADER "[NET] [IPC] "
#define DEFAULT_HOST_IP "192.168.11.1"
@ -104,7 +108,7 @@ static void iperf_client_tcp(void *arg)
char *host = (char*) arg;
uint64_t bytes_transfered = 0;
char speed[32] = { 0 };
char speed[64] = { 0 };
float f_min = 8000.0, f_max = 0.0;
exit_flag = 0;
@ -375,7 +379,7 @@ static void iperf_server_udp_recv_fn(void *arg, struct udp_pcb *pcb, struct pbuf
const ip_addr_t *addr, u16_t port)
{
struct iperf_server_udp_ctx *ctx = (struct iperf_server_udp_ctx *)arg;
char speed[32] = { 0 };
char speed[64] = { 0 };
UDP_datagram udp_header;
// 接收数据,等待接收时间
@ -404,7 +408,7 @@ static void iperf_server_udp_recv_fn(void *arg, struct udp_pcb *pcb, struct pbuf
HTONL_PTR(&hdr->outorder_cnt, ctx->out_of_order_cnt);
HTONL_PTR(&hdr->datagrams, ctx->datagram_cnt);
printf("iperf finish...\r\nreceive:%ld,out of order:%ld\r\n",
printf("iperf finish...\r\nreceive:%" PRId32 ",out of order:%" PRId32 "\r\n",
ctx->datagram_cnt, ctx->out_of_order_cnt);
udp_sendto(pcb, p, addr, port);
@ -428,7 +432,7 @@ static void iperf_server_udp_recv_fn(void *arg, struct udp_pcb *pcb, struct pbuf
if (ctx->f_max < f_now) {
ctx->f_max = f_now;
}
snprintf(speed, sizeof(speed), "%.4f(%.4f %.4f %.4f) Mbps, out of order: %lu.\r\n",
snprintf(speed, sizeof(speed), "%.4f(%.4f %.4f %.4f) Mbps, out of order: %" PRId32 ".\r\n",
f_now,
ctx->f_min,
f_avg,
@ -533,7 +537,7 @@ static void iperf_server(void *arg)
uint32_t tick0, tick1, tick2;
int sock = -1, connected, bytes_received, recvlen;
struct sockaddr_in server_addr, client_addr;
char speed[32] = { 0 };
char speed[64] = { 0 };
char *host = (char*)arg;
uint64_t bytes_transfered = 0;
float f_min = 8000.0, f_max = 0.0;

View File

@ -134,7 +134,7 @@ static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_a
find_hdr = find_and_extract(&env->req_list, iecho->seqno);
if (find_hdr) {
printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%lu ms\r\n ", p->tot_len, ipaddr_ntoa(&env->dest), ntohs(iecho->seqno), *((uint8_t *)p->payload + 8), (sys_now() - find_hdr->send_time));
printf("%" PRId16 " bytes from %s: icmp_seq=%d ttl=%d time=%" PRId32 " ms\r\n ", p->tot_len, ipaddr_ntoa(&env->dest), ntohs(iecho->seqno), *((uint8_t *)p->payload + 8), (sys_now() - find_hdr->send_time));
utils_memp_free(env->pool, find_hdr);
env->node_num--;

View File

@ -266,6 +266,8 @@ typedef enum wifi_fw_event_id
MM_FORCE_IDLE_REQ,
/// Message indicating that the switch to the scan channel is done
MM_SCAN_CHANNEL_START_IND,
/// Message indicating that the scan can end early
MM_SCAN_CHANNEL_END_EARLY,
/// Message indicating that the scan on the channel is finished
MM_SCAN_CHANNEL_END_IND,

View File

@ -32,10 +32,8 @@
#include <stdint.h>
void bugkiller_fw_queue_sent_dump(void);
void bugkiller_fw_queue_saved_dump(void);
void bugkiller_fw_queue_timer_dump(void);
void bugkiller_fw_queue_init(void);
void bugkiller_fw_task_dump(void);
void bugkiller_fw_task_init(void);
#endif

View File

@ -0,0 +1,30 @@
# Component Makefile
#
## These include paths would be exported to project level
COMPONENT_ADD_INCLUDEDIRS += include
## not be exported to project level
## This component's src
COMPONENT_SRCS := src/wifi_bt_coex.c \
src/wifi_bt_coex_cli.c \
src/wifi_bt_coex_ctx.c \
ifeq ($(CONFIG_CHIP_NAME),BL808)
COMPONENT_SRCS += src/wifi_bt_coex_impl_bl808.c
endif
ifeq ($(CONFIG_CHIP_NAME),BL606P)
COMPONENT_SRCS += src/wifi_bt_coex_impl_bl606p.c
endif
ifeq ($(CONFIG_CHIP_NAME),BL602)
COMPONENT_SRCS += src/wifi_bt_coex_impl_bl602.c
endif
COMPONENT_OBJS := $(patsubst %.c,%.o, $(COMPONENT_SRCS))
COMPONENT_SRCDIRS := src
##
#CPPFLAGS +=

View File

@ -0,0 +1,36 @@
#ifndef __WIFI_BT_COEX_BT_H__
#define __WIFI_BT_COEX_BT_H__
#include <FreeRTOS.h>
#include <timers.h>
enum WIFI_BT_COEX_FORCE_MODE {
WIFI_BT_COEX_FORCE_MODE_PTA_FORCE,
WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE,
WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE,
WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2,
};
enum WIFI_BT_COEX_EVENT {
WIFI_BT_COEX_EVENT_BT_A2DP_UNDERRUN,
};
struct wifi_bt_coex_ctx {
TimerHandle_t coexTimer;
uint32_t timer_now;
uint32_t timer_max;
uint32_t timer_toggle_start;
uint32_t timer_toggle_end;
uint32_t timeus_last_called;
uint32_t time_step_inc;
uint32_t time_step_dec;
};
int wifi_bt_coex_cli_init(void);
int wifi_bt_coex_dump_all(void);
int wifi_bt_coex_force_wlan(void);
int wifi_bt_coex_force_bt(void);
int wifi_bt_coex_force_mode(enum WIFI_BT_COEX_FORCE_MODE mode);
/*Following is the event section*/
int wifi_bt_coex_event_notify(enum WIFI_BT_COEX_EVENT event, void *event_arg);
#endif

View File

@ -0,0 +1,45 @@
#include <wifi_bt_coex.h>
#include "wifi_bt_coex_impl.h"
int wifi_bt_coex_dump_all(void)
{
wifi_bt_coex_dump_all_impl();
return 0;
}
int wifi_bt_coex_force_wlan(void)
{
return wifi_bt_coex_force_wlan_impl();
}
int wifi_bt_coex_force_bt(void)
{
return wifi_bt_coex_force_bt_impl();
}
int wifi_bt_coex_force_mode(enum WIFI_BT_COEX_FORCE_MODE mode)
{
switch (mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
return wifi_bt_coex_force_mode_impl(mode);
}
break;
default:
{
/*Empty Here*/
return -1;
}
}
return 0;
}
int wifi_bt_coex_event_notify(enum WIFI_BT_COEX_EVENT event, void *event_arg)
{
return wifi_bt_coex_event_handler_impl(event, event_arg);
}

View File

@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <wifi_bt_coex.h>
#include <cli.h>
static void cmd_coex_dump_all(char *buf, int len, int argc, char **argv)
{
wifi_bt_coex_dump_all();
}
static void cmd_coex_wlan(char *buf, int len, int argc, char **argv)
{
wifi_bt_coex_force_wlan();
}
static void cmd_coex_bt(char *buf, int len, int argc, char **argv)
{
wifi_bt_coex_force_bt();
}
static void cmd_coex_mode(char *buf, int len, int argc, char **argv)
{
int mode;
if (2 != argc) {
return;
}
mode = atoi(argv[1]);
switch (mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
printf("Use COEX Mode: WIFI_BT_COEX_FORCE_MODE_PTA_FORCE\r\n");
wifi_bt_coex_force_mode(mode);
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
printf("Use COEX Mode: WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE\r\n");
wifi_bt_coex_force_mode(mode);
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
printf("Use COEX Mode: WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE\r\n");
wifi_bt_coex_force_mode(mode);
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
printf("Use COEX Mode: WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2\r\n");
wifi_bt_coex_force_mode(mode);
}
break;
default:
{
/*Empty Here*/
printf("unknown coex mode %d\r\n", mode);
}
}
}
// STATIC_CLI_CMD_ATTRIBUTE makes this(these) command(s) static
const static struct cli_command cmds_user[] STATIC_CLI_CMD_ATTRIBUTE = {
{ "coex_dump_all", "COEX Dump All Status", cmd_coex_dump_all},
{ "coex_wlan", "coex force wlan", cmd_coex_wlan},
{ "coex_bt", "coex force bt", cmd_coex_bt},
{ "coex_mode", "coex mode", cmd_coex_mode},
};
int wifi_bt_coex_cli_init(void)
{
// static command(s) do NOT need to call aos_cli_register_command(s) to register.
// However, calling aos_cli_register_command(s) here is OK but is of no effect as cmds_user are included in cmds list.
// XXX NOTE: Calling this *empty* function is necessary to make cmds_user in this file to be kept in the final link.
//return aos_cli_register_commands(cmds_user, sizeof(cmds_user)/sizeof(cmds_user[0]));
return 0;
}

View File

@ -0,0 +1,24 @@
#include <stdio.h>
#include <wifi_bt_coex.h>
#define COEX_CTX_DEBUG(fmt, args...) printf(fmt, ##args)
int wifi_bt_coex_bt_inc(struct wifi_bt_coex_ctx *ctx, int step)
{
int target;
target = ctx->timer_toggle_end + step;
if (target <= 0 || ctx->timer_toggle_end > ctx->timer_max) {
return -1;
}
ctx->timer_toggle_end = target;
COEX_CTX_DEBUG("[COEX] [CTX] using timer_toggle_end %lu\r\n", ctx->timer_toggle_end);
return 0;
}
int wifi_bt_coex_bt_dec(struct wifi_bt_coex_ctx *ctx, int step)
{
return 0;
}

View File

@ -0,0 +1,7 @@
#ifndef __WIFI_BT_COEX_CTX_H__
#define __WIFI_BT_COEX_CTX_H__
#include <wifi_bt_coex.h>
int wifi_bt_coex_bt_inc(struct wifi_bt_coex_ctx *ctx, int step);
int wifi_bt_coex_bt_dec(struct wifi_bt_coex_ctx *ctx, int step);
#endif

View File

@ -0,0 +1,12 @@
#ifndef __WIFI_BT_COEX_BT_IMPL_H__
#define __WIFI_BT_COEX_BT_IMPL_H__
#include <wifi_bt_coex.h>
int wifi_bt_coex_dump_all_impl(void);
int wifi_bt_coex_force_wlan_impl(void);
int wifi_bt_coex_force_bt_impl(void);
int wifi_bt_coex_force_mode_impl(enum WIFI_BT_COEX_FORCE_MODE mode);
int wifi_bt_coex_event_handler_impl(enum WIFI_BT_COEX_EVENT event, void *event_arg);
#endif

View File

@ -0,0 +1,166 @@
#include <stdio.h>
#include <wifi_bt_coex.h>
#include "wifi_bt_coex_impl.h"
#include "wifi_bt_coex_ctx.h"
#define PTA_REG_BASE_ADDR (0x44920000)
#define PTA_REG_REVISION (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x00))
#define PTA_REG_CONFIG (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x04))
#define PTA_REG_BT_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x08))
#define PTA_REG_BT_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x0C))
#define PTA_REG_BT_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x10))
#define PTA_REG_BT_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x14))
#define PTA_REG_WLAN_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x18))
#define PTA_REG_WLAN_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x1C))
#define PTA_REG_WLAN_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x20))
#define PTA_REG_WLAN_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x24))
#define WLAN_COEX_REG_BASE_ADDR (0x44B00400)
#define WLAN_COEX_REG_CoexControlReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x00))
#define WLAN_COEX_REG_CoexPTIReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x04))
#define WLAN_COEX_REG_CoexStatReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x08))
#define WLAN_COEX_REG_CoexIntReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x0C))
static enum WIFI_BT_COEX_FORCE_MODE wifi_bt_coex_bl602_mode = WIFI_BT_COEX_FORCE_MODE_PTA_FORCE;
extern struct wifi_bt_coex_ctx coex_timing_control_ctx;
int wifi_bt_coex_dump_all_impl(void)
{
uint32_t val;
printf("============BL602 PTA Reg Dump============\r\n");
printf("REVISIOIN %08lx\r\n", PTA_REG_REVISION);
printf("CONFIG %08lx\r\n", PTA_REG_CONFIG);
printf("BT TX %08lx\r\n", PTA_REG_BT_TX);
printf("BT TX Abort %08lx\r\n", PTA_REG_BT_TX_ABORT);
printf("BT RX %08lx\r\n", PTA_REG_BT_RX);
printf("BT RX Abort %08lx\r\n", PTA_REG_BT_RX_ABORT);
printf("WLAN TX %08lx\r\n", PTA_REG_WLAN_TX);
printf("WLAN TX Abort %08lx\r\n", PTA_REG_WLAN_TX_ABORT);
printf("WLAN RX %08lx\r\n", PTA_REG_WLAN_RX);
printf("WLAN RX Abort %08lx\r\n", PTA_REG_WLAN_RX_ABORT);
printf("============BL602 Coex (Wi-Fi) Reg Dump============\r\n");
printf("CoexControlReg %08lx\r\n", WLAN_COEX_REG_CoexControlReg);
val = WLAN_COEX_REG_CoexPTIReg;
printf("CoexPTIReg %08lx\r\n", val);
printf(" ACK %lu\r\n", (val >> 0) & 0xF);
printf(" Cntrl %lu\r\n", (val >> 4) & 0xF);
printf(" Mgt %lu\r\n", (val >> 8) & 0xF);
printf(" VO %lu\r\n", (val >> 12) & 0xF);
printf(" VI %lu\r\n", (val >> 16) & 0xF);
printf(" BE %lu\r\n", (val >> 20) & 0xF);
printf(" BK %lu\r\n", (val >> 24) & 0xF);
printf(" BCN %lu\r\n", (val >> 28) & 0xF);
printf("CoexStatReg %08lx\r\n", WLAN_COEX_REG_CoexStatReg);
printf("CoexIntReg %08lx\r\n", WLAN_COEX_REG_CoexIntReg);
return 0;
}
int wifi_bt_coex_force_wlan_impl(void)
{
//puts("BL602 COEX WLAN force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl602_mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG = ((0x50000000 | (1 << 16) | (1 << 17)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
// PTA En WLAN Default Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF48;
WLAN_COEX_REG_CoexPTIReg = 0xFFFFFFFF;
WLAN_COEX_REG_CoexControlReg = 0xF49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
WLAN_COEX_REG_CoexControlReg = 0xF0000F58;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF0000F59;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_bt_impl(void)
{
//puts("BL602 COEX BT force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl602_mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG = ((0x50000000 | (1 << 18) | (1 << 19)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (0 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x48;
WLAN_COEX_REG_CoexPTIReg = 0x00;
WLAN_COEX_REG_CoexControlReg = 0x49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
WLAN_COEX_REG_CoexControlReg = 0x048;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x049;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_mode_impl(enum WIFI_BT_COEX_FORCE_MODE mode)
{
wifi_bt_coex_bl602_mode = mode;
return 0;
}
int wifi_bt_coex_event_handler_impl(enum WIFI_BT_COEX_EVENT event, void *event_arg)
{
switch (event) {
case WIFI_BT_COEX_EVENT_BT_A2DP_UNDERRUN:
{
wifi_bt_coex_bt_inc(&coex_timing_control_ctx, 1);
}
break;
default:
{
/*empty here*/
}
}
return 0;
}

View File

@ -0,0 +1,184 @@
#include <stdio.h>
#include <wifi_bt_coex.h>
#include "wifi_bt_coex_impl.h"
#include "wifi_bt_coex_ctx.h"
#define PTA_REG_BASE_ADDR (0x24920400)
#define PTA_REG_REVISION (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x00))
#define PTA_REG_CONFIG (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x04))
#define PTA_REG_BT_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x08))
#define PTA_REG_BT_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x0C))
#define PTA_REG_BT_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x10))
#define PTA_REG_BT_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x14))
#define PTA_REG_WLAN_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x18))
#define PTA_REG_WLAN_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x1C))
#define PTA_REG_WLAN_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x20))
#define PTA_REG_WLAN_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x24))
#define PTA_REG_CONFIG2 (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x28))
#define WLAN_COEX_REG_BASE_ADDR (0x24B00400)
#define WLAN_COEX_REG_CoexControlReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x00))
#define WLAN_COEX_REG_CoexPTIReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x04))
#define WLAN_COEX_REG_CoexStatReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x08))
#define WLAN_COEX_REG_CoexIntReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x0C))
#define WLAN_COEX_REG_CoexControl2Reg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x10))
static enum WIFI_BT_COEX_FORCE_MODE wifi_bt_coex_bl606p_mode = WIFI_BT_COEX_FORCE_MODE_PTA_FORCE;
extern struct wifi_bt_coex_ctx coex_timing_control_ctx;
int wifi_bt_coex_dump_all_impl(void)
{
uint32_t val;
printf("============BL606P PTA Reg Dump============\r\n");
printf("REVISIOIN %08lx\r\n", PTA_REG_REVISION);
printf("CONFIG %08lx\r\n", PTA_REG_CONFIG);
printf("BT TX %08lx\r\n", PTA_REG_BT_TX);
printf("BT TX Abort %08lx\r\n", PTA_REG_BT_TX_ABORT);
printf("BT RX %08lx\r\n", PTA_REG_BT_RX);
printf("BT RX Abort %08lx\r\n", PTA_REG_BT_RX_ABORT);
printf("WLAN TX %08lx\r\n", PTA_REG_WLAN_TX);
printf("WLAN TX Abort %08lx\r\n", PTA_REG_WLAN_TX_ABORT);
printf("WLAN RX %08lx\r\n", PTA_REG_WLAN_RX);
printf("WLAN RX Abort %08lx\r\n", PTA_REG_WLAN_RX_ABORT);
printf("CONFIG2 %08lx\r\n", PTA_REG_CONFIG2);
printf("============BL606P Coex (Wi-Fi) Reg Dump============\r\n");
printf("CoexControlReg %08lx\r\n", WLAN_COEX_REG_CoexControlReg);
val = WLAN_COEX_REG_CoexPTIReg;
printf("CoexPTIReg %08lx\r\n", val);
printf(" ACK %lu\r\n", (val >> 0) & 0xF);
printf(" Cntrl %lu\r\n", (val >> 4) & 0xF);
printf(" Mgt %lu\r\n", (val >> 8) & 0xF);
printf(" VO %lu\r\n", (val >> 12) & 0xF);
printf(" VI %lu\r\n", (val >> 16) & 0xF);
printf(" BE %lu\r\n", (val >> 20) & 0xF);
printf(" BK %lu\r\n", (val >> 24) & 0xF);
printf(" BCN %lu\r\n", (val >> 28) & 0xF);
printf("CoexStatReg %08lx\r\n", WLAN_COEX_REG_CoexStatReg);
printf("CoexIntReg %08lx\r\n", WLAN_COEX_REG_CoexIntReg);
val = WLAN_COEX_REG_CoexControl2Reg;
printf("CoexControl2Reg %08lx\r\n", val);
printf(" Force BK %lu\r\n", (val >> 0) & 0x1);
printf(" Force BE %lu\r\n", (val >> 1) & 0x1);
printf(" Force VI %lu\r\n", (val >> 2) & 0x1);
printf(" Force VO %lu\r\n", (val >> 3) & 0x1);
printf(" Force BCN %lu\r\n", (val >> 4) & 0x1);
return 0;
}
int wifi_bt_coex_force_wlan_impl(void)
{
//puts("BL606P COEX WLAN force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl606p) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG2 = 0;
PTA_REG_CONFIG = ((0x50000000 | (1 << 16) | (1 << 17)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Default Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF48;
WLAN_COEX_REG_CoexPTIReg = 0xFFFFFFFF;
WLAN_COEX_REG_CoexControlReg = 0xF49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
PTA_REG_CONFIG2 = 0;
WLAN_COEX_REG_CoexControlReg = 0xF0000F58;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF0000F59;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_bt_impl(void)
{
//puts("BL606p COEX BT force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl606p_mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG2 = 0;
PTA_REG_CONFIG = ((0x50000000 | (1 << 18) | (1 << 19)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (0 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x48;
WLAN_COEX_REG_CoexPTIReg = 0x00;
WLAN_COEX_REG_CoexControlReg = 0x49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
PTA_REG_CONFIG2 = 0;
WLAN_COEX_REG_CoexControlReg = 0x048;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x049;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_mode_impl(enum WIFI_BT_COEX_FORCE_MODE mode)
{
wifi_bt_coex_bl606p_mode = mode;
return 0;
}
int wifi_bt_coex_event_handler_impl(enum WIFI_BT_COEX_EVENT event, void *event_arg)
{
switch (event) {
case WIFI_BT_COEX_EVENT_BT_A2DP_UNDERRUN:
{
wifi_bt_coex_bt_inc(&coex_timing_control_ctx, 1);
}
break;
default:
{
/*empty here*/
}
}
return 0;
}

View File

@ -0,0 +1,184 @@
#include <stdio.h>
#include <wifi_bt_coex.h>
#include "wifi_bt_coex_impl.h"
#include "wifi_bt_coex_ctx.h"
#define PTA_REG_BASE_ADDR (0x24920400)
#define PTA_REG_REVISION (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x00))
#define PTA_REG_CONFIG (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x04))
#define PTA_REG_BT_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x08))
#define PTA_REG_BT_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x0C))
#define PTA_REG_BT_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x10))
#define PTA_REG_BT_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x14))
#define PTA_REG_WLAN_TX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x18))
#define PTA_REG_WLAN_TX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x1C))
#define PTA_REG_WLAN_RX (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x20))
#define PTA_REG_WLAN_RX_ABORT (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x24))
#define PTA_REG_CONFIG2 (*(volatile uint32_t *)(PTA_REG_BASE_ADDR + 0x28))
#define WLAN_COEX_REG_BASE_ADDR (0x24B00400)
#define WLAN_COEX_REG_CoexControlReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x00))
#define WLAN_COEX_REG_CoexPTIReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x04))
#define WLAN_COEX_REG_CoexStatReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x08))
#define WLAN_COEX_REG_CoexIntReg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x0C))
#define WLAN_COEX_REG_CoexControl2Reg (*(volatile uint32_t *)(WLAN_COEX_REG_BASE_ADDR + 0x10))
static enum WIFI_BT_COEX_FORCE_MODE wifi_bt_coex_bl808_mode = WIFI_BT_COEX_FORCE_MODE_PTA_FORCE;
extern struct wifi_bt_coex_ctx coex_timing_control_ctx;
int wifi_bt_coex_dump_all_impl(void)
{
uint32_t val;
printf("============BL808 PTA Reg Dump============\r\n");
printf("REVISIOIN %08lx\r\n", PTA_REG_REVISION);
printf("CONFIG %08lx\r\n", PTA_REG_CONFIG);
printf("BT TX %08lx\r\n", PTA_REG_BT_TX);
printf("BT TX Abort %08lx\r\n", PTA_REG_BT_TX_ABORT);
printf("BT RX %08lx\r\n", PTA_REG_BT_RX);
printf("BT RX Abort %08lx\r\n", PTA_REG_BT_RX_ABORT);
printf("WLAN TX %08lx\r\n", PTA_REG_WLAN_TX);
printf("WLAN TX Abort %08lx\r\n", PTA_REG_WLAN_TX_ABORT);
printf("WLAN RX %08lx\r\n", PTA_REG_WLAN_RX);
printf("WLAN RX Abort %08lx\r\n", PTA_REG_WLAN_RX_ABORT);
printf("CONFIG2 %08lx\r\n", PTA_REG_CONFIG2);
printf("============BL808 Coex (Wi-Fi) Reg Dump============\r\n");
printf("CoexControlReg %08lx\r\n", WLAN_COEX_REG_CoexControlReg);
val = WLAN_COEX_REG_CoexPTIReg;
printf("CoexPTIReg %08lx\r\n", val);
printf(" ACK %lu\r\n", (val >> 0) & 0xF);
printf(" Cntrl %lu\r\n", (val >> 4) & 0xF);
printf(" Mgt %lu\r\n", (val >> 8) & 0xF);
printf(" VO %lu\r\n", (val >> 12) & 0xF);
printf(" VI %lu\r\n", (val >> 16) & 0xF);
printf(" BE %lu\r\n", (val >> 20) & 0xF);
printf(" BK %lu\r\n", (val >> 24) & 0xF);
printf(" BCN %lu\r\n", (val >> 28) & 0xF);
printf("CoexStatReg %08lx\r\n", WLAN_COEX_REG_CoexStatReg);
printf("CoexIntReg %08lx\r\n", WLAN_COEX_REG_CoexIntReg);
val = WLAN_COEX_REG_CoexControl2Reg;
printf("CoexControl2Reg %08lx\r\n", val);
printf(" Force BK %lu\r\n", (val >> 0) & 0x1);
printf(" Force BE %lu\r\n", (val >> 1) & 0x1);
printf(" Force VI %lu\r\n", (val >> 2) & 0x1);
printf(" Force VO %lu\r\n", (val >> 3) & 0x1);
printf(" Force BCN %lu\r\n", (val >> 4) & 0x1);
return 0;
}
int wifi_bt_coex_force_wlan_impl(void)
{
//puts("BL808 COEX WLAN force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl808_mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG2 = 0;
PTA_REG_CONFIG = ((0x50000000 | (1 << 16) | (1 << 17)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Default Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF48;
WLAN_COEX_REG_CoexPTIReg = 0xFFFFFFFF;
WLAN_COEX_REG_CoexControlReg = 0xF49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
PTA_REG_CONFIG2 = 0;
WLAN_COEX_REG_CoexControlReg = 0xF0000F58;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0xF0000F59;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_bt_impl(void)
{
//puts("BL808 COEX BT force impl called\r\n");
//Force to RF1/BT/WLAN
switch (wifi_bt_coex_bl808_mode) {
case WIFI_BT_COEX_FORCE_MODE_PTA_FORCE:
{
PTA_REG_CONFIG2 = 0;
PTA_REG_CONFIG = ((0x50000000 | (1 << 18) | (1 << 19)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_DEFAULT_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (0 << 1) | (0 << 4)));
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE:
{
PTA_REG_CONFIG2 = 0;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x48;
WLAN_COEX_REG_CoexPTIReg = 0x00;
WLAN_COEX_REG_CoexControlReg = 0x49;
}
break;
case WIFI_BT_COEX_FORCE_MODE_PTI_PRIORITY_FORCE2:
{
PTA_REG_CONFIG2 = 0;
WLAN_COEX_REG_CoexControlReg = 0x048;
// PTA En WLAN Priority
PTA_REG_CONFIG = ((0x50000000 | (1 << 0) | (1 << 1) | (1 << 4)));
WLAN_COEX_REG_CoexControlReg = 0x049;
}
break;
default:
{
/*empty here*/
}
}
return 0;
}
int wifi_bt_coex_force_mode_impl(enum WIFI_BT_COEX_FORCE_MODE mode)
{
wifi_bt_coex_bl808_mode = mode;
return 0;
}
int wifi_bt_coex_event_handler_impl(enum WIFI_BT_COEX_EVENT event, void *event_arg)
{
switch (event) {
case WIFI_BT_COEX_EVENT_BT_A2DP_UNDERRUN:
{
wifi_bt_coex_bt_inc(&coex_timing_control_ctx, 1);
}
break;
default:
{
/*empty here*/
}
}
return 0;
}

View File

@ -44,13 +44,13 @@ wifi_hosal_funcs_t g_wifi_hosal_funcs =
.rf_turn_off = hosal_wifi_ret_zero,
.adc_device_get = hosal_wifi_ret_zero,
.adc_tsen_value_get = hosal_wifi_ret_zero,
.pm_init = hosal_wifi_ret_zero,
.pm_event_register = hosal_wifi_ret_zero,
.pm_deinit = hosal_wifi_ret_zero,
.pm_state_run = hosal_wifi_ret_non_zero,
.pm_capacity_set = hosal_wifi_ret_zero,
.pm_post_event = hosal_wifi_ret_zero,
.pm_event_switch = hosal_wifi_ret_zero,
.pm_init = bl_pm_init,
.pm_event_register = bl_pm_event_register,
.pm_deinit = bl_pm_deinit,
.pm_state_run = bl_pm_state_run,
.pm_capacity_set = bl_pm_capacity_set,
.pm_post_event = pm_post_event,
.pm_event_switch = bl_pm_event_switch,
};
/****************************************************************************

View File

@ -186,7 +186,7 @@ int bl_open(struct bl_hw *bl_hw)
#endif
}
int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int psk_len, const uint8_t *pmk, int pmk_len, const uint8_t *mac, const uint8_t band, const uint16_t freq)
int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int psk_len, const uint8_t *pmk, int pmk_len, const uint8_t *mac, const uint8_t band, const uint16_t freq, const uint32_t flags)
{
struct cfg80211_connect_params sme;
@ -199,6 +199,7 @@ int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int p
sme.key_len = psk_len;
sme.pmk = pmk;
sme.pmk_len = pmk_len;
sme.flags = flags;
if (mac){
sme.bssid = mac;
@ -468,13 +469,13 @@ int bl_main_cfg_task_req(uint32_t ops, uint32_t task, uint32_t element, uint32_t
return bl_send_cfg_task_req(&wifi_hw, ops, task, element, type, arg1, arg2);
}
int bl_main_scan(struct netif *netif, uint16_t *fixed_channels, uint16_t channel_num, struct mac_ssid *ssid)
int bl_main_scan(struct netif *netif, uint16_t *fixed_channels, uint16_t channel_num, struct mac_addr *bssid, struct mac_ssid *ssid)
{
if (0 == channel_num) {
bl_send_scanu_req(&wifi_hw, NULL, 0, ssid, netif->hwaddr);
bl_send_scanu_req(&wifi_hw, NULL, 0, bssid, ssid, netif->hwaddr);
} else {
if (bl_get_fixed_channels_is_valid(fixed_channels, channel_num)) {
bl_send_scanu_req(&wifi_hw, fixed_channels, channel_num, ssid, netif->hwaddr);
bl_send_scanu_req(&wifi_hw, fixed_channels, channel_num, bssid, ssid, netif->hwaddr);
} else {
bl_os_printf("---->unvalid channel");
}

View File

@ -32,6 +32,7 @@
#include <stdint.h>
#include <lwip/netif.h>
#include "lmac_mac.h"
#include <wifi_mgmr_ext.h>
struct wifi_apm_sta_info
{
@ -54,7 +55,7 @@ int bl_main_rate_config(uint8_t sta_idx, uint16_t fixed_rate_cfg);
int bl_main_if_remove(uint8_t vif_index);
int bl_main_if_add(int is_sta, struct netif *netif, uint8_t *vif_index);
int bl_main_monitor(void);
int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int psk_len, const uint8_t *pmk, int pmk_len, const uint8_t *mac, const uint8_t band, const uint16_t freq);
int bl_main_connect(const uint8_t* ssid, int ssid_len, const uint8_t *psk, int psk_len, const uint8_t *pmk, int pmk_len, const uint8_t *mac, const uint8_t band, const uint16_t freq, const uint32_t flags);
int bl_main_apm_start(char *ssid, char *password, int channel, uint8_t vif_index, uint8_t hidden_ssid, uint16_t bcn_int);
int bl_main_apm_stop(uint8_t vif_index);
int bl_main_apm_sta_cnt_get(uint8_t *sta_cnt);
@ -63,7 +64,7 @@ int bl_main_apm_sta_delete(uint8_t sta_idx);
int bl_main_apm_remove_all_sta();
int bl_main_conf_max_sta(uint8_t max_sta_supported);
int bl_main_cfg_task_req(uint32_t ops, uint32_t task, uint32_t element, uint32_t type, void *arg1, void *arg2);
int bl_main_scan(struct netif *netif, uint16_t *fixed_channels, uint16_t channel_num, struct mac_ssid *ssid);
int bl_main_scan(struct netif *netif, uint16_t *fixed_channels, uint16_t channel_num, struct mac_addr *bssid, struct mac_ssid *ssid);
int bl_main_raw_send(uint8_t *pkt , int len);
int bl_main_set_country_code(char *country_code);
int bl_main_get_channel_nums();
@ -185,7 +186,8 @@ typedef void (*wifi_event_sm_connect_ind_cb_t)(void *env, struct wifi_event_sm_c
typedef void (*wifi_event_sm_disconnect_ind_cb_t)(void *env, struct wifi_event_sm_disconnect_ind *ind);
typedef void (*wifi_event_beacon_ind_cb_t)(void *env, struct wifi_event_beacon_ind *ind);
typedef void (*wifi_event_probe_resp_ind_cb_t)(void *env, long long timestamp);
typedef void (*wifi_event_pkt_cb_t)(void *env, uint8_t *ieee80211_pkt, int len);
typedef void (*wifi_event_pkt_cb_t)(void *env, uint8_t *ieee80211_pkt, int len, bl_rx_info_t *info);
typedef void (*wifi_event_pkt_cb_adv_t)(void *env, void *pkt_wrap, bl_rx_info_t *info);
typedef void (*wifi_event_rssi_cb_t)(void *env, int8_t rssi);
typedef void (*wifi_event_cb_t)(void *env, struct wifi_event *event);
int bl_rx_sm_connect_ind_cb_register(void *env, wifi_event_sm_connect_ind_cb_t cb);
@ -197,6 +199,8 @@ int bl_rx_probe_resp_ind_cb_register(void *env, wifi_event_probe_resp_ind_cb_t c
int bl_rx_beacon_ind_cb_unregister(void *env, wifi_event_beacon_ind_cb_t cb);
int bl_rx_pkt_cb_register(void *env, wifi_event_pkt_cb_t cb);
int bl_rx_pkt_cb_unregister(void *env);
int bl_rx_pkt_adv_cb_register(void *env, wifi_event_pkt_cb_adv_t cb);
int bl_rx_pkt_adv_cb_unregister(void *env);
int bl_rx_rssi_cb_register(void *env, wifi_event_rssi_cb_t cb);
int bl_rx_rssi_cb_unregister(void *env, wifi_event_rssi_cb_t cb);
int bl_rx_event_register(void *env, wifi_event_cb_t cb);

View File

@ -104,24 +104,25 @@ static const struct mac_addr mac_addr_bcst = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF
static const struct mac_addr mac_addr_zero = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
static const struct ieee80211_channel bl_channels_24_General[] = {
{ .band = NL80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, .max_power=16},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, .max_power=20},
{ .band = NL80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, .max_power=20},
};
static const struct ieee80211_dot_d country_list[] =
{
/*First Country is the default country*/
{
.code = "CN",
.channel_num = 13,
@ -146,8 +147,9 @@ static const struct ieee80211_dot_d country_list[] =
static int channel_num_default;
static const struct ieee80211_channel *channels_default;
static const struct ieee80211_dot_d *country_default;
static int cfg80211_get_channel_list(const char *code, int *channel_num, const struct ieee80211_channel **channels)
static int cfg80211_get_channel_list(const char *code, int *channel_num, const struct ieee80211_channel **channels, const struct ieee80211_dot_d **country_default)
{
int i;
@ -159,6 +161,9 @@ static int cfg80211_get_channel_list(const char *code, int *channel_num, const s
if (channels) {
*channels = country_list[i].channels;
}
if (country_default) {
*country_default = &country_list[i];
}
return 0;
}
}
@ -168,10 +173,11 @@ static int cfg80211_get_channel_list(const char *code, int *channel_num, const s
void bl_msg_update_channel_cfg(const char *code)
{
if (cfg80211_get_channel_list(code, &channel_num_default, &channels_default)) {
if (cfg80211_get_channel_list(code, &channel_num_default, &channels_default, &country_default)) {
/*get channel list failed, so we set the default one*/
channel_num_default = sizeof(bl_channels_24_General)/sizeof(bl_channels_24_General[0]);
channels_default = bl_channels_24_General;
country_default = &country_list[0];
bl_os_printf("[WF] %s NOT found, using General instead, num of channel %d\r\n", code, channel_num_default);
} else {
bl_os_printf("[WF] country code %s used, num of channel %d\r\n", code, channel_num_default);
@ -203,7 +209,7 @@ int bl_get_fixed_channels_is_valid(uint16_t *channels, uint16_t channel_num)
return 1;
}
static inline uint16_t phy_channel_to_freq(uint8_t band, int channel)
inline uint16_t phy_channel_to_freq(uint8_t band, int channel)
{
uint16_t freq = 0xFFFF;
@ -435,9 +441,15 @@ int bl_send_me_config_req(struct bl_hw *bl_hw)
req->ht_supp = 1;
req->vht_supp = 0;
req->ht_cap.ht_capa_info = cpu_to_le16(bl_hw->ht_cap.cap);
req->ht_cap.a_mpdu_param = bl_hw->ht_cap.ampdu_factor |
(bl_hw->ht_cap.ampdu_density <<
IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
/*AMPDU MAX Length:
* 0x0:8K
* 0x1:16K
* 0x2:32K
* 0x3:64K
*/
req->ht_cap.a_mpdu_param = 0x3;
for (i = 0; i < sizeof(bl_hw->ht_cap.mcs); i++) {
req->ht_cap.mcs_rate[i] = ht_mcs[i];
}
@ -513,6 +525,7 @@ int bl_send_me_rate_config_req(struct bl_hw *bl_hw, uint8_t sta_idx, uint16_t fi
}
req->sta_idx = sta_idx;
req->fixed_rate_cfg = fixed_rate_cfg;
req->power_table_req = 1;
return bl_send_msg(bl_hw, req, 0, 0, NULL);
}
@ -603,7 +616,7 @@ int bl_send_remove_if(struct bl_hw *bl_hw, uint8_t inst_nbr)
return bl_send_msg(bl_hw, remove_if_req_param, 1, MM_REMOVE_IF_CFM, NULL);
}
int bl_send_scanu_req(struct bl_hw *bl_hw, uint16_t *channels, uint16_t channel_num, struct mac_ssid *ssid, const uint8_t *mac)
int bl_send_scanu_req(struct bl_hw *bl_hw, uint16_t *channels, uint16_t channel_num, struct mac_addr *bssid, struct mac_ssid *ssid, const uint8_t *mac)
{
struct scanu_start_req *req;
int i, index;
@ -628,18 +641,20 @@ int bl_send_scanu_req(struct bl_hw *bl_hw, uint16_t *channels, uint16_t channel_
req->chan_cnt = channel_num;
}
req->ssid_cnt = 1;
if (ssid != NULL && ssid->length) {
req->ssid_cnt = 1;
req->ssid[0].length = ssid->length;
memcpy(req->ssid[0].array, ssid->array, req->ssid[0].length);
} else {
req->ssid_cnt = 0;
req->ssid[0].length = 0;
}
req->bssid = mac_addr_bcst;
memcpy((uint8_t *)&(req->bssid), (uint8_t *)bssid, ETH_ALEN);
memcpy(&(req->mac), mac, ETH_ALEN);
req->no_cck = true;//FIXME params? talk with firmware guys
if (req->ssid_cnt == 0) {
if (req->ssid_cnt == 0)
{
chan_flags |= SCAN_PASSIVE_BIT;
}
#if 0
@ -703,7 +718,7 @@ int bl_send_sm_connect_req(struct bl_hw *bl_hw, struct cfg80211_connect_params *
{
struct sm_connect_req *req;
int i;
u32_l flags = 0;
u32_l flags = sme->flags;
RWNX_DBG(RWNX_FN_ENTRY_STR);
@ -846,6 +861,41 @@ int bl_send_mm_denoise_req(struct bl_hw *bl_hw, int mode)
return bl_send_msg(bl_hw, req, 1, MM_SET_PS_MODE_CFM, NULL);
}
/* Country IE definition
MAC_COUNTRY_2G4_USA {7, 6, 'U', 'S', 32, 1, 11, 20} // X'10' FCC
MAC_COUNTRY_2G4_CANADA {7, 6, 'C', 'A', 32, 1, 11, 20} // X'20' DOC/IC
MAC_COUNTRY_2G4_EUROPE {7, 6, 'E', 'U', 32, 1, 13, 20} // X'30' ETSI
MAC_COUNTRY_2G4_SPAIN {7, 6, 'S', 'P', 32, 10, 2, 20} // X'31'
MAC_COUNTRY_2G4_FRANCE {7, 6, 'F', 'R', 32, 10, 4, 20} // X'32'
MAC_COUNTRY_2G4_JAPAN {7, 6, 'J', 'P', 32, 14, 1, 20} // X'40'
MAC_COUNTRY_2G4_CHINA {7, 6, 'C', 'N', 32, 1, 13, 20} // X'50'
*/
static int _fill_country_code_ie(uint8_t *buf, uint8_t buf_len_max)
{
if (NULL == country_default || NULL == channels_default) {
return 0;
}
// Tag: Country Informance
buf[0] = 7;
// Tag lenth
buf[1] = 6;
//Country Code
buf[2] = country_default->code[0];
buf[3] = country_default->code[1];
//Environment
buf[4] = 32;//Any
//First Channel
buf[5] = 1;
//Channel Num
buf[6] = buf[5] - 1 + country_default ->channel_num;
//Max power
buf[7] = channels_default->max_power;
return 8;
}
int bl_send_apm_start_req(struct bl_hw *bl_hw, struct apm_start_cfm *cfm, char *ssid, char *password, int channel, uint8_t vif_index, uint8_t hidden_ssid, uint16_t bcn_int)
{
struct apm_start_req *req;
@ -911,6 +961,7 @@ int bl_send_apm_start_req(struct bl_hw *bl_hw, struct apm_start_cfm *cfm, char *
req->beacon_period = 0x1; //force AP DTIM period
req->qos_supported = 1;
#endif
req->bcn_buf_len = _fill_country_code_ie(req->bcn_buf, sizeof(req->bcn_buf));
/* Send the APM_START_REQ message to LMAC FW */
return bl_send_msg(bl_hw, req, 1, APM_START_CFM, cfm);

View File

@ -48,7 +48,7 @@ int bl_send_start(struct bl_hw *bl_hw);
int bl_send_add_if(struct bl_hw *bl_hw, const unsigned char *mac,
enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm);
int bl_send_remove_if(struct bl_hw *bl_hw, uint8_t inst_nbr);
int bl_send_scanu_req(struct bl_hw *bl_hw, uint16_t *channels, uint16_t channel_num, struct mac_ssid *ssid, const uint8_t *mac);
int bl_send_scanu_req(struct bl_hw *bl_hw, uint16_t *channels, uint16_t channel_num, struct mac_addr *bssid, struct mac_ssid *ssid, const uint8_t *mac);
int bl_send_scanu_raw_send(struct bl_hw *bl_hw, uint8_t *pkt, int len);
int bl_send_sm_connect_req(struct bl_hw *bl_hw, struct cfg80211_connect_params *sme, struct sm_connect_cfm *cfm);
int bl_send_sm_disconnect_req(struct bl_hw *bl_hw);
@ -64,4 +64,5 @@ void bl_msg_update_channel_cfg(const char *code);
int bl_msg_get_channel_nums();
int bl_get_fixed_channels_is_valid(uint16_t *channels, uint16_t channel_num);
int bl_send_beacon_interval_set(struct bl_hw *bl_hw, struct mm_set_beacon_int_cfm *cfm, uint16_t beacon_int);
uint16_t phy_channel_to_freq(uint8_t band, int channel);
#endif

View File

@ -57,6 +57,7 @@ static void* cb_beacon_ind_env;
static wifi_event_probe_resp_ind_cb_t cb_probe_resp_ind;
static void* cb_probe_resp_ind_env;
static wifi_event_pkt_cb_t cb_pkt;
static wifi_event_pkt_cb_adv_t cb_pkt_adv;
static void* cb_pkt_env;
static wifi_event_rssi_cb_t cb_rssi;
static void* cb_rssi_env;
@ -183,6 +184,22 @@ int bl_rx_pkt_cb_unregister(void *env)
return 0;
}
int bl_rx_pkt_adv_cb_register(void *env, wifi_event_pkt_cb_adv_t cb)
{
cb_pkt_adv = cb;
cb_pkt_env = env;
return 0;
}
int bl_rx_pkt_adv_cb_unregister(void *env)
{
cb_pkt_adv = NULL;
cb_pkt_env = NULL;
return 0;
}
//FIXME race condition protect?
int bl_rx_rssi_cb_register(void *env, wifi_event_rssi_cb_t cb)
{
@ -784,9 +801,12 @@ void bl_rx_e2a_handler(void *arg)
wifi_hw.cmd_mgr.msgind(&wifi_hw.cmd_mgr, msg, msg_hdlrs[MSG_T(msg->id)][MSG_I(msg->id)]);
}
void bl_rx_pkt_cb(uint8_t *pkt, int len)
void bl_rx_pkt_cb(uint8_t *pkt, int len, void *pkt_wrap, bl_rx_info_t *info)
{
if (cb_pkt) {
cb_pkt(cb_pkt_env, pkt, len);
cb_pkt(cb_pkt_env, pkt, len, info);
}
if (cb_pkt_adv) {
cb_pkt_adv(cb_pkt_env, pkt_wrap, info);
}
}

View File

@ -33,6 +33,7 @@
#define _RWNX_RX_H_
#include "bl_defs.h"
#include "lmac_types.h"
#include <wifi_mgmr_ext.h>
enum rx_status_bits
{
@ -50,6 +51,9 @@ enum rx_status_bits
RX_STAT_COPY = 1 << 5,
};
#define BL_RX_STATUS_AMSDU (1 << 0)
// XXX Value must not conflict with PBUF_FLAG_PUSH, etc in pbuf.h
#define PBUF_FLAG_AMSDU 0x80U
/*
* Decryption status subfields.
@ -210,7 +214,7 @@ int bl_txdatacfm(void *pthis, void *hostid);
void bl_prim_tbtt_ind(void *pthis);
void bl_sec_tbtt_ind(void *pthis);
void bl_rx_handle_msg(struct bl_hw *bl_hw, struct ipc_e2a_msg *msg);
void bl_rx_pkt_cb(uint8_t *pkt, int len);
void bl_rx_pkt_cb(uint8_t *pkt, int len, void *pkt_wrap, bl_rx_info_t *info);
const char* wifi_mgmr_get_sm_status_code_str(uint16_t status_code);
#endif /* _RWNX_RX_H_ */

View File

@ -45,6 +45,62 @@ int internel_cal_size_tx_hdr = sizeof(struct bl_txhdr);
extern struct bl_hw wifi_hw;
static struct bl_hw *bl_hw_static = &wifi_hw;
#if defined(CFG_CHIP_BL808)
void bl_tx_push(struct bl_hw *bl_hw, struct bl_txhdr *txhdr)
{
volatile struct hostdesc *host;
uint32_t* p = txhdr->p;
uint32_t offset;
struct txdesc_host *txdesc_host;
//host = &(ipc_host_txdesc_get(bl_hw->ipc_env)->host);
txdesc_host = ipc_host_txdesc_get(bl_hw->ipc_env);
host = &(txdesc_host->host);
ASSERT_ERR(host);//TODO protect when host is NULL
{
u8 *src, *dst;
int i;
dst = (typeof(dst))host;
src = (typeof(src))&txhdr->host;
for (i = 0; i < sizeof(*host) / sizeof(*src); i++) {
*dst++ = *src++;
}
}
offset = 0;
if (host->pbuf_chained_len[0]) {
memcpy(((uint8_t *)&(txdesc_host->eth_packet[0])) + offset, \
host->pbuf_chained_ptr[0], host->pbuf_chained_len[0]);
offset += host->pbuf_chained_len[0];
}
if (host->pbuf_chained_len[1]) {
memcpy(((uint8_t *)&(txdesc_host->eth_packet[1])) + offset, \
host->pbuf_chained_ptr[1], host->pbuf_chained_len[1]);
offset += host->pbuf_chained_len[0];
}
if (host->pbuf_chained_len[2]) {
memcpy(((uint8_t *)&(txdesc_host->eth_packet[2])) + offset, \
host->pbuf_chained_ptr[2], host->pbuf_chained_len[2]);
offset += host->pbuf_chained_len[2];
}
if (host->pbuf_chained_len[3]) {
memcpy(((uint8_t *)&(txdesc_host->eth_packet[3])) + offset, \
host->pbuf_chained_ptr[3], host->pbuf_chained_len[3]);
offset += host->pbuf_chained_len[3];
}
host->pbuf_chained_ptr[0] = (uint32_t)(&(txdesc_host->eth_packet[0]));
host->pbuf_chained_len[0] = offset;
host->pbuf_chained_ptr[1] = 0;
host->pbuf_chained_len[1] = 0;
ipc_host_txdesc_push(bl_hw->ipc_env, p);
#ifdef CFG_BL_STATISTIC
bl_hw->stats.cfm_balance++;
#endif
}
#else
void bl_tx_push(struct bl_hw *bl_hw, struct bl_txhdr *txhdr)
{
volatile struct hostdesc *host;
@ -68,6 +124,7 @@ void bl_tx_push(struct bl_hw *bl_hw, struct bl_txhdr *txhdr)
bl_hw->stats.cfm_balance++;
#endif
}
#endif
#define TXHDR_HODLER_LEN (8)
#define TXHDR_HODLER_MSK (0x7)
@ -145,6 +202,11 @@ int bl_txdatacfm(void *pthis, void *host_id)
return 0;
}
#if 0
uint32_t drop_ack_now = 0;
uint32_t droped_ack;
#endif
err_t bl_output(struct bl_hw *bl_hw, struct netif *netif, struct pbuf *p, int is_sta, struct bl_custom_tx_cfm *custom_cfm)
{
struct bl_txhdr *txhdr;
@ -165,6 +227,15 @@ err_t bl_output(struct bl_hw *bl_hw, struct netif *netif, struct pbuf *p, int is
bl_os_printf("[TX] wifi is down, return now\r\n");
return ERR_CONN;
}
#if 0
if (drop_ack_now) {
drop_ack_now++;
if (drop_ack_now & 0x02) {
droped_ack++;
return ERR_OK;
}
}
#endif
bl_hw_static = bl_hw;
packet_len = p->tot_len;

View File

@ -36,6 +36,7 @@
#include <lwip/pbuf.h>
#include <lwip/netif.h>
#include <wifi_mgmr_ext.h>
#include <wifi_pkt_hooks.h>
#include "ipc_shared.h"
#include "ipc_host.h"
@ -114,7 +115,7 @@ static inline struct bl_vif *bl_rx_get_vif(int vif_idx)
*
* Process the management frame and free the corresponding skb
*/
static void bl_rx_mgmt(uint32_t *skb, struct hw_rxhdr *hw_rxhdr, int len)
static void bl_rx_mgmt(uint32_t *skb, struct hw_rxhdr *hw_rxhdr, int len, bl_rx_info_t *info)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb;
static uint32_t counter;
@ -280,114 +281,179 @@ static void dump_pkt_infor(struct hw_rxhdr *hw_rxhdr)
}
}
int tcpip_stack_input(void *swdesc, uint8_t status, void *hwhdr, unsigned int msdu_offset, struct wifi_pkt *pkt)
static inline struct pbuf *_handle_frame_from_stack_with_mempool(void *swdesc, unsigned int msdu_offset, struct wifi_pkt *pkt)
{
struct pbuf *t, *h;
int i = 0;
h = pbuf_alloc(PBUF_RAW, pkt->len[0] - msdu_offset, PBUF_POOL);
if (NULL == h) {
printf("error mem1 ========================================== pbuf mem\r\n");
return NULL;
}
pbuf_take(h, (uint8_t*)(pkt->pkt[0]) + msdu_offset, pkt->len[0] - msdu_offset);
i = 1;//header is already set
while (i < sizeof(pkt->pkt)/sizeof(pkt->pkt[0])) {
if (0 == pkt->len[i]) {
break;
}
t = pbuf_alloc(PBUF_RAW, pkt->len[i], PBUF_POOL);
if (t) {
pbuf_take(t, (uintptr_t*)pkt->pkt[i], pkt->len[i]);
pbuf_cat(h, t);
i++;
} else {
printf("error mem2 ====================================== pbuf mem\r\n");
pbuf_free(h);
return NULL;
}
}
return h;
}
static inline struct pbuf *_handle_frame_from_stack_with_zerocopy(void *swdesc, unsigned int msdu_offset, struct wifi_pkt *pkt)
{
struct pbuf *h, *t;
int i;
bl_custom_pbuf_t* my_pbuf;
my_pbuf = (bl_custom_pbuf_t*)pkt->pbuf[0];
memset(my_pbuf, 0, sizeof(bl_custom_pbuf_t));
my_pbuf->p.custom_free_function = my_pbuf_free_custom;
my_pbuf->swdesc = swdesc;
h = pbuf_alloced_custom(
PBUF_RAW,
pkt->len[0] - msdu_offset,
PBUF_REF,
&my_pbuf->p,
(uint8_t*)(pkt->pkt[0]) + msdu_offset,
pkt->len[0] - msdu_offset
);
i = 1;//header is already set
while (i < sizeof(pkt->pkt)/sizeof(pkt->pkt[0])) {
if (0 == pkt->len[i]) {
break;
}
my_pbuf = (bl_custom_pbuf_t*)pkt->pbuf[i];
memset(my_pbuf, 0, sizeof(bl_custom_pbuf_t));
my_pbuf->p.custom_free_function = my_pbuf_free_custom_fake;
t = pbuf_alloced_custom(
PBUF_RAW,
pkt->len[i],
PBUF_REF,
&my_pbuf->p,
(uint8_t*)(pkt->pkt[i]),
pkt->len[i]
);
pbuf_cat(h, t);
i++;
}
return h;
}
#define MAC_FMT "%02X%02X%02X%02X%02X%02X"
#define MAC_LIST(arr) (arr)[0], (arr)[1], (arr)[2], (arr)[3], (arr)[4], (arr)[5]
int tcpip_stack_input(void *swdesc, uint8_t status, void *hwhdr, unsigned int msdu_offset, struct wifi_pkt *pkt, uint8_t extra_status)
{
struct hw_rxhdr *hw_rxhdr = (struct hw_rxhdr*)hwhdr;
uint32_t *skb = (uint32_t*)(pkt->pkt[0]), *skb_payload;
struct bl_vif *bl_vif;
bool sniffer = false;
bool free_by_lowlayer = true;
bool zerocopy;
struct pbuf *h;
bl_rx_info_t info;
/* Check if we need to forward the buffer */
if (status & RX_STAT_FORWARD) {
bl_vif = bl_rx_get_vif(hw_rxhdr->flags_vif_idx);
skb_payload = (uint32_t*)((uint32_t)(skb) + msdu_offset);
if (!(status & RX_STAT_FORWARD)) {
goto end;
}
if (hw_rxhdr->flags_is_80211_mpdu) {
//TODO fix spilted buff
//dump_pkt_infor(hw_rxhdr);
bl_rx_pkt_cb((uint8_t*)skb_payload, hw_rxhdr->hwvect.len);
bl_rx_mgmt(skb_payload, hw_rxhdr, hw_rxhdr->hwvect.len);
} else {
struct ethhdr *hdr = (struct ethhdr *)(skb_payload);
(void)hdr;
bl_vif = bl_rx_get_vif(hw_rxhdr->flags_vif_idx);
skb_payload = (uint32_t*)((uint32_t)(skb) + msdu_offset);
if (hw_rxhdr->flags_sta_idx != 0xff) {
if (hw_rxhdr->flags_is_4addr) {
bl_os_printf("[RX] Trigger 4addr unexpected frame\r\n");
}
}
os_printf("********************ETH Start******************************\r\n");
os_printf(" Eth Dst %02X%02X%02X%02X%02X%02X\r\n",
hdr->h_dest[0],
hdr->h_dest[1],
hdr->h_dest[2],
hdr->h_dest[3],
hdr->h_dest[4],
hdr->h_dest[5]
);
os_printf(" Eth Src %02X%02X%02X%02X%02X%02X\r\n",
hdr->h_source[0],
hdr->h_source[1],
hdr->h_source[2],
hdr->h_source[3],
hdr->h_source[4],
hdr->h_source[5]
);
os_printf(" Eth Proto %04X, %p:%p, len %u\r\n", hdr->h_proto, bl_vif, bl_vif ? bl_vif->dev : NULL, hw_rxhdr->hwvect.len);
os_printf("********************ETH End******************************\r\n");
if (wifi_mgmr_ext_dump_needed()) {
dump_pkt_infor(hw_rxhdr);
}
if (bl_vif) {
/* allocate buffer for memory piece*/
struct pbuf *h, *t;
int i;
bl_custom_pbuf_t* my_pbuf;
if (hw_rxhdr->flags_is_80211_mpdu) {
sniffer = true;
}
if (!sniffer) {
struct ethhdr *hdr = (struct ethhdr *)(skb_payload);
(void)hdr;
//FIXME performance for PSRAM?
my_pbuf = (bl_custom_pbuf_t*)pkt->pbuf[0];
memset(my_pbuf, 0, sizeof(bl_custom_pbuf_t));
my_pbuf->p.custom_free_function = my_pbuf_free_custom;
my_pbuf->swdesc = swdesc;
h = pbuf_alloced_custom(
PBUF_RAW,
pkt->len[0] - msdu_offset,
PBUF_REF,
&my_pbuf->p,
(uint8_t*)(pkt->pkt[0]) + msdu_offset,
pkt->len[0] - msdu_offset
);
#if 0
bl_os_printf("Header %p, len %u\r\n", h, pkt->len[0]);
#endif
i = 1;//header is already set
while (i < sizeof(pkt->pkt)/sizeof(pkt->pkt[0])) {
if (0 == pkt->len[i]) {
/*empty item. break now*/
#if 0
bl_os_printf("break @%d len %u\r\n", i, pkt->len[i]);
#endif
break;
}
my_pbuf = (bl_custom_pbuf_t*)pkt->pbuf[i];
memset(my_pbuf, 0, sizeof(bl_custom_pbuf_t));
my_pbuf->p.custom_free_function = my_pbuf_free_custom_fake;
t = pbuf_alloced_custom(
PBUF_RAW,
pkt->len[i],
PBUF_REF,
&my_pbuf->p,
(uint8_t*)(pkt->pkt[i]),
pkt->len[i]
);
pbuf_cat(h, t);
#if 0
bl_os_printf("chaining... %p, len %u\r\n",
t,
pkt->len[i]
);
#endif
i++;
}
if (bl_vif->dev && ERR_OK == bl_vif->dev->input(h, bl_vif->dev)) {
return 0;
}
} else {
bl_os_printf("------ Frame received but no active vif (%d)\r\n", hw_rxhdr->flags_vif_idx);
if (hw_rxhdr->flags_sta_idx != 0xff) {
if (hw_rxhdr->flags_is_4addr) {
bl_os_printf("[RX] Trigger 4addr unexpected frame\r\n");
}
}
os_printf("********************ETH Start******************************\r\n");
os_printf(" Eth Dst " MAC_FMT "\r\n", MAC_LIST(hdr->h_dest));
os_printf(" Eth Src " MAC_FMT "\r\n", MAC_LIST(hdr->h_dest));
os_printf(" Eth Proto %04X, %p:%p, len %u\r\n", hdr->h_proto, bl_vif, bl_vif ? bl_vif->dev : NULL, hw_rxhdr->hwvect.len);
os_printf("********************ETH End******************************\r\n");
if (wifi_mgmr_ext_dump_needed()) {
dump_pkt_infor(hw_rxhdr);
}
}
if (!sniffer && !bl_vif) {
bl_os_printf("------ Frame received but no active vif (%d)\r\n", hw_rxhdr->flags_vif_idx);
goto end;
}
#if defined(CFG_CHIP_BL808)
h = _handle_frame_from_stack_with_mempool(swdesc, msdu_offset, pkt);
zerocopy = false;
#else
h = _handle_frame_from_stack_with_zerocopy(swdesc, msdu_offset, pkt);
zerocopy = true;
#endif
if (!h) {
// wrapping in pbuf failed, free the packet
goto end;
}
if (extra_status & BL_RX_STATUS_AMSDU) {
h->flags |= PBUF_FLAG_AMSDU;
}
if (sniffer) {
info.rssi = hw_rxhdr->hwvect.rssi1;
//TODO fix splitted buff in zerocopy
bl_rx_pkt_cb((uint8_t*)skb_payload, hw_rxhdr->hwvect.len, (void *)h, &info);
bl_rx_mgmt(skb_payload, hw_rxhdr, hw_rxhdr->hwvect.len, &info);
pbuf_free(h);
} else {
#ifdef PKT_INPUT_HOOK
if (bl_wifi_pkt_eth_input_hook) {
bool is_sta = bl_vif->dev == wifi_mgmr_sta_netif_get();
h = bl_wifi_pkt_eth_input_hook(is_sta, h, bl_wifi_pkt_eth_input_hook_arg);
if (h == NULL) {
// hook dropped the packet
goto free;
}
}
#endif
if (bl_vif->dev && ERR_OK == bl_vif->dev->input(h, bl_vif->dev)) {
//TCP/IP stack will take care of pbuf h
} else {
//No none need pbuf h anymore, so free it now
pbuf_free(h);
}
}
goto free; // In case of error that label free is defined but not used when PKT_INPUT_HOOK is disabled
free:
if (zerocopy) {
free_by_lowlayer = false;
}
end:
if (free_by_lowlayer) {
return -1;
} else {
return 0;
}
return -1;
}
u8 bl_radarind(void *pthis, void *hostid)

View File

@ -33,51 +33,83 @@
#include <wifi_hosal.h>
enum ap_info_type {
/* The current AP information is advisory. When the AP fails to connect
* through its specified parameters, the information is no longer used
* when reconnecting. If the time_to_live field is not 0, the information
* will not be used after time_to_live times.
*/
AP_INFO_TYPE_SUGGEST,
/* The current AP information is advisory. When the AP fails to connect
* through its specified parameters, the information is no longer used
* when reconnecting. If the time_to_live field is not 0, the information
* will not be used after time_to_live times.
*/
AP_INFO_TYPE_SUGGEST,
/* The current AP information is mandatory. When the AP fails to connect
* through its specified parameters, the information is always used
* to reconnect.
*/
AP_INFO_TYPE_PRESIST,
/* The current AP information is mandatory. When the AP fails to connect
* through its specified parameters, the information is always used
* to reconnect.
*/
AP_INFO_TYPE_PRESIST,
};
struct ap_info {
enum ap_info_type type;
enum ap_info_type type;
/* when type field is AP_INFO_TYPE_SUGGEST, this field indicates the number
*of effective times
*/
int time_to_live;
/* when type field is AP_INFO_TYPE_SUGGEST, this field indicates the number
*of effective times
*/
int time_to_live;
/* bssid, NULL is disable */
uint8_t *bssid;
/* bssid, NULL is disable */
uint8_t *bssid;
/* default 0, reserved */
uint8_t band;
/* default 0, reserved */
uint8_t band;
/* freq number, 0 is disable */
uint16_t freq;
/* freq number, 0 is disable */
uint16_t freq;
uint8_t use_dhcp;
uint8_t use_dhcp;
};
/* Wifi Connecting advanced prameters */
struct ap_connect_adv {
/* Auth parameters */
char *psk;
/* Auth parameters */
char *psk;
/* AP extended information */
struct ap_info ap_info;
/* AP extended information */
struct ap_info ap_info;
/* MISC flags */
/* XXX following flag values and connection flags defined in mac.h should be identical */
#define WIFI_CONNECT_STOP_SCAN_CURRENT_CHANNEL_IF_TARGET_AP_FOUND (1 << 8)
uint32_t flags;
};
typedef struct ap_connect_adv ap_connect_adv_t;
struct bl_rx_info {
int8_t rssi;
};
typedef struct bl_rx_info bl_rx_info_t;
typedef enum {
WM_WIFI_CIPHER_NONE = 0,
WM_WIFI_CIPHER_WEP,
WM_WIFI_CIPHER_AES,
WM_WIFI_CIPHER_TKIP,
WM_WIFI_CIPHER_TKIP_AES,
WM_WIFI_CIPHER_MAX,
} wifi_mgmr_ap_cipher_t;
typedef enum {
WM_WIFI_AUTH_UNKNOWN = 0,
WM_WIFI_AUTH_OPEN,
WM_WIFI_AUTH_WEP,
WM_WIFI_AUTH_WPA_PSK,
WM_WIFI_AUTH_WPA2_PSK,
WM_WIFI_AUTH_WPA_WPA2_PSK,
WM_WIFI_AUTH_WPA_ENTERPRISE,
WM_WIFI_AUTH_WPA3_SAE,
WM_WIFI_AUTH_WPA2_PSK_WPA3_SAE,
WM_WIFI_AUTH_MAX,
} wifi_mgmr_ap_auth_mode_t;
typedef struct wifi_mgmr_ap_item {
char ssid[32];
char ssid_tail[1];//always put ssid_tail after ssid
@ -85,6 +117,7 @@ typedef struct wifi_mgmr_ap_item {
uint8_t bssid[6];
uint8_t channel;
uint8_t auth;
uint8_t cipher;
int8_t rssi;
} wifi_mgmr_ap_item_t;
@ -118,7 +151,8 @@ typedef struct wifi_sta_ps_conf {
}wifi_sta_ps_conf_t;
typedef void *wifi_interface_t;
typedef void (*sniffer_cb_t)(void *env, uint8_t *pkt, int len);
typedef void (*sniffer_cb_t)(void *env, uint8_t *pkt, int len, bl_rx_info_t *info);
typedef void (*sniffer_cb_adv_t)(void *env, void *pkt_wrap, bl_rx_info_t *info);
typedef void (*scan_item_cb_t)(wifi_mgmr_ap_item_t *env, uint32_t *param1, wifi_mgmr_ap_item_t *item);
typedef void (*scan_complete_cb_t)(void *data, void *param);
@ -192,7 +226,8 @@ int wifi_mgmr_sta_ip_set(uint32_t ip, uint32_t mask, uint32_t gw, uint32_t dns1,
int wifi_mgmr_sta_dns_get(uint32_t *dns1, uint32_t *dns2);
int wifi_mgmr_sta_ip_unset(void);
int wifi_mgmr_sta_connect_ext(wifi_interface_t *wifi_interface, char *ssid, char *passphr, const ap_connect_adv_t *conn_adv_param);
int wifi_mgmr_sta_connect(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint16_t freq);
int wifi_mgmr_sta_connect_mid(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint8_t chan_id, uint8_t use_dhcp, uint32_t flags);
int wifi_mgmr_sta_connect(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint8_t chan_id);
int wifi_mgmr_sta_disconnect(void);
int wifi_mgmr_sta_ps_enter(uint32_t ps_level);
int wifi_mgmr_sta_ps_exit();
@ -209,6 +244,7 @@ int wifi_mgmr_ap_mac_get(uint8_t mac[6]);
int wifi_mgmr_ap_ip_get(uint32_t *ip, uint32_t *gw, uint32_t *mask);
int wifi_mgmr_ap_stop(wifi_interface_t *interface);
int wifi_mgmr_ap_start(wifi_interface_t *interface, char *ssid, int hidden_ssid, char *passwd, int channel);
int wifi_mgmr_ap_start_adv(wifi_interface_t *interface, char *ssid, int hidden_ssid, char *passwd, int channel, uint8_t use_dhcp);
int wifi_mgmr_ap_sta_cnt_get(uint8_t *sta_cnt);
int wifi_mgmr_ap_sta_info_get(struct wifi_sta_basic_info *sta_info, uint8_t idx);
int wifi_mgmr_ap_sta_delete(uint8_t sta_idx);
@ -217,9 +253,14 @@ int wifi_mgmr_sniffer_enable(void);
int wifi_mgmr_sniffer_disable(void);
int wifi_mgmr_rate_config(uint16_t config);
int wifi_mgmr_conf_max_sta(uint8_t max_sta_supported);
/* Easy API gives pointer to data directly. */
int wifi_mgmr_sniffer_register(void *env, sniffer_cb_t cb);
int wifi_mgmr_sniffer_unregister(void *env);
/* Advanced exposes low level representation of data(struct pbuf for most systems). */
int wifi_mgmr_sniffer_register_adv(void *env, sniffer_cb_adv_t cb);
int wifi_mgmr_sniffer_unregister_adv(void *env);
int wifi_mgmr_state_get(int *state);
int wifi_mgmr_detailed_state_get(int *state, int *state_detailed);
int wifi_mgmr_status_code_get(int *s_code);
int wifi_mgmr_rssi_get(int *rssi);
int wifi_mgmr_channel_get(int *channel);
@ -227,8 +268,7 @@ int wifi_mgmr_channel_set(int channel, int use_40Mhz);
int wifi_mgmr_all_ap_scan(wifi_mgmr_ap_item_t **ap_ary, uint32_t *num);
int wifi_mgmr_scan_filter_hidden_ssid(int filter);
int wifi_mgmr_scan(void *data, scan_complete_cb_t cb);
int wifi_mgmr_scan_fixed_channels(void *data, scan_complete_cb_t cb, uint16_t *channels, uint16_t channel_num);
int wifi_mgmr_scan_adv(void *data, scan_complete_cb_t cb, uint16_t *channels, uint16_t channel_num, const char *ssid);
int wifi_mgmr_scan_adv(void *data, scan_complete_cb_t cb, uint16_t *channels, uint16_t channel_num, const uint8_t bssid[6], const char *ssid);
int wifi_mgmr_cfg_req(uint32_t ops, uint32_t task, uint32_t element, uint32_t type, uint32_t length, uint32_t *buf);
int wifi_mgmr_scan_complete_callback();
int wifi_mgmr_cli_scanlist(void);
@ -245,4 +285,6 @@ int wifi_mgmr_set_wifi_active_time(uint32_t ms);
int wifi_mgmr_set_listen_interval(uint16_t itv);
int wifi_mgmr_pm_ops_register(void);
int wifi_mgmr_fw_affair_ops(void);
int wifi_mgmr_bcnind_auth_to_ext(int auth);
int wifi_mgmr_bcnind_cipher_to_ext(int cipher);
#endif

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2020 Bouffalolab.
*
* This file is part of
* *** Bouffalolab Software Dev Kit ***
* (see www.bouffalolab.com).
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <stdbool.h>
typedef void *(*bl_pkt_eth_input_hook_cb_t)(bool is_sta, void *pkt, void *arg);
extern bl_pkt_eth_input_hook_cb_t bl_wifi_pkt_eth_input_hook;
extern void *bl_wifi_pkt_eth_input_hook_arg;
/**
* @brief Register a callback that is called before an eth packet is passed to TCP/IP stack.
*
* @param cb Callback. cb may inspect, manipulate or even duplicate the packet.
* The first argument passed to cb is a struct pbuf *, second being cb_arg.
* cb should return NULL if cb drops the packet(cb might need to free it if so).
* If non-NULL is returned by cb, the returned pbuf will be passed to TCP/IP stack.
* @param cb_arg Callback argument.
*/
void bl_pkt_eth_input_hook_register(bl_pkt_eth_input_hook_cb_t cb, void *cb_arg);
/**
* @brief Unregister the callback previously registered.
*/
void bl_pkt_eth_input_hook_unregister(void);
typedef void *(*bl_pkt_eth_output_hook_cb_t)(bool is_sta, void *pkt, void *arg);
extern bl_pkt_eth_output_hook_cb_t bl_wifi_pkt_eth_output_hook;
extern void *bl_wifi_pkt_eth_output_hook_arg;
/**
* @brief Register a callback that is called before an eth packet from TCP/IP stack is sent by Wi-Fi.
*
* @param cb Callback. cb may inspect, manipulate or even duplicate the packet.
* cb should return NULL if it drops the packet(cb should NOT free it if so).
* If non-NULL is returned by cb, the returned pbuf will be sent by Wi-Fi.
* @param cb_arg Callback argument.
*/
void bl_pkt_eth_output_hook_register(bl_pkt_eth_output_hook_cb_t cb, void *cb_arg);
/**
* @brief Unregister the callback previously registered.
*/
void bl_pkt_eth_output_hook_unregister(void);

View File

@ -168,6 +168,10 @@ struct txdesc_host
{
uint32_t ready;
#if defined(CFG_CHIP_BL808)
uint32_t eth_packet[1600/4];
#endif
/// API of the embedded part
struct hostdesc host;

View File

@ -791,6 +791,8 @@ struct scanu_start_req
u8_l ssid_cnt;
/// no CCK - For P2P frames not being sent at CCK rate in 2GHz band.
bool no_cck;
/// MISC flags
uint32_t flags;
};
struct scanu_raw_send_req
@ -1026,6 +1028,8 @@ struct me_rc_set_rate_req
u8_l sta_idx;
/// Rate configuration to be set
u16_l fixed_rate_cfg;
/// Force power table update
u16_l power_table_req;
};
@ -1249,6 +1253,9 @@ struct apm_start_req
/// AP Passphrase
uint8_t phrase[MAX_PSK_PASS_PHRASE_LEN];
uint8_t phrase_tail[1];
// Buf for storing IE
uint8_t bcn_buf_len;
uint8_t bcn_buf[64];
};
/// Structure containing the parameters of the @ref APM_START_CFM message.

View File

@ -37,6 +37,7 @@
#endif
#include <bl_wifi.h>
#include <wifi_pkt_hooks.h>
#include "bl_defs.h"
#include "bl_tx.h"
@ -108,6 +109,16 @@ static err_t wifi_tx(struct netif *netif, struct pbuf* p)
int dump_i;
#endif
#ifdef PKT_OUTPUT_HOOK
if (bl_wifi_pkt_eth_output_hook) {
bool is_sta = netif == wifi_mgmr_sta_netif_get();
p = bl_wifi_pkt_eth_output_hook(is_sta, p, bl_wifi_pkt_eth_output_hook_arg);
if (p == NULL) {
// hook ate the packet
return ERR_IF;
}
}
#endif
if (p->tot_len > WIFI_MTU_SIZE) {
if (bl_os_get_time_ms() - ticks > WARNING_LIMIT_TICKS_TX_SIZE) {
bl_os_printf("[TX] %s, TX size too big: %u bytes\r\n", __func__, p->tot_len);
@ -161,11 +172,11 @@ int bl_wifi_eth_tx(struct pbuf *p, bool is_sta, struct bl_custom_tx_cfm *custom_
iface = wifi_mgmr_ap_netif_get();
}
ret = bl_output(bl606a0_sta.bl_hw, iface, p, is_sta, custom_cfm);
if (ret != ERR_OK) {
pbuf_free(p);
if (ret == ERR_OK) {
return 0;
} else {
return -1;
}
return 0;
}
static void netif_status_callback(struct netif *netif)

View File

@ -57,6 +57,7 @@
#define TSEN_RELOAD_MS (10000)
wifi_mgmr_t wifiMgmr;
extern struct bl_hw wifi_hw;
const static struct state
stateGlobal,
stateIdle,
@ -168,31 +169,19 @@ char *wifi_mgmr_cipher_to_str(uint8_t cipher)
}
}
static bool stateGlobalGuard_scan_beacon( void *ch, struct event *event )
int wifi_mgmr_scan_beacon_save( wifi_mgmr_scan_item_t *scan )
{
#define SCAN_UPDATE_LIMIT_TIME_MS (3000)
int i, empty = -1, oldest = -1;
int i, empty = -1, oldest = -1, ret = 0;
uint32_t lastseen = 0xFFFFFFFF;
uint32_t counter = 0;
uint32_t lastseen_found = 0;
wifi_mgmr_msg_t *msg;
wifi_mgmr_scan_item_t *scan;
msg = event->data;
scan = (wifi_mgmr_scan_item_t*)msg->data;
if (ch != (void*)msg->ev) {
return false;
}
#ifdef DEBUG_SCAN_BEACON
bl_os_printf(DEBUG_HEADER "channel %02u, bssid %02X:%02X:%02X:%02X:%02X:%02X, rssi %3d, auth %s, cipher:%s \t, SSID %s\r\n",
bl_os_printf(DEBUG_HEADER "channel %02u, bssid %02X:%02X:%02X:%02X:%02X:%02X, rssi %3d, ppm %d:%d, auth %s, cipher:%s \t, SSID %s\r\n",
scan->channel,
scan->bssid[0],
scan->bssid[1],
scan->bssid[2],
scan->bssid[3],
scan->bssid[4],
scan->bssid[5],
MAC_ADDR_LIST(scan->bssid),
scan->rssi,
scan->ppm_abs,
scan->ppm_rel,
@ -201,10 +190,14 @@ static bool stateGlobalGuard_scan_beacon( void *ch, struct event *event )
scan->ssid
);
#endif
bl_os_mutex_lock(wifiMgmr.scan_items_lock);
if (scan->channel > wifiMgmr.channel_nums || !scan->channel){
ret = -1;
goto __exit;
}
if (0 == scan->ssid[0] && (!_features_is_set(WIFI_MGMR_FEATURES_SCAN_SAVE_HIDDEN_SSID))) {
ret = -1;
goto __exit;
}
@ -270,9 +263,9 @@ static bool stateGlobalGuard_scan_beacon( void *ch, struct event *event )
}
__exit:
bl_os_mutex_unlock(wifiMgmr.scan_items_lock);
/*we always return false, since we only store the info from beacon frame*/
return false;
return ret;
}
static bool stateGlobalGuard_disable_autoreconnect( void *ch, struct event *event )
@ -348,6 +341,7 @@ static bool stateGlobalGuard_fw_scan(void *ch, struct event *event)
uint16_t channel_num = 0;
wifi_mgmr_scan_params_t *ch_req;
struct mac_ssid *ssid = NULL;
struct mac_addr bssid;
msg = event->data;
@ -369,6 +363,7 @@ static bool stateGlobalGuard_fw_scan(void *ch, struct event *event)
ch_req = (wifi_mgmr_scan_params_t *)msg->data;
channel_num = ch_req->channel_num;
ssid = &(ch_req->ssid);
memcpy((uint8_t *)&bssid, ch_req->bssid, ETH_ALEN);
#if 0
if (channel_num) {
bl_os_printf("%s len:%d \r\n",__func__, channel_num);
@ -391,11 +386,11 @@ static bool stateGlobalGuard_fw_scan(void *ch, struct event *event)
if (channel_num) {
bl_os_printf("------>>>>>> Scan CMD fixed channels_num:%u\r\n", channel_num);
bl_main_scan(&wifiMgmr.wlan_sta.netif, ch_req->channels, channel_num, ssid);
bl_main_scan(&wifiMgmr.wlan_sta.netif, ch_req->channels, channel_num, &bssid, ssid);
} else {
/*normal scan command*/
bl_os_printf("------>>>>>> Scan CMD\r\n");
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, ssid);
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, &bssid, ssid);
}
return false;
@ -503,17 +498,22 @@ static bool stateGlobalGuard_AP(void *ev, struct event *event )
bl_os_printf(DEBUG_HEADER "%s: add AP iface failed\r\n", __func__);
return false;
}
ap = (wifi_mgmr_ap_msg_t*)msg->data;
netifapi_netif_set_link_up(&(wifiMgmr.wlan_ap.netif));
void dhcpd_start(struct netif *netif);
netifapi_netif_common(&(wifiMgmr.wlan_ap.netif), dhcpd_start, NULL);
if (ap->use_dhcp_server) {
netifapi_netif_common(&(wifiMgmr.wlan_ap.netif), dhcpd_start, NULL);
}
ap = (wifi_mgmr_ap_msg_t*)msg->data;
bl_os_printf(DEBUG_HEADER "start AP with ssid %s;\r\n", ap->ssid);
bl_os_printf(DEBUG_HEADER " pwd %s;\r\n", ap->psk);
bl_os_printf(DEBUG_HEADER " channel %ld;\r\n", ap->channel);
bl_main_apm_start(ap->ssid, ap->psk, ap->channel, wifiMgmr.wlan_ap.vif_index, ap->hidden_ssid, wifiMgmr.ap_bcn_int);
wifiMgmr.inf_ap_enabled = 1;
wifiMgmr.dns_server = dns_server_init();
if (ap->use_dhcp_server) {
wifiMgmr.dns_server = dns_server_init();
}
aos_post_event(EV_WIFI, CODE_WIFI_ON_AP_STARTED, 0);
return false;
@ -623,7 +623,6 @@ const static struct state stateGlobal = {
.entryState = NULL,
.transitions = (struct transition[])
{
{EVENT_TYPE_GLB, (void*)WIFI_MGMR_EVENT_GLB_SCAN_IND_BEACON, &stateGlobalGuard_scan_beacon, &stateGlobalAction, &stateIdle},
{EVENT_TYPE_GLB, (void*)WIFI_MGMR_EVENT_GLB_DISABLE_AUTORECONNECT, &stateGlobalGuard_disable_autoreconnect, &stateGlobalAction, &stateIdle},
{EVENT_TYPE_GLB, (void*)WIFI_MGMR_EVENT_GLB_ENABLE_AUTORECONNECT, &stateGlobalGuard_enable_autoreconnect, &stateGlobalAction, &stateIdle},
{EVENT_TYPE_APP, (void*)WIFI_MGMR_EVENT_APP_AP_START, &stateGlobalGuard_AP, &stateGlobalAction, &stateIdle},
@ -636,7 +635,7 @@ const static struct state stateGlobal = {
{EVENT_TYPE_FW, (void*)WIFI_MGMR_EVENT_FW_DATA_RAW_SEND, &stateSnifferGuard_raw_send, &stateGlobalAction, &stateIdle},
{EVENT_TYPE_FW, (void*)WIFI_MGMR_EVENT_FW_CFG_REQ, &stateGlobal_cfg_req, &stateGlobalAction, &stateIdle},
},
.numTransitions = 12,
.numTransitions = 11,
.data = "group",
.entryAction = &stateEnter,
.exitAction = &stateExit,
@ -700,6 +699,22 @@ static bool stateIdleGuard_sniffer(void *ev, struct event *event )
return true;
}
static void dump_connect_param(const wifi_mgmr_profile_msg_t *profile_msg, int band, int freq, const uint8_t *bssid)
{
bl_os_printf(DEBUG_HEADER "Action Connect\r\n");
bl_os_printf("\tssid %s\r\n", profile_msg->ssid);
bl_os_printf("\tssid len %u\r\n", (unsigned int)profile_msg->ssid_len);
bl_os_printf("\tpassphr %s\r\n", profile_msg->passphr);
bl_os_printf("\tpassphr len %u\r\n", (unsigned int)profile_msg->passphr_len);
bl_os_printf("\tpsk %s\r\n", profile_msg->psk);
bl_os_printf("\tpsk len %u\r\n", (unsigned int)profile_msg->psk_len);
bl_os_printf("\tband %d\r\n", band);
bl_os_printf("\tfreq %d\r\n", freq);
bl_os_printf("\tbssid %02X:%02X:%02X:%02X:%02X:%02X\r\n", MAC_ADDR_LIST(bssid));
bl_os_printf("\tdhcp status: %s\r\n", profile_msg->dhcp_use ? "true" : "false");
bl_os_printf("\tflags: %u\r\n", (unsigned)profile_msg->flags);
}
static void stateIdleAction_connect( void *oldStateData, struct event *event,
void *newStateData )
{
@ -710,24 +725,7 @@ static void stateIdleAction_connect( void *oldStateData, struct event *event,
profile_msg = (wifi_mgmr_profile_msg_t*)msg->data;
profile_msg->ssid_tail[0] = '\0';
profile_msg->psk_tail[0] = '\0';
bl_os_printf(DEBUG_HEADER "Action Connect\r\n");
bl_os_printf(" ssid %s\r\n", profile_msg->ssid);
bl_os_printf(" ssid len %u\r\n", (unsigned int)profile_msg->ssid_len);
bl_os_printf(" passphr %s\r\n", profile_msg->passphr);
bl_os_printf(" passphr len %u\r\n", (unsigned int)profile_msg->passphr_len);
bl_os_printf(" psk %s\r\n", profile_msg->psk);
bl_os_printf(" psk len %u\r\n", (unsigned int)profile_msg->psk_len);
bl_os_printf(" band %d\r\n", (uint8_t)profile_msg->band);
bl_os_printf(" freq %d\r\n", (uint16_t)profile_msg->freq);
bl_os_printf(" bssid %02X:%02X:%02X:%02X:%02X:%02X\r\n",
profile_msg->bssid[0],
profile_msg->bssid[1],
profile_msg->bssid[2],
profile_msg->bssid[3],
profile_msg->bssid[4],
profile_msg->bssid[5]
);
bl_os_printf(" dhcp status: %s\r\n", profile_msg->dhcp_use ? "true" : "false");
dump_connect_param(profile_msg, profile_msg->band, profile_msg->freq, profile_msg->bssid);
wifi_mgmr_profile_add(&wifiMgmr, profile_msg, -1);
bl_os_printf(DEBUG_HEADER "State Action ###%s### --->>> ###%s###\r\n",
@ -743,7 +741,8 @@ static void stateIdleAction_connect( void *oldStateData, struct event *event,
(const uint8_t *)profile_msg->psk, profile_msg->psk_len,
(const uint8_t *)profile_msg->bssid,
(const uint8_t)profile_msg->band,
(const uint16_t)profile_msg->freq
(const uint16_t)profile_msg->freq,
(const uint32_t)profile_msg->flags
);
}
@ -1052,7 +1051,7 @@ static bool stateConnectedIPYesGuard_rcconfig( void *ch, struct event *event )
}
bl_os_printf(DEBUG_HEADER "rate config, use sta_idx 0, rate_config %04X\r\n", (unsigned int)(msg->data1));
bl_main_rate_config(0, (uint32_t)msg->data1);
bl_main_rate_config(wifi_hw.sta_idx, (uint32_t)msg->data1);
/*will never trigger state change, since we just want to trigger the guard*/
return false;
}
@ -1077,7 +1076,7 @@ static void stateConnectedIPYes_enter( void *stateData, struct event *event )
aos_post_event(EV_WIFI, CODE_WIFI_ON_GOT_IP, 0);
if (_pending_task_is_set(WIFI_MGMR_PENDING_TASK_SCAN_BIT)) {
bl_os_printf(DEBUG_HEADER "Pending Scan Sent\r\n");
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, NULL);
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, (struct mac_addr *)&mac_addr_bcst, NULL);
_pending_task_clr_safely(WIFI_MGMR_PENDING_TASK_SCAN_BIT);
}
}
@ -1130,6 +1129,7 @@ static void stateDisconnect_action_reconnect( void *oldStateData, struct event *
uint8_t band = 0;
uint16_t freq = 0;
uint8_t *bssid = NULL;
uint8_t null_bssid[6] = {};
stateDisconnect_data = (disconnectData_t*)oldStateData;
@ -1163,23 +1163,7 @@ static void stateDisconnect_action_reconnect( void *oldStateData, struct event *
bssid = profile_msg->bssid;
}
bl_os_printf(DEBUG_HEADER " Action Connect\r\n");
bl_os_printf(" ssid %s\r\n", profile_msg->ssid);
bl_os_printf(" ssid len %u\r\n", (unsigned int)profile_msg->ssid_len);
bl_os_printf(" passphr %s\r\n", profile_msg->passphr);
bl_os_printf(" passphr len %u\r\n", (unsigned int)profile_msg->passphr_len);
bl_os_printf(" psk %s\r\n", profile_msg->psk);
bl_os_printf(" psk len %u\r\n", (unsigned int)profile_msg->psk_len);
bl_os_printf(" band %d\r\n", (uint8_t)band);
bl_os_printf(" freq %d\r\n", (uint16_t)freq);
bl_os_printf(" bssid %02X:%02X:%02X:%02X:%02X:%02X\r\n",
bssid ? bssid[0] : 0,
bssid ? bssid[1] : 0,
bssid ? bssid[2] : 0,
bssid ? bssid[3] : 0,
bssid ? bssid[4] : 0,
bssid ? bssid[5] : 0
);
dump_connect_param(profile_msg, band, freq, bssid ? bssid : null_bssid);
@ -1189,7 +1173,8 @@ static void stateDisconnect_action_reconnect( void *oldStateData, struct event *
(const uint8_t *)profile_msg->psk, profile_msg->psk_len,
(const uint8_t *)bssid,
(const uint8_t)band,
(const uint16_t)freq
(const uint16_t)freq,
(const uint32_t)profile_msg->flags
);
aos_post_event(EV_WIFI, CODE_WIFI_CMD_RECONNECT, 0);
}
@ -1221,7 +1206,9 @@ static void disconnect_retry(void *data)
static void stateDisconnect_enter(void *stateData, struct event *event)
{
#ifdef CFG_CHIP_BL602
int is_ok = 0;
#endif
disconnectData_t *stateDisconnect_data;
stateDisconnect_data = stateData;
@ -1248,7 +1235,7 @@ void helper_record_dump();
if (_pending_task_is_set(WIFI_MGMR_PENDING_TASK_SCAN_BIT)) {
bl_os_printf(DEBUG_HEADER "Pending Scan Sent\r\n");
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, NULL);
bl_main_scan(&wifiMgmr.wlan_sta.netif, NULL, 0, (struct mac_addr *)&mac_addr_bcst, NULL);
_pending_task_clr_safely(WIFI_MGMR_PENDING_TASK_SCAN_BIT);
}
}
@ -1359,6 +1346,7 @@ void wifi_mgmr_start(void)
ev.data = msg;
stateM_init(&(wifiMgmr.m), &stateIfaceDown, &stateError);
wifiMgmr.scan_items_lock = bl_os_mutex_create();
/*register event cb for Wi-Fi Manager*/
wifi_mgmr_event_init();
@ -1434,7 +1422,7 @@ int wifi_mgmr_status_code_clean_internal()
return 0;
}
int wifi_mgmr_state_get_internal(int *state)
int wifi_mgmr_detailed_state_get_internal(int *state, int *state_detailed)
{
const struct state *m_state;
int s_code = 0;
@ -1448,9 +1436,9 @@ int wifi_mgmr_state_get_internal(int *state)
} else {
*state = WIFI_STATE_IDLE;
if (s_code == WLAN_FW_4WAY_HANDSHAKE_ERROR_PSK_TIMEOUT_FAILURE){
*state = WIFI_STATE_PSK_ERROR;
*state_detailed = WIFI_STATE_PSK_ERROR;
} else if (s_code == WLAN_FW_SCAN_NO_BSSID_AND_CHANNEL){
*state = WIFI_STATE_NO_AP_FOUND;
*state_detailed = WIFI_STATE_NO_AP_FOUND;
}
}
} else if (m_state == &stateConnecting) {
@ -1459,9 +1447,9 @@ int wifi_mgmr_state_get_internal(int *state)
} else {
*state = WIFI_STATE_CONNECTING;
if (s_code == WLAN_FW_4WAY_HANDSHAKE_ERROR_PSK_TIMEOUT_FAILURE){
*state = WIFI_STATE_PSK_ERROR;
*state_detailed = WIFI_STATE_PSK_ERROR;
} else if (s_code == WLAN_FW_SCAN_NO_BSSID_AND_CHANNEL){
*state = WIFI_STATE_NO_AP_FOUND;
*state_detailed = WIFI_STATE_NO_AP_FOUND;
}
}
} else if (m_state == &stateConnectedIPNo) {
@ -1482,9 +1470,9 @@ int wifi_mgmr_state_get_internal(int *state)
} else {
*state = WIFI_STATE_DISCONNECT;
if (s_code == WLAN_FW_4WAY_HANDSHAKE_ERROR_PSK_TIMEOUT_FAILURE){
*state = WIFI_STATE_PSK_ERROR;
*state_detailed = WIFI_STATE_PSK_ERROR;
} else if (s_code == WLAN_FW_SCAN_NO_BSSID_AND_CHANNEL){
*state = WIFI_STATE_NO_AP_FOUND;
*state_detailed = WIFI_STATE_NO_AP_FOUND;
}
}
} else if (m_state == &stateIfaceDown) {
@ -1498,6 +1486,11 @@ int wifi_mgmr_state_get_internal(int *state)
return 0;
}
int wifi_mgmr_state_get_internal(int *state)
{
return wifi_mgmr_detailed_state_get_internal(state, state);
}
void wifi_mgmr_set_connect_stat_info(struct wifi_event_sm_connect_ind *ind, uint8_t type_ind)
{
int i;

View File

@ -41,6 +41,8 @@
#define WIFI_MGMR_MQ_MSG_SIZE (128 + 64 + 32)
#define WIFI_MGMR_MQ_MSG_COUNT (1)
#define MAC_ADDR_LIST(m) (m)[0], (m)[1], (m)[2], (m)[3], (m)[4], (m)[5]
/**
****************************************************************************************
*
@ -144,6 +146,7 @@ typedef struct wifi_mgmr_profile_msg {
int ap_info_ttl;
uint8_t dhcp_use;
uint32_t flags;
} wifi_mgmr_profile_msg_t;
typedef struct wifi_mgmr_ipgot_msg {
@ -162,6 +165,7 @@ typedef struct wifi_mgmr_ap_msg {
uint32_t ssid_len;
char psk[64];
char psk_tail[1];
uint8_t use_dhcp_server;
uint32_t psk_len;
} wifi_mgmr_ap_msg_t;
@ -182,6 +186,7 @@ typedef struct wifi_mgmr_profile {
int ap_info_ttl;
uint8_t dhcp_use;
uint32_t flags;
/*reserved field for wifi manager*/
uint8_t priority;
@ -236,6 +241,7 @@ struct wlan_netif {
#define MAX_FIXED_CHANNELS_LIMIT (14)
typedef struct wifi_mgmr_scan_params {
uint8_t bssid[6];
uint16_t channel_num;
uint16_t channels[MAX_FIXED_CHANNELS_LIMIT];
struct mac_ssid ssid;
@ -277,6 +283,7 @@ typedef struct wifi_mgmr {
wifi_mgmr_profile_t profiles[WIFI_MGMR_PROFILES_MAX];
int profile_active_index;
BL_Mutex_t scan_items_lock;
wifi_mgmr_scan_item_t scan_items[WIFI_MGMR_SCAN_ITEMS_MAX];
BL_MessageQueue_t mq;
uint8_t mq_pool[WIFI_MGMR_MQ_MSG_SIZE*WIFI_MGMR_MQ_MSG_COUNT];
@ -316,8 +323,11 @@ typedef struct wifi_mgmr {
void *dns_server;
} wifi_mgmr_t;
/// Constant value corresponding to the Broadcast MAC address
extern const struct mac_addr mac_addr_bcst;
int wifi_mgmr_pending_task_set(uint32_t bits);
int wifi_mgmr_event_notify(wifi_mgmr_msg_t *msg, int use_block);
int wifi_mgmr_detailed_state_get_internal(int *state, int *state_d);
int wifi_mgmr_state_get_internal(int *state);
int wifi_mgmr_status_code_clean_internal(void);
int wifi_mgmr_status_code_get_internal(int *s_code);
@ -330,6 +340,7 @@ extern wifi_mgmr_t wifiMgmr;
char *wifi_mgmr_auth_to_str(uint8_t auth);
char *wifi_mgmr_cipher_to_str(uint8_t cipher);
int wifi_mgmr_api_fw_tsen_reload(void);
int wifi_mgmr_scan_beacon_save( wifi_mgmr_scan_item_t *scan );
static inline int wifi_mgmr_scan_item_is_timeout(wifi_mgmr_t *mgmr, wifi_mgmr_scan_item_t *item)
{

View File

@ -99,37 +99,36 @@ int wifi_mgmr_api_connect(char *ssid, char *passphr, const ap_connect_adv_t *ext
}
profile->passphr_tail[0] = '\0';
if (ext_param != NULL) {
profile->psk_len = ext_param->psk ? strlen(ext_param->psk) : 0; //psk can be NULL
if (0 != profile->psk_len && sizeof(profile->psk) != profile->psk_len) {
return -1;
} else if (sizeof(profile->psk) == profile->psk_len) {
memcpy(profile->psk, ext_param->psk, profile->psk_len);
}
profile->psk_tail[0] = '\0';
profile->psk_len = ext_param->psk ? strlen(ext_param->psk) : 0; //psk can be NULL
if (0 != profile->psk_len && sizeof(profile->psk) != profile->psk_len) {
return -1;
} else if (sizeof(profile->psk) == profile->psk_len) {
memcpy(profile->psk, ext_param->psk, profile->psk_len);
}
profile->psk_tail[0] = '\0';
if (ext_param->ap_info.bssid) {
memcpy(profile->bssid, ext_param->ap_info.bssid, sizeof(profile->bssid));
}
if (ext_param->ap_info.bssid) {
memcpy(profile->bssid, ext_param->ap_info.bssid, sizeof(profile->bssid));
}
if (ext_param->ap_info.freq > 0) {
//define the freq
profile->band = ext_param->ap_info.band;
profile->freq = ext_param->ap_info.freq;
bl_os_printf("wifi mgmr band:%d freq: %d\r\n", profile->band, profile->freq);
}
if (ext_param->ap_info.freq > 0) {
//define the freq
profile->band = ext_param->ap_info.band;
profile->freq = ext_param->ap_info.freq;
bl_os_printf("wifi mgmr band:%d freq: %d\r\n", profile->band, profile->freq);
}
if (ext_param->ap_info.type == AP_INFO_TYPE_PRESIST) {
if (ext_param->ap_info.type == AP_INFO_TYPE_PRESIST) {
profile->ap_info_ttl = -1;
} else if (ext_param->ap_info.time_to_live >= 0){
} else if (ext_param->ap_info.time_to_live >= 0){
profile->ap_info_ttl = ext_param->ap_info.time_to_live;
} else {
} else {
profile->ap_info_ttl = -1;
bl_os_printf("invalid ap info type or time_to_live value!\r\n");
}
}
profile->dhcp_use = ext_param->ap_info.use_dhcp;
profile->flags = ext_param->flags;
return wifi_mgmr_api_common(
msg,
@ -227,32 +226,21 @@ int wifi_mgmr_api_sniffer_enable(void)
int wifi_mgmr_api_scan_item_beacon(uint8_t channel, int8_t rssi, uint8_t auth, uint8_t mac[], uint8_t ssid[], int len, int8_t ppm_abs, int8_t ppm_rel, uint8_t cipher)
{
wifi_mgmr_msg_t *msg;
wifi_mgmr_scan_item_t *scan;
uint8_t buffer[sizeof(wifi_mgmr_msg_t) + sizeof(wifi_mgmr_scan_item_t)];//XXX caution for stack overflow
wifi_mgmr_scan_item_t scan;
memset(buffer, 0, sizeof(buffer));
msg = (wifi_mgmr_msg_t*)buffer;
memset(&scan, 0, sizeof(scan));
memcpy(scan.ssid, ssid, len);
scan.ssid_tail[0] = '\0';
scan.ssid_len = len;
memcpy(scan.bssid, mac, sizeof(scan.bssid));
scan.channel = channel;
scan.rssi = rssi;
scan.auth = auth;
scan.cipher = cipher;
scan.ppm_abs = ppm_abs;
scan.ppm_rel = ppm_rel;
scan = (wifi_mgmr_scan_item_t*)msg->data;
memcpy(scan->ssid, ssid, len);
scan->ssid_tail[0] = '\0';
scan->ssid_len = len;
memcpy(scan->bssid, mac, sizeof(scan->bssid));
scan->channel = channel;
scan->rssi = rssi;
scan->auth = auth;
scan->cipher = cipher;
scan->ppm_abs = ppm_abs;
scan->ppm_rel = ppm_rel;
return wifi_mgmr_api_common(
msg,
WIFI_MGMR_EVENT_GLB_SCAN_IND_BEACON,
(void*)0x1,
(void*)0x2,
sizeof(wifi_mgmr_msg_t) + sizeof(wifi_mgmr_scan_item_t)
);
return wifi_mgmr_scan_beacon_save(&scan);
}
int wifi_mgmr_api_fw_disconnect(void)
@ -265,7 +253,7 @@ int wifi_mgmr_api_fw_tsen_reload(void)
return wifi_mgmr_api_common_msg(WIFI_MGMR_EVENT_APP_RELOAD_TSEN, (void*)0x1, (void*)0x2);
}
int wifi_mgmr_api_fw_scan(uint16_t *channels, uint16_t channel_num, const char *scanssid)
int wifi_mgmr_api_fw_scan(uint16_t *channels, uint16_t channel_num, const uint8_t bssid[6], const char *scanssid)
{
wifi_mgmr_msg_t *msg;
wifi_mgmr_scan_params_t *ch_req;
@ -277,6 +265,7 @@ int wifi_mgmr_api_fw_scan(uint16_t *channels, uint16_t channel_num, const char *
ch_req = (wifi_mgmr_scan_params_t*)msg->data;
ch_req->channel_num = channel_num;
memcpy(ch_req->bssid, bssid, ETH_ALEN);
ssid = &(ch_req->ssid);
if (channel_num) {
memcpy(ch_req->channels, channels, sizeof(ch_req->channels[0]) * channel_num);
@ -304,7 +293,7 @@ int wifi_mgmr_api_fw_powersaving(int mode)
return wifi_mgmr_api_common_msg(WIFI_MGMR_EVENT_FW_POWERSAVING, (void*)mode, (void*)0x2);
}
int wifi_mgmr_api_ap_start(char *ssid, char *passwd, int channel, uint8_t hidden_ssid)
int wifi_mgmr_api_ap_start(char *ssid, char *passwd, int channel, uint8_t hidden_ssid, uint8_t use_dhcp_server)
{
wifi_mgmr_msg_t *msg;
wifi_mgmr_ap_msg_t *ap;
@ -332,6 +321,7 @@ int wifi_mgmr_api_ap_start(char *ssid, char *passwd, int channel, uint8_t hidden
}
ap->channel = channel;
ap->hidden_ssid = hidden_ssid ? 1 : 0;
ap->use_dhcp_server = use_dhcp_server ? 1 : 0;
return wifi_mgmr_api_common(
msg,

View File

@ -61,7 +61,7 @@ int wifi_mgmr_api_rate_config(uint16_t config);
int wifi_mgmr_api_conf_max_sta(uint8_t max_sta_supported);
int wifi_mgmr_api_ifaceup(void);
int wifi_mgmr_api_sniffer_enable(void);
int wifi_mgmr_api_ap_start(char *ssid, char *passwd, int channel, uint8_t hidden_ssid);
int wifi_mgmr_api_ap_start(char *ssid, char *passwd, int channel, uint8_t hidden_ssid, uint8_t use_dhcp_server);
int wifi_mgmr_api_ap_stop(void);
int wifi_mgmr_api_idle(void);
int wifi_mgmr_api_channel_set(int channel, int use_40Mhz);
@ -70,7 +70,7 @@ int wifi_mgmr_api_set_country_code(char *country_code);
/*section for fw api*/
int wifi_mgmr_api_fw_disconnect(void);
int wifi_mgmr_api_fw_scan(uint16_t *channels, uint16_t channel_num, const char *ssid);
int wifi_mgmr_api_fw_scan(uint16_t *channels, uint16_t channel_num, const uint8_t bssid[6], const char *scanssid);
#define WIFI_MGMR_API_FW_POWERSAVING_MODE_OFF (1)
#define WIFI_MGMR_API_FW_POWERSAVING_MODE_ON (2)
#define WIFI_MGMR_API_FW_POWERSAVING_MODE_DYNAMIC_ON (3)

View File

@ -27,8 +27,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// #include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <cli.h>
@ -343,7 +342,7 @@ static void wifi_bcnint_set(char *buf, int len, int argc, char **argv)
}
}
static void _scan_channels(int channel_input_num, uint8_t channel_input[MAX_FIXED_CHANNELS_LIMIT], const char *ssid)
static void _scan_channels(int channel_input_num, uint8_t channel_input[MAX_FIXED_CHANNELS_LIMIT], uint8_t bssid[6], const char *ssid)
{
int i;
uint16_t channel_num = 0;
@ -353,7 +352,7 @@ static void _scan_channels(int channel_input_num, uint8_t channel_input[MAX_FIXE
channels[i] = channel_input[i];
}
channel_num = channel_input_num;
wifi_mgmr_scan_adv(NULL, NULL, channels, channel_num, ssid);
wifi_mgmr_scan_adv(NULL, NULL, channels, channel_num, bssid, ssid);
}
@ -363,12 +362,14 @@ static void wifi_scan_cmd(char *buf, int len, int argc, char **argv)
int channel_input_num = 0;
uint8_t channel_input[MAX_FIXED_CHANNELS_LIMIT];
const char *ssid = NULL;
int bssid_set_flag = 0;
uint8_t mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
getopt_env_t getopt_env;
utils_getopt_init(&getopt_env, 0);
while ((opt = utils_getopt(&getopt_env, argc, argv, "s:c:")) != -1) {
while ((opt = utils_getopt(&getopt_env, argc, argv, "s:c:b:")) != -1) {
switch (opt) {
case 's':
{
@ -381,7 +382,14 @@ static void wifi_scan_cmd(char *buf, int len, int argc, char **argv)
utils_parse_number_adv(getopt_env.optarg, ',', channel_input, MAX_FIXED_CHANNELS_LIMIT, 10, &channel_input_num);
}
break;
case 'b':
{
bssid_set_flag = 1;
utils_parse_number(getopt_env.optarg, ':', mac, 6, 16);
bl_os_printf("bssid: %s, mac:%02X:%02X:%02X:%02X:%02X:%02X\r\n", getopt_env.optarg,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
break;
default:
{
bl_os_printf("unknow option: %c\r\n", getopt_env.optopt);
@ -389,9 +397,9 @@ static void wifi_scan_cmd(char *buf, int len, int argc, char **argv)
}
}
if (channel_input_num || ssid) {
if (channel_input_num || ssid || bssid_set_flag) {
/*channel list specified scan*/
_scan_channels(channel_input_num, channel_input, ssid);
_scan_channels(channel_input_num, channel_input, mac, ssid);
return;
}
@ -553,60 +561,69 @@ static void wifi_sta_ip_unset_cmd(char *buf, int len, int argc, char **argv)
static void wifi_connect_cmd(char *buf, int len, int argc, char **argv)
{
wifi_interface_t wifi_interface;
wifi_interface_t wifi_interface;
getopt_env_t getopt_env;
int opt, open_bss_flag;
getopt_env_t getopt_env;
int opt, open_bss_flag;
uint16_t freq = 0;
int bssid_set_flag = 0;
uint8_t mac[6] = {0};
open_bss_flag = 0;
uint8_t channel_index = 0;
int bssid_set_flag = 0;
uint8_t mac[6] = {0};
int quick_connect = 0;
uint32_t flags = 0;
open_bss_flag = 0;
if (2 > argc) {
goto _ERROUT;
}
utils_getopt_init(&getopt_env, 0);
while ((opt = utils_getopt(&getopt_env, argc, argv, "c:b:")) != -1) {
switch (opt) {
case 'c':
freq = atoi(getopt_env.optarg);
bl_os_printf("freq: %d\r\n", freq);
break;
case 'b':
bssid_set_flag = 1;
utils_parse_number(getopt_env.optarg, ':', mac, 6, 16);
bl_os_printf("bssid: %s, mac:%02X:%02X:%02X:%02X:%02X:%02X\r\n", getopt_env.optarg,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
break;
case '?':
bl_os_printf("unknow option: %c\r\n", getopt_env.optopt);
goto _ERROUT;
if (2 > argc) {
goto _ERROUT;
}
}
if (getopt_env.optind >= argc || argc - getopt_env.optind < 1) {
bl_os_printf("Expected ssid and password\r\n");
goto _ERROUT;
}
utils_getopt_init(&getopt_env, 0);
bl_os_printf("connect wifi ssid:%s, psk:%s, bssid:%d, freq:%d\r\n", argv[getopt_env.optind], argv[getopt_env.optind+1], bssid_set_flag, freq);
if (NULL == argv[getopt_env.optind + 1]) {
open_bss_flag = 1;
}
while ((opt = utils_getopt(&getopt_env, argc, argv, "c:b:q")) != -1) {
switch (opt) {
case 'c':
channel_index = atoi(getopt_env.optarg);
bl_os_printf("channel_index: %d\r\n", channel_index);
break;
wifi_interface = wifi_mgmr_sta_enable();
wifi_mgmr_sta_connect(wifi_interface, argv[getopt_env.optind], open_bss_flag ? NULL : argv[getopt_env.optind+1], NULL, bssid_set_flag ? mac : NULL, 0, freq);
case 'b':
bssid_set_flag = 1;
utils_parse_number(getopt_env.optarg, ':', mac, 6, 16);
bl_os_printf("bssid: %s, mac:%02X:%02X:%02X:%02X:%02X:%02X\r\n", getopt_env.optarg, MAC_ADDR_LIST(mac));
break;
return;
case 'q':
++quick_connect;
break;
case '?':
bl_os_printf("unknow option: %c\r\n", getopt_env.optopt);
goto _ERROUT;
}
}
if (getopt_env.optind >= argc || argc - getopt_env.optind < 1) {
bl_os_printf("Expected ssid and password\r\n");
goto _ERROUT;
}
bl_os_printf("connect wifi ssid:%s, psk:%s, bssid:%d, ch:%d\r\n", argv[getopt_env.optind], argv[getopt_env.optind+1], bssid_set_flag, channel_index);
if (NULL == argv[getopt_env.optind + 1]) {
open_bss_flag = 1;
}
if (quick_connect > 0) {
flags |= WIFI_CONNECT_STOP_SCAN_CURRENT_CHANNEL_IF_TARGET_AP_FOUND;
}
wifi_interface = wifi_mgmr_sta_enable();
wifi_mgmr_sta_connect_mid(wifi_interface, argv[getopt_env.optind], open_bss_flag ? NULL : argv[getopt_env.optind+1], NULL, bssid_set_flag ? mac : NULL, 0, channel_index, 1, flags);
return;
_ERROUT:
bl_os_printf("[USAGE]: %s [-c <freq>] [-b <bssid>] <ssid> [password]\r\n", argv[0]);
return;
bl_os_printf("[USAGE]: %s [-c <freq>] [-b <bssid>] [-q] <ssid> [password]\r\n", argv[0]);
return;
}
static void wifi_sta_get_state_cmd(char *buf, int len, int argc, char **argv)
@ -770,7 +787,7 @@ static void wifi_power_saving_set(char *buf, int len, int argc, char **argv)
}
}
static void sniffer_cb(void *env, uint8_t *pkt, int len)
static void sniffer_cb(void *env, uint8_t *pkt, int len, struct bl_rx_info *info)
{
static unsigned int sniffer_counter, sniffer_last;
static unsigned int last_tick;
@ -993,17 +1010,6 @@ static void cmd_wifi_coex_pti_force_off(char *buf, int len, int argc, char **arg
coex_wifi_pti_forece_enable(0);
}
void coex_wifi_pta_forece_enable(int enable);
static void cmd_wifi_coex_pta_force_on(char *buf, int len, int argc, char **argv)
{
coex_wifi_pta_forece_enable(1);
}
static void cmd_wifi_coex_pta_force_off(char *buf, int len, int argc, char **argv)
{
coex_wifi_pta_forece_enable(0);
}
static void cmd_wifi_coex_pta_set(char *buf, int len, int argc, char **argv)
{
uint32_t i = 0;
@ -1121,8 +1127,6 @@ const static struct cli_command cmds_user[] STATIC_CLI_CMD_ATTRIBUTE = {
{ "wifi_coex_rf_force_off", "wifi coex RF forece off", cmd_wifi_coex_rf_force_off},
{ "wifi_coex_pti_force_on", "wifi coex PTI forece on", cmd_wifi_coex_pti_force_on},
{ "wifi_coex_pti_force_off", "wifi coex PTI forece off", cmd_wifi_coex_pti_force_off},
{ "wifi_coex_pta_force_on", "wifi coex PTA forece on", cmd_wifi_coex_pta_force_on},
{ "wifi_coex_pta_force_off", "wifi coex PTA forece off", cmd_wifi_coex_pta_force_off},
{ "wifi_coex_pta_set", "wifi coex PTA set", cmd_wifi_coex_pta_set},
{ "wifi_sta_list", "get sta list in AP mode", wifi_ap_sta_list_get_cmd},
{ "wifi_sta_del", "delete one sta in AP mode", wifi_ap_sta_delete_cmd},

View File

@ -46,6 +46,7 @@
#include "wifi_mgmr_api.h"
#include "wifi_mgmr_profile.h"
#include "bl_mod_params.h"
#include "bl_msg_tx.h"
#include "wifi_hosal.h"
#include <wifi_hosal.h>
@ -98,6 +99,7 @@ static void cb_scan_item_parse(wifi_mgmr_ap_item_t *env, uint32_t *param1, wifi_
ap_ary_ptr->ssid_tail[0] = '\0';
ap_ary_ptr->ssid_len = strlen((char *)ap_ary_ptr->ssid);
ap_ary_ptr->auth = item->auth;
ap_ary_ptr->cipher = item->cipher;
/*store back counter*/
(*param1) = counter;
@ -325,7 +327,7 @@ int wifi_mgmr_sta_connect_ext(wifi_interface_t *wifi_interface, char *ssid, char
return wifi_mgmr_api_connect(ssid, passphr, conn_adv_param);
}
int wifi_mgmr_sta_connect(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint16_t freq)
int wifi_mgmr_sta_connect_mid(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint8_t chan_id, uint8_t use_dhcp, uint32_t flags)
{
struct ap_connect_adv ext_param;
@ -334,11 +336,21 @@ int wifi_mgmr_sta_connect(wifi_interface_t *wifi_interface, char *ssid, char *ps
ext_param.ap_info.time_to_live = 5;
ext_param.ap_info.bssid = mac;
ext_param.ap_info.band = 0;
ext_param.ap_info.freq = freq;
ext_param.ap_info.use_dhcp = 1;
if (0 == chan_id || (chan_id > bl_msg_get_channel_nums())) {
ext_param.ap_info.freq = 0;
} else {
ext_param.ap_info.freq = phy_channel_to_freq(ext_param.ap_info.band, chan_id);
}
ext_param.ap_info.use_dhcp = use_dhcp;
ext_param.flags = flags;
return wifi_mgmr_sta_connect_ext(wifi_interface, ssid, psk, &ext_param);
}
int wifi_mgmr_sta_connect(wifi_interface_t *wifi_interface, char *ssid, char *psk, char *pmk, uint8_t *mac, uint8_t band, uint8_t chan_id)
{
return wifi_mgmr_sta_connect_mid(wifi_interface, ssid, psk, pmk, mac, band, chan_id, 1, 0);
}
int wifi_mgmr_sta_disconnect(void)
{
wifi_mgmr_api_disconnect();
@ -561,7 +573,13 @@ int wifi_mgmr_ap_ip_get(uint32_t *ip, uint32_t *gw, uint32_t *mask)
//TODO this API is still NOT completed, more features need to be implemented
int wifi_mgmr_ap_start(wifi_interface_t *interface, char *ssid, int hidden_ssid, char *passwd, int channel)
{
wifi_mgmr_api_ap_start(ssid, passwd, channel, hidden_ssid);
wifi_mgmr_api_ap_start(ssid, passwd, channel, hidden_ssid, 1);
return 0;
}
int wifi_mgmr_ap_start_adv(wifi_interface_t *interface, char *ssid, int hidden_ssid, char *passwd, int channel, uint8_t use_dhcp)
{
wifi_mgmr_api_ap_start(ssid, passwd, channel, hidden_ssid, use_dhcp);
return 0;
}
@ -616,6 +634,18 @@ int wifi_mgmr_sniffer_unregister(void *env)
return 0;
}
int wifi_mgmr_sniffer_register_adv(void *env, sniffer_cb_adv_t cb)
{
bl_rx_pkt_adv_cb_register(env, cb);
return 0;
}
int wifi_mgmr_sniffer_unregister_adv(void *env)
{
bl_rx_pkt_adv_cb_unregister(env);
return 0;
}
int wifi_mgmr_sniffer_enable()
{
wifi_mgmr_api_sniffer_enable();
@ -643,6 +673,11 @@ int wifi_mgmr_state_get(int *state)
return wifi_mgmr_state_get_internal(state);
}
int wifi_mgmr_detailed_state_get(int *state, int *state_detailed)
{
return wifi_mgmr_detailed_state_get_internal(state, state_detailed);
}
int wifi_mgmr_status_code_get(int *s_code)
{
return wifi_mgmr_status_code_get_internal(s_code);
@ -722,12 +757,12 @@ int wifi_mgmr_scan(void *data, scan_complete_cb_t cb)
scan_cb = cb;
scan_data = data;
wifi_mgmr_api_fw_scan(NULL, 0, NULL);
wifi_mgmr_api_fw_scan(NULL, 0, (uint8_t *)&mac_addr_bcst, NULL);
return 0;
}
int wifi_mgmr_scan_adv(void *data, scan_complete_cb_t cb, uint16_t *channels, uint16_t channel_num, const char *ssid)
int wifi_mgmr_scan_adv(void *data, scan_complete_cb_t cb, uint16_t *channels, uint16_t channel_num, const uint8_t bssid[6], const char *ssid)
{
scan_cb = cb;
scan_data = data;
@ -736,7 +771,7 @@ int wifi_mgmr_scan_adv(void *data, scan_complete_cb_t cb, uint16_t *channels, ui
return -1;
}
wifi_mgmr_api_fw_scan(channels, channel_num, ssid);
wifi_mgmr_api_fw_scan(channels, channel_num, bssid, ssid);
return 0;
}
@ -827,6 +862,7 @@ int wifi_mgmr_scan_ap_all(wifi_mgmr_ap_item_t *env, uint32_t *param1, scan_item_
item.channel = scan->channel;
item.rssi = scan->rssi;
item.auth = scan->auth;
item.cipher = scan->cipher;
cb(env, param1, &item);
}
}
@ -879,3 +915,67 @@ void wifi_mgmr_conn_result_get(uint16_t *status_code, uint16_t *reason_code)
(*status_code) = wifiMgmr.wifi_mgmr_stat_info.status_code;
(*reason_code) = wifiMgmr.wifi_mgmr_stat_info.reason_code;
}
int wifi_mgmr_bcnind_auth_to_ext(int auth)
{
int ret;
switch (auth) {
case WIFI_EVENT_BEACON_IND_AUTH_OPEN:
ret = WM_WIFI_AUTH_OPEN;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WEP:
ret = WM_WIFI_AUTH_WEP;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA_PSK:
ret = WM_WIFI_AUTH_WPA_PSK;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA2_PSK:
ret = WM_WIFI_AUTH_WPA2_PSK;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA_WPA2_PSK:
ret = WM_WIFI_AUTH_WPA_WPA2_PSK;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA_ENT:
ret = WM_WIFI_AUTH_WPA_ENTERPRISE;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA3_SAE:
ret = WM_WIFI_AUTH_WPA3_SAE;
break;
case WIFI_EVENT_BEACON_IND_AUTH_WPA2_PSK_WPA3_SAE:
ret = WM_WIFI_AUTH_WPA2_PSK_WPA3_SAE;
break;
case WIFI_EVENT_BEACON_IND_AUTH_UNKNOWN:
ret = WM_WIFI_AUTH_UNKNOWN;
break;
default:
ret = WM_WIFI_AUTH_UNKNOWN;
break;
}
return ret;
}
int wifi_mgmr_bcnind_cipher_to_ext(int cipher)
{
int ret;
switch (cipher) {
case WIFI_EVENT_BEACON_IND_CIPHER_NONE:
ret = WM_WIFI_CIPHER_NONE;
break;
case WIFI_EVENT_BEACON_IND_CIPHER_WEP:
ret = WM_WIFI_CIPHER_WEP;
break;
case WIFI_EVENT_BEACON_IND_CIPHER_AES:
ret = WM_WIFI_CIPHER_AES;
break;
case WIFI_EVENT_BEACON_IND_CIPHER_TKIP:
ret = WM_WIFI_CIPHER_TKIP;
break;
case WIFI_EVENT_BEACON_IND_CIPHER_TKIP_AES:
ret = WM_WIFI_CIPHER_TKIP_AES;
break;
default:
ret = WM_WIFI_CIPHER_NONE;
break;
}
return ret;
}

View File

@ -73,6 +73,7 @@ int wifi_mgmr_profile_add(wifi_mgmr_t *mgmr, wifi_mgmr_profile_msg_t *profile_ms
memcpy(profile->passphr, profile_msg->passphr, sizeof(profile->passphr));
memcpy(profile->bssid, profile_msg->bssid, sizeof(profile->bssid));
profile->dhcp_use = profile_msg->dhcp_use;
profile->flags = profile_msg->flags;
return 0;
}
@ -128,6 +129,7 @@ int wifi_mgmr_profile_get(wifi_mgmr_t *mgmr, wifi_mgmr_profile_msg_t *profile_ms
profile_msg->freq = profile->freq;
profile_msg->ap_info_ttl = profile->ap_info_ttl;
profile_msg->dhcp_use = profile->dhcp_use;
profile_msg->flags = profile->flags;
memcpy(profile_msg->ssid, profile->ssid, sizeof(profile->ssid));
memcpy(profile_msg->psk, profile->psk, sizeof(profile->psk));
memcpy(profile_msg->passphr, profile->passphr, sizeof(profile->passphr));

View File

@ -27,9 +27,40 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TASK_DUMP_H__
#define __TASK_DUMP_H__
#include <wifi_pkt_hooks.h>
void bugkiller_task_dump(void *res);
#include <stdio.h>
#ifdef PKT_INPUT_HOOK
bl_pkt_eth_input_hook_cb_t bl_wifi_pkt_eth_input_hook = NULL;
void *bl_wifi_pkt_eth_input_hook_arg = NULL;
void bl_pkt_eth_input_hook_register(bl_pkt_eth_input_hook_cb_t cb, void *cb_arg)
{
bl_wifi_pkt_eth_input_hook = cb;
bl_wifi_pkt_eth_input_hook_arg = cb_arg;
}
void bl_pkt_eth_input_hook_unregister(void)
{
bl_wifi_pkt_eth_input_hook = NULL;
bl_wifi_pkt_eth_input_hook_arg = NULL;
}
#endif
#ifdef PKT_OUTPUT_HOOK
bl_pkt_eth_output_hook_cb_t bl_wifi_pkt_eth_output_hook = NULL;
void *bl_wifi_pkt_eth_output_hook_arg = NULL;
void bl_pkt_eth_output_hook_register(bl_pkt_eth_output_hook_cb_t cb, void *cb_arg)
{
bl_wifi_pkt_eth_output_hook = cb;
bl_wifi_pkt_eth_output_hook_arg = cb_arg;
}
void bl_pkt_eth_output_hook_unregister(void)
{
bl_wifi_pkt_eth_output_hook = NULL;
bl_wifi_pkt_eth_output_hook_arg = NULL;
}
#endif

Some files were not shown because too many files have changed in this diff Show More