如何为两个服务的蓝牙加密?

Daniel
Posts: 28
Joined: Tue Jan 09, 2018 12:55 pm

如何为两个服务的蓝牙加密?

Postby Daniel » Wed Dec 12, 2018 12:54 pm

本人参考了“gatt_security_server” 和“gatt_server”,还有蓝牙串口程序https://github.com/sideridispas/CERTH_I ... 2_ble_UART,写了一个带有蓝牙串口和普通UUID的蓝牙程序,现在要求对这个蓝牙进行加密,经本人殚精竭虑,仍不得要领。现在只实现了在苹果手机app测试时,第一次点击“连接”,可以正常连接通信,但是,断开程序后,除非在手机蓝牙配置里把该设备给忽略,否则第二次及以后不管是否重启都不能再次连接上。请问如何给两个服务的蓝牙加密?
下文是我的部分代码:

Code: Select all

tatic char *esp_key_type_to_str(esp_ble_key_type_t key_type)
{
   char *key_str = NULL;
   switch(key_type) {
    case ESP_LE_KEY_NONE:
        key_str = "ESP_LE_KEY_NONE";
        break;
    case ESP_LE_KEY_PENC:
        key_str = "ESP_LE_KEY_PENC";
        break;
    case ESP_LE_KEY_PID:
        key_str = "ESP_LE_KEY_PID";
        break;
    case ESP_LE_KEY_PCSRK:
        key_str = "ESP_LE_KEY_PCSRK";
        break;
    case ESP_LE_KEY_PLK:
        key_str = "ESP_LE_KEY_PLK";
        break;
    case ESP_LE_KEY_LLK:
        key_str = "ESP_LE_KEY_LLK";
        break;
    case ESP_LE_KEY_LENC:
        key_str = "ESP_LE_KEY_LENC";
        break;
    case ESP_LE_KEY_LID:
        key_str = "ESP_LE_KEY_LID";
        break;
    case ESP_LE_KEY_LCSRK:
        key_str = "ESP_LE_KEY_LCSRK";
        break;
    default:
        key_str = "INVALID BLE KEY TYPE";
        break;

   }

   return key_str;
}

static void show_bonded_devices(void)
{
    int dev_num = esp_ble_get_bond_device_num();

    esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
    esp_ble_get_bond_device_list(&dev_num, dev_list);
    ESP_LOGI(FLOW_SERVICE, "Bonded devices number : %d\n", dev_num);

    ESP_LOGI(FLOW_SERVICE, "Bonded devices list : %d\n", dev_num);
    for (int i = 0; i < dev_num; i++) {
        esp_log_buffer_hex(FLOW_SERVICE, (void *)dev_list[i].bd_addr, sizeof(esp_bd_addr_t));
    }

    free(dev_list);
}

