You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

459 lines
14 KiB

//
// BluetoothTool.m
// BluetoothDemo
//
// Created by mac on 17/3/16.
// Copyright © 2017年 . All rights reserved.
//
#import "BluetoothToolFireBoltt.h"
#import <AddressBookUI/AddressBookUI.h> //通讯录库
#import "BLETools.h"
#import "BLEConstFireBoltt.h"
#import "BluetoothFireBoltt.h"
#import "FireBoltt-Swift.h"
@implementation BluetoothToolFireBoltt
/**
CRC校验数据是否正确
*/
+ (BOOL)checkCRCWithData:(NSMutableData *)data {
// 取出CRC
// int crc = [BluetoothTool intFromHexSrting:[NSString stringWithFormat:@"%02x%02x",((Byte*)([data bytes]))[4],((Byte*)([data bytes]))[5]]];
Byte *bytes = (Byte *)[data bytes];
// 利用位移管道运算转整数 modify by fangtao 2018.12.01
int crc = (bytes[4] & 0xff) << 8 | (bytes[5] & 0xff);
// L2层数据
NSData *contentData = [data subdataWithRange:NSMakeRange(8, data.length - 8)];
// 重新根据contentData计算CRC
int dataCrc = 0xff;
int contentLength = (int)contentData.length;
Byte *contentBytes = (Byte *)[contentData bytes];
for (int i = 0; i <contentLength ; i++) {
dataCrc^= contentBytes[i] & 0xFF;
// NSLog(@"dataCrc == ++ %d",dataCrc);
for (int j = 0; j < 8; j++) {
if((dataCrc & 1) !=0){
dataCrc >>=1;
dataCrc^=0xB8;
}else{
dataCrc>>=1;
}
}
}
// 如果相等则正确
if (crc == dataCrc) {
return YES;
}
return NO;
}
/**
* 16进制字符串转10进制数字
*
* @param hexString 16进制字符串
*
* @return 十进制数据
*/
+ (int)intFromHexSrting:(NSString *)hexString {
NSLog(@"%@",hexString);
if (!hexString) {
return 0;
}
#warning 陈廷峰此处有几率闪退,出现请告知
NSString * temp10 = [NSString stringWithFormat:@"%lu",strtoul([hexString UTF8String],0,16)];
return [temp10 intValue];
}
/**
10进制转16进制字符串
@param hexNumber 10进制
@return 十六进制字符串
*/
+ (NSString *)stringWithHexNumber:(int)hexNumber {
// 固件升级情况下处理一个字节超过255的情况
if (hexNumber > 255) {
hexNumber = 0;
}
char hexChar[6];
sprintf(hexChar, "%02x", (int)hexNumber);
NSString *hexString = [NSString stringWithCString:hexChar encoding:NSUTF8StringEncoding];
return hexString;
}
/**
获取系统当前时区时间数据
*/
+ (NSData *)getCurrenTime {
// 手环设置时间最后拼接一个12/24小时制,hasAMPM NO:24小时 YES:12小时
NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
NSRange containsA = [formatStringForHours rangeOfString:@"a"];
BOOL hasAMPM = containsA.location != NSNotFound;
NSMutableData *data = [NSMutableData dataWithData:[BluetoothToolFireBoltt getTimeDataWithTime:@[[NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]]] cmdType:BleCMD_setIngTime]];
[data appendBytes:&(hasAMPM) length:1];
NSData *zooeData = [[NSString stringWithFormat:@"%@",[NSTimeZone systemTimeZone]] dataUsingEncoding:NSUTF8StringEncoding];
[data appendData:zooeData];
// NSMutableData *TotalTimeData = [[NSMutableData alloc] init];
//
// NSData *timeData = [[NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]] dataUsingEncoding:NSUTF8StringEncoding];
// NSData *zooeData = [[NSString stringWithFormat:@"%@",[NSTimeZone systemTimeZone]] dataUsingEncoding:NSUTF8StringEncoding];
// // 分隔符
// NSData *charData = [@"|" dataUsingEncoding:NSUTF8StringEncoding];
// [TotalTimeData appendData:zooeData];
// [TotalTimeData appendData:charData];
// [TotalTimeData appendData:timeData];
return data;
}
/**
获取当前手机中的通讯录(字节流)
@return 20个联系人为一个数据,用数组将所有返回
*/
+ (NSMutableArray *)getCurrenContactPeploe {
// 10个联系人为一组
NSInteger contactCount = 10;
// 联系人数据数组
NSMutableArray *contactPeplpeArr = [[NSMutableArray alloc] init];
// 获取手机中所有通讯录(姓名|电话)
NSMutableArray *contactPeplpe = [self contactPeploe];
// 10个联系人为一个完整数据包
NSInteger count = contactPeplpe.count / contactCount;
for (int i = 0; i <= count; i++) {
NSString *contactStr = [[NSString alloc] init];
NSData *data = [[NSData alloc] init];
if (i < count) {
// 将10个联系人拼接成字符串
contactStr = [[contactPeplpe subarrayWithRange:NSMakeRange(i * contactCount, contactCount)] componentsJoinedByString:@"^"];
data = [contactStr dataUsingEncoding:NSUTF8StringEncoding];
}else if (contactPeplpe.count % contactCount) {
// 最后不足10个联系人的数据
contactStr = [[contactPeplpe subarrayWithRange:NSMakeRange(i * contactCount, contactPeplpe.count % contactCount)] componentsJoinedByString:@"^"];
data = [contactStr dataUsingEncoding:NSUTF8StringEncoding];
}
if (data.length) {
[contactPeplpeArr addObject:data];
}
}
return contactPeplpeArr;
}
/**
获取当前手机中的通讯录
@return 所有联系人数据
*/
+ (NSMutableArray *)contactPeploe
{
// 通讯录数组
NSMutableArray *contactArr = [NSMutableArray new];
//新建一个通讯录类
ABAddressBookRef addressBooks = nil;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)
{
addressBooks = ABAddressBookCreateWithOptions(NULL, NULL);
//获取通讯录权限
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBooks, ^(bool granted, CFErrorRef error){dispatch_semaphore_signal(sema);});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}else{
addressBooks = ABAddressBookCreate();
}
//获取通讯录中的所有人
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBooks);
//通讯录中人数
CFIndex nPeople = ABAddressBookGetPersonCount(addressBooks);
//循环,获取每个人的个人信息
for (NSInteger i = 0; i < nPeople; i++)
{
// 通讯录字符串--- 姓名|电话
NSString *contactStr = [NSString new];
//获取个人
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//获取个人名字
CFTypeRef abName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFTypeRef abLastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
CFStringRef abFullName = ABRecordCopyCompositeName(person);
NSString *nameString = (__bridge NSString *)abName;
NSString *lastNameString = (__bridge NSString *)abLastName;
if ((__bridge id)abFullName != nil) {
nameString = (__bridge NSString *)abFullName;
} else {
if ((__bridge id)abLastName != nil)
{
nameString = [NSString stringWithFormat:@"%@ %@", nameString, lastNameString];
}
}
ABPropertyID multiProperties[] = {
kABPersonPhoneProperty,
kABPersonEmailProperty
};
NSInteger multiPropertiesTotal = sizeof(multiProperties) / sizeof(ABPropertyID);
for (NSInteger j = 0; j < multiPropertiesTotal; j++) {
ABPropertyID property = multiProperties[j];
ABMultiValueRef valuesRef = ABRecordCopyValue(person, property);
NSInteger valuesCount = 0;
if (valuesRef != nil) valuesCount = ABMultiValueGetCount(valuesRef);
if (valuesCount == 0) {
CFRelease(valuesRef);
continue;
}
//获取电话号码和email
for (NSInteger k = 0; k < valuesCount; k++) {
CFTypeRef value = ABMultiValueCopyValueAtIndex(valuesRef, k);
switch (j) {
case 0: {// Phone number
// 拼接姓名以及电话
NSString *telString = [(__bridge NSString*)value stringByReplacingOccurrencesOfString:@"-" withString:@""];
contactStr = [NSString stringWithFormat:@"%@\n%@",nameString,telString];
break;
}
}
CFRelease(value);
}
CFRelease(valuesRef);
}
//将个人信息添加到数组中,循环完成后addressBookTemp中包含所有联系人的信息
if (contactStr.length) {
[contactArr addObject:contactStr];
}
if (abName) CFRelease(abName);
if (abLastName) CFRelease(abLastName);
if (abFullName) CFRelease(abFullName);
}
return contactArr;
}
/**
将时间戳转数组为Data发送给设备
@param timeArr 时间戳数组
@param type 请求类型
*/
+ (NSData *)getTimeDataWithTime:(NSArray *)timeArr
cmdType:(BleCMD_FireBoltt)type {
NSMutableData *timeData = [NSMutableData new];
for (int i = 0 ; i<timeArr.count;i++) {
NSString *time = timeArr[i];
NSString *timeStr = [NSString new];
if (type == BleCMD_setIngTime) {//时间设置
timeStr = [BLETools nsdateToTime:time.longLongValue formatStr:@"yy-MM-dd-HH-mm-ss"];
}else{//健康数据时间组
if (timeArr.count == 1) {
// timeStr = [time isEqualToString:@""] ? @"00-00-00-00-00-00" :[BLETools nsdateToTime:time.longLongValue formatStr:@"yy-MM-dd-HH-mm-ss"];
timeStr = [time isEqualToString:@""] ? @"00-00-00" :[BLETools nsdateToTime:time.longLongValue formatStr:@"yy-MM-dd"];
}
}
// 将年月日时分秒转成1字节16进制data
NSArray *arr = [timeStr componentsSeparatedByString:@"-"];
for (int i = 0; i < arr.count; i ++) {
int byte = [arr[i] intValue];
if (byte>2000) {
byte = byte%200;
}
[timeData appendBytes:&byte length:1];
}
}
return timeData;
}
/**
将闹钟数据转成Data
@param arr 闹钟数组
*/
+ (NSData *)getAlarmClockDataWithArr:(NSArray *)arr {
Byte buffer[25];
for (int i = 0; i < 5; i ++) {
AlarmModel *model = [[AlarmModel alloc] init];
// 不足五个闹钟,则给空闹钟
if (arr.count <= i) {
model.Hour = @"00";
model.Minutes = @"00";
model.Cycle = @"0000000";
model.IsOpen = NO;
// 标签 0 无效 1有效
buffer[3 + i * 5] = 0;
}else {
model = arr[i];
// 标签
buffer[3 + i * 5] = 1;
}
// 时 分
//NSArray *timeArr = [model.alarmTime componentsSeparatedByString:@":"];
buffer[0 + i * 5] = [model.Hour intValue];
buffer[1 + i * 5] = [model.Minutes intValue];
// 周期
const char *cycleStr = [model.Cycle cStringUsingEncoding:NSUTF8StringEncoding];
int cycle = 0;
for (int j = 0; j < 7; j ++) {
if (cycleStr[j] == '1') {
cycle += 1 * pow(2, j);
}
}
buffer[2 + i * 5] = cycle;
// 开关
buffer[4 + i * 5] = model.IsOpen;
}
NSData *data = [NSData dataWithBytes:buffer length:25];
return data;
}
/**
构造L1层第二个字节
@param err 1:对的 0:错的
@param ack 1:回复 0:命令
@param vision 版本
*/
+ (Byte)stitchWithErr:(int)err Ack:(int)ack Vision:(int)vision {
int a = 0 * pow(2, 7) + 0 * pow(2, 6) + err * pow(2, 5) + ack * pow(2, 4) + vision;
return a;
}
/**
倒序mac地址
*/
+ (NSString *)getInvertedOrderMacWithData:(NSData *)data {
NSString *macTemp = data.description;
NSMutableString *mutableMac = [[NSMutableString alloc]init];;
if (macTemp) {
macTemp = [macTemp stringByReplacingOccurrencesOfString:@" " withString:@""];
macTemp = [macTemp stringByReplacingOccurrencesOfString:@"<" withString:@""];
macTemp = [macTemp stringByReplacingOccurrencesOfString:@">" withString:@""];
macTemp = [macTemp substringFromIndex:4];
for (int i = 0; i<6; i++) {
NSString *str = [macTemp substringWithRange:NSMakeRange(macTemp.length-2-i*2, 2)];
if (i==5) {
[mutableMac appendString:[NSString stringWithFormat:@"%@",str]];
}
else{
[mutableMac appendString:[NSString stringWithFormat:@"%@:",str]];
}
}
}
return mutableMac;
}
/**
正序mac地址
*/
+ (NSString *)getPositiveSequenceMacWithData:(NSData *)data {
NSString *dataStr = [self hexStringFromData:data];
NSMutableString *mutableMac = [[NSMutableString alloc]init];;
if (dataStr) {
dataStr = [dataStr stringByReplacingOccurrencesOfString:@" " withString:@""];
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"<" withString:@""];
dataStr = [dataStr stringByReplacingOccurrencesOfString:@">" withString:@""];
for (int i = 0; i < 6; i++) {
NSString *str = [dataStr substringWithRange:NSMakeRange(i*2, 2)];
if (i == 5) {
[mutableMac appendString:[NSString stringWithFormat:@"%@",str]];
}else {
[mutableMac appendString:[NSString stringWithFormat:@"%@:",str]];
}
}
}
return [mutableMac uppercaseString];
}
/**
Data转16进制字符串
*/
+ (NSString *)hexStringFromData:(NSData*)data {
if (![data isKindOfClass:[NSData class]]) {
return nil;
}
if (data == nil) {
return nil;
}
NSMutableString *hexString = [NSMutableString string];
const unsigned char *p = [data bytes];
for (int i=0; i < [data length]; i++) {
[hexString appendFormat:@"%02x", *p++];
}
return hexString;
}
@end