//
//  BLEDevice.m
//  ENBLEProject
//
//  Created by lvwang2002 on 16/4/4.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import "BLEDevice.h"
#import "ENDLog.h"
#import <CommonCrypto/CommonDigest.h>

@implementation BLEDevice{
  CBPeripheral *_peripheral;
  CBCentralManager *_centralManager;
//	ENNativeDevice *_nativeDevice;
	ENBLEDeviceManager *_deviceManger;
	NSTimer *_overTimer;
	
}


-(id)initWithPeripheral:(CBPeripheral *)peripheral CentralManager:(CBCentralManager *)centerManager DeviceManager:(ENBLEDeviceManager *)deviceManager{
	@synchronized (self) {
		self = [super init];
		if(self){
			_peripheral = peripheral;
			_centralManager = centerManager;
			_deviceManger = deviceManager;
			self.connectStatus = DeviceSearchedStatus;
			_nativeDevice = [ENNativeDevice getNativeDeviceWithDevice:self
																							 WithPeripheral:peripheral
																							 CentralManager:centerManager];
		}
		return self;
	}
}


/** 设置已经连接成功 */
-(void)setConnectedDevice{
    if([self.deviceDelegate respondsToSelector:@selector(connectedDevice:)]){
        [self.deviceDelegate connectedDevice:self];
    }
}


/** 得到管理器 */
-(ENBLEDeviceManager *)getDeviceManager{
	return _deviceManger;
}

/** 得到设备显示名字 */
-(NSString *)getDeviceDisplayName{
	return [_nativeDevice getDeviceDisplayName];
}
/** 返回UUID  */
-(NSUUID *)getUUID{
  return _peripheral.identifier;
}

/** 返回对应的原生设备 */
-(ENNativeDevice *)getNativeDevice{
	return _nativeDevice;
}


/**  连接设备  */
-(void)connect{
	if(self.connectStatus == DeviceConnectingStatus ||
		 self.connectStatus == DeviceConnectedStatus){
		ENLog(@"设备正在连接或已经连接");
		return;
	}
	
	self.connectStatus = DeviceConnectingStatus;
	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
		[_centralManager connectPeripheral:_peripheral options:nil];
	});
	
	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
		if(self.connectStatus == DeviceConnectedStatus ||
		   self.connectStatus == DeviceDisconnectingStatus){
			ENLog(@"device has been disconneted,not overtime.");
			return ;
		};
		
		if(self.connectStatus == DeviceConnectedStatus){
			return ;
		};
		
			//超时状态
		[_deviceManger uhoh:self];
		
		dispatch_async(dispatch_get_main_queue(), ^{
			if([self.deviceDelegate respondsToSelector:@selector(didOverTimeForConnectDevice:)]){
				[self.deviceDelegate didOverTimeForConnectDevice:self];
			};
		});
	});
}


/** 断开连接 */
-(void)disconnect{
	_connectStatus = DeviceDisconnectingStatus;
    [_centralManager cancelPeripheralConnection:_peripheral];
}

/** 获取名字 */
-(NSString *)getDeviceName{
	return _peripheral.name;
}

/** 获取设备UUID */
-(NSUUID *)getDeviceUUID{
	return _peripheral.identifier; 
}

/** 获得附件 */
-(CBPeripheral *)getPeripheral{
	return _peripheral;
}



#pragma mark -
#pragma Peripheral delegate
-(void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error{
	
}

- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral{
	ENLog(@"peripheralDidUpdateName");
}

- (void)peripheralDidInvalidateServices:(CBPeripheral *)peripheral{
	ENLog(@"peripheralDidInvalidateServices");
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
	ENLog(@"didWriteValueForDescriptor");
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{

}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
	ENLog(@"didUpdateValueForDescriptor");
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
	NSData *data = [characteristic.value copy];
	CBUUID *uuid = [characteristic.UUID copy];
	dispatch_async(dispatch_get_main_queue(), ^{
		if([_nativeDevice respondsToSelector:@selector(peripheral:didUpdateValueForCharacteristic:error:)]){
			[_nativeDevice peripheral:peripheral didUpdateValueForCharacteristic:characteristic error:error];
		}else{
			[_nativeDevice peripheral:peripheral didUpdateValueForReceiveData:data UUID:uuid error:error];
		}
		
	});
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
	ENLog(@"didUpdateNotificationStateForCharacteristic");
}

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray *)invalidatedServices{
	ENLog(@"didModifyServices");
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
	dispatch_async(dispatch_get_main_queue(), ^{
		[_nativeDevice peripheral:peripheral didDiscoverServices:error];
	});
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(NSError *)error{
	ENLog(@"didDiscoverIncludedServicesForService");
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
	ENLog(@"didDiscoverDescriptorsForCharacteristic");
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
	dispatch_async(dispatch_get_main_queue(), ^{
		[_nativeDevice peripheral:peripheral didDiscoverCharacteristicsForService:service error:error];
	});
}

+(NSString *)getDataIDWithUserID:(NSString *)userID
														Type:(NSString *)type
												TimeFlag:(NSNumber *)timeFlag
													 Value:(NSString *)value{
	NSString *content = [NSString stringWithFormat:@"%@_%@_%@_%@",userID,type,timeFlag,value];
	NSString *dataID = [self md5:content];
	return dataID;
}

+ (NSString *) md5:(NSString *)str {
 const char *cStr = [str UTF8String];
	unsigned char result[16];
	CC_MD5( cStr, strlen(cStr), result );
	return [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
					result[0], result[1], result[2], result[3],
					result[4], result[5], result[6], result[7],
					result[8], result[9], result[10], result[11],
					result[12], result[13], result[14], result[15]
					];
}

@end
