移动端开发进阶之蓝牙通讯(一)

移动端开发进阶之蓝牙通讯(一)

移动端进阶之蓝牙通讯需要综合考虑蓝牙版本选择、协议栈使用、服务匹配、设备连接、安全性和硬件支持等方面。
移动端

一、蓝牙版本选择

根据实际需求和应用场景选择合适的蓝牙版本;
1.0,1M/s。
2.0+EDR,2-3M/s,增加了简易配对的功能。
3.0+HS,24M/s-Generic Alternate MAC/PHY(AMP),支持802.11高速数据传输。
4.0,引入低功耗蓝牙BLE,适用于不需占用太多带宽的设备连接。
5.0,提升BLE的性能,增加了广播容量,扩大通信距离和速度。
5.1,增加定向定位和角度测量的功能。
5.2,增加多音频和低复杂度通信编码(LC3)的功能,可实现更好的音质和更低的功耗。
5.3,完善了BLE的周期性广播、连接更新、频道分级等功能,提高通讯效率、降低功耗并提高无线共存性。移除了AMP,不再支持24M/s。
5.4,新增带响应的周期性广播,带加密的EIR、广播数据加密、Host支持Advertising Coding选择等。
蓝牙版本

选择蓝牙版本时,主要应考虑以下几点:
蓝牙应用的需求:不同的蓝牙应用需要不同的蓝牙版本。例如,对于需要传输大量数据的应用,应选择蓝牙5.0或更高版本,因为它们提供了更高的传输速率和更低的功耗。而对于需要音频传输的应用,蓝牙4.0或更高版本即可满足需求。
设备兼容性:不同版本的蓝牙具有不同的兼容性。如果设备需要与其他蓝牙设备进行通信,应选择与这些设备兼容的蓝牙版本。
成本:不同版本的蓝牙模块成本不同。蓝牙5.0模块的成本高于蓝牙4.0模块,因此在预算有限的情况下,可以选择更低版本的蓝牙。
开发难度:不同版本的蓝牙模块开发难度不同。蓝牙5.0模块的开发难度高于蓝牙4.0模块,因此对于开发能力有限的企业或个人,可以选择更低版本的蓝牙。

二、蓝牙协议栈

蓝牙协议栈(Bluetooth Protocol Stack)是实现蓝牙通信的一组协议的集合,它定义了蓝牙设备之间如何进行数据传输和通信;
蓝牙协议栈包括多个层次,每个层次都有不同的功能和职责;
常见的蓝牙协议栈包括BlueCore、CSR8670/CSR8675和RTKBT11等。
蓝牙

物理层(Physical Layer):物理层负责无线信号的传输,包括信号的调制、解调、频率选择等。
数据链路层(Link Layer):数据链路层负责数据的打包和解包,以及设备间的连接和断开。它还负责处理数据传输中的错误检测和纠正。
网络层(Network Layer):网络层负责设备的寻址和连接管理,包括设备间的安全连接和数据传输。
传输层(Transport Layer):传输层负责数据的分段和重组,以及数据传输的可靠性和流量控制。
应用层(Application Layer):应用层负责提供各种蓝牙服务,如音频传输、文件传输、设备控制等。

BLUECORE(蓝牙核心动力)

这是长安汽车集团推出的高效节能环保动力总成(发动机+变速箱)的解决方案。BLUECORE 涵盖了长安汽车自主研发的多种技术,如TEi、GDi、D-VVT、TC、新能源等,致力于提供纯净、清新的动力系统。

CSR8670/CSR8675

这是CSR(Cambridge Silicon Radio)公司推出的蓝牙音频解决方案芯片。其中,CSR8670是CSR 86xx系列中的高级闪存产品,旨在提供高质量的无线音频性能并支持高差异优质无线音频产品的开发。而CSR8675是一款先进的蓝牙音频解决方案芯片,具有出色的音质表现,采用了aptX高清音频编解码器技术,可以在传输过程中保持音频的高质量。

RTKBT11

