一、简介
iOS与硬件设备模块(C语言)通信,iOS发送消息指令给硬件,硬件收到消息后,进行逻辑处理,再将应答消息返回iOS解析,界面展示结果
C语言采用unsigned char接收二进制数据,iOS需要将16进制数据转换成Byte数组,以NSData类型向设备发送协议
unsigned char(等于Byte) 1个字节 值域范围:0~255
*_t类型为:
序号 | 类型 | 字节长度 |
---|---|---|
1 | uint8_t | 1字节 |
2 | uint16_t | 2字节 |
3 | uint32_t | 4字节 |
4 | uint64_t | 8字节 |
二、发送协议消息
1.将拼接的16进制消息内容转换为Data数据
NSData *verificationData = [self convertHexStrToData:msgContent];
2.调用CRC16方法,将消息内容生成4位校验码,返回(消息内容+CRC校验码)
NSData *converData = [self calCRCWithData:verificationData];
3.将消息体内容进行转义处理,比如:AA <————> BB后紧跟一个 01
NSString *strMsg =[self convertDataToHexStr:finalDataM];
4.在转义内容前后增加标识位
NSString *flagBit = @"FF";
strMsg = [flagBit stringByAppendingString:strMsg];
strMsg = [strMsg stringByAppendingString:flagBit];
5.拆分NSString字符,每2位转换为unsigned char,放入数组中
NSData *trandata2 = [self convertHexStrToData:strMsg];
6.通过TCP将NSData数据发送给设备
三、接收应答消息
1.解析设备返回的应答数据,转换为16进制字符串
NSData *dataMsg = [NSData dataWithBytes:bytes length:sizeof(bytes)];
2.判断应答字符串前后缀是否为“FF“
NSString *headeMsg = [strMsg substringWithRange:range];
range.location = [strMsg length]-2;
NSString *footMsg = [strMsg substringWithRange:range];
BOOL result1 = [@"FF" caseInsensitiveCompare:headeMsg] == NSOrderedSame;
BOOL result2 = [@"FF" caseInsensitiveCompare:footMsg] == NSOrderedSame;
if(result1 == YES && result2){
NSLog(@"标示位错误!");
}else{
NSLog(@"标示位错误!");
}
3.将应答字符串反转义
NSData *finalUnescapesData= [self UnescapesData:verificationData];
NSString *unescapesStr =[self convertDataToHexStr:finalUnescapesData];
4.调用CRC16方法,将消息体生成4位校验码
NSData *crcData = [self calCRCValidCodeWithData:[self convertHexStrToData:msg1]];
NSString *crcStr =[self convertDataToHexStr:crcData];
5.判断生成的校验码和应答字符串的校验码是否一致
BOOL valideResult = [validCodeMsg caseInsensitiveCompare:crcStr] == NSOrderedSame;
if(valideResult){
NSLog(@"解析成功!");
}else{
NSLog(@"解析失败!");
}
四、通用转换方法
1.将16进制字符串转换成NSData
+ (NSMutableData *)convertHexStrToData:(NSString *)str {
if (!str || [str length] == 0) {
return nil;
}
NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
NSRange range;
if ([str length] %2 == 0) {
range = NSMakeRange(0,2);
} else {
range = NSMakeRange(0,1);
}
for (NSInteger i = range.location; i < [str length]; i += 2) {
unsigned int anInt;
NSString *hexCharStr = [str substringWithRange:range];
NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
[scanner scanHexInt:&anInt];
NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
NSLog(@"转换数据--%ld:%@", (long)i,entity);
[hexData appendData:entity];
range.location += range.length;
range.length = 2;
}
return hexData;
}
2.将NSData转换成16进制的字符串
+ (NSString *)convertDataToHexStr:(NSData *)data {
if (!data || [data length] == 0) {
return @"";
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange,BOOL *stop) {
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i =0; i < byteRange.length; i++) {
NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) &0xff];
if ([hexStr length] == 2) {
[string appendString:hexStr];
} else {
[string appendFormat:@"0%@", hexStr];
}
}
}];
return string;
}
3.将16进制字符串转成NSData+CRC数据
+ (NSData *)calCRCWithData:(NSData *)visibleData
{
//将16进制字符串转成NSData数据
NSMutableData *visibleDataM = [visibleData mutableCopy];
//NSData做crc验证得到short返回值
Byte *byte = (Byte *)[visibleDataM bytes];
unsigned short crcShort = u16CRC_Calc162(byte, (int)visibleDataM.length);
//将short返回值转成byte类型添加到可变数组末尾
Byte bytes[2];
bytes[0] = (Byte) (crcShort >> 8);
bytes[1] = (Byte) (crcShort);
[visibleDataM appendBytes:bytes length:sizeof(bytes)];
return visibleDataM;
}
4、获取CRC校验码
+ (NSData *)calCRCValidCodeWithData:(NSData *)visibleData
{
//NSData做crc验证得到short返回值
Byte *byte = (Byte *)[visibleData bytes];
unsigned short crcShort = u16CRC_Calc162(byte, (int)visibleData.length);
//将short返回值转成byte类型添加到可变数组末尾
Byte bytes[2];
bytes[0] = (Byte) (crcShort >> 8);
bytes[1] = (Byte) (crcShort);
return [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
}
5、对Data+CRC数据进行转义
+ (NSData *)EscapedData:(NSData *)converData
{
/**
对Data+CRC数据进行转义
*/
Byte *myBytes = (Byte *)[converData bytes];
NSMutableData *finalDataM = [NSMutableData data];
for (int i = 0; i < converData.length; i++) {
if (myBytes[i] == 0xAA) {
Byte temByte[2];
temByte[0] = 0xBB;
temByte[1] = 0x01;
[finalDataM appendBytes:temByte length:sizeof(temByte)];
}
else if (myBytes[i] == 0xCC) {
Byte temByte[2];
temByte[0] = 0xDD;
temByte[1] = 0x02;
[finalDataM appendBytes:temByte length:sizeof(temByte)];
}
else{
Byte temByte[1];
temByte[0] = myBytes[i];
[finalDataM appendBytes:temByte length:sizeof(temByte)];
}
}
return finalDataM;
}
6、对Data+CRC数据进行反转义
+ (NSData *)UnescapesData:(NSData *)converData
{
/**
对Data+CRC数据进行反转义
*/
Byte *myBytes = (Byte *)[converData bytes];
NSMutableData *finalDataM = [NSMutableData data];
for (int i = 0; i < converData.length; i++) {
if (myBytes[i] == 0xBB && myBytes[i+1] == 01) {
Byte temByte[1];
temByte[0] = 0xAA;
[finalDataM appendBytes:temByte length:sizeof(temByte)];
i++;
}
else if (myBytes[i] == 0xDD && myBytes[i+1] == 02) {
Byte temByte[1];
temByte[0] = 0xCC;
[finalDataM appendBytes:temByte length:sizeof(temByte)];
i++;
}
else{
Byte temByte[1];
temByte[0] = myBytes[i];
[finalDataM appendBytes:temByte length:sizeof(temByte)];
}
}
return finalDataM;
}