当前位置: 首页 > news >正文

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

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发送加密后的音频数据。

相关文章:

  • spring boot前后端开发上传文件时报413(Request Entity Too Large)错误的可能原因及解决方案
  • 统计局数据分析网站基于Spring Boot SSM原创
  • 各种环境下安装软件的命令对比与总结
  • 算法导论(动态规划)——简单多状态
  • Docker学习--容器操作相关命令--docker wait 命令
  • k8s EmptyDir(空目录)详解
  • C#测试Excel开源组件ExcelDataReader
  • 为什么可视化大屏越来越多应用3D元素呢?
  • Android 11.0 framework中增加开启和关闭飞行模式的接口
  • 使用Redis实现轻量级消息队列
  • C++位运算精要:高效解题的利器
  • Elasticsearch笔记
  • 一个极简的词法分析器实现
  • OpenCV 图形API(6)将一个矩阵(或图像)与一个标量值相加的函数addC()
  • Pycharm(十一):字符串练习题
  • PHP 开发API接口签名验证
  • 翻译: 人工智能如何让世界变得更美好二
  • 链表算法的技巧和方法
  • 移动零+复写零+快乐数+盛最多水的容器+有效三角形的个数
  • 智能导诊系统的技术体系组成
  • 男男做暧网站免费/关键词优化公司电话
  • b2b网站推广方法/竞价专员是做什么的
  • 西安网站建设工作室/制作网站的基本步骤
  • 安徽网站建设公司/佛山本地网站建设
  • 哪个市文化和旅游网站做的好/北京seo编辑
  • 淘客网站怎么做/推广引流方法有哪些推广方法