这是一款蓝牙模块,符合蓝牙5.0标准,支持经典蓝牙和低功耗蓝牙双模工作模式。该模块具有高性能、低功耗、易于集成等特点,适用于各种需要蓝牙连接的应用场景。

移动端开发通常使用的是Bluetooth Low Energy(BLE),常用的支持BLE的协议栈包括:
BlueZ:BlueZ是Linux操作系统下的开源蓝牙协议栈,支持蓝牙经典(Classic)和低功耗(Low Energy)两种模式。它是Linux下开发蓝牙应用程序的主要协议栈之一。
Windows Bluetooth API:Windows操作系统提供了对蓝牙的支持,包括对BLE的支持。Windows Bluetooth API提供了用于开发蓝牙应用程序的接口和协议栈。
Nordic Semiconductor SDK:Nordic Semiconductor是一家专注于蓝牙低功耗技术的芯片厂商,提供了针对其蓝牙SoC的软件开发套件(SDK),其中包括了完整的蓝牙协议栈和工具链,支持BLE和其他蓝牙技术。
CSR BLE SDK:CSR(Cambridge Silicon Radio)是一家提供蓝牙技术的芯片厂商,也提供了针对其蓝牙SoC的软件开发套件,支持BLE和其他蓝牙技术。

其中使用最多的就是CSR提供的CSR8670/CSR8675。

三、蓝牙服务

移动端需要提供或发现蓝牙服务,并进行服务匹配;
常见的蓝牙服务包括音频服务、文件传输服务、网络服务等;
需要了解并实现这些服务的通讯协议和逻辑。
蓝牙音频服务

蓝牙音频服务

在蓝牙音频服务中,主要有以下几个规范和协议:
A2DP(Advanced Audio Distribution Profile):这是一个专注于音频流传输的规范。它允许传输立体声音频信号,是蓝牙音频传输中的重要组成部分。典型的应用场景是将音乐内容从立体声音乐播放器流式传输到耳机或扬声器。音频数据以适当的格式压缩,以提高效率并使用有限的带宽。
HFP(Hands-free Profile):这是一个基于SCO(Synchronous Connection Oriented)链路的规范,用于双向传输通话语音。它让蓝牙设备可以控制电话,如接听、挂断、拒接、语音拨号等。
AVRCP(Audio/Video Remote Control Profile):这是一个用于远程控制音频和视频播放的规范。通过这个协议,用户可以通过无线方式控制音乐播放器和其他音频设备的基本操作,例如播放、暂停、下一曲和音量控制等。
aptX、aptX-HD和aptX voice:这些都是用于提升蓝牙音频质量的协议。它们通过不同的参数(如16bit/48k、24bit/48k和16bit/32k)提供更高质量的音频传输。
ANC(Active Noise Cancellation):这是一种主动降噪功能,通过消除外部噪音来提高音频质量。
TWS(True Wireless Stereo):这是一种蓝牙无线耳机技术,允许两个耳机在没有有线连接的情况下进行通信,从而提供真正的立体声体验。

四、蓝牙设备连接

移动端需要建立与蓝牙设备的连接,并进行数据传输。需要了解并实现连接的建立、管理和断开逻辑,以及数据传输的协议和流程。
例如在iOS开发中建立蓝牙连接的步骤如下:

  1. 导入蓝牙框架:在项目中使用蓝牙功能,需要导入CoreBluetooth框架。
  2. 创建CBCentralManager实例:CBCentralManager是iOS中用于管理蓝牙的中心管理者,负责扫描、连接和与外围设备的通信。
  3. 配置CBCentralManagerDelegate和CBPeripheralDelegate协议:需要遵守这两个协议,以便在蓝牙连接过程中处理相关事件。
  4. 初始化CBCentralManager:创建一个CBCentralManager实例,并传入self来遵守CBCentralManagerDelegate协议。
  5. 启动CBCentralManager:调用CBCentralManager的startScan方法开始扫描附近的蓝牙设备。
  6. 发现外围设备:当扫描到周围有可连接的蓝牙设备时,CBCentralManager会调用其代理方法并传入CBPeripheral对象。
  7. 连接外围设备:使用CBPeripheral对象的connect方法来连接指定的外围设备。
  8. 获取外围设备的服务:连接成功后,可以通过CBPeripheral对象获取外围设备提供的服务。
  9. 获取服务的特征:从服务中获取特征,这些特征用于读写数据。
  10. 读取和写入数据:通过特征值进行数据的读写操作。