void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {

	static uint8_t  printf_cnt=0; esp_bd_addr_t bd_addr;
	printf("%d.adv_config_done= %d , event = %d \n",++printf_cnt,adv_config_done,event);
    switch (event) {
  /*  #ifdef CONFIG_SET_RAW_ADV_DATA
        case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
            adv_config_done &= (~ADV_CONFIG_FLAG);
            if (adv_config_done == 0){
                esp_ble_gap_start_advertising(&ble_adv_params);
            }
            break;
        case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
            adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
            if (adv_config_done == 0){
                esp_ble_gap_start_advertising(&ble_adv_params);
            }
            break;
    #else*/
        case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
            adv_config_done &= (~ADV_CONFIG_FLAG);
            if (adv_config_done == 0){
                esp_ble_gap_start_advertising(&ble_adv_params);
            }
            break;
        case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
            adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
            if (adv_config_done == 0){
                esp_ble_gap_start_advertising(&ble_adv_params);
            }
            break;
  //  #endif
        case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
            /* advertising start complete event to indicate advertising start successfully or failed */
            if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(FLOW_SERVICE, "advertising start failed");

            }else{
               // ESP_LOGI(FLOW_SERVICE, "advertising start successfully");
            }


            break;
        case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
            if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(FLOW_SERVICE, "advertising stop failed");
            }
            else {
                ESP_LOGI(FLOW_SERVICE, "stop adv successfully\n");
            }
            break;
        case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT://连接完成事件
        /*    ESP_LOGI(FLOW_SERVICE, "status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
                  param->update_conn_params.status,
                  param->update_conn_params.min_int,
                  param->update_conn_params.max_int,
                  param->update_conn_params.conn_int,
                  param->update_conn_params.latency,
                  param->update_conn_params.timeout);*/
            break;
        case ESP_GAP_BLE_AUTH_CMPL_EVT: {

            memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
            ESP_LOGI(FLOW_SERVICE, "remote BD_ADDR: %08x%04x",\
                    (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
                    (bd_addr[4] << 8) + bd_addr[5]);
            ESP_LOGI(FLOW_SERVICE, "address type = %d", param->ble_security.auth_cmpl.addr_type);
            ESP_LOGI(FLOW_SERVICE, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
            if(!param->ble_security.auth_cmpl.success) {
                ESP_LOGI(FLOW_SERVICE, "fail reason = 0x%x",param->ble_security.auth_cmpl.fail_reason);
                is_connected = false;
                printf("fail\n");
            }
            else
            {
            	printf("success\n");
            	is_connected = true;
            	show_bonded_devices();
            }

            break;
        }
        case ESP_GAP_BLE_KEY_EVT:
            //shows the ble key info share with peer device to the user.
        	// esp_bd_addr_t bd_addr1;
        	            memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
        	            ESP_LOGI(FLOW_SERVICE, "remote BD_ADDR: %08x%04x",\
        	                    (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
        	                    (bd_addr[4] << 8) + bd_addr[5]);
        	            ESP_LOGI(FLOW_SERVICE, "address type = %d", param->ble_security.auth_cmpl.addr_type);
        	            ESP_LOGI(FLOW_SERVICE, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
            if(!param->ble_security.auth_cmpl.success) {
                ESP_LOGI(FLOW_SERVICE, "fail reason = 0x%x",param->ble_security.auth_cmpl.fail_reason);
                is_connected = false;
                printf("fail\n");
            }
            else
            {
            	printf("success\n");
            	is_connected = true;
            	//show_bonded_devices();
            }
            show_bonded_devices();
           // ESP_LOGI(FLOW_SERVICE, "key type = %s", esp_key_type_to_str(param->ble_security.ble_key.key_type));
            break;
        case ESP_GAP_BLE_PASSKEY_REQ_EVT:                           /* passkey request event */
            //ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_PASSKEY_REQ_EVT");
            //esp_ble_passkey_reply(heart_rate_profile_tab[HEART_PROFILE_APP_IDX].remote_bda, true, 0x00);
            break;
        case ESP_GAP_BLE_OOB_REQ_EVT:                                /* OOB request event */
            //ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_OOB_REQ_EVT");
            break;
        case ESP_GAP_BLE_LOCAL_IR_EVT:                               /* BLE local IR event */
            //ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_LOCAL_IR_EVT");
            break;
        case ESP_GAP_BLE_LOCAL_ER_EVT:                               /* BLE local ER event */
           // ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_LOCAL_ER_EVT");
            break;
        case ESP_GAP_BLE_NC_REQ_EVT:
            /* The app will receive this evt when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
            show the passkey number to the user to confirm it with the number displayed by peer deivce. */
            //ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_NC_REQ_EVT, the passkey Notify number:%d", param->ble_security.key_notif.passkey);
            break;
        case ESP_GAP_BLE_SEC_REQ_EVT:
            /* send the positive(true) security response to the peer device to accept the security request.
            If not accept the security request, should sent the security response with negative(false) accept value*/
            esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
            break;
        case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:  ///the app will receive this evt when the IO  has Output capability and the peer device IO has Input capability.
            ///show the passkey number to the user to input it in the peer deivce.
           // ESP_LOGI(FLOW_SERVICE, "The passkey Notify number:%d", param->ble_security.key_notif.passkey);
            break;

        case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
            //ESP_LOGD(FLOW_SERVICE, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
            ESP_LOGI(FLOW_SERVICE, "ESP_GAP_BLE_REMOVE_BOND_DEV");
            //ESP_LOGI(FLOW_SERVICE, "-----ESP_GAP_BLE_REMOVE_BOND_DEV----");
            esp_log_buffer_hex(FLOW_SERVICE, (void *)param->remove_bond_dev_cmpl.bd_addr, sizeof(esp_bd_addr_t));
            //ESP_LOGI(FLOW_SERVICE, "------------------------------------");
            break;
        }
        case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
            if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){
                ESP_LOGE(FLOW_SERVICE, "config local privacy failed, error status = %x", param->local_privacy_cmpl.status);
                break;
            }
            esp_err_t ret = esp_ble_gap_config_adv_data(&ble_uart_adv_data);
            if (ret){
                ESP_LOGE(FLOW_SERVICE, "config adv data failed, error code = %x", ret);
            }else{
                adv_config_done |= ADV_CONFIG_FLAG;
            }
            ret = esp_ble_gap_config_adv_data(&flow_sevice_adv_data);
            if (ret){
                ESP_LOGE(FLOW_SERVICE, "config adv data failed, error code = %x", ret);
            }else{
                adv_config_done |= SCAN_RSP_CONFIG_FLAG;
            }

        default:
            break;
    }
}

