【iOS】smartconfig 广播实现

一、框架

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
...


截屏2021-04-29 15.49.01.png

你可能感兴趣的:(【iOS】smartconfig 广播实现)