/****************************************************************************** @brief 实现APP与设备握手连接 ******************************************************************************/ #include "am_util_debug.h" #include "sys_config.h" #include "FreeRTOS.h" #include "task.h" #include "ble_management_server.h" #include "user_adapter.h" #include "amotas_api.h" #include "task_ble.h" #include "ble_data_transmission.h" #include "sys_typedef.h" #include "ui_port_resource.h" #include "task_ui.h" //#include "fs_user_app.h" //#include "data_log.h" #include "rtc_api.h" #include "ui_ble_pair.h" #include "ui_port_fw.h" #include "fs_api.h" #include "fs_user_init.h" #include "sql_setting.h" static conn_param_t conn_param= { FRAM_MAX_SIZ, //链路层最大帧长度 BLE_NOTIF_LEN, //MTU大小 0x03,//500, // 最大超时时间 3s }; static bond_info_t user_bond_info = {0}; //用户绑定信息 static uint8_t user_iphone_id[6] = {0}; //***************************************************************************** // // brief: 输出反向的mac地址数组 // example: 如果 mac_addr = {06,05,04,03,02,01}; // 输出"{01,02,03,04,05,06}" //***************************************************************************** extern uint8_t* HciVscGetCustom_BDAddr(void); //void user_get_reverse_ble_mac(uint8_t *output, uint16_t len) //{ // uint8_t* pMacAddr = NULL; // uint8_t i = 0; // if(output == NULL || len < 6) // return; // pMacAddr = HciVscGetCustom_BDAddr(); // for(; i < 6; i++) { // output[i] = pMacAddr[5 - i]; // } //} uint8_t GetBandStatus(void) { return user_bond_info.status; } void SetBandstatus(uint8_t status) { user_bond_info.status = status; } // 获取绑定手机的操作系统 //0:Android; 1:ios uint8_t GetBandPhoneOS(void) { return user_bond_info.os; } // 设备是否绑定过 bool IsTheDeviceBuand(void) { uint8_t bondIdEmpty[BDA_ADDR_LEN] = {0}; uint8_t bondIdFull[BDA_ADDR_LEN] = {0xff}; if((memcmp(user_bond_info.id, bondIdEmpty, BDA_ADDR_LEN) == 0) || (memcmp(user_bond_info.id, bondIdFull, BDA_ADDR_LEN) == 0)) { return false; } else { return true; } } void LoadBleConfig(void) { int len = 0; char path[48]; bool is_dir; fs_user_get_dir_by_full_path(FILE_CONFIG_BLUETOOTH, path); if(fs_api_dir_exist(path) != RET_SUCCESS) { fs_user_create_dir(path); } if(fs_api_stat(FILE_CONFIG_BLUETOOTH,&is_dir) != sizeof(user_bond_info)) { //文件长度不符 ble_printf("notify message file length err,need default\r\n"); goto NEED_DEFAULT; } len = fs_api_file_load(FILE_CONFIG_BLUETOOTH, 0, &user_bond_info, sizeof(user_bond_info)); if(len != sizeof(user_bond_info)) { //读取文件的长度不符 ble_printf("read notify message file err,ret=%d,need default\r\n", len); goto NEED_DEFAULT; } return; NEED_DEFAULT: memset(&user_bond_info, 0, sizeof(user_bond_info)); SaveBleConfig(); } void SaveBleConfig(void) { fs_api_file_store(FILE_CONFIG_BLUETOOTH, 0, &user_bond_info, sizeof(user_bond_info)); } // 在没有文件路径的情况下保存文件,连接复位测试用 void SavePairingFileWithoutDir(void) { #if 1 char path[48]; fs_user_get_dir_by_full_path(FILE_CONFIG_BLUETOOTH, path); if(fs_api_dir_exist(path) != RET_SUCCESS) { fs_user_create_dir(path); } SaveBleConfig(); #endif } void BleConifgInit(void) { LoadBleConfig(); } void BleBondReqRespond(uint8_t BondStatus) { uint16_t write_idx = 0; uint8_t buf_temp[5] = {0}; if(BondStatus == BAND_REJECT) // 协议回复的绑定拒绝与设备定义的不一致 BondStatus = PROTOCOL_BAND_REJECT; buf_temp[write_idx++] = 0x03; //LTV - length buf_temp[write_idx++] = get_bt_bond_status_type; //type buf_temp[write_idx++] = BondStatus; //value BLE_SendFrameById(DEVICE_MANAGEMENT_SERVER, BLE_BOND_REQ_ID, buf_temp, write_idx); } void UserPairOperate(uint8_t pair_opcode) { int ret; uint8_t *p_save_data; uint32_t len; char* path; BleBondReqRespond(pair_opcode); if((pair_opcode == AGREE_PAIR_RESPONSE) || (pair_opcode == FORCE_AGREE_PAIR)) { ble_printf("Device Pairing Success.\r\n"); user_bond_info.status = BAND_SUCC; memcpy(user_bond_info.id, user_iphone_id, sizeof(user_iphone_id)); //log_api_record_action(rtc_api_get_utc_timestamp(), EVT_BLE_MANAGE, INFO1_BLE_PAIRING, pair_opcode, 0, NULL); sql_setting_set_ble_bind(true); SaveBleConfig(); p_save_data = sql_setting_get_info(&len,&path); ret = fs_api_file_store(path, 0, p_save_data, len); ble_printf("[%s] ret=%d len=%d\r\n",path,ret,len); } else { ble_printf("Device Pairing fail.\r\n"); if(pair_opcode == REJECT_PAIR_RESPONSE) { user_bond_info.status = BAND_REJECT; } else if(pair_opcode == TIMEOUT_AUTO_REJECT_PAIR_RESPONSE) { user_bond_info.status = BAND_TIMEOUT; } vTaskDelay(1000); amota_disconnect(); } } /***************************************************************************** 功能描述 : 4.1.1连接参数协商 *****************************************************************************/ void user_rev_conn_param_cmd(uint8_t *in_data,uint16_t in_len,uint8_t *out_data,uint16_t *out_len) { uint16_t write_idx = 0; protocol_data_info_t data_info = {0}; uint8_t rev_ipone_type_flag = 0; do { user_get_data_info(&data_info,&in_data,&in_len); switch((data_info.type &0x7F)) { case max_frame_size_type: out_data[write_idx++]=4; out_data[write_idx++]=data_info.type; out_data[write_idx++]=((conn_param.max_frame_size >> 8) & 0xff); out_data[write_idx++]=((conn_param.max_frame_size) & 0xff); break; case max_transimission_unit_type: out_data[write_idx++]=4; out_data[write_idx++]=data_info.type; conn_param.max_trans_unit = user_app_mtu_get(); out_data[write_idx++] = ((conn_param.max_trans_unit >> 8) & 0xff);; out_data[write_idx++] = ((conn_param.max_trans_unit ) & 0xff); break; case max_transimission_timeout_type: out_data[write_idx++]=4; out_data[write_idx++]=data_info.type; out_data[write_idx++]=((conn_param.max_trans_timeout>> 8) & 0xff); out_data[write_idx++]=((conn_param.max_trans_timeout) & 0xff); ble_printf("upload mtu is %d\n", conn_param.max_trans_unit); break; case phone_operating_system_type: rev_ipone_type_flag = 1; user_bond_info.os = *in_data; ble_printf("****** phone_operating_system_type: os = %d *****\r\n", user_bond_info.os); break; default: break; } in_data= data_info.p_data; in_data+=(data_info.len); in_len-=(2+data_info.len); if(in_len>FRAM_MAX_SIZ) { in_len=0; } } while(in_len); if(rev_ipone_type_flag == 0) {// 若app未发手机类型则默认为安卓类型 user_bond_info.os = ANDROID_PHONE; } *out_len=write_idx; } /***************************************************************************** 功能描述 : 4.1.2 查询蓝牙绑定状态 *****************************************************************************/ void user_rev_get_ble_bond_status(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { // uint8_t i; uint16_t write_idx = 0, bond_status_index = 0; protocol_data_info_t data_info = {0}; ble_printf("user_rev_get_ble_bond_status\n"); memset(user_bond_info.phone_mac_addr, 0xff, sizeof(user_bond_info.phone_mac_addr)); do { user_get_data_info(&data_info, &in_data, &in_len); switch((data_info.type & 0x7F)) { case get_bt_bond_status_type: out_data[write_idx++] = 3; out_data[write_idx++] = get_bt_bond_status_type; bond_status_index = write_idx; out_data[write_idx++] = user_bond_info.status; break; case get_bt_bond_id_type: if(data_info.len == 6) { // 比较ID是否与上次连接的手机ID一致 // for(i = 0; i < data_info.len; i++) { // ble_printf("get_bound_status memcmp id[%d]= 0x%x,in_data[%d]=0x%x.\r\n", i, user_bond_info.id[i], i, in_data[i]); // } if(memcmp(user_bond_info.id, in_data, data_info.len) == 0 && sql_setting_get_ble_bind()) { user_bond_info.status = BAND_SUCC; ble_printf(" connect succ!!! \r\n"); } else { user_bond_info.status = NOT_BAND; // 手环与手机未绑定 ble_printf("NOT_BAND!!! \r\n"); } out_data[bond_status_index] = user_bond_info.status; } break; case get_bt_device_mac_addr_type: out_data[write_idx++] = 8; //手环蓝牙地址需要带: out_data[write_idx++] = get_bt_device_mac_addr_type; user_get_reverse_ble_mac(user_bond_info.device_mac_addr, 6); memcpy(&out_data[write_idx], user_bond_info.device_mac_addr, 6); write_idx += 6; break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if(in_len > FRAM_MAX_SIZ) { in_len = 0; } } while(in_len); if(data_info.error) { write_idx = user_set_protocol_error(out_data, DEVICE_MANAGEMENT_SERVER, data_info.error); } *out_len = write_idx; } /***************************************************************************** 功能描述 : 4.1.3 蓝牙绑定请求 *****************************************************************************/ void user_rev_req_bond(uint8_t *in_data, uint16_t in_len, uint8_t *out_data, uint16_t *out_len) { uint16_t write_idx = 0; uint16_t bond_bit = 0; protocol_data_info_t data_info = {0}; // log_api_record_action(rtc_api_get_utc_timestamp(), EVT_BLE_MANAGE, INFO1_BLE_PAIRING, INFO2_BLE_PAIRING_REQ, 0, NULL); do { user_get_data_info(&data_info, &in_data, &in_len); switch((data_info.type & 0x7F)) { case require_bt_bond_type: bond_bit = bond_bit | (1 << require_bt_bond_type); break; case bt_bond_os_type: bond_bit = bond_bit | (1 << bt_bond_os_type); user_bond_info.os = *in_data; ble_printf("user_bond_info.os = %d\r\n",user_bond_info.os); break; case bt_bond_id_type: if(data_info.len == 6) { bond_bit = bond_bit | (1 << bt_bond_id_type); memcpy(user_iphone_id, in_data, data_info.len); } break; case bt_bond_key_type: if(data_info.len == 16) { bond_bit = bond_bit | (1 << bt_bond_key_type); memcpy(user_bond_info.key, in_data, data_info.len); } break; case bt_bond_IV_type: if(data_info.len == 16) { bond_bit = bond_bit | (1 << bt_bond_IV_type); memcpy(user_bond_info.iv, in_data, data_info.len); } break; default: break; } in_data = data_info.p_data; in_data += (data_info.len); in_len -= (2 + data_info.len); if(in_len > FRAM_MAX_SIZ) { in_len = 0; } } while(in_len); DeviceReadPeerMacAddr(user_bond_info.phone_mac_addr); if(data_info.error) { write_idx = user_set_protocol_error(out_data, DEVICE_MANAGEMENT_SERVER, data_info.error); } else { ble_printf("user_bond_info.status is %d\n", user_bond_info.status); user_bond_info.status = BAND_REQUEST; if(ui_get_resource_check_result()) { ui_port_send_sys_remind_event(EVENT_REMIND_PAIR,PAIR_REQUEST_STATE,NULL,0); } else { ble_printf("force pair because resource is bad\r\n"); task_ble_notify(BLE_PAIRING_OPER_MSG, BAND_SUCC); } } *out_len = write_idx; } const p_func_t user_manamagement_server_func[mamagement_server_max_ID]= { user_null_func, user_rev_conn_param_cmd, //4.1.1 user_rev_get_ble_bond_status, //4.1.2 user_rev_req_bond, //4.1.3 };