void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    ESP_LOGI(FLOW_SERVICE, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len);
    esp_gatt_status_t status = ESP_GATT_OK;
    if (prepare_write_env->prepare_buf == NULL) {
        prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
        prepare_write_env->prepare_len = 0;
        if (prepare_write_env->prepare_buf == NULL) {
            ESP_LOGE(FLOW_SERVICE, "%s, gatt_server prep no mem", __func__);
            status = ESP_GATT_NO_RESOURCES;
        }
    } else {
        if(param->write.offset > PREPARE_BUF_MAX_SIZE) {
            status = ESP_GATT_INVALID_OFFSET;
        } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
            status = ESP_GATT_INVALID_ATTR_LEN;
        }
    }
    /*send response when param->write.need_rsp is true */
    if (param->write.need_rsp){
        esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
        if (gatt_rsp != NULL){
            gatt_rsp->attr_value.len = param->write.len;
            gatt_rsp->attr_value.handle = param->write.handle;
            gatt_rsp->attr_value.offset = param->write.offset;
            gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
            memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
            esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
            if (response_err != ESP_OK){
               ESP_LOGE(FLOW_SERVICE, "send response error");
            }
            free(gatt_rsp);
        }else{
            ESP_LOGE(FLOW_SERVICE, "%s, malloc failed", __func__);
        }
    }
    if (status != ESP_GATT_OK){
        return;
    }
    memcpy(prepare_write_env->prepare_buf + param->write.offset,
           param->write.value,
           param->write.len);
    prepare_write_env->prepare_len += param->write.len;

}
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){
    if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC && prepare_write_env->prepare_buf){
        esp_log_buffer_hex(FLOW_SERVICE, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
    }else{
        ESP_LOGI(FLOW_SERVICE,"ESP_GATT_PREP_WRITE_CANCEL");
    }
    if (prepare_write_env->prepare_buf) {
        free(prepare_write_env->prepare_buf);
        prepare_write_env->prepare_buf = NULL;
    }
    prepare_write_env->prepare_len = 0;
}
static void flow_service_gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
	if(event!=5)
		{printf("flowevent = %d \n",event);}

	switch (event) {
		    case ESP_GATTS_REG_EVT:
		    {
				esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(BLE_DEVICE_NAME);
				if (set_dev_name_ret){
					ESP_LOGE(FLOW_SERVICE, "set device name failed, error code = %x", set_dev_name_ret);
				}
				//config adv data
				esp_err_t ret = esp_ble_gap_config_adv_data(&flow_sevice_adv_data);
				ESP_LOGI(BLE_UART_SERVICE, "ble_uart_adv_data");
				if (ret){
					ESP_LOGE(BLE_UART_SERVICE, "config adv data failed, error code = %x", ret);
				}
				adv_config_done |= ADV_CONFIG_FLAG;
				//config scan response data
				ret = esp_ble_gap_config_adv_data(&ble_uart_adv_data);
			   // ESP_LOGI(FLOW_SERVICE, "flow_sevice_adv_data");
				if (ret){
					ESP_LOGE(FLOW_SERVICE, "config scan response data failed, error code = %x", ret);
				}
				adv_config_done |= SCAN_RSP_CONFIG_FLAG;
				esp_ble_gap_config_local_privacy(true);
				esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(flow_service_gatt_db, gatts_if, HRS_IDX_NB, SVC_INST_ID);
				if (create_attr_ret){
					ESP_LOGE(FLOW_SERVICE, "create attr table failed, error code = %x", create_attr_ret);
				}
		    }
       	    break;
        case ESP_GATTS_READ_EVT:
           // ESP_LOGI(FLOW_SERVICE, "---ESP_GATTS_READ_EVT");
       	    break;
        case ESP_GATTS_WRITE_EVT:
        	
      	    break;
        case ESP_GATTS_EXEC_WRITE_EVT:
           // ESP_LOGI(FLOW_SERVICE, "ESP_GATTS_EXEC_WRITE_EVT");
            example_exec_write_event_env(&prepare_write_env, param);
            break;
        case ESP_GATTS_MTU_EVT:
        	//ESP_LOGI(FLOW_SERVICE,"ESP_GATTS_MTU_EVT");
           // ESP_LOGI(FLOW_SERVICE, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
            break;
        case ESP_GATTS_CONF_EVT:
          //  ESP_LOGI(FLOW_SERVICE, "ESP_GATTS_CONF_EVT, status = %d", param->conf.status);
            break;
        case ESP_GATTS_START_EVT:
           // ESP_LOGI(FLOW_SERVICE, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
            break;
        case ESP_GATTS_CONNECT_EVT:

            esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);

            break;
        case ESP_GATTS_DISCONNECT_EVT:
        	is_connected = false;
        	esp_ble_gatts_stop_service(flow_handle_table[SMART_FLOW_SVC]);
            //ESP_LOGI(FLOW_SERVICE, "ESP_GATTS_DISCONNECT_EVT, reason = %d", param->disconnect.reason);
           // esp_ble_gap_start_advertising(&ble_adv_params);
        /*	esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(BLE_DEVICE_NAME);
			if (set_dev_name_ret){
				ESP_LOGE(FLOW_SERVICE, "set device name failed, error code = %x", set_dev_name_ret);
			}*/
			//config adv data
			esp_err_t ret = esp_ble_gap_config_adv_data(&flow_sevice_adv_data);
			ESP_LOGI(BLE_UART_SERVICE, "ble_uart_adv_data");
			if (ret){
				ESP_LOGE(BLE_UART_SERVICE, "config adv data failed, error code = %x", ret);
			}
			adv_config_done |= ADV_CONFIG_FLAG;
			//config scan response data
			ret = esp_ble_gap_config_adv_data(&ble_uart_adv_data);
		   // ESP_LOGI(FLOW_SERVICE, "flow_sevice_adv_data");
			if (ret){
				ESP_LOGE(FLOW_SERVICE, "config scan response data failed, error code = %x", ret);
			}
			adv_config_done |= SCAN_RSP_CONFIG_FLAG;
			esp_ble_gap_config_local_privacy(true);
			esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(flow_service_gatt_db, gatts_if, HRS_IDX_NB, SVC_INST_ID);
							if (create_attr_ret){
								ESP_LOGE(FLOW_SERVICE, "create attr table failed, error code = %x", create_attr_ret);
							}
            break;
        case ESP_GATTS_CREAT_ATTR_TAB_EVT:{
        	//ESP_LOGI(FLOW_SERVICE,"ESP_GATTS_CREAT_ATTR_TAB_EVT");
           if (param->add_attr_tab.status != ESP_GATT_OK){
                ESP_LOGE(FLOW_SERVICE, "create attribute table failed, error code=0x%x", param->add_attr_tab.status);
            }
            else if (param->add_attr_tab.num_handle != HRS_IDX_NB){
                ESP_LOGE(FLOW_SERVICE, "create attribute table abnormally, num_handle (%d) \
                        doesn't equal to HRS_IDX_NB(%d)", param->add_attr_tab.num_handle, HRS_IDX_NB);
            }
            else {
               // ESP_LOGI(FLOW_SERVICE, "create attribute table successfully, the number handle = %d\n",param->add_attr_tab.num_handle);
                memcpy(flow_handle_table, param->add_attr_tab.handles, sizeof(flow_handle_table));
                esp_ble_gatts_start_service(flow_handle_table[SMART_FLOW_SVC]);
            }
            break;
        }
        case ESP_GATTS_STOP_EVT:break;
        case ESP_GATTS_OPEN_EVT:break;
        case ESP_GATTS_CANCEL_OPEN_EVT:break;
        case ESP_GATTS_CLOSE_EVT:break;
        case ESP_GATTS_LISTEN_EVT:break;
        case ESP_GATTS_CONGEST_EVT:break;
        case ESP_GATTS_UNREG_EVT:break;
        case ESP_GATTS_DELETE_EVT:break;
        default:
            break;
    }
}
void ble_uart_gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
	esp_err_t ret;
	printf("ble_uart_event = %d \n",event);

	switch (event) {
    case ESP_GATTS_REG_EVT:
       // ESP_LOGI(BLE_UART_SERVICE, "REGISTER_APP_EVT, status %d, app_id %d", param->reg.status, param->reg.app_id);
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.is_primary = true;
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.inst_id = 0x00;
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.uuid.len = ESP_UUID_LEN_128;
        for (uint8_t pos=0;pos<ESP_UUID_LEN_128;pos++) {
        	gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.uuid.uuid.uuid128[pos]=ble_service_uuid128[pos];
        }
        //esp_ble_gap_set_device_name(BLE_DEVICE_NAME);
       // ret=esp_ble_gap_config_adv_data(&ble_uart_adv_data);
      //  ESP_LOGI(BLE_UART_SERVICE, "esp_ble_gap_config_adv_data %d", ret);
        //esp_ble_gap_config_local_privacy(true);
        esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[BLE_UART_SERCIVE_ID].service_id, GATTS_NUM_HANDLE);
        break;
    case ESP_GATTS_READ_EVT: {
       // ESP_LOGI(BLE_UART_SERVICE, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle);
        gatts_check_callback(event, gatts_if, param);
        break;
    }
    case ESP_GATTS_WRITE_EVT: {
       // ESP_LOGI(BLE_UART_SERVICE, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle);
       // ESP_LOGI(BLE_UART_SERVICE, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value);
//       esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
        gatts_check_callback(event, gatts_if, param);
        break;
    }
    case ESP_GATTS_EXEC_WRITE_EVT:
    	break;
    case ESP_GATTS_MTU_EVT:
    	//ESP_LOGI(BLE_UART_SERVICE,"ESP_GATTS_MTU_EVT");
       //ESP_LOGI(BLE_UART_SERVICE, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
        break;
    case ESP_GATTS_CONF_EVT:
    	break;
    case ESP_GATTS_UNREG_EVT:
        break;
    case ESP_GATTS_CREATE_EVT:
        //ESP_LOGI(BLE_UART_SERVICE, "1-CREATE_SERVICE_EVT, status %d,  service_handle %d\n", param->create.status, param->create.service_handle);
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_handle = param->create.service_handle;
        gl_profile_tab[BLE_UART_SERCIVE_ID].char_uuid.len = ble_uart_char[0].char_uuid.len;
        gl_profile_tab[BLE_UART_SERCIVE_ID].char_uuid.uuid.uuid16 = ble_uart_char[0].char_uuid.uuid.uuid16;
        esp_ble_gatts_start_service(gl_profile_tab[BLE_UART_SERCIVE_ID].service_handle);
        gatts_add_char();
        break;
    case ESP_GATTS_ADD_INCL_SRVC_EVT:
        break;
    case ESP_GATTS_ADD_CHAR_EVT: {
       // ESP_LOGI(BLE_UART_SERVICE, "ADD_CHAR_EVT, status 0x%X,  attr_handle %d, service_handle %d\n",
       //         param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
        gl_profile_tab[BLE_UART_SERCIVE_ID].char_handle = param->add_char.attr_handle;
        if (param->add_char.status==ESP_GATT_OK) {
        	gatts_check_add_char(param->add_char.char_uuid,param->add_char.attr_handle);
        }
        break;
    }
    case ESP_GATTS_ADD_CHAR_DESCR_EVT:
        //ESP_LOGI(BLE_UART_SERVICE, "ADD_DESCR_EVT char, status %d, attr_handle %d, service_handle %d\n",
        //         param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
       // ESP_LOGI(BLE_UART_SERVICE, "ADD_DESCR_EVT desc, status %d, attr_handle %d, service_handle %d\n",
        //         param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
        if (param->add_char_descr.status==ESP_GATT_OK) {
        	gatts_check_add_descr(param->add_char.char_uuid,param->add_char.attr_handle);
        }
        break;
    case ESP_GATTS_DELETE_EVT:
        break;
    case ESP_GATTS_START_EVT:
        //ESP_LOGI(BLE_UART_SERVICE, "SERVICE_START_EVT, status %d, service_handle %d\n",
         //        param->start.status, param->start.service_handle);

        break;
    case ESP_GATTS_STOP_EVT:
        break;
    case ESP_GATTS_CONNECT_EVT:
    	 esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
        /*ESP_LOGI(BLE_UART_SERVICE, "SERVICE_START_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x: \n",
                 param->connect.conn_id,
                 param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
                 param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);*/
        //gl_profile_tab[BLE_UART_SERCIVE_ID].conn_id = param->connect.conn_id;
       // esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);

        break;
    case ESP_GATTS_DISCONNECT_EVT:
        is_connected = false;
        esp_ble_gatts_stop_service(gl_profile_tab[BLE_UART_SERCIVE_ID].service_handle);
        esp_ble_gap_start_advertising(&ble_adv_params);
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.is_primary = true;
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.inst_id = 0x00;
        gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.uuid.len = ESP_UUID_LEN_128;
        for (uint8_t pos=0;pos<ESP_UUID_LEN_128;pos++) {
        	gl_profile_tab[BLE_UART_SERCIVE_ID].service_id.id.uuid.uuid.uuid128[pos]=ble_service_uuid128[pos];
        }
        esp_ble_gatts_start_service(gl_profile_tab[BLE_UART_SERCIVE_ID].service_handle);
        break;
    case ESP_GATTS_OPEN_EVT:break;
    case ESP_GATTS_CANCEL_OPEN_EVT:break;
    case ESP_GATTS_CLOSE_EVT:break;
    case ESP_GATTS_LISTEN_EVT:break;
    case ESP_GATTS_CONGEST_EVT:break;
    default:
        break;
    }
}
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
    /* If event is register event, store the gatts_if for each profile */
    if (event == ESP_GATTS_REG_EVT) {
        if (param->reg.status == ESP_GATT_OK) {
            gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;

        } else {
            ESP_LOGI(BLE_UART_SERVICE, "Reg app failed, app_id %04x, status %d\n",
                    param->reg.app_id, 
                    param->reg.status);
            return;
        }
    }
    do {
        int idx;
        for (idx = 0; idx < PROFILE_NUM; idx++) {
            if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
                    gatts_if == gl_profile_tab[idx].gatts_if) {
                if (gl_profile_tab[idx].gatts_cb) {
                    gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
                }
            }
        }
    } while (0);
}