五、蓝牙安全

移动端需要考虑蓝牙通讯的安全性。由于蓝牙通讯是一种无线通讯方式,容易被截获或干扰,因此需要进行安全设置和保护。需要了解并实现安全设置和保护的逻辑,如加密、认证等。
加解密

#include <iostream>  
#include <string>  
#include <cryptopp/aes.h>  
#include <cryptopp/modes.h>  
#include <cryptopp/filters.h>  
  
std::string EncryptAES(const std::string& plainText, const std::string& key) {  
    CryptoPP::AES::Encryption aesEncryption(key.begin(), key.end());  
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, key.begin());  
  
    std::string cipherText;  
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(cipherText));  
    stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plainText.c_str()), plainText.length() + 1);  
    stfEncryptor.MessageEnd();  
  
    return cipherText;  
}  
  
std::string DecryptAES(const std::string& cipherText, const std::string& key) {  
    CryptoPP::AES::Decryption aesDecryption(key.begin(), key.end());  
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, key.begin());  
  
    std::string plainText;  
    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(plainText));  
    stfDecryptor.Put(reinterpret_cast<const unsigned char*>(cipherText.c_str()), cipherText.size());  
    stfDecryptor.MessageEnd();  
  
    return plainText;  
}
#include <iostream>  
#include <string>  
#include <cryptopp/sha.h>  
#include <cryptopp/hex.h>  
#include <cryptopp/modes.h>  
#include <cryptopp/filters.h>  
  
std::string sha256(const std::string& data) {  
    CryptoPP::SHA256 sha;  
    byte digest[CryptoPP::SHA256::DIGESTSIZE];  
    sha.CalculateDigest(digest, reinterpret_cast<const byte*>(data.c_str()), data.size());  
  
    std::string hash;  
    CryptoPP::HexEncoder encoder;  
    encoder.Attach(new CryptoPP::StringSink(hash));  
    encoder.Put(digest, sizeof(digest));  
    encoder.MessageEnd();  
  
    return hash;  
}  
  
std::string encryptSha(const std::string& plainText, const std::string& key) {  
    CryptoPP::AES::Encryption aesEncryption(key.begin(), key.end());  
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, key.begin());  
  
    std::string cipherText;  
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(cipherText));  
    stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plainText.c_str()), plainText.size());  
    stfEncryptor.MessageEnd();  
  
    std::string encryptedHash = sha256(cipherText);  
    return encryptedHash;  
}  
  
std::string decryptSha(const std::string& cipherText, const std::string& key) {  
    std::string decryptedText = cipherText; // Assuming the SHA256 hash is the only encrypted data here.  
  
    CryptoPP::AES::Decryption aesDecryption(key.begin(), key.end());  
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, key.begin());  
  
    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedText));  
    stfDecryptor.Put(reinterpret_cast<const unsigned char*>(decryptedText.c_str()), decryptedText.size());  
    stfDecryptor.MessageEnd();  
  
    std::string decryptedHash = sha256(decryptedText); // Decrypted text should match the original hash.  
    return decryptedHash;  
}

校验

#include <bluetooth/bluetooth.h>  
  
uint16_t crc16(const uint8_t *data, size_t len) {  
    uint16_t crc = 0xFFFF;  
    const uint8_t *ptr = data;  
  
    while (len--) {  
        crc ^= (*ptr++) << 8;  
        for (int i = 0; i < 8; i++) {  
            if (crc & 0x8000) {  
                crc = (crc << 1) ^ 0x1021; // Polynomial 0x1021 (CRC-CCITT)  
            } else {  
                crc <<= 1;  
            }  
        }  
    }  
  
    return crc & 0xFFFF;  
}

六、蓝牙硬件支持

