一、框架
1.UDP框架 GCDAsyncUdpSocket;
2.加密方式,采用aes_cfb128 iv为0 ;
3.抓包验证wireshark
二、数据初始化
1.初始化UDPSocket
_castSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:_castQueue];
(1)开启广播 Broadcast;
if (![_castSocket enableBroadcast:YES error:&error]) {
UdpLog(@"enableBroadcast error:%@",error);
}
(2)接收数据 beginReceiving;
if (![_castSocket beginReceiving:&error]) {
UdpLog(@"beginReceiving error:%@",error);
}
(3)指定端口 不指定则会随机分配;
三、数据发送
(1)发送地址
端口与设备端协商,这里以60000举例
local:port -> 192.168.2.255 : 60000 + index
(2)数据
说明 | |
---|---|
dataByte | 总长度(1) + flag(1) + ssidLen(1) + pwdLen(1) + ssid + pwd + checkSum(2) |
ssid: | ssid为中文则采用utf-8编码,其他则为ASCII编码 |
pwd | pwd需要加密 |
checkSum | 校验和 |
//判断中文
- (BOOL)isChinese:(NSString *) str{
for(int i=0; i< [str length];i++){
int a = [str characterAtIndex:i];
if( a > 0x4E00 && a < 0x9FFF){
return YES;
}
}
return NO;
}
//aes加密
- (NSData *)gnAesEncryptData:(uint8_t *)crypt_data len:(int)crypt_len keyData:(NSData *)keydata{
unsigned char *keyResult=(Byte*)[keydata bytes];
AES_KEY aes_key;
unsigned char *outByte = NULL;
outByte = (unsigned char *)malloc(crypt_len+1);
memset(outByte, 0, crypt_len+1);
AES_set_encrypt_key(keyResult, 128, &aes_key);
int number = 0;
NSData *ivData = [NSData dataWithBytes:&number length:1];
unsigned char *ivResult = (Byte*)[ivData bytes];
NSData *numData = [NSData dataWithBytes:&number length:1];
int *numResult = (int *)[numData bytes];
AES_cfb128_encrypt(crypt_data,outByte,crypt_len, &aes_key,ivResult,numResult ,AES_ENCRYPT);
NSData *Decrydata = [NSData dataWithBytes:outByte length:crypt_len];
return Decrydata;
}
(3)发送结构
利用广播的数据长度length发送数据 每次发送11bit数据,
帧头与设备端协商,这里以0x480举例
数据分为
说明 | |
---|---|
帧头 | 0x480 , 0x481,0x482,0x483… |
帧数据 | index(4bit) + data(7bit) |
bit7 帧头固定为1 ,数据帧固定为0;
发送数按组发送 一组是一个帧头*2 + 8个数据帧;
[self.castClient sendData:[self zeroDataWithCount:value] toHost:_broadcastIP port:60000+_sendCount];
(4)转码
由于bit7是帧头位, 所以每次只能发送6bit数据,就需要对整个数据 进行8bit->6bit转码
例如
0x 11 22 (0b 0001 0001 0010 0010 (高位到低位)) -> 1000 1000 0100 0100(低位到高位)
-> 100010 000100 010000(低位到高位) -> 010001 001000 0000010(高位到低位) ->0x11 08 02
int bitCount = 6;
int dataLength = (int)data.length;
Byte codeData[dataLength * bitCount];
int outLength = (dataLength * 8 + bitCount - 1) /bitCount;
Byte outData[outLength];
Byte *dataByte = (Byte *)data.bytes;
for (int i = 0; i < dataLength; i ++) {
for (int j = 0; j < 8; j++) {
codeData[i * 8 + j] = (dataByte[i] >> j) & 0x01;
}
}
for (int i = 0; i < outLength; i++) {
outData[i] = 0;
for (int j = 0; j < bitCount; j ++) {
outData[i] |= codeData[i * bitCount + j] << j;
}
}
NSData *tempCodeData = [NSData dataWithBytes:outData length:sizeof(outData)];
return tempCodeData;
(5)传输规则
每包之间间隔20ms;间隔时间可按实际情况调整
(1) 帧头*2 (0x480 -> 1152)
(2) 帧数据 8 (组序号<<7 + data[index])
(3) 帧头2 (0x481 -> 1153)
(4) 帧数据 8
(5) 帧头2 (0x482 -> 1154)
(6) 帧数据 *8
...