void main_app()
{


    esp_err_t ret;
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(BLE_UART_SERVICE, "%s init controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  /*  esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);///
    if (ret) {
        ESP_LOGE(BLE_UART_SERVICE, "%s initialize controller failed\n", __func__);
        return;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
    if (ret) {
        ESP_LOGE(BLE_UART_SERVICE, "%s enable controller failed\n", __func__);
        return;
    }*/
    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(BLE_UART_SERVICE, "%s init bluetooth failed\n", __func__);
        return;
    }
    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(BLE_UART_SERVICE, "%s enable bluetooth failed\n", __func__);
        return;
    }
    ret  = esp_ble_gatt_set_local_mtu(500);
    if (ret){
        ESP_LOGE(BLE_UART_SERVICE, "set local  MTU failed, error code = %x", ret);
    }
    esp_ble_gatts_register_callback(gatts_event_handler);
    esp_ble_gap_register_callback(gap_event_handler);
    esp_ble_gatts_app_register(PROFILE_FLOW_SERVICE_ID);
    esp_ble_gatts_app_register(BLE_UART_SERCIVE_ID);
    /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
    esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND;     //bonding with peer device after authentication
    esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;           //set the IO capability to No output No input
    uint8_t key_size = 8;      //the key size should be 7~16 bytes
    uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
    uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
    esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
    /* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribut to you,
    and the response key means which key you can distribut to the Master;
    If your BLE device act as a master, the response key means you hope which types of key of the slave should distribut to you,
    and the init key means which key you can distribut to the slave. */
    esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
    
    }
