一、SDK版本和例子
- 这里采用的SDK版本为
4.4
版本 - 从机例子:
esp-idf-4.4/examples/bluetooth/bluedroid/ble/gatt_server
- 主机例子:
esp-idf-4.4/examples/bluetooth/bluedroid/ble/gatt_client
二、注意事项
- 最大链接数,为
9
个,无论是一主多从,还是一从多主,这是和ble的 controller 相关的,具体可以看看 issue https://github.com/espressif/esp-idf/issues/3924 - 可以多个设备对一个profile进行操作,通过
conn_id
可以进行 读 写 notify/indicate 的区分 - 从机在被一个主机连接后,会自动关掉广播,这里需要重新手动打开,保证一直有广播,主机连接分机,必须要先经过广播的阶段
三、从机修改
-
memnuconfig设置最大连接数为9
-
去掉一个profile ,这里我只保留一个,这里注释2个地方,(非必要,只是为了简单)
tab去掉第二个
/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */ static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = { [PROFILE_A_APP_ID] = { .gatts_cb = gatts_profile_a_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ }, // [PROFILE_B_APP_ID] = { // .gatts_cb = gatts_profile_b_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 */ // }, };
不注册第二个APP
ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID); if (ret){ ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); return; } /* ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID); if (ret){ ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); return; } */ esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); if (local_mtu_ret){ ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret); }
-
连接成功后,重新打开广播(必须)
case ESP_GATTS_CONNECT_EVT: { esp_ble_conn_update_params_t conn_params = {0}; memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */ conn_params.latency = 0; conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms conn_params.timeout = 400; // timeout = 400*10ms = 4000ms ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:", 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[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; //start sent the update connection parameters to the peer device. esp_ble_gap_update_conn_params(&conn_params); esp_ble_gap_start_advertising(&adv_params);//重新打开adv break; }