导入airkiss获取mac

This commit is contained in:
祝发冬
2023-08-15 20:26:29 +08:00
parent fb139ab149
commit a27efea1f6
8 changed files with 627 additions and 2 deletions
BIN
View File
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
//
// JMAirKiss.h
// JMAirKiss
//
// Created by shengxiao on 16/3/2.
// Copyright © 2016年 shengxiao. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for JMAirKiss.
FOUNDATION_EXPORT double JMAirKissVersionNumber;
//! Project version string for JMAirKiss.
FOUNDATION_EXPORT const unsigned char JMAirKissVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <JMAirKiss/PublicHeader.h>
#import "GCDAsyncUdpSocket.h"
#import "JMAirKissConnection.h"
+30
View File
@@ -0,0 +1,30 @@
//
// JMAirKissConnection.h
// JMAirKiss
//
// Created by shengxiao on 16/3/2.
// Copyright © 2016年 shengxiao. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^AirKissConnectionSuccess) (NSString*macAddress);
typedef void (^AirKissConnectionFailure) (void);
@interface JMAirKissConnection : NSObject
@property(nonatomic,copy) AirKissConnectionSuccess connectionSuccess;
@property(nonatomic,copy) AirKissConnectionFailure connectionFailure;
/**
* AirKiss连接
*
* @param ssidStr ssid
* @param pswStr psw
*/
- (void)connectAirKissWithSSID:(NSString *)ssidStr
password:(NSString *)password;
- (void)closeConnection;
@end
+252
View File
@@ -0,0 +1,252 @@
//
// JMAirKissConnection.m
// JMAirKiss
//
// Created by shengxiao on 16/3/2.
// Copyright © 2016年 shengxiao. All rights reserved.
//
#import "JMAirKissConnection.h"
#import "JMAirKissEncoder.h"
#import "GCDAsyncUdpSocket.h"
#import "ESPTouchTaskParameter.h"
#import "ESP_NetUtil.h"
#define kAirKiss_Port 10000
#define kAirKiss_Host @"255.255.255.255"
#define kAirKiss_Limit_Return_Random_Num 20
@interface JMAirKissConnection()<GCDAsyncUdpSocketDelegate>
{
JMAirKissEncoder *_airKissEncoder;
NSTimer *_timer; // 超过1分钟未连接成功则表示失败
GCDAsyncUdpSocket *_clientUdpSocket;
GCDAsyncUdpSocket *_serverUdpSocket;
long _tag;
int _returnRandomNum;
BOOL _connectionDone;
}
@property (nonatomic,strong) ESPTaskParameter *_parameter;
@end
@implementation JMAirKissConnection
- (instancetype)init
{
self = [super init];
if (self) {
_airKissEncoder = [[JMAirKissEncoder alloc] init];
_tag = 0;
_returnRandomNum = 0;
_connectionDone = false;
self._parameter = [[ESPTaskParameter alloc]init];
// check whether IPv4 and IPv6 is supported
NSString *localInetAddr4 = [ESP_NetUtil getLocalIPv4];
if (![ESP_NetUtil isIPv4PrivateAddr:localInetAddr4]) {
localInetAddr4 = nil;
}
NSString *localInetAddr6 = [ESP_NetUtil getLocalIPv6];
[self._parameter setIsIPv4Supported:localInetAddr4!=nil];
[self._parameter setIsIPv6Supported:localInetAddr6!=nil];
[self setupClientUdpSocket];
[self setupServerUdpSocket];
}
return self;
}
#pragma mark - Connection
/**
* AirKiss连接
*
* @param ssidStr ssid
* @param pswStr psw
*/
- (void)connectAirKissWithSSID:(NSString *)ssidStr
password:(NSString *)password {
NSMutableArray *dataArray = [_airKissEncoder createAirKissEncorderWithSSID:ssidStr ? :@""
password:password ? :@""];
_tag = 0;
_returnRandomNum = 0;
_connectionDone = false;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
_timer = [NSTimer scheduledTimerWithTimeInterval:60
target:self
selector:@selector(connectFailure)
userInfo:nil
repeats:NO];
});
for (int i = 0;i < dataArray.count;i++) {
if (_connectionDone == true) {
break;
}
UInt16 length = [dataArray[i] unsignedShortValue];
NSMutableData *mData = [NSMutableData data];
UInt8 value = 0;
for (int j = 0; j < length; j++) {
[mData appendBytes:&value length:1];
}
[_clientUdpSocket sendData:mData
toHost:kAirKiss_Host
port:kAirKiss_Port
withTimeout:-1
tag:_tag];
[NSThread sleepForTimeInterval:0.004];
_tag++;
}
});
}
- (void)closeConnection {
_connectionDone = true;
[_timer invalidate];
_timer = nil;
[_clientUdpSocket close];
[_serverUdpSocket close];
_clientUdpSocket = nil;
_serverUdpSocket = nil;
}
#pragma mark - Set up udp socket
- (void)setupClientUdpSocket
{
NSError *error = nil;
if (!_clientUdpSocket) {
_clientUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[_clientUdpSocket enableBroadcast:YES error:&error];
}
if (![_clientUdpSocket bindToPort:0 error:&error])
{
return;
}
if (![_clientUdpSocket beginReceiving:&error])
{
return;
}
}
- (void)setupServerUdpSocket {
if (!_serverUdpSocket) {
_serverUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[_serverUdpSocket enableBroadcast:YES error:nil];
}
NSError *error = nil;
if (![_serverUdpSocket bindToPort:kAirKiss_Port error:&error])
{
return;
}
if (![_serverUdpSocket beginReceiving:&error])
{
return;
}
}
#pragma mark - Event Response
- (void)connectFailure {
[_timer invalidate];
_timer = nil;
_connectionDone = true;
if (_connectionFailure) {
_connectionFailure();
}
}
#pragma mark - GCDAsyncUdpSocketDelegate
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag
{
// You could add checks here
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
{
// You could add checks here
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock
didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
if (_serverUdpSocket == sock) {
if (_connectionDone) {
return;
}
// 设备连接WIFI成功后会像10000端口发送至少20个UDP广播包所附带的随机数
if (data != nil) {
UInt8 *bytes = (UInt8 *) [data bytes];
if (bytes[0] == _airKissEncoder.randomChar) {
_returnRandomNum ++;
if (_returnRandomNum >= 2) {
// 成功
[_timer invalidate];
_timer = nil;
if (_returnRandomNum == kAirKiss_Limit_Return_Random_Num) {
_connectionDone = true;
NSData*MacData = [data subdataWithRange:NSMakeRange(1, data.length-1)];
NSString*macstring = [self.class dataToHexString:MacData];
if (_connectionSuccess) {
_connectionSuccess(macstring);
}
}
}
}
}
}
}
// NSdata进制转十六进制字符串
+(NSString *) dataToHexString:(NSData*)data
{
NSUInteger len = [data length];
char * chars = (char *)[data bytes];
NSMutableString * hexString = [[NSMutableString alloc] init];
for(NSUInteger i = 0; i < len; i++ )
[hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]];
return hexString;
}
// 十六进制字符串转NSdata进制
+(NSData *) stringToHexData:(NSString*)string{
NSInteger len = [string length] / 2; // Target length
unsigned char *buf = malloc(len);
unsigned char *whole_byte = buf;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [string length] / 2; i++) {
byte_chars[0] = [string characterAtIndex:i*2];
byte_chars[1] = [string characterAtIndex:i*2+1];
*whole_byte = strtol(byte_chars, NULL, 16);
whole_byte++;
}
NSData *data = [NSData dataWithBytes:buf length:len];
free( buf );
return data;
}
@end
+28
View File
@@ -0,0 +1,28 @@
//
// JMAirKissEncoder.h
// UdpEchoClient
//
// Created by shengxiao on 16/2/27.
//
//
#import <Foundation/Foundation.h>
@interface JMAirKissEncoder : NSObject
/**
* 创建AirKiss数据
*
* @param ssid <#ssid description#>
* @param psd <#psd description#>
*
* @return 装载要发送的每条数据的长度的数组
*/
- (NSMutableArray *)createAirKissEncorderWithSSID:(NSString *)ssid
password:(NSString *)password;
/**
*@description 随机数
*/
@property (nonatomic,readonly) UInt8 randomChar;
@end
+199
View File
@@ -0,0 +1,199 @@
//
// JMAirKissEncoder.m
// UdpEchoClient
//
// Created by shengxiao on 16/2/27.
//
//
#import "JMAirKissEncoder.h"
#define kRandomChar arc4random() % 127
@interface JMAirKissEncoder()
{
NSMutableArray *_mEncodedDatas;
UInt8 _mRandomChar;
}
@end
@implementation JMAirKissEncoder
- (instancetype)init {
self = [super init];
if (self) {
_mEncodedDatas = [NSMutableArray array];
}
return self;
}
/**
* 创建AirKiss数据
*
* @param ssid <#ssid description#>
* @param psd <#psd description#>
*
* @return 装载要发送的每条数据的长度的数组
*/
- (NSMutableArray *)createAirKissEncorderWithSSID:(NSString *)ssid
password:(NSString *)password {
[_mEncodedDatas removeAllObjects];
int times = 5;
_mRandomChar = kRandomChar;
while (times-- > 0) {
[self getLeadingPart];
[self getMagicCodeWithSSID:ssid
password:password];
for (int i = 0; i < 15; i++) {
[self getPrefixCodeWithPSW:password];
NSMutableData *data = [NSMutableData dataWithData:[password dataUsingEncoding:NSUTF8StringEncoding]];// 密码
[data appendBytes:&_mRandomChar length:1]; // 随机数
[data appendData:[ssid dataUsingEncoding:NSUTF8StringEncoding]]; // ssid
int size = 4;
int index = 0;
NSData *tempData = nil;
for (index = 0;index < (data.length / size); index++) {
// 以4为粒度
tempData = [data subdataWithRange:NSMakeRange(index * size, size)];
[self getSequenceWithIndex:index
data:tempData];
}
if ((data.length % size) != 0) {
tempData = [data subdataWithRange:NSMakeRange(index * size, data.length % size)];
[self getSequenceWithIndex:index
data:tempData];
}
}
}
return _mEncodedDatas;
}
/**
* 前导域数据
*/
- (void)getLeadingPart {
for (int i = 0; i < 50; ++i) {
for (int j = 1; j <= 4; ++j) {
[_mEncodedDatas addObject:[NSNumber numberWithInt:j]];
}
}
}
/**
* magic code
*/
- (void)getMagicCodeWithSSID:(NSString *)ssid
password:(NSString *)password {
UInt8 length = ssid.length + password.length + 1;
UInt8 magicCode[4] = {0x00,0x00,0x00,0x00};
magicCode[0] = 0x00 | (length >> 4 & 0xF);
if (magicCode[0] == 0) {
magicCode[0] = 0x08;
}
magicCode[1] = 0x10 | (length & 0xF);
UInt8 *cipherBuffer = (UInt8*)[ssid UTF8String];
UInt8 crc8 = CRC8(cipherBuffer, (int)ssid.length);
magicCode[2] = 0x20 | (crc8 >> 4 & 0xF);
magicCode[3] = 0x30 | (crc8 & 0xF);
for (int i = 0; i < 20; ++i) {
for (int j = 0; j < 4; ++j) {
[_mEncodedDatas addObject:[NSNumber numberWithUnsignedChar:magicCode[j]]];
}
}
}
/**
* prefix code
*
* @param psw <#psw description#>
*/
- (void)getPrefixCodeWithPSW:(NSString *)psw {
UInt8 length = psw.length;
UInt8 crc8 = CRC8(&length, 1);
UInt8 prefixCode[4] = {0x00,0x00,0x00,0x00};
prefixCode[0] = 0x40 | (length >> 4 & 0xF);
prefixCode[1] = 0x50 | (length & 0xF);
prefixCode[2] = 0x60 | (crc8 >> 4 & 0xF);
prefixCode[3] = 0x70 | (crc8 & 0xF);
for (int j = 0; j < 4; ++j) {
[_mEncodedDatas addObject:[NSNumber numberWithUnsignedChar:prefixCode[j]]];
}
}
/**
* sequence
*
* @param index <#index description#>
* @param data <#data description#>
*/
- (void)getSequenceWithIndex:(UInt8)index
data:(NSData *)data {
UInt8 newIndex = index & 0xFF;
NSMutableData *mData = [NSMutableData dataWithBytes:&newIndex
length:1];
[mData appendData:data];
UInt8 *originUData = (UInt8 *)[data bytes];
UInt8 *newUData = (UInt8 *)[mData bytes];
UInt8 crc8 = CRC8(newUData, (int)mData.length);
[_mEncodedDatas addObject:[NSNumber numberWithUnsignedChar:(0x80 | crc8)]];
[_mEncodedDatas addObject:[NSNumber numberWithUnsignedChar:(0x80 | index)]];
for (int i = 0;i < data.length;i++) {
[_mEncodedDatas addObject:[NSNumber numberWithUnsignedShort:(0x100 | originUData[i])]];
}
}
/**
* 获取CRC8值
*
* @param data <#data description#>
* @param len <#len description#>
*
* @return <#return value description#>
*/
UInt8 CRC8(UInt8 * data, int len)
{
UInt8 cFcs = 0;
int i, j;
for( i = 0; i < len; i ++ ) {
cFcs ^= data[i];
for(j = 0; j < 8; j ++) {
if(cFcs & 1) {
cFcs ^= 0x18; /* CRC (X(8) + X(5) + X(4) + 1) */
cFcs >>= 1;
cFcs |= 0x80;
//cFcs = (BYTE)((cFcs >> 1) ^ AL2_FCS_COEF);
} else {
cFcs >>= 1;
}
}
}
return cFcs;
}
#pragma mark - Properties
- (UInt8)randomChar {
return _mRandomChar;
}
@end
+64
View File
@@ -0,0 +1,64 @@
//
// Defines.h
// JMAirKiss
//
// Created by shengxiao on 16/3/28.
// Copyright © 2016年 shengxiao. All rights reserved.
//
#ifndef Defines_h
#define Defines_h
#define kMagic_Num_0 0xFD
#define kMagic_Num_1 0x01
#define kMagic_Num_2 0xFE
#define kMagic_Num_3 0xFC
#define kHead_Length_0 0x00
#define kHead_Length_1 0x20
#define kProto_Version_0 0x00
#define kProto_Version_1 0x02
#define kCMD_Discorvery_Req_0 0x00
#define kCMD_Discorvery_Req_1 0x00
#define kCMD_Discorvery_Req_2 0x00
#define kCMD_Discorvery_Req_3 0x01
#define kCMD_Discorvery_Resp_0 0x00
#define kCMD_Discorvery_Resp_1 0x00
#define kCMD_Discorvery_Resp_2 0x10
#define kCMD_Discorvery_Resp_3 0x01
#define kCMD_Get_Dev_Pro_Req_0 0x00
#define kCMD_Get_Dev_Pro_Req_1 0x00
#define kCMD_Get_Dev_Pro_Req_2 0x00
#define kCMD_Get_Dev_Pro_Req_3 0x03
#define kCMD_Get_Dev_Pro_Resp_0 0x00
#define kCMD_Get_Dev_Pro_Resp_1 0x00
#define kCMD_Get_Dev_Pro_Resp_2 0x10
#define kCMD_Get_Dev_Pro_Resp_3 0x03
#define kCMD_User_Dev_Ser_Req_0 0x00
#define kCMD_User_Dev_Ser_Req_1 0x00
#define kCMD_User_Dev_Ser_Req_2 0x00
#define kCMD_User_Dev_Ser_Req_3 0x07
#define kCMD_User_Dev_Ser_Resp_0 0x00
#define kCMD_User_Dev_Ser_Resp_1 0x00
#define kCMD_User_Dev_Ser_Resp_2 0x10
#define kCMD_User_Dev_Ser_Resp_3 0x07
#define kPrefix_Data_Length 32
#define kTotalLength_Start_Index 8
#define kTotalLength_Bytes_Num 4
#define kCMD_Start_Index 12
#define kCMD_Bytes_Num 4
#define kCheckNum_Start_Index 20
#define kCheckNum_Bytes_Num 4
#endif /* Defines_h */