更新EsptouchForIOS

This commit is contained in:
kai60
2020-06-10 20:27:25 +08:00
parent 1f69653c19
commit b8d6ad08ea
42 changed files with 1625 additions and 853 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
@@ -1,37 +0,0 @@
//
// ESPNetUtil.h
// EspTouchDemo
//
// Created by 白 桦 on 5/15/15.
// Copyright (c) 2015 白 桦. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ESP_NetUtil : NSObject
/**
* get the local ip address by IOS System
*
*/
+ (NSData *) getLocalInetAddress;
/**
* parse InetAddress
*/
+ (NSData *) parseInetAddrByData: (NSData *) inetAddrData andOffset: (int) offset andCount: (int) count;
/**
* descrpion inetAddrData for print pretty
*/
+ (NSString *) descriptionInetAddrByData: (NSData *) inetAddrData;
/**
* parse bssid
*
* @param bssid the bssid
* @return byte converted from bssid
*/
+ (NSData *) parseBssid2bytes: (NSString *) bssid;
@end
@@ -1,92 +0,0 @@
//
// ESPNetUtil.m
// EspTouchDemo
//
// Created by 白 桦 on 5/15/15.
// Copyright (c) 2015 白 桦. All rights reserved.
//
#import "ESP_NetUtil.h"
#include "IPAddress.h"
#include "ESP_ByteUtil.h"
// only support ipV4 at the moment
#define IP_LEN 4
@implementation ESP_NetUtil
+ (NSData *) getLocalInetAddress
{
InitAddresses();
GetIPAddresses();
GetHWAddresses();
NSData *localInetAddrData = nil;
Byte localIpBytes[IP_LEN];
for (int i=0; i<MAXADDRS; ++i)
{
static unsigned long localHost = 0x100007F; // 127.0.0.1
unsigned long theAddr;
theAddr = ip_addrs[i];
if (theAddr == 0) break;
if (theAddr == localHost) continue;
// NSLog(@"theAddr=%lu",theAddr);
// hard coding
localIpBytes[0] = (theAddr & 0xff) >> 0;
localIpBytes[1] = (theAddr & 0xff00) >> 8;
localIpBytes[2] = (theAddr & 0xff0000) >> 16;
localIpBytes[3] = (theAddr & 0xff000000) >> 24;
// NSLog(@"ESP_NetUtil:: %d.%d.%d.%d",localIpBytes[0],localIpBytes[1],localIpBytes[2],localIpBytes[3]);
// if (theAddr != 0) break;
// NSLog(@"ESP_NetUtil:: Name: %s MAC: %s IP: %s\n", if_names[i], hw_addrs[i], ip_names[i]);
}
localInetAddrData = [[NSData alloc]initWithBytes:localIpBytes length:IP_LEN];
FreeAddresses();
Byte byte1 = 0;
Byte byte2 = 0;
Byte byte3 = 0;
Byte byte4 = 0;
[localInetAddrData getBytes:&byte1 range:NSMakeRange(0, 1)];
[localInetAddrData getBytes:&byte2 range:NSMakeRange(1, 1)];
[localInetAddrData getBytes:&byte3 range:NSMakeRange(2, 1)];
[localInetAddrData getBytes:&byte4 range:NSMakeRange(3, 1)];
NSLog(@"ESP_NetUtil:: %d.%d.%d.%d", byte1,byte2,byte3,byte4);
return localInetAddrData;
}
+ (NSData *) parseInetAddrByData: (NSData *) inetAddrData andOffset: (int) offset andCount: (int) count
{
return [inetAddrData subdataWithRange:NSMakeRange(offset, count)];
}
+ (NSString *) descriptionInetAddrByData: (NSData *) inetAddrData
{
Byte inetAddrBytes[IP_LEN];
[inetAddrData getBytes:inetAddrBytes length:IP_LEN];
// hard coding
return [NSString stringWithFormat:@"%d.%d.%d.%d",inetAddrBytes[0],inetAddrBytes[1],inetAddrBytes[2],inetAddrBytes[3]];
}
+ (NSData *) parseBssid2bytes: (NSString *) bssid
{
NSArray *bssidArray = [bssid componentsSeparatedByString:@":"];
NSInteger size = [bssidArray count];
Byte bssidBytes[size];
for (NSInteger i = 0; i < size; i++) {
NSString *bssidStr = [bssidArray objectAtIndex:i];
bssidBytes[i] = strtoul([bssidStr UTF8String], 0, 16);
}
return [[NSData alloc]initWithBytes:bssidBytes length:size];
}
@end
@@ -1,216 +0,0 @@
//
// IPAddress.c
// LocalIpDemo
//
// Created by 白 桦 on 5/11/15.
// Copyright (c) 2015 白 桦. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <errno.h>
#include <net/if_dl.h>
#include <net/ethernet.h>
#include "IPAddress.h"
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define BUFFERSIZE 4000
char *if_names[MAXADDRS];
char *ip_names[MAXADDRS];
char *hw_addrs[MAXADDRS];
unsigned long ip_addrs[MAXADDRS];
static int nextAddr = 0;
void InitAddresses()
{
int i;
for (i=0; i<MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
ip_addrs[i] = 0;
}
}
void FreeAddresses()
{
int i;
for (i=0; i<MAXADDRS; ++i)
{
if (if_names[i] != 0) free(if_names[i]);
if (ip_names[i] != 0) free(ip_names[i]);
if (hw_addrs[i] != 0) free(hw_addrs[i]);
ip_addrs[i] = 0;
nextAddr = 0;
}
InitAddresses();
}
void GetIPAddresses()
{
int i, len, flags;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
struct sockaddr_in *sin;
char temp[80];
int sockfd;
for (i=0; i<MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = NULL;
ip_addrs[i] = 0;
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket failed");
return;
}
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
{
perror("ioctl error");
return;
}
lastname[0] = 0;
for (ptr = buffer; ptr < buffer + ifc.ifc_len; )
{
ifr = (struct ifreq *)ptr;
len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
ptr += sizeof(ifr->ifr_name) + len; // for next one in buffer
if (ifr->ifr_addr.sa_family != AF_INET)
{
continue; // ignore if not desired address family
}
if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL)
{
*cptr = 0; // replace colon will null
}
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
{
continue; /* already processed this interface */
}
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
flags = ifrcopy.ifr_flags;
if ((flags & IFF_UP) == 0)
{
continue; // ignore if interface not up
}
if_names[nextAddr] = (char *)malloc(strlen(ifr->ifr_name)+1);
if (if_names[nextAddr] == NULL)
{
return;
}
strcpy(if_names[nextAddr], ifr->ifr_name);
sin = (struct sockaddr_in *)&ifr->ifr_addr;
strcpy(temp, inet_ntoa(sin->sin_addr));
ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);
if (ip_names[nextAddr] == NULL)
{
return;
}
strcpy(ip_names[nextAddr], temp);
ip_addrs[nextAddr] = sin->sin_addr.s_addr;
++nextAddr;
}
close(sockfd);
}
void GetHWAddresses()
{
struct ifconf ifc;
struct ifreq *ifr;
int i, sockfd;
char buffer[BUFFERSIZE], *cp, *cplim;
char temp[80];
for (i=0; i<MAXADDRS; ++i)
{
hw_addrs[i] = NULL;
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket failed");
return;
}
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
{
perror("ioctl error");
close(sockfd);
return;
}
ifr = ifc.ifc_req;
cplim = buffer + ifc.ifc_len;
for (cp=buffer; cp < cplim; )
{
ifr = (struct ifreq *)cp;
if (ifr->ifr_addr.sa_family == AF_LINK)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
int a,b,c,d,e,f;
int i;
strcpy(temp, (char *)ether_ntoa((const struct ether_addr *)LLADDR(sdl)));
sscanf(temp, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
sprintf(temp, "%02X:%02X:%02X:%02X:%02X:%02X",a,b,c,d,e,f);
for (i=0; i<MAXADDRS; ++i)
{
if ((if_names[i] != NULL) && (strcmp(ifr->ifr_name, if_names[i]) == 0))
{
if (hw_addrs[i] == NULL)
{
hw_addrs[i] = (char *)malloc(strlen(temp)+1);
strcpy(hw_addrs[i], temp);
break;
}
}
}
}
cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
}
close(sockfd);
}
@@ -1,26 +0,0 @@
//
// IPAddress.h
// LocalIpDemo
//
// Created by 白 桦 on 5/11/15.
// Copyright (c) 2015 白 桦. All rights reserved.
//
#ifndef LocalIpDemo_IPAddress_h
#define LocalIpDemo_IPAddress_h
#define MAXADDRS 32
extern char *if_names[MAXADDRS];
extern char *ip_names[MAXADDRS];
extern char *hw_addrs[MAXADDRS];
extern unsigned long ip_addrs[MAXADDRS];
// Function prototypes
void InitAddresses();
void FreeAddresses();
void GetIPAddresses();
void GetHWAddresses();
#endif
@@ -1,197 +0,0 @@
//
// ESPUDPSocketServer.m
// EspTouchDemo
//
// Created by 白 桦 on 4/13/15.
// Copyright (c) 2015 白 桦. All rights reserved.
//
#import "ESPUDPSocketServer.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include "ESPTouchTask.h"
@interface ESPUDPSocketServer ()
@property(nonatomic,assign) int _sck_fd;
@property(nonatomic,assign) int _port;
// it is used to check whether the socket is closed already to prevent close more than once.
// especially, when you close the socket second time, it is created just now, it will crash.
//
// // suppose fd1 = 4, fd1 belong to obj1
// e.g. int fd1 = socket(AF_INET,SOCK_DRAM,0);
// close(fd1);
//
// // suppose fd2 = 4 as well, fd2 belong to obj2
// int fd2 = socket(AF_INET,SOCK_DRAM,0);
//
// // obj1's dealloc() is called by system, so
// close(fd1);
//
// // Amazing!!! at the moment, fd2 is close by others
//
@property(nonatomic,assign) volatile bool _isClosed;
// it is used to lock the close method
@property(nonatomic,strong) volatile NSLock *_lock;
@end
@implementation ESPUDPSocketServer
- (id) initWithPort: (int) port AndSocketTimeout: (int) socketTimeout
{
self = [super init];
if (self)
{
// create local
self._lock = [[NSLock alloc]init];
// create socket
self._isClosed = NO;
self._sck_fd = socket(AF_INET,SOCK_DGRAM,0);
if (DEBUG_ON)
{
NSLog(@"##########################server init(): _sck_fd=%d", self._sck_fd);
}
if (self._sck_fd < 0)
{
if (DEBUG_ON)
{
perror("server: _skd_fd init() fail\n");
}
return nil;
}
// init socket params
struct sockaddr_in server_addr;
socklen_t addr_len;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
addr_len = sizeof(server_addr);
// set broadcast
const int opt = 1;
if (setsockopt(self._sck_fd,SOL_SOCKET,SO_BROADCAST,(char *)&opt, sizeof(opt)) < 0)
{
if (DEBUG_ON)
{
perror("server init(): setsockopt SO_BROADCAST fail\n");
}
[self close];
return nil;
}
// set timeout
[self setSocketTimeout:socketTimeout];
// bind
if (bind(self._sck_fd, (struct sockaddr*)&server_addr, addr_len) < 0)
{
if (DEBUG_ON)
{
perror("server init(): bind fail\n");
}
[self close];
return nil;
}
}
return self;
}
// make sure the socket will be closed sometime
- (void)dealloc
{
if (DEBUG_ON)
{
NSLog(@"###################server dealloc()");
}
[self close];
}
- (void) close
{
[self._lock lock];
if (!self._isClosed)
{
if (DEBUG_ON)
{
NSLog(@"###################server close() fd=%d",self._sck_fd);
}
close(self._sck_fd);
self._isClosed = true;
}
[self._lock unlock];
}
- (void) interrupt
{
[self close];
}
- (void) setSocketTimeout: (int) timeout
{
struct timeval tv;
tv.tv_sec = timeout/1000;
tv.tv_usec = timeout%1000*1000;
if (setsockopt(self._sck_fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv, sizeof(tv)) < 0)
{
if (DEBUG_ON)
{
perror("server: setsockopt SO_RCVTIMEO fail\n");
}
}
}
- (Byte) receiveOneByte
{
ssize_t recNumber = recv(self._sck_fd, _buffer, BUFFER_SIZE, 0);
if (recNumber > 0)
{
return _buffer[0];
}
else if(recNumber == 0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte socket is closed by the other\n");
}
}
else
{
if (DEBUG_ON)
{
perror("server: receiveOneByte fail\n");
}
}
return UINT8_MAX;
}
- (NSData *) receiveSpecLenBytes: (int)len
{
ssize_t recNumber = recv(self._sck_fd, _buffer, BUFFER_SIZE, 0);
if (recNumber==len)
{
NSData *data = [[NSData alloc]initWithBytes:_buffer length:recNumber];
return data;
}
else if(recNumber==0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte socket is closed by the other\n");
}
}
else if(recNumber<0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte fail\n");
}
}
else
{
// receive rubbish message, just ignore it
}
return nil;
}
@end
+19
View File
@@ -0,0 +1,19 @@
//
// ESPAES.h
// EspTouchDemo
//
// Created by AE on 2018/4/5.
//
#import <Foundation/Foundation.h>
@interface ESPAES : NSObject {
@private NSString *key;
}
- (instancetype)initWithKey:(NSString *)secretKey;
- (NSData *)AES128EncryptData:(NSData *)data;
- (NSData *)AES128DecryptData:(NSData *)data;
@end
+66
View File
@@ -0,0 +1,66 @@
//
// ESPAES.m
// EspTouchDemo
//
// Created by AE on 2018/4/5.
//
#import "ESPAES.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation ESPAES
- (instancetype)initWithKey:(NSString *)secretKey
{
self = [super init];
if (self) {
key = secretKey;
}
return self;
}
- (NSData *)AES128EncryptData:(NSData *)data {
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES128DecryptData:(NSData *)data {
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
+22
View File
@@ -0,0 +1,22 @@
//
// EspNetUtils.h
// Esp32Mesh
//
// Created by AE on 2018/4/19.
// Copyright © 2018年 AE. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ESPTools : NSObject
+ (nullable NSString *)getCurrentWiFiSsid;
+ (nullable NSString *)getCurrentBSSID;
+ (NSString *)getIPAddress:(BOOL)preferIPv4;
+ (NSDictionary *)getIPAddresses;
NS_ASSUME_NONNULL_END
@end
+132
View File
@@ -0,0 +1,132 @@
//
// EspNetUtils.m
// Esp32Mesh
//
// Created by AE on 2018/4/19.
// Copyright © 2018年 AE. All rights reserved.
//
#import "ESPTools.h"
#import <ifaddrs.h>
#import <arpa/inet.h>
#import <net/if.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
@implementation ESPTools
+ (nullable NSString *)getCurrentWiFiSsid {
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
id info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info && [info count]) {
break;
}
}
// Key: BSSID, SSID, SSIDDATA
return [(NSDictionary*)info objectForKey:@"SSID"];
}
+ (nullable NSString *)getCurrentBSSID {
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
id info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info && [info count]) {
break;
}
}
// Key: BSSID, SSID, SSIDDATA
return [(NSDictionary*)info objectForKey:@"BSSID"];
}
+ (NSString *)getIPAddress:(BOOL)preferIPv4 {
NSArray *searchArray = preferIPv4 ?
@[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
@[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
NSDictionary *addresses = [self getIPAddresses];
NSLog(@"addresses: %@", addresses);
__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
address = addresses[key];
//筛选出IP地址格式
if([self isValidatIP:address]) *stop = YES;
} ];
return address ? address : @"0.0.0.0";
}
+ (BOOL)isValidatIP:(NSString *)ipAddress {
if (ipAddress.length == 0) {
return NO;
}
NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error];
if (regex != nil) {
NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])];
if (firstMatch) {
NSRange resultRange = [firstMatch rangeAtIndex:0];
NSString *result=[ipAddress substringWithRange:resultRange];
//输出结果
NSLog(@"ESPTools 输出结果:%@",result);
return YES;
}
}
return NO;
}
+ (NSDictionary *)getIPAddresses {
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
// Loop through linked list of interfaces
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
continue; // deeply nested code harder to read
}
const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) {
if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
type = IP_ADDR_IPv6;
}
}
if(type) {
NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free memory
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
@end
+20
View File
@@ -0,0 +1,20 @@
//
// ESPVersionMacro.h
// suite
//
// Created by fby on 5/16/16.
// Copyright © 2016 fby. All rights reserved.
//
#ifndef ESPVersionMacro_h
#define ESPVersionMacro_h
#import <UIKit/UIKit.h>
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
#endif /* ESPVersionMacro_h */
@@ -2,8 +2,8 @@
// ESP_ByteUtil.h
// EspTouchDemo
//
// Created by 白 桦 on 4/7/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/7/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -48,7 +48,6 @@
* @return the high and low bytes be split, byte[0] is high and byte[1] is
* low
*/
+ (NSData *) splitUint8To2Bytes: (UInt8) uint8;
/**
@@ -60,7 +59,6 @@
* the low byte
* @return the whole byte
*/
+ (Byte) combine2bytesToOneWithHigh: (Byte) high andLow: (Byte) low;
/**
@@ -2,8 +2,8 @@
// ESP_ByteUtil.m
// EspTouchDemo
//
// Created by on 4/7/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/7/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESP_ByteUtil.h"
@@ -57,6 +57,7 @@
high = 0;
low = [self intFromHexString:[hexString substringWithRange:NSMakeRange(0, 1)]];
}
Byte bytes[] = { high, low };
NSData *data = [[NSData alloc] initWithBytes:bytes length:2];
return data;
@@ -108,7 +109,6 @@
+ (NSString *) parseBssid:(Byte[]) bssidBytes Offset: (int) offset Count: (int) count
{
Byte bytes[count];
for (int i = 0; i < count; i++ )
{
bytes[i] = bssidBytes[i + offset];
@@ -2,8 +2,8 @@
// ESP_CRC8.h
// EspTouchDemo
//
// Created by 白 桦 on 3/23/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 3/23/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -53,7 +53,7 @@
/**
* Updates the checksum value with the given byte.
*
* @param val
* @param value
* the byte to update the checksum with.
*/
- (void)updateWithValue:(int)value;
@@ -2,8 +2,8 @@
// ESP_CRC8.m
// EspTouchDemo
//
// Created by on 3/23/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 3/23/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESP_CRC8.h"
+82
View File
@@ -0,0 +1,82 @@
//
// ESPNetUtil.h
// EspTouchDemo
//
// Created by fby on 5/15/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ESP_NetUtil : NSObject
/**
* get local ip v4 or nil
*
* @return local ip v4 or nil
*/
+ (NSString *) getLocalIPv4;
/**
* get local ip v6 or nil
*
* @return local ip v6 or nil
*/
+ (NSString *) getLocalIPv6;
/**
* whether the ipAddr is v4
*
* @return whether the ipAddr is v4
*/
+ (BOOL) isIPv4Addr:(NSString *)ipAddr;
/**
* whether the ipAddr v4 is private
*
* @return whether the ipAddr v4 is private
*/
+ (BOOL) isIPv4PrivateAddr:(NSString *)ipAddr;
/**
* get the local ip address by local inetAddress ip4
*
* @param localInetAddr4 local inetAddress ip4
*/
+ (NSData *) getLocalInetAddress4ByAddr:(NSString *) localInetAddr4;
/**
* get the invented local ip address by local port
*
*/
+ (NSData *) getLocalInetAddress6ByPort:(int) localPort;
/**
* parse InetAddress
*/
+ (NSData *) parseInetAddrByData: (NSData *) inetAddrData andOffset: (int) offset andCount: (int) count;
/**
* descrpion inetAddrData for print pretty IPv4
*/
+ (NSString *) descriptionInetAddr4ByData: (NSData *) inetAddrData;
/**
* descrpion inetAddrData for print pretty IPv6
*/
+ (NSString *) descriptionInetAddr6ByData: (NSData *) inetAddrData;
/**
* parse bssid
*
* @param bssid the bssid
* @return byte converted from bssid
*/
+ (NSData *) parseBssid2bytes: (NSString *) bssid;
/**
* send a dummy GET to "https://8.8.8.8" just to get Network Permission after ios10.0(including)
*/
+ (void) tryOpenNetworkPermission;
@end
+153
View File
@@ -0,0 +1,153 @@
//
// ESPNetUtil.m
// EspTouchDemo
//
// Created by fby on 5/15/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESP_NetUtil.h"
#import "ESP_WifiUtil.h"
#import "ESP_ByteUtil.h"
#import "ESPVersionMacro.h"
#define IP4_LEN 4
#define IP6_LEN 16
@implementation ESP_NetUtil
/**
* get local ip v4 or nil
*
* @return local ip v4 or nil
*/
+ (NSString *) getLocalIPv4
{
return [ESP_WifiUtil getIPAddress4];
}
/**
* get local ip v6 or nil
*
* @return local ip v6 or nil
*/
+ (NSString *) getLocalIPv6
{
return [ESP_WifiUtil getIpAddress6];
}
+ (BOOL) isIPv4Addr:(NSString *)ipAddr
{
NSArray *ip4array = [ipAddr componentsSeparatedByString:@"."];
return [ip4array count]==4;
}
+ (BOOL) isIPv4PrivateAddr:(NSString *)ipAddr4
{
NSArray *ip4array = [ipAddr4 componentsSeparatedByString:@"."];
Byte byte0 = [[ip4array objectAtIndex:0]intValue];
Byte byte1 = [[ip4array objectAtIndex:1]intValue];
// Byte byte2 = [[ip4array objectAtIndex:2]intValue];
// Byte byte3 = [[ip4array objectAtIndex:3]intValue];
if (byte0==10) {
// 10.0.0.0~10.255.255.255
return YES;
} else if (byte0==172&&16<=byte1&&byte1<=31) {
// 172.16.0.0~172.31.255.255
return YES;
} else if (byte0==192&&byte1==168) {
// 192.168.0.0~192.168.255.255
return YES;
}
return NO;
}
+ (NSData *) getLocalInetAddress4ByAddr:(NSString *) localInetAddr4
{
NSArray *ip4array = [localInetAddr4 componentsSeparatedByString:@"."];
Byte byte0 = [[ip4array objectAtIndex:0]intValue];
Byte byte1 = [[ip4array objectAtIndex:1]intValue];
Byte byte2 = [[ip4array objectAtIndex:2]intValue];
Byte byte3 = [[ip4array objectAtIndex:3]intValue];
Byte bytes[] = {byte0,byte1,byte2,byte3};
NSData *ip4data = [NSData dataWithBytes:bytes length:IP4_LEN];
return ip4data;
}
+ (NSData *) getLocalInetAddress6ByPort:(int) localPort
{
Byte lowPort = localPort & 0xff;
Byte highPort = (localPort>>8) & 0xff;
Byte bytes[] = {highPort,lowPort,0xff,0xff};
NSData *ip6data = [NSData dataWithBytes:bytes length:IP4_LEN];
return ip6data;
}
+ (NSData *) parseInetAddrByData: (NSData *) inetAddrData andOffset: (int) offset andCount: (int) count
{
return [inetAddrData subdataWithRange:NSMakeRange(offset, count)];
}
+ (NSString *) descriptionInetAddr4ByData: (NSData *) inetAddrData
{
// check whether inetAddrData is belong to IPv4
if ([inetAddrData length]!=IP4_LEN) {
return nil;
}
Byte inetAddrBytes[IP4_LEN];
[inetAddrData getBytes:inetAddrBytes length:IP4_LEN];
// hard coding
return [NSString stringWithFormat:@"%d.%d.%d.%d",inetAddrBytes[0],inetAddrBytes[1],inetAddrBytes[2],inetAddrBytes[3]];
}
+ (NSString *) descriptionInetAddr6ByData: (NSData *) inetAddrData
{
// check whether inetAddrData is belong to IPv4
if ([inetAddrData length]!=IP6_LEN) {
return nil;
}
Byte inetAddrBytes[IP6_LEN];
[inetAddrData getBytes:inetAddrBytes length:IP6_LEN];
// hard coding
return [NSString stringWithFormat:@"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",inetAddrBytes[0],inetAddrBytes[1],inetAddrBytes[2],inetAddrBytes[3],inetAddrBytes[4],inetAddrBytes[5],inetAddrBytes[6],inetAddrBytes[7],inetAddrBytes[8],inetAddrBytes[9],inetAddrBytes[10],inetAddrBytes[11],inetAddrBytes[12],inetAddrBytes[13],inetAddrBytes[14],inetAddrBytes[15]];
}
+ (NSData *) parseBssid2bytes: (NSString *) bssid
{
NSArray *bssidArray = [bssid componentsSeparatedByString:@":"];
NSInteger size = [bssidArray count];
Byte bssidBytes[size];
for (NSInteger i = 0; i < size; i++) {
NSString *bssidStr = [bssidArray objectAtIndex:i];
bssidBytes[i] = strtoul([bssidStr UTF8String], 0, 16);
}
return [[NSData alloc]initWithBytes:bssidBytes length:size];
}
+ (NSURLSessionConfiguration *) DEFAULT_SESSION_CONFIGURATION
{
static dispatch_once_t predicate;
static NSURLSessionConfiguration *DEFAULT_SESSION_CONFIGURATION;
dispatch_once(&predicate, ^{
DEFAULT_SESSION_CONFIGURATION = [NSURLSessionConfiguration defaultSessionConfiguration];
});
return DEFAULT_SESSION_CONFIGURATION;
}
+ (void) tryOpenNetworkPermission
{
// only ios 10.0 later required to try open network permission
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
NSURL *url = [NSURL URLWithString:@"https://8.8.8.8"];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:1000];
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[self DEFAULT_SESSION_CONFIGURATION] delegate:nil delegateQueue:[NSOperationQueue currentQueue]];
[[urlSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
}] resume];
}
}
@end
+33
View File
@@ -0,0 +1,33 @@
//
// ESP_WifiUtil.h
// EspTouchDemo
//
// Created by fby on 6/15/16.
// Copyright © 2016 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ESP_WifiUtil : NSObject
// refer to http://stackoverflow.com/questions/7072989/iphone-ipad-osx-how-to-get-my-ip-address-programmatically
+ (NSString *)getIPAddress:(BOOL)preferIPv4;
// refer to http://stackoverflow.com/questions/7072989/iphone-ipad-osx-how-to-get-my-ip-address-programmatically
+ (NSDictionary *)getIPAddresses;
/**
* get local ip address by IPv4
*
* @return local ip address by IPv4(or nil when en0/ipv4 unaccessible)
*/
+ (NSString *)getIPAddress4;
/**
* get local ip address by IPv6
*
* @return local ip address by IPv6(or nil when en0/ipv6 unaccessible)
*/
+ (NSString *)getIpAddress6;
@end
+95
View File
@@ -0,0 +1,95 @@
//
// ESP_WifiUtil.m
// EspTouchDemo
//
// Created by fby on 6/15/16.
// Copyright © 2016 fby. All rights reserved.
//
#import "ESP_WifiUtil.h"
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
@implementation ESP_WifiUtil
+ (NSString *)getIPAddress:(BOOL)preferIPv4
{
NSArray *searchArray = preferIPv4 ?
@[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
@[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
NSDictionary *addresses = [self getIPAddresses];
// NSLog(@"addresses: %@", addresses);
__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
address = addresses[key];
if(address) *stop = YES;
} ];
return address ? address : @"0.0.0.0";
}
+ (NSDictionary *)getIPAddresses
{
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
// Loop through linked list of interfaces
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
continue; // deeply nested code harder to read
}
const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) {
if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
type = IP_ADDR_IPv6;
}
}
if(type) {
NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free memory
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
+ (NSString *)getIPAddress4
{
NSString *key = [NSString stringWithFormat:@"%@/%@",IOS_WIFI,IP_ADDR_IPv4];
NSString *ipv4 = [[self getIPAddresses]objectForKey:key];
return ipv4;
}
+ (NSString *)getIpAddress6
{
NSString *key = [NSString stringWithFormat:@"%@/%@",IOS_WIFI,IP_ADDR_IPv6];
NSString *ipv6 = [[self getIPAddresses]objectForKey:key];
return ipv6;
}
@end
@@ -2,8 +2,8 @@
// ESPDataCode.h
// EspTouchDemo
//
// Created by 白 桦 on 4/9/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -2,8 +2,8 @@
// ESPDataCode.m
// EspTouchDemo
//
// Created by on 4/9/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPDataCode.h"
@@ -2,8 +2,8 @@
// ESPDatumCode.h
// EspTouchDemo
//
// Created by 白 桦 on 4/9/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -29,7 +29,7 @@
* whether the Ap's ssid is hidden
*
*/
- (id) initWithSsid: (NSString *) apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString*) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden;
- (id) initWithSsid: (NSData *) apSsid andApBssid: (NSData *) apBssid andApPwd: (NSData*) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden;
- (NSData *) getBytes;
@@ -2,8 +2,8 @@
// ESPDatumCode.m
// EspTouchDemo
//
// Created by on 4/9/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPDatumCode.h"
@@ -18,34 +18,34 @@
@implementation ESPDatumCode
- (id) initWithSsid: (NSString *) apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString*) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden
- (id) initWithSsid: (NSData *) apSsid andApBssid: (NSData *) apBssid andApPwd: (NSData*) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden
{
self = [super init];
if (self)
{
// Data = total len(1 byte) + apPwd len(1 byte) + SSID CRC(1 byte) +
// BSSID CRC(1 byte) + TOTAL XOR(1 byte) + ipAddress(4 byte) + apPwd + apSsid apPwdLen <=
// 105 at the moment
// BSSID CRC(1 byte) + TOTAL XOR(1 byte) + ipAddress(4 byte) + apPwd + apSsid apPwdLen <=
// 105 at the moment
// total xor
UInt8 totalXor = 0;
NSData *apPwdBytesData = [ESP_ByteUtil getBytesByNSString:apPwd];
NSData *apSsidBytesData = [ESP_ByteUtil getBytesByNSString:apSsid];
NSData *apPwdBytesData = apPwd;
NSData *apSsidBytesData = apSsid;
Byte apPwdBytes[[apPwdBytesData length]];
Byte apSsidBytes[[apSsidBytesData length]];
[apPwdBytesData getBytes:apPwdBytes];
[apSsidBytesData getBytes:apSsidBytes];
[apPwdBytesData getBytes:apPwdBytes length:[apPwdBytesData length]];
[apSsidBytesData getBytes:apSsidBytes length:[apSsidBytesData length]];
Byte apPwdLen = [apPwdBytesData length];
ESP_CRC8 *crc = [[ESP_CRC8 alloc]init];
[crc updateWithBuf:apSsidBytes Nbytes:(int)sizeof(apSsidBytes)];
Byte apSsidCrc = [crc getValue];
[crc reset];
NSData *apBssidData = [ESP_NetUtil parseBssid2bytes:apBssid];
NSData *apBssidData = apBssid;
int apBssidDataLen = (int)[apBssidData length];
Byte apBssidBytes[apBssidDataLen];
[apBssidData getBytes:apBssidBytes];
[apBssidData getBytes:apBssidBytes length:[apBssidData length]];
[crc updateWithBuf:apBssidBytes Nbytes:apBssidDataLen];
UInt8 apBssidCrc = [crc getValue];
@@ -54,14 +54,14 @@
// only support ipv4 at the moment
UInt8 ipLen = [ipAddrData length];
Byte ipAddrUint8s[ipLen];
[ipAddrData getBytes:ipAddrUint8s];
[ipAddrData getBytes:ipAddrUint8s length:[ipAddrData length]];
UInt8 _totalLen = EXTRA_HEAD_LEN + ipLen + apPwdLen + apSsidLen;
UInt8 totalLen = isSsidHidden ? (EXTRA_HEAD_LEN + ipLen + apPwdLen + apSsidLen):(EXTRA_HEAD_LEN + ipLen + apPwdLen);
// build data codes
_dataCodes = [[NSMutableArray alloc]initWithCapacity:totalLen];
_dataCodes = [[NSMutableArray alloc]initWithCapacity:totalLen + apBssidDataLen];
ESPDataCode *dataCode = [[ESPDataCode alloc]initWithU8:_totalLen andIndex:0];
[_dataCodes addObject:dataCode];
totalXor ^= _totalLen;
@@ -106,6 +106,20 @@
// add total xor last
dataCode = [[ESPDataCode alloc]initWithU8:totalXor andIndex:4];
[_dataCodes insertObject:dataCode atIndex:4];
// add bssid
NSUInteger bssidInsertIndex = EXTRA_HEAD_LEN;
for (int i = 0; i < apBssidDataLen; i++) {
int index = totalLen + i;
Byte b = apBssidBytes[i];
ESPDataCode *dc = [[ESPDataCode alloc] initWithU8:b andIndex:index];
if (bssidInsertIndex >= _dataCodes.count) {
[_dataCodes addObject:dc];
} else {
[_dataCodes insertObject:dc atIndex:bssidInsertIndex];
}
bssidInsertIndex += 4;
}
}
return self;
}
@@ -2,8 +2,8 @@
// ESPGuideCode.h
// EspTouchDemo
//
// Created by 白 桦 on 4/9/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -2,8 +2,8 @@
// ESPGuideCode.m
// EspTouchDemo
//
// Created by on 4/9/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPGuideCode.h"
@@ -2,8 +2,8 @@
// ESPTouchGenerator.h
// EspTouchDemo
//
// Created by 白 桦 on 4/9/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -29,13 +29,12 @@
* @param isSsidHidden
* whether the Ap's ssid is hidden
*/
- (id) initWithSsid: (NSString *) apSsid andApBssid: (NSString *) apBssid andApPassword: (NSString *) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden;
- (id) initWithSsid: (NSData *)apSsid andApBssid: (NSData *)apBssid andApPassword: (NSData *)apPwd andInetAddrData: (NSData *)ipAddrData andIsSsidHidden: (BOOL)isSsidHidden;
/**
* Get guide code by the format of byte[][]
* @return guide code by the format of byte[][]
*/
- (NSArray *) getGCBytes2;
/**
@@ -2,8 +2,8 @@
// ESPTouchGenerator.m
// EspTouchDemo
//
// Created by on 4/9/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/9/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPTouchGenerator.h"
@@ -14,20 +14,18 @@
@implementation ESPTouchGenerator
- (id) initWithSsid: (NSString *) apSsid andApBssid: (NSString *) apBssid andApPassword: (NSString *) apPwd andInetAddrData: (NSData *) ipAddrData andIsSsidHidden: (BOOL) isSsidHidden
- (id) initWithSsid: (NSData *)apSsid andApBssid: (NSData *)apBssid andApPassword: (NSData *)apPwd andInetAddrData: (NSData *)ipAddrData andIsSsidHidden:(BOOL) isSsidHidden
{
self = [super init];
if (self)
{
// generate guide code
ESPGuideCode *gc = [[ESPGuideCode alloc]init];
NSData *gcData1 = [gc getU16s];
NSUInteger gcData1Len = [gcData1 length];
UInt16 gcU16_1[gcData1Len/2];
[gcData1 getBytes:gcU16_1 length:gcData1Len];
_gcBytes2 = [[NSMutableArray alloc]initWithCapacity:gcData1Len];
for (int i = 0; i < gcData1Len/2; i++)
{
NSData* data = [ESP_ByteUtil genSpecBytesWithU16:gcU16_1[i]];
@@ -35,26 +33,19 @@
}
// generate data code
ESPDatumCode *dc = [[ESPDatumCode alloc]initWithSsid:apSsid andApBssid:apBssid andApPwd:apPwd andInetAddrData:ipAddrData andIsSsidHidden:isSsidHidden];
NSData *dcData1 = [dc getU16s];
NSUInteger dcDataLen = [dcData1 length];
UInt16 dcU16_1[dcDataLen/2];
[dcData1 getBytes:dcU16_1 length:dcDataLen];
_dcBytes2 = [[NSMutableArray alloc]initWithCapacity:dcDataLen];
for (int i = 0; i < dcDataLen/2; i++)
{
NSData* data = [ESP_ByteUtil genSpecBytesWithU16:dcU16_1[i]];
[_dcBytes2 addObject:data];
}
}
return self;
}
- (NSArray *) getGCBytes2
@@ -2,8 +2,8 @@
// ESPTouchDelegate.h
// EspTouchDemo
//
// Created by 白 桦 on 8/14/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 8/14/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -2,8 +2,8 @@
// ESPTouchResult.h
// EspTouchDemo
//
// Created by 白 桦 on 4/14/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/14/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -31,4 +31,6 @@
*/
- (id) initWithIsSuc: (BOOL) isSuc andBssid: (NSString *) bssid andInetAddrData: (NSData *) ipAddrData;
- (NSString *) getAddressString;
@end
@@ -2,8 +2,8 @@
// ESPTouchResult.m
// EspTouchDemo
//
// Created by on 4/14/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/14/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPTouchResult.h"
@@ -24,9 +24,17 @@
return self;
}
- (NSString *)getAddressString {
NSString *ipAddrDataStr = [ESP_NetUtil descriptionInetAddr4ByData:self.ipAddrData];
if (ipAddrDataStr==nil) {
ipAddrDataStr = [ESP_NetUtil descriptionInetAddr6ByData:self.ipAddrData];
}
return ipAddrDataStr;
}
- (NSString *)description
{
NSString *ipAddrDataStr = [ESP_NetUtil descriptionInetAddrByData:self.ipAddrData];
NSString *ipAddrDataStr = [self getAddressString];
return [[NSString alloc]initWithFormat:@"[isSuc: %@,isCancelled: %@,bssid: %@,inetAddress: %@]",self.isSuc? @"YES":@"NO",
self.isCancelled? @"YES":@"NO"
,self.bssid
@@ -2,13 +2,16 @@
// ESPTouchTask.h
// EspTouchDemo
//
// Created by 白 桦 on 4/14/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/14/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ESPTouchResult.h"
#import "ESPTouchDelegate.h"
#import "ESPAES.h"
#define ESPTOUCH_VERSION @"SDK-v1.0.0"
#define DEBUG_ON YES
@@ -16,19 +19,7 @@
@property (atomic,assign) BOOL isCancelled;
/**
* Constructor of EsptouchTask
*
* @param apSsid
* the Ap's ssid
* @param apBssid
* the Ap's bssid
* @param apPassword
* the Ap's password
* @param isSsidHidden
* whether the Ap's ssid is hidden
*/
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden;
- (id)initWithApSsid:(NSString *)apSsid andApBssid:(NSString *)apBssid andApPwd:(NSString *)apPwd andAES:(ESPAES *)aes;
/**
* Constructor of EsptouchTask
@@ -37,21 +28,49 @@
* the Ap's ssid
* @param apBssid
* the Ap's bssid
* @param apPassword
* @param apPwd
* the Ap's password
*/
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd;
/**
* Deprecated
*/
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden __deprecated_msg("Use initWithApSsid:(NSString *) andApBssid:(NSString *) andApPwd:(NSString *) instead.");
/**
* Constructor of EsptouchTask
*
* @param apSsid
* the Ap's ssid
* @param apBssid
* the Ap's bssid
* @param apPwd
* the Ap's password
* @param timeoutMillisecond (it should be >= 15000+6000)
* millisecond of total timeout
*/
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andTimeoutMillisecond: (int) timeoutMillisecond;
/**
* Constructor of EsptouchTask
*
* @param apSsid
* the Ap's ssid
* @param apBssid
* the Ap's bssid
* @param apPwd
* the Ap's password
* @param isSsidHidden
* whether the Ap's ssid is hidden
* @param timeoutMillisecond(it should be >= 15000+6000)
* millisecond of total timeout
* @param context
* the Context of the Application
* @param timeoutMillisecond (it should be >= 15000+6000)
* millisecond of total timeout
*/
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden andTimeoutMillisecond: (int) timeoutMillisecond;
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden andTimeoutMillisecond: (int) timeoutMillisecond __deprecated_msg("Use initWithApSsid:(NSString *) andApBssid:(NSString *) andApPwd:(NSString *) andTimeoutMillisecond:(int) instead.");
/**
* Interrupt the Esptouch Task when User tap back or close the Application.
*/
- (void) interrupt;
/**
@@ -88,4 +107,9 @@
*/
- (void) setEsptouchDelegate: (NSObject<ESPTouchDelegate> *) esptouchDelegate;
/**
* Set boradcast or multicast when post config info
* @param broadcast YES is boradcast, NO is multicast
*/
- (void) setPackageBroadcast: (BOOL) broadcast;
@end
@@ -2,8 +2,8 @@
// ESPTouchTask.m
// EspTouchDemo
//
// Created by on 4/14/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/14/15.
// Copyright (c) 2015 fby. All rights reserved.
//
// The usage of NSCondition refer to: https://gist.github.com/prachigauriar/8118909
@@ -16,16 +16,15 @@
#import "ESP_NetUtil.h"
#import "ESPTouchTaskParameter.h"
#import "AppDelegate.h"
#define ONE_DATA_LEN 3
@interface ESPTouchTask ()
@property (nonatomic,strong) NSString *_apSsid;
@property (nonatomic,strong) NSData *_apSsid;
@property (nonatomic,strong) NSString *_apBssid;
@property (nonatomic,strong) NSData *_apBssid;
@property (nonatomic,strong) NSString *_apPwd;
@property (nonatomic,strong) NSData *_apPwd;
@property (atomic,assign) BOOL _isSuc;
@@ -55,15 +54,20 @@
@property (nonatomic,strong) id<ESPTouchDelegate> _esptouchDelegate;
@property (nonatomic,strong) NSData *_localInetAddrData;
@end
@implementation ESPTouchTask
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden
- (id)initWithApSsid:(NSString *)apSsid andApBssid:(NSString *)apBssid andApPwd:(NSString *)apPwd andAES:(ESPAES *)aes
{
self = [super init];
NSLog(@"Welcome Esptouch %@",ESPTOUCH_VERSION);
if (apSsid==nil||[apSsid isEqualToString:@""])
{
perror("ESPTouchTask initWithApSsid() apSsid shouldn't be null or empty");
return self;
}
// the apSsid should be null or empty
assert(apSsid!=nil&&![apSsid isEqualToString:@""]);
@@ -72,26 +76,60 @@
apPwd = @"";
}
self = [super init];
if (self)
{
if (DEBUG_ON)
{
NSLog(@"ESPTouchTask init");
}
self._apSsid = apSsid;
self._apPwd = apPwd;
self._apBssid = apBssid;
if (aes == nil) {
self._apSsid = [ESP_ByteUtil getBytesByNSString:apSsid];
self._apPwd = [ESP_ByteUtil getBytesByNSString:apPwd];
} else {
self._apSsid = [aes AES128EncryptData:[ESP_ByteUtil getBytesByNSString:apSsid]];
self._apPwd = [aes AES128EncryptData:[ESP_ByteUtil getBytesByNSString:apPwd]];
}
self._apBssid = [ESP_NetUtil parseBssid2bytes:apBssid];
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];
// create udp client and udp server
self._client = [[ESPUDPSocketClient alloc]init];
self._server = [[ESPUDPSocketServer alloc]initWithPort: [self._parameter getPortListening]
AndSocketTimeout: [self._parameter getWaitUdpTotalMillisecond]];
// update listening port for IPv6
[self._parameter setListeningPort6:self._server.port];
if (DEBUG_ON) {
NSLog(@"ESPTouchTask app server port is %d",self._server.port);
}
if (localInetAddr4!=nil) {
self._localInetAddrData = [ESP_NetUtil getLocalInetAddress4ByAddr:localInetAddr4];
} else {
int localPort = [self._parameter getPortListening];
self._localInetAddrData = [ESP_NetUtil getLocalInetAddress6ByPort:localPort];
}
if (DEBUG_ON)
{
// for ESPTouchGenerator only receive 4 bytes for local address no matter IPv4 or IPv6
NSLog(@"ESPTouchTask executeForResult() localInetAddr: %@", [ESP_NetUtil descriptionInetAddr4ByData:self._localInetAddrData]);
}
self._isSuc = NO;
self._isInterrupt = NO;
self._isWakeUp = NO;
self._isExecutedAlready = NO;
self._condition = [[NSCondition alloc]init];
self._isSsidHidden = isSsidHidden;
self._isSsidHidden = YES;
self._esptouchResultArray = [[NSMutableArray alloc]init];
self._bssidTaskSucCountDict = [[NSMutableDictionary alloc]init];
self._esptouchResultArrayCondition = [[NSCondition alloc]init];
@@ -99,9 +137,18 @@
return self;
}
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden andTimeoutMillisecond: (int) timeoutMillisecond
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd {
return [self initWithApSsid:apSsid andApBssid:apBssid andApPwd:apPwd andAES:nil];
}
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden
{
ESPTouchTask *_self = [self initWithApSsid:apSsid andApBssid:apBssid andApPwd:apPwd andIsSsidHiden:isSsidHidden];
return [self initWithApSsid:apSsid andApBssid:apBssid andApPwd:apPwd];
}
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andTimeoutMillisecond: (int) timeoutMillisecond
{
ESPTouchTask *_self = [self initWithApSsid:apSsid andApBssid:apBssid andApPwd:apPwd];
if (_self)
{
[_self._parameter setWaitUdpTotalMillisecond:timeoutMillisecond];
@@ -109,6 +156,11 @@
return _self;
}
- (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden andTimeoutMillisecond: (int) timeoutMillisecond
{
return [self initWithApSsid:apSsid andApBssid:apBssid andApPwd:apPwd andTimeoutMillisecond:timeoutMillisecond];
}
- (void) __putEsptouchResultIsSuc: (BOOL) isSuc AndBssid: (NSString *)bssid AndInetAddr:(NSData *)inetAddr
{
[self._esptouchResultArrayCondition lock];
@@ -174,10 +226,8 @@
esptouchResult.isCancelled = self.isCancelled;
[self._esptouchResultArray addObject:esptouchResult];
}
[self._esptouchResultArrayCondition unlock];
return self._esptouchResultArray;
}
@@ -216,8 +266,8 @@
NSLog(@"ESPTouchTask __listenAsyn() start an asyn listen task, current thread is: %@", [NSThread currentThread]);
}
NSTimeInterval startTimestamp = [[NSDate date] timeIntervalSince1970];
NSString *apSsidAndPwd = [NSString stringWithFormat:@"%@%@",self._apSsid,self._apPwd];
Byte expectOneByte = [ESP_ByteUtil getBytesByNSString:apSsidAndPwd].length + 9;
// NSString *apSsidAndPwd = [NSString stringWithFormat:@"%@%@",self._apSsid,self._apPwd];
Byte expectOneByte = [self._apSsid length] + [self._apPwd length] + 9;
if (DEBUG_ON)
{
NSLog(@"ESPTouchTask __listenAsyn() expectOneByte: %d",expectOneByte);
@@ -226,7 +276,11 @@
NSData *receiveData = nil;
while ([self._esptouchResultArray count] < [self._parameter getExpectTaskResultCount] && !self._isInterrupt)
{
receiveData = [self._server receiveSpecLenBytes:expectDataLen];
if ([self._parameter isIPv4Supported]) {
receiveData = [self._server receiveSpecLenBytes4:expectDataLen];
} else {
receiveData = [self._server receiveSpecLenBytes6:expectDataLen];
}
if (receiveData != nil)
{
[receiveData getBytes:&receiveOneByte length:1];
@@ -396,14 +450,9 @@
[self __checkTaskValid];
NSData *localInetAddrData = [ESP_NetUtil getLocalInetAddress];
if (DEBUG_ON)
{
NSLog(@"ESPTouchTask executeForResult() localInetAddr: %@", [ESP_NetUtil descriptionInetAddrByData:localInetAddrData]);
}
// generator the esptouch byte[][] to be transformed, which will cost
// some time(maybe a bit much)
ESPTouchGenerator *generator = [[ESPTouchGenerator alloc]initWithSsid:self._apSsid andApBssid:self._apBssid andApPassword:self._apPwd andInetAddrData:localInetAddrData andIsSsidHidden:self._isSsidHidden];
ESPTouchGenerator *generator = [[ESPTouchGenerator alloc]initWithSsid:self._apSsid andApBssid:self._apBssid andApPassword:self._apPwd andInetAddrData:self._localInetAddrData andIsSsidHidden:self._isSsidHidden];
// listen the esptouch result asyn
[self __listenAsyn:[self._parameter getEsptouchResultTotalLen]];
BOOL isSuc = NO;
@@ -464,4 +513,8 @@
self._esptouchDelegate = esptouchDelegate;
}
- (void)setPackageBroadcast:(BOOL)broadcast {
[self._parameter setBroadcast:broadcast];
}
@end
@@ -2,8 +2,8 @@
// ESPTaskParameter.h
// EspTouchDemo
//
// Created by 白 桦 on 5/20/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 5/20/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -136,4 +136,38 @@
*/
- (void) setExpectTaskResultCount: (int) expectTaskResultCount;
/**
* get whether the router support IPv4
* @return whether the router support IPv4
*/
- (BOOL) isIPv4Supported;
/**
* set whether the router support IPv4
* @param isIPv4Supported whether the router support IPv4
*/
- (void) setIsIPv4Supported:(BOOL) isIPv4Supported;
/**
* get whether the router support IPv6
* @return whether the router support IPv6
*/
- (BOOL) isIPv6Supported;
/**
* set whether the router support IPv6
* @param isIPv6Supported whether the router support IPv6
*/
- (void) setIsIPv6Supported:(BOOL) isIPv6Supported;
/**
* set listening port for IPv6
*/
- (void) setListeningPort6:(int) listeningPort6;
/**
* Set broadcast or multicast
*/
- (void) setBroadcast:(BOOL) broadcast;
@end
@@ -2,8 +2,8 @@
// ESPTaskParameter.m
// EspTouchDemo
//
// Created by on 5/20/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 5/20/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPTouchTaskParameter.h"
@@ -17,14 +17,21 @@
@property (nonatomic,assign) int totalRepeatTime;
@property (nonatomic,assign) int esptouchResultOneLen;
@property (nonatomic,assign) int esptouchResultMacLen;
@property (nonatomic,assign) int esptouchResultIpLen;
@property (nonatomic,assign) int esptouchResultTotalLen;
@property (nonatomic,assign) int portListening;
@property (nonatomic,assign) int targetPort;
@property (nonatomic,assign) int esptouchResultIpLen4;
@property (nonatomic,assign) int esptouchResultIpLen6;
@property (nonatomic,assign) int esptouchResultTotalLen4;
@property (nonatomic,assign) int esptouchResultTotalLen6;
@property (nonatomic,assign) int portListening4;
@property (nonatomic,assign) int portListening6;
@property (nonatomic,assign) int targetPort4;
@property (nonatomic,assign) int targetPort6;
@property (nonatomic,assign) int waitUdpReceivingMillisecond;
@property (nonatomic,assign) int waitUdpSendingMillisecond;
@property (nonatomic,assign) int thresholdSucBroadcastCount;
@property (nonatomic,assign) int expectTaskResultCount;
@property (nonatomic,assign) BOOL isIPv4Supported0;
@property (nonatomic,assign) BOOL isIPv6Supported0;
@property (nonatomic,assign) BOOL broadcast;
@end
@implementation ESPTaskParameter
@@ -35,22 +42,28 @@ static int _datagramCount = 0;
{
self = [super init];
if (self) {
self.intervalGuideCodeMillisecond = 10;
self.intervalDataCodeMillisecond = 10;
self.intervalGuideCodeMillisecond = 8;
self.intervalDataCodeMillisecond = 8;
self.timeoutGuideCodeMillisecond = 2000;
self.timeoutDataCodeMillisecond = 4000;
self.timeoutTotalCodeMillisecond = 2000 + 4000;
self.totalRepeatTime = 1;
self.esptouchResultOneLen = 1;
self.esptouchResultMacLen = 6;
self.esptouchResultIpLen = 4;
self.esptouchResultTotalLen = 1 + 6 + 4;
self.portListening = 18266;
self.targetPort = 7001;
self.esptouchResultIpLen4 = 4;
self.esptouchResultIpLen6 = 16;
self.esptouchResultTotalLen4 = 1 + 6 + 4;
self.esptouchResultTotalLen6 = 1 + 6 + 16;
self.portListening4 = 18266;
self.portListening6 = 0;
self.targetPort4 = 7001;
self.targetPort6 = 7001;
self.waitUdpReceivingMillisecond = 15000;
self.waitUdpSendingMillisecond = 45000;
self.thresholdSucBroadcastCount = 1;
self.expectTaskResultCount = 1;
self.isIPv4Supported0 = YES;
self.isIPv6Supported0 = YES;
}
return self;
}
@@ -105,30 +118,52 @@ static int _datagramCount = 0;
- (int) getEsptouchResultIpLen
{
return self.esptouchResultIpLen;
return _isIPv4Supported0 ? _esptouchResultIpLen4 : _esptouchResultIpLen6;
}
- (int) getEsptouchResultTotalLen
{
return self.esptouchResultTotalLen;
if (_isIPv4Supported0) {
return _esptouchResultTotalLen4;
} else {
return _esptouchResultTotalLen6;
}
}
- (int) getPortListening
{
return self.portListening;
if (_isIPv4Supported0) {
return _portListening4;
} else {
return _portListening6;
}
}
// target hostname is : 234.1.1.1, 234.2.2.2, 234.3.3.3 to 234.100.100.100
// target hostname is : 234.1.1.1, 234.2.2.2, 234.3.3.3 to 234.100.100.100 for IPv4
// target hostname is : ff02::1 for IPv6
- (NSString *) getTargetHostname
{
int count = [self __getNextDatagramCount];
return [NSString stringWithFormat: @"234.%d.%d.%d", count, count, count];
if (_isIPv4Supported0) {
if (self.broadcast) {
return @"255.255.255.255";
} else {
int count = [self __getNextDatagramCount];
return [NSString stringWithFormat: @"234.%d.%d.%d", count, count, count];
}
} else {
return @"ff02::1%en0";
}
}
- (int) getTargetPort
{
return self.targetPort;
if (_isIPv4Supported0) {
return _targetPort4;
} else {
return _targetPort6;
}
}
- (int) getWaitUdpReceivingMillisecond
@@ -171,4 +206,34 @@ static int _datagramCount = 0;
{
_expectTaskResultCount = expectTaskResultCount;
}
- (BOOL) isIPv4Supported
{
return _isIPv4Supported0;
}
- (void) setIsIPv4Supported:(BOOL) isIPv4Supported
{
_isIPv4Supported0 = isIPv4Supported;
}
- (BOOL) isIPv6Supported
{
return _isIPv6Supported0;
}
- (void) setIsIPv6Supported:(BOOL) isIPv6Supported
{
_isIPv6Supported0 = isIPv6Supported;
}
- (void) setListeningPort6:(int) listeningPort6
{
_portListening6 = listeningPort6;
}
- (void)setBroadcast:(BOOL)broadcast {
_broadcast = broadcast;
}
@end
@@ -2,8 +2,8 @@
// ESPUDPSocketClient.h
// EspTouchDemo
//
// Created by 白 桦 on 4/13/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/13/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -17,11 +17,11 @@
/**
* send the data by UDP
*
* @param bytes
* @param bytesArray2
* the array of datas to be sent
* @param targetHost
* @param targetHostName
* the host name of target, e.g. 192.168.1.101
* @param targetPort
* @param port
* the port of target
* @param interval
* the milliseconds to between each UDP sent
@@ -32,15 +32,15 @@
/**
* send the data by UDP
*
* @param data
* @param bytesArray2
* the data to be sent
* @param offset
* the offset which data to be sent
* @param count
* the count of the data
* @param targetHost
* @param targetHostName
* the host name of target, e.g. 192.168.1.101
* @param targetPort
* @param port
* the port of target
* @param interval
* the milliseconds to between each UDP sent
@@ -2,19 +2,24 @@
// ESPUDPSocketClient.m
// EspTouchDemo
//
// Created by on 4/13/15.
// Copyright (c) 2015 . All rights reserved.
// Created by fby on 4/13/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPUDPSocketClient.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#import <netdb.h>
#include "ESPTouchTask.h"
#import "ESP_NetUtil.h"
#define SOCKET_NULL -1
@interface ESPUDPSocketClient ()
@property(nonatomic, assign) int _sck_fd;
@property(nonatomic, assign) int _sck_fd4;
@property(nonatomic, assign) int _sck_fd6;
@property(nonatomic, assign) BOOL _isStop;
// it is used to check whether the socket is closed already to prevent close more than once.
// especially, when you close the socket second time, it is created just now, it will crash.
@@ -45,16 +50,31 @@
if (self)
{
self._isStop = NO;
self._sck_fd = socket(AF_INET,SOCK_DGRAM,0);
self._sck_fd4 = SOCKET_NULL;
self._sck_fd6 = SOCKET_NULL;
self._sck_fd4 = socket(AF_INET,SOCK_DGRAM,0);
if (DEBUG_ON)
{
NSLog(@"##########################client init() _sck_fd=%d",self._sck_fd);
NSLog(@"##########################client init() _sck_fd4=%d",self._sck_fd4);
}
if (self._sck_fd < 0)
if (self._sck_fd4 < 0)
{
if (DEBUG_ON)
{
perror("client: init() _skd_fd init fail\n");
perror("client: init() _skd_fd4 init fail\n");
}
return nil;
}
self._sck_fd6 = socket(AF_INET6,SOCK_DGRAM,0);
if (DEBUG_ON)
{
NSLog(@"##########################client init() _sck_fd6=%d",self._sck_fd6);
}
if (self._sck_fd6 < 0)
{
if (DEBUG_ON)
{
perror("client: init() _skd_fd6 init fail\n");
}
return nil;
}
@@ -77,11 +97,22 @@
[self._lock lock];
if (!self._isClosed)
{
if (DEBUG_ON)
{
NSLog(@"###################client close() fd=%d",self._sck_fd);
if (self._sck_fd4!=SOCKET_NULL) {
if (DEBUG_ON)
{
NSLog(@"###################client close() fd4=%d",self._sck_fd4);
}
close(self._sck_fd4);
self._sck_fd4 = SOCKET_NULL;
}
if (self._sck_fd6!=SOCKET_NULL) {
if (DEBUG_ON)
{
NSLog(@"###################client close() fd6=%d",self._sck_fd6);
}
close(self._sck_fd6);
self._sck_fd6 = SOCKET_NULL;
}
close(self._sck_fd);
self._isClosed = YES;
}
[self._lock unlock];
@@ -98,19 +129,9 @@
return [self sendDataWithBytesArray2:bytesArray2 Offset:0 Count:[bytesArray2 count] ToTargetHostName:targetHostName WithPort:port andInterval:interval];
}
- (void) sendDataWithBytesArray2: (NSArray *) bytesArray2 Offset: (NSUInteger) offset Count: (NSUInteger) count ToTargetHostName: (NSString *)targetHostName WithPort: (int) port
- (void) sendDataWithBytesArray2Ipv4: (NSArray *) bytesArray2 Offset: (NSUInteger) offset Count: (NSUInteger) count ToTargetHostName: (NSString *)targetHostName WithPort: (int) port
andInterval: (long) interval
{
// check data is valid
if (nil == bytesArray2 || 0 == [bytesArray2 count])
{
if (DEBUG_ON)
{
perror("client: data is null or data's length equals 0, so sendData fail\n");
}
[self close];
return;
}
// init socket parameters
bool isBroadcast = [targetHostName isEqualToString:@"255.255.255.255"];
socklen_t addr_len;
@@ -123,7 +144,7 @@
if (isBroadcast) {
const int opt = 1;
// set whether the socket is broadcast or not
if (setsockopt(self._sck_fd,SOL_SOCKET,SO_BROADCAST,(char *)&opt, sizeof(opt)) < 0)
if (setsockopt(self._sck_fd4,SOL_SOCKET,SO_BROADCAST,(char *)&opt, sizeof(opt)) < 0)
{
if (DEBUG_ON)
{
@@ -145,7 +166,7 @@
Byte bytes[dataLen];
[data getBytes:bytes length:dataLen];
// send data
if (sendto(self._sck_fd, bytes, dataLen, 0, (struct sockaddr*)&target_addr, addr_len) < 0)
if (sendto(self._sck_fd4, bytes, dataLen, 0, (struct sockaddr*)&target_addr, addr_len) < 0)
{
if (DEBUG_ON)
{
@@ -163,4 +184,81 @@
}
}
- (void) sendDataWithBytesArray2Ipv6: (NSArray *) bytesArray2 Offset: (NSUInteger) offset Count: (NSUInteger) count ToTargetHostName: (NSString *)targetHostName WithPort: (int) port
andInterval: (long) interval
{
// init socket parameters
socklen_t addr_len;
struct sockaddr_in6 target_addr6;
memset(&target_addr6, 0, sizeof(target_addr6));
target_addr6.sin6_family = AF_INET6;
target_addr6.sin6_port = htons(port);
addr_len = sizeof(target_addr6);
NSString *portStr = [NSString stringWithFormat:@"%hu",(uint16_t)port];
struct addrinfo *res0,hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
int gai_error = getaddrinfo([targetHostName UTF8String], [portStr UTF8String], &hints, &res0);
if (gai_error) {
perror("client: gai_error, stop");
return;
}
NSData *dstData = [NSData dataWithBytes:res0->ai_addr length:res0->ai_addrlen];
const void *dst = [dstData bytes];
socklen_t dstSize = addr_len;
// send data gotten from the array
for (NSUInteger i = offset; !self._isStop && i < offset + count; i++) {
// get data
NSData* data = [bytesArray2 objectAtIndex:i];
NSUInteger dataLen = [data length];
if (0 == dataLen)
{
continue;
}
Byte bytes[dataLen];
[data getBytes:bytes length:dataLen];
// send data
if (sendto(self._sck_fd6, bytes, dataLen, 0, dst, dstSize) < 0)
{
if (DEBUG_ON)
{
perror("client: sendto fail, but just ignore it\n");
}
// for the Ap will make some troubles when the phone send too many UDP packets,
// but we don't expect the UDP packet received by others, so just ignore it
}
// sleep interval
usleep((useconds_t)(interval*1000));
}
// check whether the client is stop
if (self._isStop) {
[self close];
}
}
- (void) sendDataWithBytesArray2: (NSArray *) bytesArray2 Offset: (NSUInteger) offset Count: (NSUInteger) count ToTargetHostName: (NSString *)targetHostName WithPort: (int) port
andInterval: (long) interval
{
// check data is valid
if (nil == bytesArray2 || 0 == [bytesArray2 count])
{
if (DEBUG_ON)
{
perror("client: data is null or data's length equals 0, so sendData fail\n");
}
[self close];
return;
}
if ([ESP_NetUtil isIPv4Addr:targetHostName]) {
[self sendDataWithBytesArray2Ipv4:bytesArray2 Offset:offset Count:count ToTargetHostName:targetHostName WithPort:port andInterval:interval];
} else {
[self sendDataWithBytesArray2Ipv6:bytesArray2 Offset:offset Count:count ToTargetHostName:targetHostName WithPort:port andInterval:interval];
}
}
@end
@@ -2,8 +2,8 @@
// ESPUDPSocketServer.h
// EspTouchDemo
//
// Created by 白 桦 on 4/13/15.
// Copyright (c) 2015 白 桦. All rights reserved.
// Created by fby on 4/13/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -16,6 +16,8 @@
Byte _buffer[BUFFER_SIZE];
}
@property (nonatomic, assign) int port;
- (void) close;
- (void) interrupt;
@@ -25,7 +27,6 @@
*
* @param timeout
* the timeout in milliseconds or 0 for no timeout.
* @return true whether the timeout is set suc
*/
- (void) setSocketTimeout: (int) timeout;
@@ -34,9 +35,13 @@
*
* @return one byte receive from the port or UINT8_MAX(it impossible receive it from the socket)
*/
- (Byte) receiveOneByte;
- (Byte) receiveOneByte4;
- (NSData *) receiveSpecLenBytes: (int)len;
- (NSData *) receiveSpecLenBytes4: (int)len;
- (Byte) receiveOneByte6;
- (NSData *) receiveSpecLenBytes6:(int)len;
- (id) initWithPort: (int) port AndSocketTimeout: (int) socketTimeout;
+379
View File
@@ -0,0 +1,379 @@
//
// ESPUDPSocketServer.m
// EspTouchDemo
//
// Created by fby on 4/13/15.
// Copyright (c) 2015 fby. All rights reserved.
//
#import "ESPUDPSocketServer.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include "ESPTouchTask.h"
#define SOCKET_NULL -1
@interface ESPUDPSocketServer ()
@property(nonatomic,assign) int _sck_fd4;
@property(nonatomic,assign) int _sck_fd6;
// it is used to check whether the socket is closed already to prevent close more than once.
// especially, when you close the socket second time, it is created just now, it will crash.
//
// // suppose fd1 = 4, fd1 belong to obj1
// e.g. int fd1 = socket(AF_INET,SOCK_DRAM,0);
// close(fd1);
//
// // suppose fd2 = 4 as well, fd2 belong to obj2
// int fd2 = socket(AF_INET,SOCK_DRAM,0);
//
// // obj1's dealloc() is called by system, so
// close(fd1);
//
// // Amazing!!! at the moment, fd2 is close by others
//
@property(nonatomic,assign) volatile bool _isClosed;
// it is used to lock the close method
@property(nonatomic,strong) volatile NSLock *_lock;
@end
@implementation ESPUDPSocketServer
- (BOOL) initWithPort4: (int) port AndSocketTimeout: (int) socketTimeout
{
self._sck_fd4 = socket(AF_INET,SOCK_DGRAM,0);
if (DEBUG_ON)
{
NSLog(@"##########################server init(): _sck_fd4=%d", self._sck_fd4);
}
if (self._sck_fd4 < 0)
{
if (DEBUG_ON)
{
perror("server: _skd_fd4 init() fail\n");
}
return NO;
}
// init socket4 params
struct sockaddr_in server_addr;
socklen_t addr_len;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
addr_len = sizeof(server_addr);
// set broadcast
const int opt = 1;
if (setsockopt(self._sck_fd4,SOL_SOCKET,SO_BROADCAST,(char *)&opt, sizeof(opt)) < 0)
{
if (DEBUG_ON)
{
perror("server init() sck4: setsockopt SO_BROADCAST fail\n");
}
[self close];
return NO;
}
// set socket timeout
if (![self setSocketTimeout:socketTimeout SocketFd:self._sck_fd4]) {
if (DEBUG_ON) {
perror("server: sck4: setsockopt SO_RCVTIMEO fail\n");
}
[self close];
return NO;
}
// set SO_REUSEADDR for ipv4
if (setsockopt(self._sck_fd4, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))< 0) {
if (DEBUG_ON)
{
perror("server init() sck4: setsockopt SO_REUSEADDR fail\n");
}
[self close];
return NO;
}
// bind for ipv4
if (bind(self._sck_fd4, (struct sockaddr*)&server_addr, addr_len) < 0)
{
if (DEBUG_ON)
{
perror("server init() sck4: bind fail\n");
}
[self close];
return NO;
}
return YES;
}
- (BOOL) initWithPort6: (int) port AndSocketTimeout: (int) socketTimeout
{
self._sck_fd6 = socket(AF_INET6,SOCK_DGRAM,0);
if (DEBUG_ON)
{
NSLog(@"##########################server init(): _sck_fd6=%d", self._sck_fd6);
}
if (self._sck_fd6 < 0)
{
if (DEBUG_ON)
{
perror("server: _skd_fd6 init() fail\n");
}
return NO;
}
// init socket6 params
struct sockaddr_in6 server_addr6;
socklen_t addr6_len = sizeof(server_addr6);
memset(&server_addr6, 0, addr6_len);
server_addr6.sin6_family = AF_INET6;
server_addr6.sin6_port = htons(port);
server_addr6.sin6_addr = in6addr_any;
// set socket timeout
if (![self setSocketTimeout:socketTimeout SocketFd:self._sck_fd6]) {
if (DEBUG_ON) {
perror("server: sck4: setsockopt SO_RCVTIMEO fail\n");
}
[self close];
return NO;
}
// set SO_REUSEADDR for ipv6
const int opt = 1;
if (setsockopt(self._sck_fd6, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))< 0) {
if (DEBUG_ON)
{
perror("server init() sck6: setsockopt SO_REUSEADDR fail\n");
}
[self close];
return NO;
}
// bind for ipv6
if (bind(self._sck_fd6, (struct sockaddr*)&server_addr6, addr6_len) < 0)
{
if (DEBUG_ON)
{
perror("server init() sck6: bind fail\n");
}
[self close];
return NO;
}
return YES;
}
- (id) initWithPort:(int)port AndSocketTimeout:(int)socketTimeout
{
self = [super init];
if (self) {
// create lock
self._lock = [[NSLock alloc]init];
// init
self._isClosed = NO;
self._sck_fd4 = SOCKET_NULL;
self._sck_fd6 = SOCKET_NULL;
// init sck4
if (![self initWithPort4:port AndSocketTimeout:socketTimeout]) {
if (DEBUG_ON) {
NSLog(@"fail to init socket for ipv4");
}
return nil;
}
if (port==0) {
struct sockaddr_in local_addr;
socklen_t len = sizeof(local_addr);
if (getsockname(self._sck_fd4, (struct sockaddr *)&local_addr, &len)==0) {
port = ntohs(local_addr.sin_port);
}
else {
if (DEBUG_ON) {
NSLog(@"fail to get socket port for ipv4");
}
[self close];
return nil;
}
}
_port = port;
// init sck6
if (![self initWithPort6:port AndSocketTimeout:socketTimeout]) {
if (DEBUG_ON) {
NSLog(@"fail to init socket for ipv6");
}
return nil;
}
}
return self;
}
// make sure the socket will be closed sometime
- (void)dealloc
{
if (DEBUG_ON)
{
NSLog(@"###################server dealloc()");
}
[self close];
}
- (void) close
{
[self._lock lock];
if (!self._isClosed)
{
if (self._sck_fd4!=SOCKET_NULL) {
if (DEBUG_ON)
{
NSLog(@"###################server close() fd4=%d",self._sck_fd4);
}
close(self._sck_fd4);
self._sck_fd4 = SOCKET_NULL;
}
if (self._sck_fd6!=SOCKET_NULL) {
if (DEBUG_ON)
{
NSLog(@"###################server close() fd6=%d",self._sck_fd6);
}
close(self._sck_fd6);
self._sck_fd6 = SOCKET_NULL;
}
self._isClosed = true;
}
[self._lock unlock];
}
- (void) interrupt
{
[self close];
}
- (BOOL) setSocketTimeout: (int) timeout SocketFd:(int) socketFd
{
struct timeval tv;
tv.tv_sec = timeout/1000;
tv.tv_usec = timeout%1000*1000;
if (setsockopt(socketFd,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv, sizeof(tv)) < 0)
{
if (DEBUG_ON)
{
perror("server: setsockopt SO_RCVTIMEO fail\n");
}
return NO;
} else {
return YES;
}
}
- (void) setSocketTimeout:(int)timeout
{
[self setSocketTimeout:timeout SocketFd:self._sck_fd4];
[self setSocketTimeout:timeout SocketFd:self._sck_fd6];
}
- (Byte) receiveOneByte4
{
ssize_t recNumber = recv(self._sck_fd4, _buffer, BUFFER_SIZE, 0);
if (recNumber > 0)
{
return _buffer[0];
}
else if(recNumber == 0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte4 socket is closed by the other\n");
}
}
else
{
if (DEBUG_ON)
{
perror("server: receiveOneByte4 fail\n");
}
}
return UINT8_MAX;
}
- (Byte) receiveOneByte6
{
ssize_t recNumber = recv(self._sck_fd6, _buffer, BUFFER_SIZE, 0);
if (recNumber > 0)
{
return _buffer[0];
}
else if(recNumber == 0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte6 socket is closed by the other\n");
}
}
else
{
if (DEBUG_ON)
{
perror("server: receiveOneByte6 fail\n");
}
}
return UINT8_MAX;
}
- (NSData *) receiveSpecLenBytes4: (int)len
{
ssize_t recNumber = recv(self._sck_fd4, _buffer, BUFFER_SIZE, 0);
if (recNumber==len)
{
NSData *data = [[NSData alloc]initWithBytes:_buffer length:recNumber];
return data;
}
else if(recNumber==0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte4 socket is closed by the other\n");
}
}
else if(recNumber<0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte4 fail\n");
}
}
else
{
// receive rubbish message, just ignore it
}
return nil;
}
- (NSData *) receiveSpecLenBytes6:(int)len
{
ssize_t recNumber = recv(self._sck_fd6, _buffer, BUFFER_SIZE, 0);
if (recNumber==len)
{
NSData *data = [[NSData alloc]initWithBytes:_buffer length:recNumber];
return data;
}
else if(recNumber==0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte6 socket is closed by the other\n");
}
}
else if(recNumber<0)
{
if (DEBUG_ON)
{
perror("server: receiveOneByte6 fail\n");
}
}
else
{
// receive rubbish message, just ignore it
}
return nil;
}
@end