ios ble 蓝牙锁开发用例
程序员文章站
2022-06-21 19:23:04
开发流程:1. 建立中心管家2. 扫描外部设备3. 获取扫描的 外部设备,获取外部设备 , 连接外部设备4. 连接外设 成功,获取 发现服务5. 发现服务 uuid, 发现 服务下 特征值6. 读取 特征值 ,订阅 ble->app 通道 获取app->ble 特征值7. 接收 读取的特征值8. 锁入网,传递psw2 给app9. p1+p2 加密 systemId 鉴权 10. 锁回复 psw3 11.发送 开锁 确认帧代码......
开发流程:
1. 建立中心管家
2. 扫描外部设备
3. 获取扫描的 外部设备,获取外部设备 , 连接外部设备
4. 连接外设 成功,获取 发现服务
5. 发现服务 uuid, 发现 服务下 特征值
6. 读取 特征值 ,订阅 ble->app 通道 获取app->ble 特征值
7. 接收 读取的特征值
8. 锁入网,传递psw2 给app
9. p1+p2 加密 systemId 鉴权
10. 锁回复 psw3
11.发送 开锁 确认帧
代码实现:
//
// ViewController.m
// mutipeerConnectivityTest
//
// Created by 邓安置 on 2020/6/11.
// Copyright © 2020 邓安置. All rights reserved.
//
#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import "CBPeripheral+Extension.h"
#import "KDSBleOptions.h"
#import "NSData+JKEncrypt.h"
#import "KDSBleAssistant.h"
#import "NSTimer+KDSBlock.h"
@interface ViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate>
@property(nonatomic,strong) CBCentralManager* mgr;
@property(nonatomic,strong) CBPeripheral* peripheral;
@property(nonatomic,copy,nullable) void(^myBlock)(CBPeripheral* cbP);
@property (nonatomic, strong) CBCharacteristic *batteryCharacteristic; //电量
@property (nonatomic, strong) CBCharacteristic *systemIDCharacteristic; //系统ID
@property (nonatomic, strong) CBCharacteristic *modelNumCharacteristic; //
@property (nonatomic, strong) CBCharacteristic *seriaNumCharacteristic; //
///要写入到哪个特征
@property (nonatomic, strong) CBCharacteristic *writeCharacteristic;
@property (nonatomic, strong) CBCharacteristic *functionSetCharacteristic;//功能集
@property (nonatomic, strong, nullable) CBPeripheral *connectedPeripheral;
@property (nonatomic, strong) NSData *systemID;
///连接外设绑定时,收到SN后,从服务器请求回来。绑定后从绑定设备列表获得。测试没有上市的蓝牙时,服务器没有值返回,这是使用mac提取。
@property (nonatomic, copy, nullable) NSString *pwd1;
///用户入网(绑定)的时候生成,锁蓝牙返回的payload数据的1~4字节。
@property (nonatomic, strong, nullable) NSData *pwd2;
///鉴权成功时,锁蓝牙返回的payload数据的1~4字节。
@property (nonatomic, strong, nullable) NSData *pwd3;
/**传输序号,每次传输+1,到了255置为50 (为了区分心跳包 设置范围为50-255)*/
@property (nonatomic, assign) int tsn;
///心跳包tsn 1 - 49
@property (nonatomic, assign) NSInteger heartbeatTsn;
@property (nonatomic, weak) NSTimer *heartbeatTimer;
@end
@implementation ViewController
- (IBAction)searchShow:(id)sender {
// 1. 建立中心管家
// nil: 在主线程中扫描
CBCentralManager *centralManager= [[CBCentralManager alloc] initWithDelegate:self queue:nil];
_mgr = centralManager;
NSLog(@"%@",@"开始扫描");
//
}
- (void)viewDidLoad {
[super viewDidLoad];
self.myBlock= ^(CBPeripheral* cbP){
NSLog(@"block回调--->%@",cbP.advDataLocalName);
};
self.pwd1=@"62375ea279e77356aa0a77f9";
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSLog(@"%ld",central.state);
// 开机状态 5
if(central.state== CBManagerStatePoweredOn ){
// 2. 扫描外部设备 CBPeripheral表示外部设备
[self.mgr scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
}
__weak typeof(self) weakSelf = self;
dispatch_block_t block = dispatch_block_create(DISPATCH_BLOCK_ASSIGN_CURRENT, ^{
if (weakSelf.mgr.isScanning) {
[weakSelf stopScan];
}
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
block();
});
}
- (void)stopScan
{
NSLog(@"%@",@"停止扫描");
[self.mgr stopScan];
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
/**
===peripheral名:Kaadas DoorLock
===广播名:KDSF0F8F2BFB618
===设备uuid:22F116CE-D746-16A4-8408-BE1476E11B0C
===peripheral:<CBPeripheral: 0x2822b4fa0, identifier = 22F116CE-D746-16A4-8408-BE1476E11B0C, name = Kaadas DoorLock, state = disconnected>
===设备广播数据:{
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = KDSF0F8F2BFB618;
kCBAdvDataRxPrimaryPHY = 0;
kCBAdvDataRxSecondaryPHY = 0;
kCBAdvDataServiceUUIDs = (
FFD0,
FFF0
);
kCBAdvDataTimestamp = "614075187.3347189";
kCBAdvDataTxPowerLevel = 0;
}
*/
// NSLog(@"\n\n===peripheral名:%@ \n===广播名:%@\n ===设备uuid:%@\n ===peripheral:%@\n ===设备广播数据:%@\n\n",peripheral.name,advertisementData[@"kCBAdvDataLocalName"],peripheral.identifier.UUIDString,peripheral,advertisementData);
//解析广播包中的kCBAdvDataLocalName 区分凯迪仕的设备
NSString *key = CBAdvertisementDataLocalNameKey;
// 3. 获取扫描的 外部设备,获取外部设备 , 连接外部设备
if (peripheral==nil || peripheral.name==nil || ![advertisementData[key] containsString:@"KDSA434F1CC143A"]) return;
[self stopScan];
NSLog(@"peripheral==%@",advertisementData[key]);
peripheral.advDataLocalName = advertisementData[key];
self.myBlock(peripheral);
self.peripheral = peripheral;
// 连接外部设备
[self.mgr connectPeripheral:peripheral options:nil];
}
// 4. 连接外设 成功,获取 发现服务
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// 通过连接的外部设置保存扫描到的
NSLog(@"连接成功:%@",peripheral.advDataLocalName);
_connectedPeripheral = peripheral;
NSInteger allLenth =peripheral.advDataLocalName.length;
if (allLenth >= 12) {
NSString *orgStr = [peripheral.advDataLocalName substringFromIndex:allLenth-12];
NSData *password1 = [orgStr dataUsingEncoding:NSASCIIStringEncoding];
}
peripheral.delegate =self;
// 扫描服务 根据服务 扫描特征值
[self.peripheral discoverServices:nil];
}
// 5. 发现服务 uuid, 发现 服务下 特征值
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
NSArray* services= peripheral.services;
NSLog(@"设备服务值:%@",services);
for (CBService *sevice in peripheral.services) {
/**
设备服务值:(
"<CBService: 0x2803c6800, isPrimary = YES, UUID = Device Information>",
"<CBService: 0x2803c5840, isPrimary = YES, UUID = FFF0>",
"<CBService: 0x2803c66c0, isPrimary = YES, UUID = FFE0>",
"<CBService: 0x2803c6740, isPrimary = YES, UUID = FFE5>",
"<CBService: 0x2803c6640, isPrimary = YES, UUID = FFB0>",
"<CBService: 0x2803c60c0, isPrimary = YES, UUID = F000FFD0-0451-4000-B000-000000000000>"
)
*/
// NSLog(@"%@",sevice.UUID.UUIDString);
if ([sevice.UUID.UUIDString isEqualToString:OADResetServiceUUID]
||[sevice.UUID.UUIDString isEqualToString:DFUResetServiceUUID]) {
//存在FFD0或1802服务,OAD复位服务
//存在FFD0或1802服务,OAD复位服务
peripheral.isNewDevice = YES;
peripheral.bleVersion = 2;
NSLog(@"--{Kaadas}--bleVersion:%d",peripheral.bleVersion);
}
[peripheral discoverCharacteristics:nil forService:sevice];//发现服务下面所有的特征
}
}
// 6. 读取 特征值 ,订阅 ble->app 通道 获取app->ble 特征值,发送 心跳包
// 发现特征值就会调用
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {
if (error){
NSLog(@"获取服务:%@的特征失败: %@", service.UUID, error);
return;
}
UInt64 uuid = strtoul(service.UUID.UUIDString.UTF8String, 0, 16);
KDSBleService serviceType = (KDSBleService)uuid;
NSLog(@"读的服务-service===%@",service.characteristics);
switch (serviceType)
{
case KDSBleServiceModule:
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"读的服务-模块信息 (电量 pwd3):severUUId:%@====charUUId:%@",service.UUID.UUIDString,characteristic.UUID.UUIDString);
// [peripheral setNotifyValue:YES forCharacteristic:characteristic];
if ([characteristic.UUID.UUIDString isEqualToString:batteryDUUID]) {
[peripheral readValueForCharacteristic:characteristic];
//电量特征值
_batteryCharacteristic = characteristic;
}
}
break;
case KDSBleServiceDevice:
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"读的服务-BLE设备信息参数:severUUId:%@====charUUId:%@",service.UUID.UUIDString,characteristic.UUID.UUIDString);
//监听characteristic值变化
// [peripheral setNotifyValue:YES forCharacteristic:characteristic];
if ([characteristic.UUID.UUIDString isEqualToString:systemIDUUID]) {
_systemIDCharacteristic = characteristic;
[peripheral readValueForCharacteristic:characteristic];
}
else if ([characteristic.UUID.UUIDString isEqualToString:modelNumUUID]) {
_modelNumCharacteristic = characteristic;
[peripheral readValueForCharacteristic:characteristic];
}
else if ([characteristic.UUID.UUIDString isEqualToString:seriaLNumUUID]) {
_seriaNumCharacteristic = characteristic;
[peripheral readValueForCharacteristic:characteristic];
}
}
break;
case KDSBleServiceLock:
break;
case KDSBleServiceApp2BleTunnel: // app->蓝牙 0xFFE5 ,下只有一个特征值,app->ble
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"读的服务-APP-->BLE数据通道severUUId:%@====charUUId:%@",service.UUID.UUIDString,characteristic.UUID.UUIDString);
//主动去读取一次外围设备的消息
[peripheral readValueForCharacteristic:characteristic];
// [peripheral setNotifyValue:YES forCharacteristic:characteristic];
self.writeCharacteristic = characteristic;
}
if(self.connectedPeripheral.isNewDevice){
[self createHeartbeatTimer];
}
break;
case KDSBleServiceBle2AppTunnel: //0xFFE0
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"读的服务-BLE-->APP数据通道:severUUId:%@====charUUId:%@",service.UUID.UUIDString,characteristic.UUID.UUIDString);
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
// ffe0 下功能集 ffe1
if ([characteristic.UUID.UUIDString isEqualToString:kFFE1])
{
peripheral.bleVersion = 3;
NSLog(@"--{Kaadas}--bleVersion:%d",peripheral.bleVersion);
_functionSetCharacteristic = characteristic;
[peripheral readValueForCharacteristic:characteristic];
}
}
break;
case KDSApp2BleDisNetworkTunnel:
break;
case KDSBle2AppDisNetworkTunnel:
break;
}
}
// 7. 接收 读取的特征值 ,
#pragma mark 接收特征的数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if (error) return;
NSString *uuid = characteristic.UUID.UUIDString;
NSLog(@"读取所有特征值的时候蓝牙UUID的值:%@",uuid);
if ([uuid isEqualToString:batteryDUUID]) {//电量信息
NSData *batteryData = characteristic.value;
u_int8_t tt;
[batteryData getBytes:&tt length:sizeof(tt)];
int elct = tt;//0-100
peripheral.power = elct;
NSLog(@"电量值是=%d",elct);
}
else if ([uuid isEqualToString:seriaLNumUUID]) {//SN
peripheral.serialNumber = characteristic.value.jk_UTF8String;
NSLog(@"sn是=%@",peripheral.serialNumber);
}
else if ([uuid isEqualToString:systemIDUUID]){//System ID
//获取systemId
_systemID = characteristic.value;
NSString *systemIDStr = [KDSBleAssistant convertDataToHexStr:_systemID];
if (!systemIDStr || strtol(systemIDStr.UTF8String, NULL, 16) == 0) {
_systemID = [KDSBleAssistant extractSystemIDFromAdvName:peripheral.advDataLocalName];
}
NSLog(@"systemID是=%@",_systemID);
}
else if ([uuid isEqualToString:modelNumUUID]) // modulenum
{
self.connectedPeripheral.lockModelNumber = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"modulenum是=%@",self.connectedPeripheral.lockModelNumber);
}
else if ([uuid isEqualToString:bleToAppDUUID]){//模块向App发送数据通道
if (characteristic.value.length == 16) { //没用,都是20个字节
NSData *pwd1Data = [characteristic.value subdataWithRange:NSMakeRange(0, 12)];
NSData *pwd = [KDSBleAssistant convertHexStrToData:self.pwd1];
NSString* pwdS= [KDSBleAssistant convertDataToHexStr:pwd];
NSLog(@"%@",pwdS);
return;
}
if (characteristic.value.length < 20) {return;/**数据丢包了 */ }
//新设备数据的处理
NSData *data = characteristic.value;
NSLog(@"--{Kaadas}--蓝牙--处理模块发来的数据==%@",data);
const unsigned char* bytes = (const unsigned char*)data.bytes;
u_int8_t control = bytes[0];
u_int8_t check1 = bytes[2];
NSData *decryptData = data;
if (control != 0) {//心跳包不加密
//解密数据
decryptData = [self getAes256_decryptDataWithOriginData:data];
NSLog(@"解密以后的数据:%@",[KDSBleAssistant convertDataToHexStr:decryptData]);
}
u_int8_t check2 = [KDSBleAssistant sumOfDataThroughoutBytes:[decryptData subdataWithRange:NSMakeRange(4, 16)]];
if (check1 == check2) {
// KDSLog(@"校验正确=%@",decryptData)
NSLog(@"处理校验正确之后的数据------%@",decryptData);
const unsigned char *bytes = (const unsigned char *)decryptData.bytes;
unsigned char transferSerialNumber = bytes[1]; //tsn
unsigned char cmd = bytes[3];
unsigned char status = bytes[4];
if (cmd==0 && transferSerialNumber<50) return;//心跳包确认帧。
NSString *receipt = @(transferSerialNumber).stringValue;
//如果是app主动发送命令,那么队列里会有记录,根据tsn和命令值执行相应的命令就行。
//执行app主动发送命令队列中不存在的上报命令
KDSBleTunnelOrder order = (KDSBleTunnelOrder)cmd;
switch (order) {
case KDSBleTunnelOrderEncrypt:
// 8. 锁入网,传递psw2 给app
if (status == 1)//收到锁发送过来的入网(绑定)指令,可以在返回数据中提取pwd2
{
self.pwd2 = [decryptData subdataWithRange:NSMakeRange(5, 4)];
// 9. p1+p2 加密 systemId 鉴权
[self sendResponseInOrOutNet:(int)transferSerialNumber];
NSLog(@"~~~~~收到入网命令self.pwd2=%@",self.pwd2);
[self authenticationWithPwd1:self.pwd1 pwd2:self.pwd2];
}
else if (status == 2)//收到pwd3,绑定成功。
{
// 10. 锁回复 psw3
self.pwd3 = [decryptData subdataWithRange:NSMakeRange(5, 4)];
NSLog(@"~~~~~收到self.pwd3,绑定成功=%@",self.pwd3);
[self sendResponseInOrOutNet:(int)transferSerialNumber];
}
break;
case KDSBleTunnelOrderLockOperate:
NSLog(@"%@",@"锁操作上报");
break;
};
}else{
NSLog(@"--{Kaadas}--校验出错--check1=%d--check2=%d",check1,check2);
}
}
else if ([uuid isEqualToString:kFFE1])//功能集
{
NSString *FunctionSetKey = [NSString stringWithFormat:@"0x%@",[KDSBleAssistant convertDataToHexStr:characteristic.value]];
NSLog(@"--{Kaadas}--功能集=锁上=%@",FunctionSetKey);
}
}
#pragma mark - 获取解密数据
///解密数据,绑定/重置时只能使用密码1+4字节都为0的NSData解密(即密码2必须为nil);鉴权时只能使用密码1+密码2解密(即密码3必须为nil);鉴权成功获取密码3后只能使用密码1+密码3解密;否则解密的数据都不正确。
- (NSData *)getAes256_decryptDataWithOriginData:(NSData *)data{
NSMutableData *keyData = [NSMutableData data];
NSData *key1Data = [KDSBleAssistant convertHexStrToData:_pwd1]; //12个字节
[keyData appendData:key1Data];
if (self.pwd2 == nil) {//解密pwd2 4个字节
Byte behindByte[] = {0x00,0x00,0x00,0x00};
NSData *behindData= [NSData dataWithBytes:behindByte length:sizeof(behindByte)];
[keyData appendData:behindData];
NSLog(@"keyData:%@",keyData);
}else if(self.pwd2 && self.pwd3 == nil){//解密pwd3
[keyData appendData:self.pwd2];
NSLog(@"keyData2:%@",keyData);
}
else if(self.pwd2 && self.pwd3){//建立通道以后 解密数据
[keyData appendData:self.pwd3];
// KDSLog(@"keyData3:%@",keyData);
}
// KDSLog(@"收到的原始数据:%@",data);
NSData *resultData = [[data subdataWithRange:NSMakeRange(4, 16)] aes256_decryptData:keyData];
NSMutableData *decryptData = [NSMutableData data];
[decryptData appendData:[data subdataWithRange:NSMakeRange(0, 4)]];
[decryptData appendData:resultData];
// KDSLog(@"--{Kaadas}--蓝牙--收到的解密后数据%@",decryptData);
return decryptData.copy;
}
#pragma mark - 发送收到 入网/退网 确认帧
- (void)sendResponseInOrOutNet:(int)tsn{
if (_connectedPeripheral.isNewDevice) {
[self sendConfirmDataToBleDevice:tsn];
return;
}
}
#pragma mark - 新模块发送确认帧
- (void)sendConfirmDataToBleDevice:(NSInteger)tsn{
if (tsn != 0) {
// [self pauseTimer];
Byte conformByte[] = {0x00,tsn,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
NSData *conformData = [[NSData alloc] initWithBytes:conformByte length:sizeof(conformByte)];
if (self.writeCharacteristic && self.connectedPeripheral ) {///设备已经连接且要写入特征
// KDSLog(@"发送了确认帧:%@ %@",conformData,getcurretenDate);
[self.connectedPeripheral writeValue:conformData forCharacteristic:self.writeCharacteristic type:0];
}
return;
}
}
- (NSString *)authenticationWithPwd1:(NSString *)pwd1 pwd2:(id)pwd2
{
Byte payload[16] = {0};
for (int i = 0; i < self.systemID.length; ++i)
{
// 把NSData 转化为 Byte
payload[i] = ((Byte *)self.systemID.bytes)[i];
}
int sum = [KDSBleAssistant sumOfDataThroughoutBytes:[[NSData alloc] initWithBytes:payload length:16]];
self.tsn++;
unsigned char* bytes = (unsigned char*)malloc(20);
bytes[0] = 1; bytes[1] = self.tsn; bytes[2] = sum; bytes[3] = KDSBleTunnelOrderAuth;
memcpy(bytes + 4, payload, 16);
NSData* sendData= [[NSData alloc] initWithBytesNoCopy:bytes length:20];
NSMutableData *key = [NSMutableData dataWithData:[KDSBleAssistant convertHexStrToData:self.pwd1]]; //12个字节
[key appendData:self.pwd2]; //4个字节
NSData *encryptData = [[sendData subdataWithRange:NSMakeRange(4, 16)] aes256_encryptData:key];
NSLog(@"--{Kaadas}--encryptData=key=%@",key);
NSLog(@"--{Kaadas}--encryptData====%@",encryptData);
[key setData:[sendData subdataWithRange:NSMakeRange(0, 4)]];
[key appendData:encryptData];
[self.connectedPeripheral writeValue:key forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithResponse];
return nil;
}
#pragma mark - 发送心跳包
- (void)createHeartbeatTimer{
if (self.heartbeatTimer==nil) {
//重复每3秒发送一次心跳包
__weak typeof(self) weakSelf = self;
NSTimer *timer = [NSTimer kdsScheduledTimerWithTimeInterval:3 repeats:YES block:^(NSTimer * _Nonnull timer) {
self.heartbeatTsn ++;
Byte bytePayload[16] = {0xFF, 0};
NSData *payloadData = [[NSData alloc] initWithBytes:bytePayload length:sizeof(bytePayload)];
Byte byteHeader[] = {0x00,self.heartbeatTsn,0xff,0xAA};
NSData *headerData = [[NSData alloc] initWithBytes:byteHeader length:sizeof(byteHeader)];
NSMutableData *senderData = [NSMutableData data];
[senderData appendData:headerData];
[senderData appendData:payloadData];
NSLog(@"发送心跳:%@",[KDSBleAssistant convertDataToHexStr:senderData]);
[self.connectedPeripheral writeValue:senderData forCharacteristic:self.writeCharacteristic type:0];
}];
self.heartbeatTimer = timer;
[timer fire];
}
}
// 如果发送开锁命令,暂停3s发送心跳包
- (void)pauseTimer{
self.heartbeatTimer.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
}
- (IBAction)openLock:(id)sender {
[self operateLockWithPwd:@"147258" actionType:KDSBleLockControlActionUnlock keyType:KDSBleLockControlKeyPIN
completion:^(KDSBleError error, CBPeripheral * _Nullable peripheral) {
}];
}
// 11.发送 开锁 确认帧
- (NSString *)operateLockWithPwd:(NSString *)pwd actionType:(KDSBleLockControl)action keyType:(KDSBleLockControl)key completion:(nullable void(^)(KDSBleError error, CBPeripheral * __nullable peripheral))completion{
Byte payload[16] = {(char)action, (char)key, 0, 0};
payload[3] = pwd.length;//密码长度
//第4个字节开始是密码,每一个字节保存一位密码。
for (int i = 0; i< pwd.length; i++)
{
payload[i + 4] = pwd.UTF8String[i];
}
int sum = [KDSBleAssistant sumOfDataThroughoutBytes:[[NSData alloc] initWithBytes:payload length:16]];
self.tsn++;
unsigned char* bytes = (unsigned char*)malloc(20);
bytes[0] = 1; bytes[1] = self.tsn; bytes[2] = sum; bytes[3] = KDSBleTunnelOrderControl;
memcpy(bytes + 4, payload, 16);
NSData* sendData= [[NSData alloc] initWithBytesNoCopy:bytes length:20];
NSMutableData *key13 = [NSMutableData dataWithData:[KDSBleAssistant convertHexStrToData:self.pwd1]];
if (self.pwd3)//鉴权后+密码3加密
{
[key13 appendData:self.pwd3];
}
NSData *encryptData = [[sendData subdataWithRange:NSMakeRange(4, 16)] aes256_encryptData:key13];
[key13 setData:[sendData subdataWithRange:NSMakeRange(0, 4)]];
[key13 appendData:encryptData];
[self.connectedPeripheral writeValue:key13 forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithResponse];
return nil;
}
@end
源码下载 : https://download.csdn.net/download/dreams_deng/12576424
本文地址:https://blog.csdn.net/dreams_deng/article/details/107126490
上一篇: 随记,定个小目标
下一篇: .NET与你若只如初见(一)