//
// UDP网络数据发送管理 该类主要用户封装要发送的数据,和解析udp数据
#import <Foundation/Foundation.h>
#import "DeviceInfo.h"
#import "TimeingInfo.h"
#define setbit(x,y) x|=(1<<y) //将X的第Y位置1
#define clrbit(x,y) x&=~(1<<y) //将X的第Y位清0
#define BitGet(Number,pos) Number >> (pos)&1 //用宏得到某数的某位
typedefenum
{
SingleTimeing,//单次定时
WeekTimeing,//周定时
SingleSection,//单次时间段
WeekSection,//周时间段
}SendTimeingType;
@interface NetWordDataManager : NSObject
+(NSData *)sendBeatMsg;//发送心跳包
+(DeviceInfo *)decBeatMsg:(NSData *)data;//解析心跳包
+(NSData *)sendChangeDevState:(DeviceInfo *)info isOpen:(BOOL)state;//设置设备开关
+(NSData *)sendQueryDevState:(DeviceInfo *)info;//查询设备开关状态
+(DeviceInfo *)decQueryDevState:(NSData *)data;//解析查询状态回复
//查询该设备的所有定时
+(NSData *)sendQueryAllTime:(NSString *)mac;
//解析该设备的所有定时
+(NSMutableArray *)decQueryAllTime:(NSData *)data;
//发送定时数据
+(NSData *)sendTimeChange:(TimeingInfo *)info sendTimeType:(SendTimeingType)type;
//解析定时数据
+(NSMutableDictionary *)decTimeChangeState:(NSData *)data;
//删除定时
+(NSData *)sendDeleteTime:(TimeingInfo *)info;
@end
//
// NetWordDataManager.m
// SmartHomeWIFI
//
// Created by 深圳市 秀软科技有限公司 on 14-2-21.
// Copyright (c) 2014年 huhuaxiang. All rights reserved.
//
#import "NetWordDataManager.h"
#import "l1dataFormat.h"
#import "MAESUnit.h"
#import "ByteUnit.h"
#import "DeviceTimeManager.h"
@implementation NetWordDataManager
//发送心跳包
+(NSData *)sendBeatMsg
{
//心跳
Byte transByte[] = {0x01,0x01,0x01,0x7E,0x40,0x40,0x48,0x65,0x6C,0x6C,0x6F,0x2C,0x54,0x68,0x69,0x6E,0x67,0x21,0x2A,0x2A,0x23};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
return mutablData;
}
//解析心跳包
+(DeviceInfo *)decBeatMsg:(NSData *)data
{
//前8个字节是L1层的数据,包含了指令类型,设备的mac地址
NSData *l1data=[data subdataWithRange:NSMakeRange(0, 8)];
L1DataFormat *l1dataFormat=[[L1DataFormat alloc]initWidthData:l1data];
// short l1=[l1dataFormat getL1Commad];
short l2=[l1dataFormat getFlag];//指令类型
NSString *l3=[l1dataFormat getMACAddress];//设备的mac地址
//后面的是加密的L2层数据,如果是0x47,则使用自定义秘钥解密,否则需要使用出厂秘钥解密
NSData *dataT=[data subdataWithRange:NSMakeRange(8, data.length-8)];
NSString *keyT=l2==0x47?customKey:delaultKey;
//解密数据
NSData *sData=[MAESUnit AES128Decrypt:dataT key:keyT];
DeviceInfo *info=[[DeviceInfoalloc]init];
info.isAddDev=l2==0x47?YES:NO;
info.isConnect=YES;
info.mac=l3;
//16进制的ip
NSData *ipdata=[sData subdataWithRange:NSMakeRange(8, 4)];
Byte *testByte = (Byte *)[ipdata bytes];
//拼接IP地址
info.ip=[NSString stringWithFormat:@"%d.%d.%d.%d",testByte[0],testByte[1],testByte[2],testByte[3]];
return info;
}
//设置设备开关
+(NSData *)sendChangeDevState:(DeviceInfo *)info isOpen:(BOOL)state
{
//l1
Byte transByte[] = {0x11,0x49};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
[mutablData appendData:[ByteUnit stringToByte:info.mac]];
//l2
NSMutableData *l2Data=[[NSMutableDataalloc]init];
Byte transByte1[] = {0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
[l2Data appendBytes:transByte1 length:ArraySize(transByte1)];
//控制
int stateInt=state?0x02:0x01;
Byte transByte2[] = {0xFE,0x00,0x00,0x11,0x01,0x00,stateInt,0xFF,0xFF,0x10,0x01,0xFF,0xFF,0x20,0x01,0xFF,0xFF,0x30,0x01,0xFF,0xFF};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
NSData *l2encData=[MAESUnit AES128Encrypt:l2Data key:customKey];
[mutablData appendData:l2encData];
return mutablData;
}
//查询设备状态
+(NSData *)sendQueryDevState:(DeviceInfo *)info
{
//l1
Byte transByte[] = {0x11,0x49};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
[mutablData appendData:[ByteUnit stringToByte:info.mac]];
//l2
NSMutableData *l2Data=[[NSMutableDataalloc]init];
Byte transByte1[] = {0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
[l2Data appendBytes:transByte1 length:ArraySize(transByte1)];
//控制
Byte transByte2[] = {0xFD,0x00,0x00,0x01,0x02};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
NSData *l2encData=[MAESUnit AES128Encrypt:l2Data key:customKey];
[mutablData appendData:l2encData];
return mutablData;
}
//解析查询状态回复
+(DeviceInfo *)decQueryDevState:(NSData *)data
{
//l1
NSData *l1data=[data subdataWithRange:NSMakeRange(0, 8)];
L1DataFormat *l1dataFormat=[[L1DataFormat alloc]initWidthData:l1data];
NSString *l3=[l1dataFormat getMACAddress];
//l2
NSData *dataT=[data subdataWithRange:NSMakeRange(8, data.length-8)];
NSData *sData=[MAESUnit AES128Decrypt:dataT key:customKey];
//解析各个字节
DeviceInfo *info=[[DeviceInfoalloc]init];
info.isConnect=YES;
info.mac=l3;
int startCommd=[ByteUnitsubDataLength:sData startCount:8lenghtCount:1];
int subCommd=[ByteUnitsubDataLength:sData startCount:12lenghtCount:1];
if(startCommd!=253&&startCommd!=254)return nil;
if(subCommd!=1&&subCommd!=2)return nil;
//dddd 代表开关状态
NSData *dddd=[sData subdataWithRange:NSMakeRange(13, 16)];
info.isOpen=[self transferTheDDDD:dddd];
/*
if(dddd.length==16)
{
short stateT=[ByteUnit subDataLength:dddd startCount:0 lenghtCount:2];
if(stateT==0x01)//@"0001FFFF1001FFFF2001FFFF3001FFFF"//关
{
info.isOpen=NO;
}else//@"0002FFFF1001FFFF2001FFFF3001FFFF"//开
{
info.isOpen=YES;
}
}
*/
return info;
}
//查询该设备的所有定时
+(NSData *)sendQueryAllTime:(NSString *)mac
{
//l1
Byte transByte[] = {0x11,0x49};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
[mutablData appendData:[ByteUnit stringToByte:mac]];
//l2
NSMutableData *l2Data=[[NSMutableDataalloc]init];
Byte transByte1[] = {0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
[l2Data appendBytes:transByte1 length:ArraySize(transByte1)];
//l2层中设备查询的指令
Byte transByte2[] = {0xFD,0x00,0x00,0x01,0x05};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
NSData *l2encData=[MAESUnit AES128Encrypt:l2Data key:customKey];
[mutablData appendData:l2encData];
return mutablData;
}
//解析该设备的所有定时
+(NSMutableArray *)decQueryAllTime:(NSData *)data
{
//l1
NSData *l1data=[data subdataWithRange:NSMakeRange(0, 8)];
L1DataFormat *l1dataFormat=[[L1DataFormat alloc]initWidthData:l1data];
NSString *l3=[l1dataFormat getMACAddress];
//l2
NSData *dataT=[data subdataWithRange:NSMakeRange(8, data.length-8)];
NSData *sData=[MAESUnit AES128Decrypt:dataT key:customKey];
NSData *l2data=[sData subdataWithRange:NSMakeRange(8, sData.length-8)];
//获取定时数据
NSData *timeingData=[l2data subdataWithRange:NSMakeRange(6, l2data.length-6)];
//指令判断---确定该数据是否是定时返回的数据
int commd=[ByteUnitsubDataLength:l2data startCount:0lenghtCount:1];
if(commd!=0xFD)return nil;
int subcommd=[ByteUnitsubDataLength:l2data startCount:4lenghtCount:1];
if(subcommd!=0x05)return nil;
int timeTotal=[ByteUnitsubDataLength:l2data startCount:5lenghtCount:1];//定时总数
NSMutableArray *timeInfos=[[NSMutableArrayalloc]init];
//循环递减遍历所有定时
do {
TimeingInfo *timeInfo=[[TimeingInfo alloc]init];
//定时组号
int index=[ByteUnit subDataLength:timeingData startCount:0 lenghtCount:1];
//定时类型
int xx=[ByteUnitsubDataLength:timeingData startCount:1lenghtCount:1];
if(xx==0x01)//单次定时 (延时)
{
//截取各个时间
int month=[ByteUnit subDataLength:timeingData startCount:2 lenghtCount:1];
int day=[ByteUnit subDataLength:timeingData startCount:3 lenghtCount:1];
int hours=[ByteUnit subDataLength:timeingData startCount:4 lenghtCount:1];
int minute=[ByteUnit subDataLength:timeingData startCount:5 lenghtCount:1];
//定时到期后制定的动作(开/关)
NSData *dddd=[timeingData subdataWithRange:NSMakeRange(6, 16)];
//---------保存定时数据-----------
timeInfo.mac=l3;
//数字小于10的显示两位
NSString * hourStr=hours<10?@"0":@"";
NSString *minuteStr=minute<10?@"0":@"";
timeInfo.toTime=[NSString stringWithFormat:@"%@%d:%@%d",hourStr,hours,minuteStr,minute];
timeInfo.timeIndex=index;
timeInfo.timeType=delay;//延时
timeInfo.action=[self transferTheDDDD:dddd]?ON:OFF;
//把该条定时添加到定时数组中
[timeInfos addObject:timeInfo];
//剩余的定时数据=把当前总的定时数据减去该条定时数据
timeingData=[timeingData subdataWithRange:NSMakeRange(22, timeingData.length-22)];
}elseif(xx==0x02)//周定时 解析方式与单次定时一样
{
int flag=[ByteUnit subDataLength:timeingData startCount:2 lenghtCount:1];
int hours=[ByteUnit subDataLength:timeingData startCount:3 lenghtCount:1];
int minute=[ByteUnit subDataLength:timeingData startCount:4 lenghtCount:1];
NSData *dddd=[timeingData subdataWithRange:NSMakeRange(5, 16)];
NSString * hourStr=hours<10?@"0":@"";
NSString *minuteStr=minute<10?@"0":@"";
timeInfo.toTime=[NSString stringWithFormat:@"%@%d:%@%d",hourStr,hours,minuteStr,minute];
timeInfo.mac=l3;
// timeInfo.toTime=[NSString stringWithFormat:@"%d:%d",hours,minute];
timeInfo.timeIndex=index;
timeInfo.timeType=timeing;//延时
timeInfo.action=[self transferTheDDDD:dddd]?ON:OFF;
timeInfo.repeatWeek=[self transferTheWeekInt:flag];
[timeInfos addObject:timeInfo];
timeingData=[timeingData subdataWithRange:NSMakeRange(21, timeingData.length-21)];
}
} while (timeingData.length>=20);//如果剩余的数据大于一条定时数据,则继续解析剩余的定时
return timeInfos;
}
//发送定时数据
+(NSData *)sendTimeChange:(TimeingInfo *)info sendTimeType:(SendTimeingType)type
{
//l1
Byte transByte[] = {0x11,0x49};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
[mutablData appendData:[ByteUnit stringToByte:info.mac]];
//l2
NSMutableData *l2Data=[[NSMutableDataalloc]init];
Byte transByte1[] = {0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
[l2Data appendBytes:transByte1 length:ArraySize(transByte1)];
//l2 定时控制
//格式化当前时间
NSCalendar *calendar = [[NSCalendaralloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *now;
NSDateComponents *comps = [[NSDateComponentsalloc] init];
NSInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit |
NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
now=[NSDate date];
comps = [calendar components:NSUIntegerMax fromDate:now];
int month = [comps month];
int day=[comps day];
//用户选择的时间
NSArray *time=[info.toTimecomponentsSeparatedByString:@":"];
int hours=[[time objectAtIndex:0]integerValue];
int min=[[time objectAtIndex:1]integerValue];
//定时到期后执行的动作
int ddddFlag=info.action==ON?0x02:0x01;
if(type==SingleTimeing)//单次定时 延时
{
//延时是从当前时间加上设置时间
NSTimeInterval secondsPerDay = hours * 60 * 60+(min)*60;
NSDate *today = [[NSDate alloc] init];
NSDate *twoTime;
twoTime = [today dateByAddingTimeInterval: secondsPerDay];
comps = [calendar components:unitFlags fromDate:twoTime];
month=[comps month];
day=[comps day];
hours=[comps hour];
min=[comps minute];
//设置延时命令
int xx=0x01;
Byte transByte2[] = {0xFE,0x00,0x00,0x17,0x03,info.timeIndex,xx,month,day,hours,min,0x00,ddddFlag,0xFF,0xFF,0x10,0x01,0xFF,0xFF,0x20,0x01,0xFF,0xFF,0x30,0x01,0xFF,0xFF};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
}else if(type==WeekTimeing)//周定时
{
int xx=0x02;
//周定时位设置
int flag=[self transferTheWeekString:info.repeatWeek];
Byte transByte2[] = {0xFE,0x00,0x00,0x16,0x03,info.timeIndex,xx,flag,hours,min,0x00,ddddFlag,0xFF,0xFF,0x10,0x01,0xFF,0xFF,0x20,0x01,0xFF,0xFF,0x30,0x01,0xFF,0xFF};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
}
NSData *l2encData=[MAESUnit AES128Encrypt:l2Data key:customKey];
[mutablData appendData:l2encData];
return mutablData;
}
//删除定时
+(NSData *)sendDeleteTime:(TimeingInfo *)info
{
//l1
Byte transByte[] = {0x11,0x49};
NSMutableData *mutablData=[[NSMutableDataalloc]init];
[mutablData appendBytes:transByte length:ArraySize(transByte)];
[mutablData appendData:[ByteUnit stringToByte:info.mac]];
//l2
NSMutableData *l2Data=[[NSMutableDataalloc]init];
Byte transByte1[] = {0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01};
[l2Data appendBytes:transByte1 length:ArraySize(transByte1)];
//l2 定时控制层
Byte transByte2[] = {0xFE,0x00,0x00,0x02,0x06,info.timeIndex};
[l2Data appendBytes:transByte2 length:ArraySize(transByte2)];
//加密l2层数据
NSData *l2encData=[MAESUnit AES128Encrypt:l2Data key:customKey];
[mutablData appendData:l2encData];
return mutablData;
}
//解析定时数据
+(NSMutableDictionary *)decTimeChangeState:(NSData *)data
{
NSMutableDictionary *dic=[[NSMutableDictionaryalloc]init];
//l1
NSData *l1data=[data subdataWithRange:NSMakeRange(0, 8)];
L1DataFormat *l1dataFormat=[[L1DataFormat alloc]initWidthData:l1data];
NSString *l3=[l1dataFormat getMACAddress];
//l2
NSData *dataT=[data subdataWithRange:NSMakeRange(8, data.length-8)];
NSData *sData=[MAESUnit AES128Decrypt:dataT key:customKey];
//l2层定时数据
NSData *l2data=[sData subdataWithRange:NSMakeRange(8, sData.length-8)];
int startCommd=[ByteUnitsubDataLength:l2data startCount:0lenghtCount:1];
int commd=[ByteUnitsubDataLength:l2data startCount:4lenghtCount:1];
int nn=[ByteUnitsubDataLength:l2data startCount:5lenghtCount:1];
int endFlag=[ByteUnitsubDataLength:l2data startCount:6lenghtCount:1];
[dic setObject:[NSNumbernumberWithInt:commd] forKey:@"COMMD"];
[dic setObject:[NSNumbernumberWithInt:nn] forKey:@"NN"];
[dic setObject:[NSNumbernumberWithInt:endFlag] forKey:@"ENDFLAG"];
return dic;
}
//根据DDDD数据返回相应的开关状态
+(BOOL)transferTheDDDD:(NSData *)dddd
{
if(dddd.length==16)
{
short stateT=[ByteUnitsubDataLength:dddd startCount:0lenghtCount:2];
if(stateT==0x01)//@"0001FFFF1001FFFF2001FFFF3001FFFF"//关
{
return NO;
}else//@"0002FFFF1001FFFF2001FFFF3001FFFF"//开
{
return YES;
}
}
returnNO;
}
//通过一个字节返回该字节对应的星期
+(NSString *)transferTheWeekInt:(int)weekInt
{
NSMutableString *weekStr=[[NSMutableStringalloc]init];
NSArray *originArray = [NSArray arrayWithObjects:@"周一",
@"周二",
@"周三",@"周四",@"周五",@"周六",@"周日",nil];
if(weekInt==159)//工作日
{
[weekStr appendFormat:@"工作日"];
}else if(weekInt==224)
{
[weekStr appendFormat:@"周末"];
}else
{
for (int i=0; i<7; i++)
{
int flag=weekInt >> i&1;//判断指定位是否为1 如果为1则该位设置了星期
if(flag==1)
{
[weekStr appendString:[originArray objectAtIndex:i]];
}
}
}
return weekStr;
}
//更具字符串设置位 并返回该数值
+(int)transferTheWeekString:(NSString *)str
{
int weekInt=0;
if(str.length<2)
{
clrbit(weekInt,7);//不执行重复动作
return weekInt;
}
if([str isEqualToString:@"工作日"])
{
setbit(weekInt, 0);
setbit(weekInt, 1);
setbit(weekInt, 2);
setbit(weekInt, 3);
setbit(weekInt, 4);
}else if([str isEqualToString:@"周末"])
{
setbit(weekInt, 5);
setbit(weekInt, 6);
}else
{
if([str rangeOfString:@"周一"].location!=NSNotFound)
setbit(weekInt, 0);
if([str rangeOfString:@"周二"].location!=NSNotFound)
setbit(weekInt, 1);
if([str rangeOfString:@"周三"].location!=NSNotFound)
setbit(weekInt, 2);
if([str rangeOfString:@"周四"].location!=NSNotFound)
setbit(weekInt, 3);
if([str rangeOfString:@"周五"].location!=NSNotFound)
setbit(weekInt, 4);
if([str rangeOfString:@"周六"].location!=NSNotFound)
setbit(weekInt, 5);
if([str rangeOfString:@"周日"].location!=NSNotFound)
setbit(weekInt, 6);
}
setbit(weekInt, 7);//对周重复执行
return weekInt;
}
@end