【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使专心得 (一)

打印 上一主题 下一主题

主题 991|帖子 991|积分 2973

【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使专心得(一)

     一、前言

     

     鸿蒙官网文档中蓝牙部分,对于之前没有开发过蓝牙的同学,使用和查阅起来不是很方便。由于只是API的调用阐明。并没有蓝牙整个调用流程的讲授,以是看起来会云里雾里。特别是针对低功耗蓝牙来说,对于寻常蓝牙,开发步调较少还好。
     在开发蓝牙和低功耗蓝牙之前,我们最好对蓝牙开发有肯定的基础认识,如许开发起来才气团体框架,知道本身在做什么,只是根据文档API的调用,很容易漏处理。
     本章主要讲授低功耗蓝牙BLE的开发调用,寻常蓝牙在之前的章节已经系统的讲过了。可以拜见,【HarmonyOS】鸿蒙应用蓝牙功能实现 (一,二,三)系列。
     二、BLE低功耗蓝牙的基础知识

     1.低功耗蓝牙是什么? 低功耗蓝牙(Bluetooth Low Energy,简称BLE)是蓝牙技术的一种变体,也被称为蓝牙4.0。BLE技术通过一系列的技术和优化措施,如减少广播频段和广播时射频开启时间、采用深度就寝状态(Duty-Cycle)、优化毗连机制等,明显低落了装备的功耗。这使得BLE装备在长时间运行下,电池寿命得到大大延长。比如智能穿着装备、智能家电、传感器等
     2.低功耗蓝牙与寻常蓝牙的区别是什么? 见名知意,在功耗上前者更为良好,并且易维护,非常得当对能耗敏感的场景。相比之下,寻常蓝牙的功耗较高。一旦激活,它就会始终保持毗连,比力耗能。因此,它主要应用在对功耗要求不高的装备上,如无线耳机、音箱、游戏手柄等。
     在广播信道上,前者为3,这有助于减少网络干扰并低落功耗。后者为32,虽然提供了更多的选择,但相应地也增长了功耗和复杂性。
     数据传输速率和包长度,前者都更短些。
     3.低功耗蓝牙相关专有名词表明:
     设置文件 (Profile) Profile 是被蓝牙标准预先定义的一些 Service 的集合,并不真实存在于蓝牙装备中。如果蓝牙装备之间要相互兼容,它们只要支持雷同的 Profile 即可。一个蓝牙装备可以支持多个 Profile。
     服务 Service 是蓝牙装备对外提供的服务,一个装备可以提供多个服务,比如电量信息服务、系统信息服务等。每个服务由一个 UUID 唯一标识。
     特征 每个 Service 包含 0 至多个 Characteristic。比如,电量信息服务就会有个 Characteristic 表示电量数据。Characteristic 包含一个值 (value)和 0 至多个描述符 (Descriptor) 构成。在与蓝牙装备通讯时,主要就是通过读写 Characteristic 的 value 完成。 每个 Characteristic 由一个 UUID 唯一标识。
     描述符 Descriptor 是描述特征值的已定义属性。例如,Descriptor 可指定人类可读的描述、特征值的取值范围或特定于特征值的度量单位。每个 Descriptor 由一个 UUID 唯一标识。
     GATT-Generic Attribute Profile GATT 设置文件是关于通过 BLE 链路发送和吸收一小段数据(称为“属性”)的一样寻通例范。当前的全部 BLE 应用设置文件都基于 GATT。
     Bluetooth SIG 为 BLE 装备定义了许多设置文件。设置文件是规定装备如安在特定应用中工作的规范。请注意,一个装备可以实现多个设置文件。例如,装备大概包含心率监测器和电池电量检测器。
     GATT 是基于属性协议 (ATT) 构建的。这也称为 GATT/ATT。ATT 颠末优化,可在 BLE 装备上运行。为此,它会尽大概减少使用的字节数量。每个属性均由通用唯一标识符 (UUID) 举行唯一标识。UUID 是一种标准化的 128 位格式,用于对信息举行唯一标识的字符串 ID。由 ATT 传输的特性会采用“特征”和服务的格式。
     中央装备Central和外围装备Peripheral 这是低功耗蓝牙中十分告急的概念。通过低功耗蓝牙链接的两个装备,一个为中央装备(获取信息的信息使用方),一个为外围装备(产出信息的信息提供方)。例如手机和电子温度计通过蓝牙链接,前者就是中央装备,后者就是外围装备。
     中央装备Central 中央装备可以扫描外围装备,并在发现有外围装备存在后与之建立毗连,之后就可以使用外围装备提供的服务(Service)。一样寻常而言,手机会担任中央装备的脚色,利用外围装备提供的数据举行处理或展示等等。小步伐提供低功耗蓝牙接口是默认设定手机为中央装备的。
     外围装备Peripheral 外围装备一直处于广播状态,等待被中央装备搜索和毗连,不能自动发起搜索。例如智能手环、传感器等装备。如果外围装备广播时被设置为不可毗连的状态,也被称为广播模式 (Broadcaster),常见的例子是蓝牙信标 (Beacon) 装备。
     三、BLE低功耗蓝牙的使用流程:

     

     该流程分为两个部分,中央装备的角度和外围装备的角度。
     首先作为中央装备,需要: 1.初始化蓝牙模块 2.扫描并发现蓝牙外围装备 3.毗连装备 4.获取蓝牙外围装备的服务 5. 读写服务的特征值 6. 断开毗连和关闭蓝牙适配器
     之后作为外围设别,需要: 1.初始化蓝牙模块 2.添加服务,写入特征值和描述 3.发送广播,设置广播各种参数
     DEMO示例:

     中央装备操作步调函数:
                 
  1. import { ble } from '@kit.ConnectivityKit';
  2. import { constant } from '@kit.ConnectivityKit';
  3. import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
  4. const TAG: string = 'GattClientManager';
  5. export class GattClientManager {
  6.   device: string = undefined;
  7.   gattClient: ble.GattClientDevice = undefined;
  8.   connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
  9.   myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
  10.   myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
  11.   myFirstDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
  12.   mySecondDescriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB';
  13.   found: boolean = false;
  14.   // 构造BLEDescriptor
  15.   private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
  16.     let descriptor: ble.BLEDescriptor = {
  17.       serviceUuid: this.myServiceUuid,
  18.       characteristicUuid: this.myCharacteristicUuid,
  19.       descriptorUuid: des,
  20.       descriptorValue: value
  21.     };
  22.     return descriptor;
  23.   }
  24.   // 构造BLECharacteristic
  25.   private initCharacteristic(): ble.BLECharacteristic {
  26.     let descriptors: Array<ble.BLEDescriptor> = [];
  27.     let descBuffer = new ArrayBuffer(2);
  28.     let descValue = new Uint8Array(descBuffer);
  29.     descValue[0] = 11;
  30.     descValue[1] = 12;
  31.     descriptors[0] = this.initDescriptor(this.myFirstDescriptorUuid, new ArrayBuffer(2));
  32.     descriptors[1] = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
  33.     let charBuffer = new ArrayBuffer(2);
  34.     let charValue = new Uint8Array(charBuffer);
  35.     charValue[0] = 1;
  36.     charValue[1] = 2;
  37.     let characteristic: ble.BLECharacteristic = {
  38.       serviceUuid: this.myServiceUuid,
  39.       characteristicUuid: this.myCharacteristicUuid,
  40.       characteristicValue: charBuffer,
  41.       descriptors: descriptors
  42.     };
  43.     return characteristic;
  44.   }
  45.   private logCharacteristic(char: ble.BLECharacteristic) {
  46.     let message = 'logCharacteristic uuid:' + char.characteristicUuid + '\n';
  47.     let value = new Uint8Array(char.characteristicValue);
  48.     message += 'logCharacteristic value: ';
  49.     for (let i = 0; i < char.characteristicValue.byteLength; i++) {
  50.       message += value[i] + ' ';
  51.     }
  52.     console.info(TAG, message);
  53.   }
  54.   private logDescriptor(des: ble.BLEDescriptor) {
  55.     let message = 'logDescriptor uuid:' + des.descriptorUuid + '\n';
  56.     let value = new Uint8Array(des.descriptorValue);
  57.     message += 'logDescriptor value: ';
  58.     for (let i = 0; i < des.descriptorValue.byteLength; i++) {
  59.       message += value[i] + ' ';
  60.     }
  61.     console.info(TAG, message);
  62.   }
  63.   private checkService(services: Array<ble.GattService>): boolean {
  64.     for (let i = 0; i < services.length; i++) {
  65.       if (services[i].serviceUuid != this.myServiceUuid) {
  66.         continue;
  67.       }
  68.       for (let j = 0; j < services[i].characteristics.length; j++) {
  69.         if (services[i].characteristics[j].characteristicUuid != this.myCharacteristicUuid) {
  70.           continue;
  71.         }
  72.         for (let k = 0; k < services[i].characteristics[j].descriptors.length; k++) {
  73.           if (services[i].characteristics[j].descriptors[k].descriptorUuid == this.myFirstDescriptorUuid) {
  74.             console.info(TAG, 'find expected service from server');
  75.             return true;
  76.           }
  77.         }
  78.       }
  79.     }
  80.     console.error(TAG, 'no expected service from server');
  81.     return false;
  82.   }
  83.   // 1. 订阅连接状态变化事件
  84.   public onGattClientStateChange() {
  85.     if (!this.gattClient) {
  86.       console.error(TAG, 'no gattClient');
  87.       return;
  88.     }
  89.     try {
  90.       this.gattClient.on('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
  91.         let state = '';
  92.         switch (stateInfo.state) {
  93.           case 0:
  94.             state = 'DISCONNECTED';
  95.             break;
  96.           case 1:
  97.             state = 'CONNECTING';
  98.             break;
  99.           case 2:
  100.             state = 'CONNECTED';
  101.             break;
  102.           case 3:
  103.             state = 'DISCONNECTING';
  104.             break;
  105.           default:
  106.             state = 'undefined';
  107.             break;
  108.         }
  109.         console.info(TAG, 'onGattClientStateChange: device=' + stateInfo.deviceId + ', state=' + state);
  110.         if (stateInfo.deviceId == this.device) {
  111.           this.connectState = stateInfo.state;
  112.         }
  113.       });
  114.     } catch (err) {
  115.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  116.     }
  117.   }
  118.   // 2. client端主动连接时调用
  119.   public startConnect(peerDevice: string) { // 对端设备一般通过ble scan获取到
  120.     if (this.connectState != constant.ProfileConnectionState.STATE_DISCONNECTED) {
  121.       console.error(TAG, 'startConnect failed');
  122.       return;
  123.     }
  124.     console.info(TAG, 'startConnect ' + peerDevice);
  125.     this.device = peerDevice;
  126.     // 2.1 使用device构造gattClient,后续的交互都需要使用该实例
  127.     this.gattClient = ble.createGattClientDevice(peerDevice);
  128.     try {
  129.       this.onGattClientStateChange(); // 2.2 订阅连接状态
  130.       this.gattClient.connect(); // 2.3 发起连接
  131.     } catch (err) {
  132.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  133.     }
  134.   }
  135.   // 3. client端连接成功后,需要进行服务发现
  136.   public discoverServices() {
  137.     if (!this.gattClient) {
  138.       console.info(TAG, 'no gattClient');
  139.       return;
  140.     }
  141.     console.info(TAG, 'discoverServices');
  142.     try {
  143.       this.gattClient.getServices().then((result: Array<ble.GattService>) => {
  144.         console.info(TAG, 'getServices success: ' + JSON.stringify(result));
  145.         this.found = this.checkService(result); // 要确保server端的服务内容有业务所需要的服务
  146.       });
  147.     } catch (err) {
  148.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  149.     }
  150.   }
  151.   // 4. 在确保拿到了server端的服务结果后,读取server端特定服务的特征值时调用
  152.   public readCharacteristicValue() {
  153.     if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
  154.       console.error(TAG, 'no gattClient or not connected');
  155.       return;
  156.     }
  157.     if (!this.found) { // 要确保server端有对应的characteristic
  158.       console.error(TAG, 'no characteristic from server');
  159.       return;
  160.     }
  161.     let characteristic = this.initCharacteristic();
  162.     console.info(TAG, 'readCharacteristicValue');
  163.     try {
  164.       this.gattClient.readCharacteristicValue(characteristic).then((outData: ble.BLECharacteristic) => {
  165.         this.logCharacteristic(outData);
  166.       })
  167.     } catch (err) {
  168.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  169.     }
  170.   }
  171.   // 5. 在确保拿到了server端的服务结果后,写入server端特定服务的特征值时调用
  172.   public writeCharacteristicValue() {
  173.     if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
  174.       console.error(TAG, 'no gattClient or not connected');
  175.       return;
  176.     }
  177.     if (!this.found) { // 要确保server端有对应的characteristic
  178.       console.error(TAG, 'no characteristic from server');
  179.       return;
  180.     }
  181.     let characteristic = this.initCharacteristic();
  182.     console.info(TAG, 'writeCharacteristicValue');
  183.     try {
  184.       this.gattClient.writeCharacteristicValue(characteristic, ble.GattWriteType.WRITE, (err) => {
  185.         if (err) {
  186.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  187.           return;
  188.         }
  189.         console.info(TAG, 'writeCharacteristicValue success');
  190.       });
  191.     } catch (err) {
  192.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  193.     }
  194.   }
  195.   // 6. 在确保拿到了server端的服务结果后,读取server端特定服务的描述符时调用
  196.   public readDescriptorValue() {
  197.     if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
  198.       console.error(TAG, 'no gattClient or not connected');
  199.       return;
  200.     }
  201.     if (!this.found) { // 要确保server端有对应的descriptor
  202.       console.error(TAG, 'no descriptor from server');
  203.       return;
  204.     }
  205.     let descBuffer = new ArrayBuffer(0);
  206.     let descriptor = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
  207.     console.info(TAG, 'readDescriptorValue');
  208.     try {
  209.       this.gattClient.readDescriptorValue(descriptor).then((outData: ble.BLEDescriptor) => {
  210.         this.logDescriptor(outData);
  211.       });
  212.     } catch (err) {
  213.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  214.     }
  215.   }
  216.   // 7. 在确保拿到了server端的服务结果后,写入server端特定服务的描述符时调用
  217.   public writeDescriptorValue() {
  218.     if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
  219.       console.error(TAG, 'no gattClient or not connected');
  220.       return;
  221.     }
  222.     if (!this.found) { // 要确保server端有对应的descriptor
  223.       console.error(TAG, 'no descriptor from server');
  224.       return;
  225.     }
  226.     let descBuffer = new ArrayBuffer(2);
  227.     let descValue = new Uint8Array(descBuffer);
  228.     descValue[0] = 11;
  229.     descValue[1] = 12;
  230.     let descriptor = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
  231.     console.info(TAG, 'writeDescriptorValue');
  232.     try {
  233.       this.gattClient.writeDescriptorValue(descriptor, (err) => {
  234.         if (err) {
  235.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  236.           return;
  237.         }
  238.         console.info(TAG, 'writeDescriptorValue success');
  239.       });
  240.     } catch (err) {
  241.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  242.     }
  243.   }
  244.   // 8.client端主动断开时调用
  245.   public stopConnect() {
  246.     if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
  247.       console.error(TAG, 'no gattClient or not connected');
  248.       return;
  249.     }
  250.     console.info(TAG, 'stopConnect ' + this.device);
  251.     try {
  252.       this.gattClient.disconnect(); // 8.1 断开连接
  253.       this.gattClient.off('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
  254.       });
  255.       this.gattClient.close() // 8.2 如果不再使用此gattClient,则需要close
  256.     } catch (err) {
  257.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  258.     }
  259.   }
  260. }
  261. let gattClientManager = new GattClientManager();
  262. export default gattClientManager as GattClientManager;