移动端需要使用合适的蓝牙硬件模块来支持蓝牙通讯。常见的蓝牙硬件模块包括CSR、Broadcom、Freescale等厂商提供的模块。需要了解并选择适合自己应用的蓝牙硬件模块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/322517.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

细说JavaScript函数(JavaScript函数详解)

函数的作用就是封装一段JavaScript代码&#xff0c;让开发者可以通古简单的方式使用这段代码 一、函数的分类 在几乎所有的编程语言中&#xff0c;都有函数这一概念&#xff0c;并且没中语言本身都继承了丰富的函数&#xff0c;这类函数被称为系统函数或者内置函数&#xff0…

vue:使用【3.0】:条件模块

一、条件层级效果图 二、代码 <template><ContentWrap><!-- 添加条件分支:level1 --><div class"btnBox" v-if"isEdit"><el-button type"primary" click"add">添加条件分支</el-button></div…

YOLOv8改进 | 细节涨点篇 | UNetv2提出的一种SDI多层次特征融合模块(分割高效涨点)

一、本文介绍 本问给大家带来的改进机制是UNetv2提出的一种多层次特征融合模块(SDI)其是一种用于替换Concat操作的模块,SDI模块的主要思想是通过整合编码器生成的层级特征图来增强图像中的语义信息和细节信息。该方法已在多个公开的医学图像分割数据集上进行了验证,包括皮…

HANA:传参,游标(Cursor)应用,FOR循环,解决存储表内存溢出的问题

作者 idan lian 如需转载备注出处 1.应用场景 最近项目上用HANA开发的比较多&#xff0c;之前我是bw用的比较多&#xff0c;就不会有这种问题。我们这个项目很多都是开发的计算视图&#xff0c;但最近做acdoca的逻辑时&#xff0c;计算视图在生产环境执行的时候报错&#xf…

阿里巴巴分拆业务板块,中台架构已经死了吗?

阿里巴巴集团董事会主席兼首席执行官张勇发布全员信&#xff0c;宣布启动“16N”组织变革。在阿里巴巴集团之下&#xff0c;将设立阿里云智能、淘宝天猫商业、本地生活、菜鸟、国际数字商业、大文娱等六大业务集团和多家业务公司。 业务集团和业务公司分别成立董事会&#xff…

基于电源完整性的一些PCB设计建议

基于电源完整性的一些PCB设计建议 1. 尽量减少电源和地通路之间的环路电感&#xff0c;在相邻的层上分配电源和接地面时&#xff0c;使用尽可能薄的电介质&#xff1b; 2. 通过在平面之间使用尽可能高的介电常数来获得平面之间的最低阻抗&#xff0c;与尽可能薄的介电常数设计…

深入理解 Flink(七)Flink Slot 管理详解

1.JobMaster 注册成功之后开始调度 JobMaster 中封装了一个 DefaultScheduler&#xff0c;在 DefaultScheduler.startSchedulingInternal() 方法中生成 ExecutionGraph 以执行调度。 2.Flink 的资源管理机制 资源调度的大体流程如下&#xff1a; a.TaskExecutor 注册 Reg…

从CISC到RISC-V:揭开指令集的面纱

对于大多数同学来说&#xff0c;计算机或智能手机的运行似乎就像魔法一样神奇。你可能知道它们内部都是一些复杂的电子组件&#xff0c;比如CPU、内存等等&#xff0c;但这些组件是如何协同工作&#xff0c;让我们可以在电脑上打字&#xff0c;或者在手机上看视频呢&#xff1f…

matplotlib绘制动态瀑布图

绘制瀑布图思路&#xff1a;遍历指定文件目录下所有的csv文件&#xff0c;每读一个文件&#xff0c;取文件前20行数据进行保存&#xff0c;如果超过规定的行数300行&#xff0c;将最旧的数据删除&#xff0c;仅保留300行数据进行展示。 网上找的大部分绘制瀑布图的代码&#x…

ssh远程登录协议 搞定远程访问控制

