// // BluetoothTool.m // BluetoothDemo // // Created by mac on 17/3/16. // Copyright © 2017年 . All rights reserved. // #import "BluetoothToolFireBoltt.h" #import //通讯录库 #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 >=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 ; i2000) { 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