复制代码
               外围装备操作步调函数:
                 
  1. import { ble } from '@kit.ConnectivityKit';
  2. import { constant } from '@kit.ConnectivityKit';
  3. import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
  4. const TAG: string = 'GattServerManager';
  5. export class GattServerManager {
  6.   gattServer: ble.GattServer = undefined;
  7.   connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
  8.   myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
  9.   myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
  10.   myFirstDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
  11.   mySecondDescriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB';
  12.   // 构造BLEDescriptor
  13.   private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
  14.     let descriptor: ble.BLEDescriptor = {
  15.       serviceUuid: this.myServiceUuid,
  16.       characteristicUuid: this.myCharacteristicUuid,
  17.       descriptorUuid: des,
  18.       descriptorValue: value
  19.     };
  20.     return descriptor;
  21.   }
  22.   // 构造BLECharacteristic
  23.   private initCharacteristic(): ble.BLECharacteristic {
  24.     let descriptors: Array<ble.BLEDescriptor> = [];
  25.     let descBuffer = new ArrayBuffer(2);
  26.     let descValue = new Uint8Array(descBuffer);
  27.     descValue[0] = 31;
  28.     descValue[1] = 32;
  29.     descriptors[0] = this.initDescriptor(this.myFirstDescriptorUuid, new ArrayBuffer(2));
  30.     descriptors[1] = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
  31.     let charBuffer = new ArrayBuffer(2);
  32.     let charValue = new Uint8Array(charBuffer);
  33.     charValue[0] = 21;
  34.     charValue[1] = 22;
  35.     let characteristic: ble.BLECharacteristic = {
  36.       serviceUuid: this.myServiceUuid,
  37.       characteristicUuid: this.myCharacteristicUuid,
  38.       characteristicValue: charBuffer,
  39.       descriptors: descriptors
  40.     };
  41.     return characteristic;
  42.   }
  43.   // 1. 订阅连接状态变化事件
  44.   public onGattServerStateChange() {
  45.     if (!this.gattServer) {
  46.       console.error(TAG, 'no gattServer');
  47.       return;
  48.     }
  49.     try {
  50.       this.gattServer.on('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
  51.         let state = '';
  52.         switch (stateInfo.state) {
  53.           case 0:
  54.             state = 'DISCONNECTED';
  55.             break;
  56.           case 1:
  57.             state = 'CONNECTING';
  58.             break;
  59.           case 2:
  60.             state = 'CONNECTED';
  61.             break;
  62.           case 3:
  63.             state = 'DISCONNECTING';
  64.             break;
  65.           default:
  66.             state = 'undefined';
  67.             break;
  68.         }
  69.         console.info(TAG, 'onGattServerStateChange: device=' + stateInfo.deviceId + ', state=' + state);
  70.       });
  71.     } catch (err) {
  72.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  73.     }
  74.   }
  75.   // 2. server端注册服务时调用
  76.   public registerServer() {
  77.     let characteristics: Array<ble.BLECharacteristic> = [];
  78.     let characteristic = this.initCharacteristic();
  79.     characteristics.push(characteristic);
  80.     let gattService: ble.GattService = {
  81.       serviceUuid: this.myServiceUuid,
  82.       isPrimary: true,
  83.       characteristics: characteristics
  84.     };
  85.     console.info(TAG, 'registerServer ' + this.myServiceUuid);
  86.     try {
  87.       this.gattServer = ble.createGattServer(); // 2.1 构造gattServer,后续的交互都需要使用该实例
  88.       this.onGattServerStateChange(); // 2.2 订阅连接状态
  89.       this.gattServer.addService(gattService);
  90.     } catch (err) {
  91.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  92.     }
  93.   }
  94.   // 3. 订阅来自gattClient的读取特征值请求时调用
  95.   public onCharacteristicRead() {
  96.     if (!this.gattServer) {
  97.       console.error(TAG, 'no gattServer');
  98.       return;
  99.     }
  100.     console.info(TAG, 'onCharacteristicRead');
  101.     try {
  102.       this.gattServer.on('characteristicRead', (charReq: ble.CharacteristicReadRequest) => {
  103.         let deviceId: string = charReq.deviceId;
  104.         let transId: number = charReq.transId;
  105.         let offset: number = charReq.offset;
  106.         console.info(TAG, 'receive characteristicRead');
  107.         let rspBuffer = new ArrayBuffer(2);
  108.         let rspValue = new Uint8Array(rspBuffer);
  109.         rspValue[0] = 21;
  110.         rspValue[1] = 22;
  111.         let serverResponse: ble.ServerResponse = {
  112.           deviceId: deviceId,
  113.           transId: transId,
  114.           status: 0, // 0表示成功
  115.           offset: offset,
  116.           value: rspBuffer
  117.         };
  118.         try {
  119.           this.gattServer.sendResponse(serverResponse);
  120.         } catch (err) {
  121.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  122.         }
  123.       });
  124.     } catch (err) {
  125.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  126.     }
  127.   }
  128.   // 4. 订阅来自gattClient的写入特征值请求时调用
  129.   public onCharacteristicWrite() {
  130.     if (!this.gattServer) {
  131.       console.error(TAG, 'no gattServer');
  132.       return;
  133.     }
  134.     console.info(TAG, 'onCharacteristicWrite');
  135.     try {
  136.       this.gattServer.on('characteristicWrite', (charReq: ble.CharacteristicWriteRequest) => {
  137.         let deviceId: string = charReq.deviceId;
  138.         let transId: number = charReq.transId;
  139.         let offset: number = charReq.offset;
  140.         console.info(TAG, 'receive characteristicWrite: needRsp=' + charReq.needRsp);
  141.         if (!charReq.needRsp) {
  142.           return;
  143.         }
  144.         let rspBuffer = new ArrayBuffer(0);
  145.         let serverResponse: ble.ServerResponse = {
  146.           deviceId: deviceId,
  147.           transId: transId,
  148.           status: 0, // 0表示成功
  149.           offset: offset,
  150.           value: rspBuffer
  151.         };
  152.         try {
  153.           this.gattServer.sendResponse(serverResponse);
  154.         } catch (err) {
  155.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  156.         }
  157.       });
  158.     } catch (err) {
  159.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  160.     }
  161.   }
  162.   // 5. 订阅来自gattClient的读取描述符请求时调用
  163.   public onDescriptorRead() {
  164.     if (!this.gattServer) {
  165.       console.error(TAG, 'no gattServer');
  166.       return;
  167.     }
  168.     console.info(TAG, 'onDescriptorRead');
  169.     try {
  170.       this.gattServer.on('descriptorRead', (desReq: ble.DescriptorReadRequest) => {
  171.         let deviceId: string = desReq.deviceId;
  172.         let transId: number = desReq.transId;
  173.         let offset: number = desReq.offset;
  174.         console.info(TAG, 'receive descriptorRead');
  175.         let rspBuffer = new ArrayBuffer(2);
  176.         let rspValue = new Uint8Array(rspBuffer);
  177.         rspValue[0] = 31;
  178.         rspValue[1] = 32;
  179.         let serverResponse: ble.ServerResponse = {
  180.           deviceId: deviceId,
  181.           transId: transId,
  182.           status: 0, // 0表示成功
  183.           offset: offset,
  184.           value: rspBuffer
  185.         };
  186.         try {
  187.           this.gattServer.sendResponse(serverResponse);
  188.         } catch (err) {
  189.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  190.         }
  191.       });
  192.     } catch (err) {
  193.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  194.     }
  195.   }
  196.   // 6. 订阅来自gattClient的写入描述符请求时调用
  197.   public onDescriptorWrite() {
  198.     if (!this.gattServer) {
  199.       console.error(TAG, 'no gattServer');
  200.       return;
  201.     }
  202.     console.info(TAG, 'onDescriptorWrite');
  203.     try {
  204.       this.gattServer.on('descriptorWrite', (desReq: ble.DescriptorWriteRequest) => {
  205.         let deviceId: string = desReq.deviceId;
  206.         let transId: number = desReq.transId;
  207.         let offset: number = desReq.offset;
  208.         console.info(TAG, 'receive descriptorWrite: needRsp=' + desReq.needRsp);
  209.         if (!desReq.needRsp) {
  210.           return;
  211.         }
  212.         let rspBuffer = new ArrayBuffer(0);
  213.         let serverResponse: ble.ServerResponse = {
  214.           deviceId: deviceId,
  215.           transId: transId,
  216.           status: 0, // 0表示成功
  217.           offset: offset,
  218.           value: rspBuffer
  219.         };
  220.         try {
  221.           this.gattServer.sendResponse(serverResponse);
  222.         } catch (err) {
  223.           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  224.         }
  225.       });
  226.     } catch (err) {
  227.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  228.     }
  229.   }
  230.   // 7. server端删除服务,不再使用时调用
  231.   public unRegisterServer() {
  232.     if (!this.gattServer) {
  233.       console.error(TAG, 'no gattServer');
  234.       return;
  235.     }
  236.     console.info(TAG, 'unRegisterServer ' + this.myServiceUuid);
  237.     try {
  238.       this.gattServer.removeService(this.myServiceUuid); // 7.1 删除服务
  239.       this.gattServer.off('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => { // 7.2 取消订阅连接状态
  240.       });
  241.       this.gattServer.close() // 7.3 如果不再使用此gattServer,则需要close
  242.     } catch (err) {
  243.       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
  244.     }
  245.   }
  246. }
  247. let gattServerManager = new GattServerManager();
  248. export default gattServerManager as GattServerManager;
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

飞不高

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表