其中,配置文件
static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
[PROFILE_FLOW_SERVICE_ID] = {
.gatts_cb = flow_service_gatts_profile_event_handler,
.gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
},
[BLE_UART_SERCIVE_ID] = {
.gatts_cb = ble_uart_gatts_profile_event_handler, /* This demo does not implement, similar as profile A */
.gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
},
};
串口配置如下

Code: Select all

static struct gatts_char_inst ble_uart_char[GATTS_CHAR_NUM] = {
		{
				.char_uuid.len = ESP_UUID_LEN_128, // RX
				.char_uuid.uuid.uuid128 =  { 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E },
				.char_perm = ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,//ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
				.char_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
				.char_val = &RX_gatts_demo_char_val,
				.char_control = NULL,
				.char_handle = 0,
				.char_read_callback=RX_char_read_handler,
				.char_write_callback=RX_char_write_handler,
				//.descr_uuid.len = ESP_UUID_LEN_16,
				//.descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,//2902
				//.descr_perm=ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
				//.descr_val = NULL,//&RX_gatts_demo_descr_val,
				//.descr_control=NULL,
				//.descr_handle=0,
				//.descr_read_callback=RX_descr_read_handler,
				//.descr_write_callback=RX_descr_write_handler
		},
		{
				.char_uuid.len = ESP_UUID_LEN_128,  // TX
				.char_uuid.uuid.uuid128 =  { 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E },
				.char_perm = ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,//ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
				.char_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
				.char_val = &TX_gatts_demo_char_val,
				.char_control=NULL,
				.char_handle=0,
				.char_read_callback=TX_char_read_handler,
				.char_write_callback=TX_char_write_handler,
				/*.descr_uuid.len = ESP_UUID_LEN_16,
				.descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG, // ESP_GATT_UUID_CHAR_DESCRIPTION,
				.descr_perm=ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
				.descr_val = NULL,//&TX_gatts_demo_descr_val,
				.descr_control=NULL,
				.descr_handle=0,*/
				//.descr_read_callback=TX_descr_read_handler,
				//.descr_write_callback=TX_descr_write_handler
		}
};
另一个服务配置如下

