You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BluetoothGatt.writeCharacteristic返回201错误,ESP32未收到BLE写入数据

问题分析与解决方案

错误码201对应GATT_INVALID_ATTRIBUTE_LENGTH,说明写入的数据长度超出了BLE特征允许的最大长度限制,以下是针对性排查和解决步骤:

1. 调整ESP32特征的长度配置

ESP32默认BLE特征的最大数据长度为20字节(MTU默认23,扣除3字节ATT协议头),如果加密后的会话密钥长度超过这个值,会直接触发201错误。
修改ESP32端代码,手动设置特征的最大支持长度:

caracteristicRecive=service->createCharacteristic(CHARACTERISTIC_UUID_2 , 
  BLECharacteristic::PROPERTY_READ |
  BLECharacteristic::PROPERTY_WRITE|
  BLECharacteristic::PROPERTY_NOTIFY |
  BLECharacteristic::PROPERTY_INDICATE);
// 设置特征最大支持长度,示例为64字节,可按需调整
caracteristicRecive->setLength(64);
BLE2902 * desc= new BLE2902();
desc->setNotifications(true);
caracteristicRecive->addDescriptor(desc); 
caracteristicRecive->setCallbacks(new MyCharacteristicCallback());

2. 主动协商BLE MTU

Android默认不会自动协商更大的MTU,需要主动请求扩展MTU以支持更大数据传输:

  • 在连接成功后(比如onConnectionStateChange回调中状态为BluetoothProfile.STATE_CONNECTED时)调用MTU请求:
    btGatt.requestMtu(256); // 请求256字节MTU,可根据需求调整
    
  • 重写onMtuChanged回调,确认MTU协商成功后再执行写入操作:
    @Override
    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
      super.onMtuChanged(gatt, mtu, status);
      if (status == BluetoothGatt.GATT_SUCCESS) {
        // MTU协商成功后执行写入逻辑
        if(!aes.createSessionKey()) disconnect();    
        int res=btGatt.writeCharacteristic(characteristicSend, aes.encrypt(aes.sesKey), BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
        Log.d("data",String.valueOf(res));
      }
    }
    

3. 检查加密后数据的实际长度

计算aes.encrypt(aes.sesKey)返回的字节数组长度,确保不超过MTU - 3(ATT协议头占用3字节)。比如MTU为256时,最大可写入253字节数据。

4. 验证ESP32端回调实现

确认MyCharacteristicCallback的onWrite方法正确重写,避免因回调未实现导致误以为未收到数据:

class MyCharacteristicCallback : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) override {
    std::string receivedData = pCharacteristic->getValue();
    Serial.print("Received data length: ");
    Serial.println(receivedData.length());
    Serial.print("Received data: ");
    for (uint8_t c : receivedData) {
      Serial.printf("%02X ", c);
    }
    Serial.println();
  }
};

5. 尝试切换写入类型

暂时将写入类型改为带响应的WRITE_TYPE_DEFAULT,获取更明确的错误反馈,排查无响应写入的兼容性问题:

int res=btGatt.writeCharacteristic(characteristicSend, aes.encrypt(aes.sesKey), BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);

内容的提问来源于stack exchange,提问作者Andrei S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:22:44