NORDIC softDevice 蓝牙协议栈初始化程序分析(蓝牙从机,ble_peripheral)
https://blog.csdn.net/weixin_42396877/article/details/81240822
基于 NORDIC softDevice 蓝牙协议栈 S132
蓝牙角色: 从机,ble_peripheral
应用主函数 main() 中必须的函数:
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
advertising_start();
/**@brief Function for application main entry.*/
int main(void)
{
// Initialize.
log_init();
leds_init();
timers_init();
buttons_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
NRF_LOG_INFO("Blinky example started.");
advertising_start();
application_timers_start();
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
ble_stack_init()
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); 语句中, ble_evt_handler 为 BLE 事件回调函数 (handler for BLE events).
/**@brief Function for initializing the BLE stack.
* @details Initializes the SoftDevice and the BLE event interrupt.
*/
static void ble_stack_init(void)
{
ret_code_t err_code;
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// Configure the BLE stack using the default settings.
// Fetch the start address of the application RAM.
uint32_t ram_start = 0;
err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
APP_ERROR_CHECK(err_code);
// Enable BLE stack.
err_code = nrf_sdh_ble_enable(&ram_start);
APP_ERROR_CHECK(err_code);
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}
BLE 事件回调函数,ble_evt_handler
/**@brief Function for handling BLE events.
* @param[in] p_ble_evt Bluetooth stack event.
* @param[in] p_context Unused.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("Connected");
bsp_board_led_on(CONNECTED_LED);
bsp_board_led_off(ADVERTISING_LED);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
APP_ERROR_CHECK(err_code);
err_code = app_button_enable();
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_DISCONNECTED:
NRF_LOG_INFO("Disconnected");
bsp_board_led_off(CONNECTED_LED);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = app_button_disable();
APP_ERROR_CHECK(err_code);
advertising_start();
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
NULL,
NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
{
NRF_LOG_DEBUG("PHY update request.");
ble_gap_phys_t const phys =
{
.rx_phys = BLE_GAP_PHY_AUTO,
.tx_phys = BLE_GAP_PHY_AUTO,
};
err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
APP_ERROR_CHECK(err_code);
} break;
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTC_EVT_TIMEOUT:
// Disconnect on GATT Client timeout event.
NRF_LOG_DEBUG("GATT Client Timeout.");
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_TIMEOUT:
// Disconnect on GATT Server timeout event.
NRF_LOG_DEBUG("GATT Server Timeout.");
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
break;
default:
// No implementation needed.
break;
}
}
BLE GAP 事件列表 (GAP Event IDs.); (BLE 事件回调函数 ble_evt_handler 中常处理的事件)
enum BLE_GAP_EVTS |
GAP Event IDs. IDs that uniquely identify an event coming from the stack to the application.
Enumerator | |
---|---|
BLE_GAP_EVT_CONNECTED |
GAP BLE Event base. |
BLE_GAP_EVT_DISCONNECTED |
GAP BLE Event base. Disconnected from peer. |
BLE_GAP_EVT_CONN_PARAM_UPDATE |
GAP BLE Event base. Connection Parameters updated. |
BLE_GAP_EVT_SEC_PARAMS_REQUEST |
GAP BLE Event base. Request to provide security parameters. |
BLE_GAP_EVT_SEC_INFO_REQUEST |
GAP BLE Event base. Request to provide security information. |
BLE_GAP_EVT_PASSKEY_DISPLAY |
GAP BLE Event base. Request to display a passkey to the user. |
BLE_GAP_EVT_KEY_PRESSED |
GAP BLE Event base. Notification of a keypress on the remote device. |
BLE_GAP_EVT_AUTH_KEY_REQUEST |
GAP BLE Event base. Request to provide an authentication key. |
BLE_GAP_EVT_LESC_DHKEY_REQUEST |
GAP BLE Event base. Request to calculate an LE Secure Connections DHKey. |
BLE_GAP_EVT_AUTH_STATUS |
GAP BLE Event base. Authentication procedure completed with status. |
BLE_GAP_EVT_CONN_SEC_UPDATE |
GAP BLE Event base. Connection security updated. |
BLE_GAP_EVT_TIMEOUT |
GAP BLE Event base. Timeout expired. |
BLE_GAP_EVT_RSSI_CHANGED |
GAP BLE Event base. RSSI report. |
BLE_GAP_EVT_ADV_REPORT |
GAP BLE Event base. Advertising report. |
BLE_GAP_EVT_SEC_REQUEST |
GAP BLE Event base. Security Request. |
BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST |
GAP BLE Event base. Connection Parameter Update Request. |
BLE_GAP_EVT_SCAN_REQ_REPORT |
GAP BLE Event base. Scan request report. |
BLE_GAP_EVT_PHY_UPDATE_REQUEST |
GAP BLE Event base. PHY Update Request. |
BLE_GAP_EVT_PHY_UPDATE |
GAP BLE Event base. PHY Update Procedure is complete. |
BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST |
GAP BLE Event base. Data Length Update Request. |
BLE_GAP_EVT_DATA_LENGTH_UPDATE |
GAP BLE Event base. LL Data Channel PDU payload length updated. |
BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT |
GAP BLE Event base. Channel survey report. |
BLE_GAP_EVT_ADV_SET_TERMINATED |
GAP BLE Event base. Advertising set terminated. |
BLE GATT Server 事件列表 (GATT Server Event IDs.)(BLE 事件回调函数 ble_evt_handler 中常处理的事件)
enum BLE_GATTS_EVTS |
GATT Server Event IDs.
Enumerator | |
---|---|
BLE_GATTS_EVT_WRITE |
GATTS BLE Event base. Write operation performed. |
BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST |
Read/Write Authorization request. |
BLE_GATTS_EVT_SYS_ATTR_MISSING |
A persistent system attribute access is pending. |
BLE_GATTS_EVT_HVC |
Handle Value Confirmation. |
BLE_GATTS_EVT_SC_CONFIRM |
Service Changed Confirmation. |
BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST |
Exchange MTU Request. |
BLE_GATTS_EVT_TIMEOUT |
Peer failed to respond to an ATT request in time. |
BLE_GATTS_EVT_HVN_TX_COMPLETE |
Handle Value Notification transmission complete. |
BLE GATT Client 事件列表 (GATT Client Event IDs.)(BLE 事件回调函数 ble_evt_handler 中常处理的事件)
enum BLE_GATTC_EVTS |
GATT Client Event IDs.
Enumerator | |
---|---|
BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP |
GATTC BLE Event base. Primary Service Discovery Response event. |
BLE_GATTC_EVT_REL_DISC_RSP |
Relationship Discovery Response event. |
BLE_GATTC_EVT_CHAR_DISC_RSP |
Characteristic Discovery Response event. |
BLE_GATTC_EVT_DESC_DISC_RSP |
Descriptor Discovery Response event. |
BLE_GATTC_EVT_ATTR_INFO_DISC_RSP |
Attribute Information Response event. |
BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP |
Read By UUID Response event. |
BLE_GATTC_EVT_READ_RSP |
Read Response event. |
BLE_GATTC_EVT_CHAR_VALS_READ_RSP |
Read multiple Response event. |
BLE_GATTC_EVT_WRITE_RSP |
Write Response event. |
BLE_GATTC_EVT_HVX |
Handle Value Notification or Indication event. |
BLE_GATTC_EVT_EXCHANGE_MTU_RSP |
Exchange MTU Response event. |
BLE_GATTC_EVT_TIMEOUT |
Timeout event. |
BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE |
Write without Response transmission complete. |
gap_params_init()
/**@brief Function for the GAP initialization.
* @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
* device including the device name, appearance, and the preferred connection parameters.
*/
static void gap_params_init(void)
{
ret_code_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)DEVICE_NAME,
strlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency = SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
APP_ERROR_CHECK(err_code);
}
gatt_init()
/**@brief Function for initializing the GATT module.*/
static void gatt_init(void)
{
ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
APP_ERROR_CHECK(err_code);
}
ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler)
{
VERIFY_PARAM_NOT_NULL(p_gatt);
p_gatt->evt_handler = evt_handler;
p_gatt->att_mtu_desired_periph = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
p_gatt->att_mtu_desired_central = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
p_gatt->data_length = NRF_SDH_BLE_GAP_DATA_LENGTH;
for (uint32_t i = 0; i < NRF_BLE_GATT_LINK_COUNT; i++)
{
link_init(&p_gatt->links[i]);
}
return NRF_SUCCESS;
}
services_init()
本例 services_init() 中,实现的是 LED Button Service; 其具体内容根据应用需求修改。
/**@brief Function for initializing services that will be used by the application.
*/
static void services_init(void)
{
ret_code_t err_code;
ble_lbs_init_t init = {0};
nrf_ble_qwr_init_t qwr_init = {0};
// Initialize Queued Write Module.
qwr_init.error_handler = nrf_qwr_error_handler;
err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
APP_ERROR_CHECK(err_code);
// Initialize LBS.
init.led_write_handler = led_write_handler;
err_code = ble_lbs_init(&m_lbs, &init);
APP_ERROR_CHECK(err_code);
}
/**@brief Function for handling write events to the LED characteristic.
* @param[in] p_lbs Instance of LED Button Service to which the write applies.
* @param[in] led_state Written/desired state of the LED.
*/
static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)
{
if (led_state)
{
bsp_board_led_on(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED ON!");
}
else
{
bsp_board_led_off(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED OFF!");
}
}
advertising_init()
/**@brief Function for initializing the Advertising functionality.
* @details Encodes the required advertising data and passes it to the stack.
* Also builds a structure to be passed to the stack when starting advertising.
*/
static void advertising_init(void)
{
ret_code_t err_code;
ble_advdata_t advdata;
ble_advdata_t srdata;
ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};
// Build and set advertising data.
memset(&advdata, 0, sizeof(advdata));
advdata.name_type = BLE_ADVDATA_FULL_NAME;
advdata.include_appearance = true;
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
memset(&srdata, 0, sizeof(srdata));
srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
srdata.uuids_complete.p_uuids = adv_uuids;
err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
APP_ERROR_CHECK(err_code);
err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
APP_ERROR_CHECK(err_code);
ble_gap_adv_params_t adv_params;
// Set advertising parameters.
memset(&adv_params, 0, sizeof(adv_params));
adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
adv_params.duration = APP_ADV_DURATION;
adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
adv_params.p_peer_addr = NULL;
adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
adv_params.interval = APP_ADV_INTERVAL;
err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
APP_ERROR_CHECK(err_code);
}
BLE 广播重要函数 sd_ble_advdata_encode
ret_code_t ble_advdata_encode | ( | ble_advdata_t const *const | p_advdata, |
uint8_t *const | p_encoded_data, | ||
uint16_t *const | p_len | ||
) |
Function for encoding data in the Advertising and Scan Response data format (AD structures).
This function encodes data into the Advertising and Scan Response data format (AD structures) based on the fields in the supplied structures. This function can be used to create a payload of Advertising packet or Scan Response packet, or a payload of NFC message intended for initiating the Out-of-Band pairing.
Parameters
[in] | p_advdata | Pointer to the structure for specifying the content of encoded data. |
[out] | p_encoded_data | Pointer to the buffer where encoded data will be returned. |
[in,out] | p_len |
in: Size of p_encoded_data buffer. out: Length of encoded data.
|
Return values
NRF_SUCCESS | If the operation was successful. |
NRF_ERROR_INVALID_PARAM |
If the operation failed because a wrong parameter was provided in p_advdata .
|
NRF_ERROR_DATA_SIZE | If the operation failed because not all the requested data could fit into the provided buffer or some encoded AD structure is too long and its length cannot be encoded with one octet. |
Warning
This API may override the application's request to use the long name and use a short name instead. This truncation will occur in case the long name does not fit the provided buffer size. The application can specify a preferred short name length if truncation is required. For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name. However, it should be noted that this is just a preference that the application can specify, and if the preference is too large to fit in the provided buffer, the name can be truncated further.
BLE 广播重要函数 sd_ble_gap_adv_set_configure
uint32_t sd_ble_gap_adv_set_configure | ( | uint8_t * | p_adv_handle, |
ble_gap_adv_data_t const * | p_adv_data, | ||
ble_gap_adv_params_t const * | p_adv_params | ||
) |
Configure an advertising set. Set, clear or update advertising and scan response data.
Note
The format of the advertising data will be checked by this call to ensure interoperability. Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and duplicating the local name in the advertising data and scan response data.
In order to update advertising data while advertising, new advertising buffers must be provided.
Relevant Message Sequence Charts
Advertising |
Whitelist Sharing |
Parameters
[in,out] | p_adv_handle | Provide a pointer to a handle containing BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure a new advertising set. On success, a new handle is then returned through the pointer. Provide a pointer to an existing advertising handle to configure an existing advertising set. |
[in] | p_adv_data | Advertising data. If set to NULL, no advertising data will be used. See ble_gap_adv_data_t. |
[in] | p_adv_params | Advertising parameters. When this function is used to update advertising data while advertising, this parameter must be NULL. See ble_gap_adv_params_t. |
Return values
NRF_SUCCESS | Advertising set successfully configured. |
NRF_ERROR_INVALID_PARAM |
Invalid parameter(s) supplied:
|
BLE_ERROR_GAP_INVALID_BLE_ADDR | ble_gap_adv_params_t::p_peer_addr is invalid. |
NRF_ERROR_INVALID_STATE |
Invalid state to perform operation.
|
BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST | Discoverable mode and whitelist incompatible. |
BLE_ERROR_INVALID_ADV_HANDLE | The provided advertising handle was not found. Use BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure a new advertising handle. |
NRF_ERROR_INVALID_ADDR | Invalid pointer supplied. |
NRF_ERROR_INVALID_FLAGS | Invalid combination of advertising flags supplied. |
NRF_ERROR_INVALID_DATA | Invalid data type(s) supplied. Check the advertising data format specification given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11. |
NRF_ERROR_INVALID_LENGTH | Invalid data length(s) supplied. |
NRF_ERROR_NOT_SUPPORTED | Unsupported data length or advertising parameter configuration. |
NRF_ERROR_NO_MEM | Not enough memory to configure a new advertising handle. Update an existing advertising handle instead. |
BLE_ERROR_GAP_UUID_LIST_MISMATCH | Invalid UUID list supplied. |
advertising_start()
/**@brief Function for starting advertising.
*/
static void advertising_start(void)
{
ret_code_t err_code;
err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
bsp_board_led_on( ADVERTISING_LED );
}
BLE 广播重要函数 sd_ble_gap_adv_start
uint32_t sd_ble_gap_adv_start | ( | uint8_t | adv_handle, |
uint8_t | conn_cfg_tag | ||
) |
Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
Note
Only one advertiser may be active at any time.
Events generated
BLE_GAP_EVT_CONNECTED | Generated after connection has been established through connectable advertising. |
BLE_GAP_EVT_ADV_SET_TERMINATED | Advertising set has terminated. |
BLE_GAP_EVT_SCAN_REQ_REPORT | A scan request was received. |
Relevant Message Sequence Charts
Advertising |
Peripheral Connection Establishment with Private Peer |
Directed Advertising |
Whitelist Sharing |
Parameters
[in] | adv_handle | Advertising handle to advertise on, received from sd_ble_gap_adv_set_configure. |
[in] | conn_cfg_tag | Tag identifying a configuration set by sd_ble_cfg_set or BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable advertising, this is ignored. |
Return values
NRF_SUCCESS | The BLE stack has started advertising. |
NRF_ERROR_INVALID_STATE | Invalid state to perform operation. adv_handle is not configured or already advertising. |
NRF_ERROR_CONN_COUNT | The limit of available connections has been reached; connectable advertiser cannot be started. |
BLE_ERROR_INVALID_ADV_HANDLE | Advertising handle not found. Configure a new adveriting handle with sd_ble_gap_adv_set_configure. |
NRF_ERROR_NOT_FOUND | conn_cfg_tag not found. |
NRF_ERROR_INVALID_PARAM |
Invalid parameter(s) supplied:
|
NRF_ERROR_RESOURCES |
Either:
|
NORDIC softDevice 蓝牙协议栈初始化程序分析(蓝牙从机,ble_peripheral)相关推荐
- 8255a初始化c语言程序,单片机8255型号大全(工作字的选择,单片机连接,初始化程序分析)...
描述 单片机8255型号大全(工作字的选择,单片机连接,初始化程序分析):工作字该如何选择? 1. 工作方式的控制字 例:设8255A的控制端口地址为00E6H,要把A口指定为方式1输入,C口上半部定 ...
- nrf52840蓝牙协议栈样例分析
蓝牙SDK的example 文件夹提供了开发BLE的模板工程,它具有通用性,可以为自己开发工程提供参考.打开examples\ble_peripheral\ble_app_template文件夹下 ...
- C语言蓝牙协议栈讲解,通俗易懂讲解蓝牙协议栈软件框架
BLE 协议架构总体上分成3块,从下到上分别是:控制器(Controller),主机(Host)和应用端(Apps):3者可以在同一芯片类实现,也可以分不同芯片内实现,控制器(Controller)是 ...
- nrf52840蓝牙协议栈从机BLE串口
nrf52840蓝牙协议栈从机BLE串口,参考蓝牙SDK的example中的ble_app_uart样例.本文主要是分析ble_app_uart样例. 蓝牙从机串口的工作模式是:主机通过蓝牙发 ...
- ARM平台上蓝牙协议栈Bluez的移植使用和配置
版权所有,转载请注明出处http://blog.csdn.net/gatieme/article/details/48751743 参考 http://blog.csdn.net/lizzywu/ar ...
- 蓝牙学习(二)-- 三种蓝牙架构实现方案(蓝牙协议栈方案)
蓝牙架构实现方案有哪几种?我们一般把整个蓝牙实现方案叫做蓝牙协议栈,因此这个问题也可以这么阐述:蓝牙协议栈有哪些具体的架构方案?在蓝牙协议栈中,host是什么?controller是什么?HCI又是 ...
- C语言蓝牙协议栈讲解,蓝牙协议栈记录—BTStack
TSTack User Guid 翻译过来的 1.简介 2.BTStack 架构 BTStack在所实现的协议和服务之间采用很多状态机实现相互作用,特点: <1>单线程.BTStack只有 ...
- 三种蓝牙架构实现方案(蓝牙协议栈方案)
蓝牙架构实现方案有哪几种?我们一般把整个蓝牙实现方案叫做蓝牙协议栈,因此这个问题也可以这么阐述:蓝牙协议栈有哪些具体的架构方案?在蓝牙协议栈中,host是什么?controller是什么?HCI又是什 ...
- 3种蓝牙架构实现方案(蓝牙协议栈方案)
导言 不同的蓝牙架构可以用在不同的场景中.从而协议帧的架构方案也会不同. 转载自:https://www.cnblogs.com/schips/p/12293141.html <三种蓝牙架构实现 ...
最新文章
- 关于UIWebView与js交互的问题
- mtk一键usb驱动_三菱MRJEB驱动器报错,导致报错原因37.1参数设置范围异常?
- 澳元兑美元震荡整理,后市可否追高
- oracle的分支语句,oracle中的分支与循环语句
- ospf的七类lsa存在于_OSPF抑制7类LSA的转发
- html5 删除llocalstorage变量,删除存储在浏览器中的 Local Storage 数据《 HTML5:Web 存储 》...
- 硬盘服务器作用,文件服务器有什么作用?
- 微信小程序开发之——WeUI快速上手
- 将2010年的旧电脑升级为Win8.1遇到的问题及解决办法
- Java冒泡算法(优化版)
- 工业物联网的体系架构
- 基于共振解调的轴承故障诊断方法总结(一)
- 如何将PDF转成PPT?为什么转换后不能编辑
- 小程序学习 - 02 微信小程序案例实践
- 2023最新苹果CMS10暗色系动漫影视网站模板源码+UI高端大气
- 弘辽科技:新手开淘宝店的步骤有哪些?如何起步?
- 并行传输数据和串行传输数据_为什么串行数据传输比并行数据传输快?
- 【好工具】安利一款优秀的图片浏览器
- 计算机软考地址,各省市计算机软考分数查询地址
- Python爬虫——新浪微博(网页版)