Code: Select all

/* Full Database Description - Used to add attributes into the database */
static const esp_gatts_attr_db_t flow_service_gatt_db[HRS_IDX_NB] =
{
	// Service Declaration服务声明
	[SMART_FLOW_SVC]        =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
	sizeof(uint16_t), sizeof(SMART_FLOW_UUID), (uint8_t *)&SMART_FLOW_UUID}},
	/* Characteristic Declaration *///特征值声明
	[HEATER_CHAR_A]     =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
	sizeof(heater_temperature), sizeof(heater_temperature), (uint8_t *)&char_prop_read_notify_broadcast}},
	/* Characteristic Value */
	[HEATER_VALUE_A] =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&FLOW_VALUE_UUID, ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,//ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
	sizeof(heater_temperature), sizeof(heater_temperature), (uint8_t *)&heater_temperature}},
	/* Characteristic Declaration */
	[FLOW_CHAR_B]      =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
	sizeof(flow_value), sizeof(flow_value), (uint8_t *)&char_prop_read_notify_broadcast}},

	/* Characteristic Value */
	[FLOW_VALUE_B]  =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&HEATER_TEM_UUID, ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,//ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
	sizeof(flow_value), sizeof(flow_value), (uint8_t *)&flow_value}},
	/* Characteristic Declaration */
	[BATTERY_CHAR_C]      =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
	sizeof(battery_value), sizeof(battery_value), (uint8_t *)&char_prop_read_notify_broadcast}},

	/* Characteristic Value */
	[BATTERY_VALUE_C]  =
	{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&BATTARY_UUID, ESP_GATT_PERM_WRITE_ENCRYPTED|ESP_GATT_PERM_READ_ENCRYPTED,//ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
	sizeof(battery_value), sizeof(battery_value), (uint8_t *)&battery_value}},

};
不加密时,运行良好,现在要求连接通信过程进行加密,请问有什么方法?
出现的问题是,第一次连接时设备可以加密,如gatt_security_server一样,但断线重连之后就连接不上了。用nrf connect 连接也是一样。谢谢大家。
Daniel