远程管理linux系统基本上都要使用到ssh&#xff0c;原因很简单&#xff1a;telnet、FTP等传输方式是以明文传送用户认证信息&#xff0c;本质上是不安全的&#xff0c;存在被网络窃听的危险。SSH&#xff08;Secure Shell&#xff09;目前较可靠&#xff0c;是专为远程登录会话…

走迷宫(c语言)

前言&#xff1a; 制作一个迷宫游戏是一个有趣的编程挑战。首先&#xff0c;我们需要设计一个二维数组来表示迷宫的布局&#xff0c;其中每个元素代表迷宫中的一个格子。我们可以使用不同的值来表示空格、墙壁和起点/终点。接下来&#xff0c;我们需生成迷宫。在生成迷宫的过程…

智能手表喇叭无气孔导致老化播放后没声音

智能音箱喇叭老化播放后没声音 智能手表要做防水&#xff0c;在外壳上打了防水胶&#xff0c;结果出现播放突然没声音的现象&#xff0e; 原因 一直播放&#xff0c;设备温度升高&#xff0c;因为做了防水密闭导致喇叭腔体气压异常&#xff0c;导致播放没声音&#xff0e; …

nginx入门学习

nginx简介 nginx 是什么?用来干嘛的 通俗解释&#xff1a;客户端向服务器请求时&#xff0c;提供让多个服务器一起处理请求的东西 是一个反向代理服务器&#xff0c;能够提供负载均衡&#xff0c;和进行反向代理的功能 正向代理&反向代理 客户端向代理服务器请求&#…

短剧分销系统,助力短剧市场发展,实现短剧收益

近几年来&#xff0c;我国短剧兴起&#xff0c;在经过几年的蓄力后迎来了爆发期&#xff0c;短剧市场规模一路狂飙&#xff01;短剧拥有节奏快、剧情“爽”的优势&#xff0c;成功占领了各大观众的碎片化时间&#xff0c;短剧已经成为了影视行业的新力量&#xff0c;也成为了当…

微服务概述之微服务特性

前言 既然系统采用了微服务架构&#xff0c;就需要了解一些微服务的特性&#xff0c;这样在进行微服务开发时&#xff0c;脑海中才会有一些指导方向。微服务具有以下特性。 1. 服务组件化 组件是独立、可替换、可升级的软件的单元。将整体应用拆分成独立的服务组件后&#xff…

嵌入式软件开发对硬件知识的掌握要求要多高?

嵌入式软件开发对硬件知识的掌握要求要多高&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff0…

并发编程(一)线程基础知识与线程控制

进程与线程 进程&#xff1a;如任务管理器中各种程序叫做正在运行的进程。对于操作系统来说&#xff0c;仅仅是一个数据结构&#xff0c;并不真实的执行代码 线程&#xff1a;真实执行代码的 每个进程启动的是时候会同步启动一个主线程即main函数&#xff0c;当main函数结束…

倒F天线设计经验分享

一、IFA天线理论分析 为了改善&#xff29;&#xff2c;&#xff21;天线难以使用的缺点&#xff0c;在&#xff29;&#xff2c;&#xff21;天线的基础上再增加一个倒L结构&#xff0c;形成IFA天线&#xff0c;此种天线体积小、易于匹配并具有双极化的特点&#xff0c;而在蓝…

帆软报表11.0.19增加postgres数据源方案

项目使用postgres数据库&#xff0c;帆软报表集成开发时需要手工增加该数据源。 https://help.fanruan.com/finereport/doc-view-2563.html 但增加数据源后测试报告无此驱动&#xff0c;经查看文档&#xff0c;现在是通过驱动管理来上传&#xff0c; 但新版又不允许上传驱动JAR…

外贸群发邮件最好的软件?群发软件哪个好?

外贸开发信群发软件推荐&#xff1f;做外贸用什么邮件群发软件&#xff1f; 在外贸业务中&#xff0c;与潜在客户建立联系并保持沟通是至关重要的。那么&#xff0c;如何快速有效地发送邮件给大量的潜在客户呢&#xff1f;这就涉及到了外贸群发邮件。蜂邮EDM来探讨一下&#x…