小智机器人关键函数解析:MqttProtocol::SendAudio()对输入的音频数据进行加密处理,通过UDP发送加密后的音频数据

发布于:2025-04-01 ⋅ 阅读:(57) ⋅ 点赞:(0)

MqttProtocol::SendAudio()对输入的音频数据进行加密处理,通过UDP发送加密后的音频数据。
源码:

void MqttProtocol::SendAudio(const std::vector<uint8_t>& data) {
    // 使用互斥锁保护临界区,确保同一时间只有一个线程可以访问该函数内的共享资源
    std::lock_guard<std::mutex> lock(channel_mutex_);
    // 检查udp_指针是否为空,如果为空则直接返回,避免后续操作出现空指针异常
    if (udp_ == nullptr) {
        return;
    }

    // 复制aes_nonce_到nonce字符串中,用于后续加密操作
    std::string nonce(aes_nonce_);
    // 将音频数据的大小(以网络字节序)存储到nonce字符串的第2个字节开始的位置
    *(uint16_t*)&nonce[2] = htons(data.size());
    // 将本地序列号(以网络字节序)存储到nonce字符串的第12个字节开始的位置,并递增本地序列号
    *(uint32_t*)&nonce[12] = htonl(++local_sequence_);

    // 创建一个字符串encrypted,用于存储加密后的数据,其大小为nonce的大小加上音频数据的大小
    std::string encrypted;
    encrypted.resize(aes_nonce_.size() + data.size());
    // 将nonce数据复制到encrypted字符串的开头
    memcpy(encrypted.data(), nonce.data(), nonce.size());

    // 初始化计数器偏移量
    size_t nc_off = 0;
    // 初始化一个16字节的流块,用于AES加密
    uint8_t stream_block[16] = {0};
    // 使用AES-CTR模式对音频数据进行加密
    if (mbedtls_aes_crypt_ctr(&aes_ctx_, data.size(), &nc_off, (uint8_t*)nonce.c_str(), stream_block,
        (uint8_t*)data.data(), (uint8_t*)&encrypted[nonce.size()]) != 0) {
        // 如果加密失败,记录错误日志并返回
        ESP_LOGE(TAG, "Failed to encrypt audio data");
        return;
    }
    // 通过UDP发送加密后的音频数据
    udp_->Send(encrypted);
}

以下是对 MqttProtocol::SendAudio 函数的详细解释:

函数概述

MqttProtocol::SendAudio 函数的主要功能是对输入的音频数据进行加密处理,然后通过UDP(User Datagram Protocol)发送加密后的音频数据。

代码详细解释

void MqttProtocol::SendAudio(const std::vector<uint8_t>& data) {
    // 使用互斥锁保护临界区,确保同一时间只有一个线程可以访问该函数内的共享资源
    std::lock_guard<std::mutex> lock(channel_mutex_);
    // 检查udp_指针是否为空,如果为空则直接返回,避免后续操作出现空指针异常
    if (udp_ == nullptr) {
        return;
    }

    // 复制aes_nonce_到nonce字符串中,用于后续加密操作
    std::string nonce(aes_nonce_);
    // 将音频数据的大小(以网络字节序)存储到nonce字符串的第2个字节开始的位置
    *(uint16_t*)&nonce[2] = htons(data.size());
    // 将本地序列号(以网络字节序)存储到nonce字符串的第12个字节开始的位置,并递增本地序列号
    *(uint32_t*)&nonce[12] = htonl(++local_sequence_);

    // 创建一个字符串encrypted,用于存储加密后的数据,其大小为nonce的大小加上音频数据的大小
    std::string encrypted;
    encrypted.resize(aes_nonce_.size() + data.size());
    // 将nonce数据复制到encrypted字符串的开头
    memcpy(encrypted.data(), nonce.data(), nonce.size());

    // 初始化计数器偏移量
    size_t nc_off = 0;
    // 初始化一个16字节的流块,用于AES加密
    uint8_t stream_block[16] = {0};
    // 使用AES-CTR模式对音频数据进行加密
    if (mbedtls_aes_crypt_ctr(&aes_ctx_, data.size(), &nc_off, (uint8_t*)nonce.c_str(), stream_block,
        (uint8_t*)data.data(), (uint8_t*)&encrypted[nonce.size()]) != 0) {
        // 如果加密失败,记录错误日志并返回
        ESP_LOGE(TAG, "Failed to encrypt audio data");
        return;
    }
    // 通过UDP发送加密后的音频数据
    udp_->Send(encrypted);
}

各部分详细解释

  1. 互斥锁保护

    std::lock_guard<std::mutex> lock(channel_mutex_);
    

    使用 std::lock_guard 来自动管理 channel_mutex_ 互斥锁,确保同一时间只有一个线程可以访问该函数内的共享资源,避免数据竞争。

  2. 空指针检查

    if (udp_ == nullptr) {
        return;
    }
    

    检查 udp_ 指针是否为空,如果为空则直接返回,避免后续操作出现空指针异常。

  3. 准备加密参数

    std::string nonce(aes_nonce_);
    *(uint16_t*)&nonce[2] = htons(data.size());
    *(uint32_t*)&nonce[12] = htonl(++local_sequence_);
    
    • 复制 aes_nonce_nonce 字符串中。
    • 将音频数据的大小(以网络字节序)存储到 nonce 字符串的第2个字节开始的位置。
    • 将本地序列号(以网络字节序)存储到 nonce 字符串的第12个字节开始的位置,并递增本地序列号。
  4. 初始化加密结果字符串

    std::string encrypted;
    encrypted.resize(aes_nonce_.size() + data.size());
    memcpy(encrypted.data(), nonce.data(), nonce.size());
    
    • 创建一个字符串 encrypted,用于存储加密后的数据,其大小为 nonce 的大小加上音频数据的大小。
    • nonce 数据复制到 encrypted 字符串的开头。
  5. AES-CTR加密

    size_t nc_off = 0;
    uint8_t stream_block[16] = {0};
    if (mbedtls_aes_crypt_ctr(&aes_ctx_, data.size(), &nc_off, (uint8_t*)nonce.c_str(), stream_block,
        (uint8_t*)data.data(), (uint8_t*)&encrypted[nonce.size()]) != 0) {
        ESP_LOGE(TAG, "Failed to encrypt audio data");
        return;
    }
    
    • 初始化计数器偏移量 nc_off 和流块 stream_block
    • 使用 mbedtls_aes_crypt_ctr 函数对音频数据进行加密,将加密结果存储在 encrypted 字符串中。
    • 如果加密失败,记录错误日志并返回。
  6. 发送加密后的数据

    udp_->Send(encrypted);
    

    通过UDP发送加密后的音频数据。


网站公告

今日签到

点亮在社区的每一天
去签到