Daniel
Posts: 28
Joined: Tue Jan 09, 2018 12:55 pm

Re: 如何为两个服务的蓝牙加密?

Postby Daniel » Thu Dec 13, 2018 1:03 am

如果问题过于复杂,那么我简单一点,如何把“gatt_server”https://github.com/espressif/esp-idf/tr ... att_server这个带有两个服务的蓝牙进行加密?

Weijian-Espressif
Posts: 29
Joined: Wed Aug 09, 2017 6:16 am

Re: 如何为两个服务的蓝牙加密?

Postby Weijian-Espressif » Mon Dec 17, 2018 6:22 am

hi 请参考gatt_security_server example , 加密成功以后蓝牙通信已经被加密了,底层数据交互是加密的, 设备收到数据后解密然后才传到应用层. 请用ihone 测试 gatt_security_server example, 我测试的结果是正常的. 如果你的测试结果依然有问题, 请提供你的测试log 和 你使用的IDF 的ccommit id, 谢谢.

ESP_Alvin
Posts: 195
Joined: Thu May 17, 2018 2:26 am

Re: 如何为两个服务的蓝牙加密?

Postby ESP_Alvin » Wed Jan 02, 2019 2:11 am

Hi, Daniel

Do you have more updates for this topic?

Thanks.

Daniel
Posts: 28
Joined: Tue Jan 09, 2018 12:55 pm

