695X BLE应用开发

Fiona ·
更新时间:2024-09-21
· 664 次阅读

    首先是确定与APP通信的BLE服务,这个服务如果不是公共服务,就定义私有服务,比如SDK里面的0X1800为公共服务,为显示电池电量等来用的。定义一个与APP通信的私有服务为0X2020。至于哪些为公共服务,可以查看BLE协议相关手册,除了公共服务以外其余皆为私有服务。平时我们在手机搜索到的BLE图标显示为键盘,手柄等等,就是因为搜索到的蓝牙定义的服务有公共服务,有什么公共服务,就显示为什么样的图标。

    确定好私有服务0X2020,剩下的就是特征值了,一般定义3个特征值,一个用来写(0xa0a0),一个读(0xa0a1),一个Notify(0xa0a2),之后用gatt工具生成profile表格,替换掉sdk里面表格,到这里特征值和服务的工作已经做完。

    接下去是sdk的读写回调,里面代码已经实现,需要做的是把自己定义的读写notify三个通道替换掉原来的。读回调,即app读蓝牙端数据后蓝牙给出怎样的结果,通道替换成0xa0a1即可。举例:用APP读取蓝牙端的音量,是通过0xa0a1这个通道来读取的,只要在回调中把音量放进去,APP即可读回蓝牙端音量。写回调:同理,在app发一个0x01过来,就会调用一次写回调函数。至于发送怎样的数据,跟读回调一个道理。接下去是notify,这个比较重要,这个通道是APP用来监听的通道,也是蓝牙端最常用的通道,蓝牙端想要主动发送数据到APP端就是通过这个通道来实现的,相关的代码在sdk里面已经实现了。

    以下服务0XA035,写0XA040,读0XA041,Notify0XA042

#define ATT_CHARACTERISTIC_2A00_01_VALUE_HANDLE 0x0003 #define ATT_CHARACTERISTIC_a042_01_VALUE_HANDLE 0x0006 //蓝牙发送通道 需要client在该通道处于监听状态 #define ATT_CHARACTERISTIC_a042_01_CLIENT_CONFIGURATION_HANDLE 0x0007 // #define ATT_CHARACTERISTIC_a040_01_VALUE_HANDLE 0x0009//client写通道 #define ATT_CHARACTERISTIC_a041_01_VALUE_HANDLE 0x000b // client读通道 蓝牙准备好数据给app读取 #define ATT_CHARACTERISTIC_a043_01_VALUE_HANDLE 0x000d // 没有用到的通道 #define ATT_CHARACTERISTIC_a043_01_CLIENT_CONFIGURATION_HANDLE 0x000e static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { int result = 0; u16 tmp16; u16 handle = att_handle; // log_info("write_callback, handle= 0x%04x,size = %d\n", handle, buffer_size); switch (handle) { case ATT_CHARACTERISTIC_a042_01_CLIENT_CONFIGURATION_HANDLE: case ATT_CHARACTERISTIC_a043_01_CLIENT_CONFIGURATION_HANDLE: set_ble_work_state(BLE_ST_NOTIFY_IDICATE); check_connetion_updata_deal(); log_info("\n------write ccc:%04x,%02x\n", handle, buffer[0]); att_set_ccc_config(handle, buffer[0]); break; case ATT_CHARACTERISTIC_a040_01_VALUE_HANDLE: if (buffer_size){ user_ble_rx_parse(buffer, buffer_size); } break; default: break; } return 0; } static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { uint16_t att_value_len = 0; uint16_t handle = att_handle; u8* ptr = NULL; // log_info("read_callback, handle= 0x%04x,buffer= %08x\n", handle, (u32)buffer); switch (handle) { case ATT_CHARACTERISTIC_a041_01_VALUE_HANDLE: ptr = user_ble_app_read_cbk(&att_value_len); if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) { break; } if (buffer) { memcpy(buffer, &ptr[offset], buffer_size); att_value_len = buffer_size; } break; default: break; } return att_value_len; } /** * \brief user_ble_tx_data * \note ble数据直发 * */ static int ble_tx_data(u8 *tx_buf, u16 len) { u32 vaild_len = 0; ble_user_cmd_prepare(BLE_CMD_ATT_VAILD_LEN, 1, &vaild_len); if (len <= vaild_len) { /// printf("ble send\n"); return app_send_user_data(ATT_CHARACTERISTIC_a042_01_VALUE_HANDLE, tx_buf, len, ATT_OP_AUTO_READ_CCC); } return APP_BLE_OPERATION_ERROR; } /** * \brief user_ble_rx_parse * \note ble原始数据解析 * */ void user_ble_rx_parse(u8 *rx_buf, u16 len) { u8 rx_user_data[128]={0}; u8 user_data_len = 0; u16 command = 0; u8 error_ack = 0xff; user_uart_tx_data(rx_buf, len);/*!透传*/ bool check_result = ble_user_defined_protocol_check(rx_buf, len, rx_user_data, &user_data_len, &command); if (check_result == TRUE) { ble_command_parse(command,rx_user_data); } else { printf("ble protocol check fail\n"); user_ble_app_rsp_package(command,&ble_rsp_error,1); } }
作者:渔夫与魔鬼的故事



ble

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章