Re: 如何为两个服务的蓝牙加密?

Postby Daniel » Thu Feb 21, 2019 1:42 am

ESP_Alvin wrote:
Wed Jan 02, 2019 2:11 am
Hi, Daniel

Do you have more updates for this topic?

Thanks.
gatt_security_server example 例程是单个服务,这个我已经能做到,但是对于“gatt_server”“https://github.com/espressif/esp-idf/tr ... att_server”这个带有两个服务的例程来说,加密对我们来说就显得有点过于复杂,摸不着头脑了。如果这个“gatt_server”例程可以加密,那我的问题就解决了。
谢谢

Daniel
Posts: 28
Joined: Tue Jan 09, 2018 12:55 pm

Re: 如何为两个服务的蓝牙加密?

Postby Daniel » Tue Mar 05, 2019 7:02 am

Daniel wrote:
Thu Feb 21, 2019 1:42 am
ESP_Alvin wrote:
Wed Jan 02, 2019 2:11 am
Hi, Daniel

Do you have more updates for this topic?

Thanks.
gatt_security_server example 例程是单个服务,这个我已经能做到,但是对于“gatt_server”“https://github.com/espressif/esp-idf/tr ... att_server”这个带有两个服务的例程来说,加密对我们来说就显得有点过于复杂,摸不着头脑了。如果这个“gatt_server”例程可以加密,那我的问题就解决了。
谢谢


这是我问问题的答案!https://github.com/DanielXie00/gatt_server_3.1.1

Who is online

Users browsing this forum: No registered users and 35 guests