使用时要讲Capabilities中的Background Modes 中勾选上Uses Bluetooth LE accessories。
BTServer.h
//
// BTServer.h
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import " PeriperalInfo.h "
#define UUIDPrimaryService @"0xFF00" // tmp 0XFFA0 should be 0xFF00
#define UUIDPrimaryService2 @"0xFFA0" // tmp 0XFFA0 should be 0xFF00
#define UUIDDeviceInfo @"0xFF01"
#define UUIDRealTimeDate @"0xFF02"
#define UUIDControlPoint @"0xFF03"
#define UUIDData @"0xFF04"
#define UUIDFirmwareData @"0xFF05"
#define UUIDDebugData @"0xFF06"
#define UUIDBLEUserInfo @"0xFF07"
#define AUTO_CANCEL_CONNECT_TIMEOUT 10
typedef void (^eventBlock)(CBPeripheral *peripheral, BOOL status, NSError *error);
typedef enum{
KNOT = 0,
KING = 1,
KSUCCESS = 2,
KFAILED = 3,
}myStatus;
@protocol BTServerDelegate
@optional
-( void)didStopScan;
-( void)didFoundPeripheral;
-( void)didReadvalue;
@required
-( void)didDisconnect;
@end
@interface BTServer : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate>
+(BTServer*)defaultBTServer; // 初始化方法
@property(weak, nonatomic) id<BTServerDelegate> delegate;
//
@property (strong,nonatomic)NSMutableArray *discoveredPeripherals;
@property (strong,nonatomic)CBPeripheral* selectPeripheral;
@property (strong,nonatomic)CBService* discoveredSevice;
@property (strong,nonatomic)CBCharacteristic *selectCharacteristic;
/* ************************************
连接方法
************************************ */
-( void)startScan;
-( void)startScan:(NSInteger)forLastTime;
-( void)stopScan;
-( void)stopScan:(BOOL)withOutEvent;
-( void)connect:(PeriperalInfo *)peripheralInfo withFinishCB:(eventBlock)callback;
-( void)disConnect;
-( void)discoverService:(CBService*)service;
-( void)readValue:(CBCharacteristic*)characteristic;
/* ************************************
常用读取值或写入值方法
************************************* */
- ( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID;
/* *
* 通过设备名来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param periperalName 设备名
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals peripheralName:(NSString *)periperalName;
/* *
* 通过设备的UUID来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param psUUID 设备的UUID
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals psUUID:(NSString *)psUUID;
/* *
* 通过设备的UUID来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param psUUID 设备的UUID
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals pcUUID:(CBUUID *)pcUUID;
/* *
* 选择characteristic
*
* @param peripheral 选择的peripheral
* @param ssUUID service的UUID
* @param csUUID characteristic的UUID
*
* @return 选择好的characteristic
*/
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral ssUUID:(NSString *)ssUUID csUUID:(NSString *)csUUID;
/* *
* 选择characteristic
*
* @param peripheral 选择的peripheral
* @param ssUUID service的UUID
* @param csUUID characteristic的UUID
*
* @return 选择好的characteristic
*/
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral scUUID:(CBUUID *)scUUID ccUUID:(CBUUID *)ccUUID;
/* *
* 向特征值写入值 :CBCharacteristicWriteWithoutResponse
*/
+( void)writeCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID data:(NSData *)data;
/* *
* 向特征值写入值 :CBCharacteristicWriteWithResponse
*/
+( void)writeCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID data:(NSData *)data;
/* *
* 读取特征值
*/
+( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID;
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID enable:(BOOL)enable;
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID enable:(BOOL)enable;
/* *
* 判断特征值是否可以设置notify
*/
+( bool) isCharacteristicNotifiable:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *) cCBUUID;
/* *
***************************************
*
* 连接状态
****************************************
*/
-(NSInteger)getConnectState;
-(NSInteger)getServiceState;
-(NSInteger)getCharacteristicState;
// BTServer.h
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import " PeriperalInfo.h "
#define UUIDPrimaryService @"0xFF00" // tmp 0XFFA0 should be 0xFF00
#define UUIDPrimaryService2 @"0xFFA0" // tmp 0XFFA0 should be 0xFF00
#define UUIDDeviceInfo @"0xFF01"
#define UUIDRealTimeDate @"0xFF02"
#define UUIDControlPoint @"0xFF03"
#define UUIDData @"0xFF04"
#define UUIDFirmwareData @"0xFF05"
#define UUIDDebugData @"0xFF06"
#define UUIDBLEUserInfo @"0xFF07"
#define AUTO_CANCEL_CONNECT_TIMEOUT 10
typedef void (^eventBlock)(CBPeripheral *peripheral, BOOL status, NSError *error);
typedef enum{
KNOT = 0,
KING = 1,
KSUCCESS = 2,
KFAILED = 3,
}myStatus;
@protocol BTServerDelegate
@optional
-( void)didStopScan;
-( void)didFoundPeripheral;
-( void)didReadvalue;
@required
-( void)didDisconnect;
@end
@interface BTServer : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate>
+(BTServer*)defaultBTServer; // 初始化方法
@property(weak, nonatomic) id<BTServerDelegate> delegate;
//
@property (strong,nonatomic)NSMutableArray *discoveredPeripherals;
@property (strong,nonatomic)CBPeripheral* selectPeripheral;
@property (strong,nonatomic)CBService* discoveredSevice;
@property (strong,nonatomic)CBCharacteristic *selectCharacteristic;
/* ************************************
连接方法
************************************ */
-( void)startScan;
-( void)startScan:(NSInteger)forLastTime;
-( void)stopScan;
-( void)stopScan:(BOOL)withOutEvent;
-( void)connect:(PeriperalInfo *)peripheralInfo withFinishCB:(eventBlock)callback;
-( void)disConnect;
-( void)discoverService:(CBService*)service;
-( void)readValue:(CBCharacteristic*)characteristic;
/* ************************************
常用读取值或写入值方法
************************************* */
- ( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID;
/* *
* 通过设备名来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param periperalName 设备名
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals peripheralName:(NSString *)periperalName;
/* *
* 通过设备的UUID来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param psUUID 设备的UUID
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals psUUID:(NSString *)psUUID;
/* *
* 通过设备的UUID来选择设备
*
* @param discoveredPeripherals 发现的设备
* @param psUUID 设备的UUID
*
* @return 选择的设备
*/
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals pcUUID:(CBUUID *)pcUUID;
/* *
* 选择characteristic
*
* @param peripheral 选择的peripheral
* @param ssUUID service的UUID
* @param csUUID characteristic的UUID
*
* @return 选择好的characteristic
*/
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral ssUUID:(NSString *)ssUUID csUUID:(NSString *)csUUID;
/* *
* 选择characteristic
*
* @param peripheral 选择的peripheral
* @param ssUUID service的UUID
* @param csUUID characteristic的UUID
*
* @return 选择好的characteristic
*/
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral scUUID:(CBUUID *)scUUID ccUUID:(CBUUID *)ccUUID;
/* *
* 向特征值写入值 :CBCharacteristicWriteWithoutResponse
*/
+( void)writeCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID data:(NSData *)data;
/* *
* 向特征值写入值 :CBCharacteristicWriteWithResponse
*/
+( void)writeCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID data:(NSData *)data;
/* *
* 读取特征值
*/
+( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID;
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID enable:(BOOL)enable;
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID enable:(BOOL)enable;
/* *
* 判断特征值是否可以设置notify
*/
+( bool) isCharacteristicNotifiable:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *) cCBUUID;
/* *
***************************************
*
* 连接状态
****************************************
*/
-(NSInteger)getConnectState;
-(NSInteger)getServiceState;
-(NSInteger)getCharacteristicState;
@end
BTServer.m
//
// BTServer.m
//
#import " BTServer.h "
#import " MBProgressHUD+MJ.h "
@interface BTServer()
@end
@implementation BTServer{
BOOL inited;
CBCentralManager *myCenter;
// state
NSInteger scanState;
NSInteger connectState;
NSInteger serviceState;
NSInteger characteristicState;
NSInteger readState;
eventBlock connectBlock;
}
static BTServer* _defaultBTServer = nil;
-(NSInteger)getScanState
{
return scanState;
}
-(NSInteger)getConnectState
{
return connectState;
}
-(NSInteger)getServiceState
{
return serviceState;
}
-(NSInteger)getCharacteristicState
{
return characteristicState;
}
-(NSInteger)getReadState
{
return readState;
}
+(BTServer*)defaultBTServer
{
if (nil == _defaultBTServer) {
_defaultBTServer = [[BTServer alloc]init];
[_defaultBTServer initBLE];
}
return _defaultBTServer;
}
-( void)initBLE
{
if (inited) {
return;
}
inited = TRUE;
self. delegate = nil;
self.discoveredPeripherals = [NSMutableArray array];
self.selectPeripheral = nil;
connectState = KNOT;
connectBlock = nil;
// NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerOptionShowPowerAlertKey, @"zStrapRestoreIdentifier",CBCentralManagerOptionRestoreIdentifierKey,nil];
myCenter = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
}
-( void)finishBLE
{
}
#pragma mark -- APIs
-( void)startScan
{
[self startScan: 3];
}
/* *
* 开始扫描并设置超时时间
*/
-( void)startScan:(NSInteger)forLastTime
{
[myCenter scanForPeripheralsWithServices:nil options:nil];
if (forLastTime > 0) {
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(stopScan)
object:nil];
[self performSelector:@selector(stopScan)
withObject:nil
afterDelay:forLastTime];
}
}
/* *
* 自动断开连接
*/
-( void)stopScan:(BOOL)withOutEvent
{
if (scanState != KING) {
return;
}
[MBProgressHUD hideHUD];
NSLog( @" stop scan ... ");
scanState = KSUCCESS;
[myCenter stopScan];
if(withOutEvent)
return;
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didStopScan)]){
[self. delegate didStopScan];
}
}
}
/* *
* 停止扫描
*/
-( void)stopScan
{
[MBProgressHUD hideHUD];
[self stopScan:FALSE];
}
/* *
* 去掉连接
*/
-( void)cancelConnect
{
if (myCenter && self.selectPeripheral) {
if(self.selectPeripheral.state == CBPeripheralStateConnecting){
NSLog( @" timeout cancel connect to peripheral:%@ ",self.selectPeripheral.name);
[myCenter cancelPeripheralConnection:self.selectPeripheral];
connectState = KNOT;
}
}
}
/* *
* 连接外设
*/
-( void)connect:(PeriperalInfo *)peripheralInfo
{
NSLog( @" connecting to peripheral:%@ ",peripheralInfo.peripheral.name);
[myCenter connectPeripheral:peripheralInfo.peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey: @YES, CBConnectPeripheralOptionNotifyOnDisconnectionKey: @YES, CBConnectPeripheralOptionNotifyOnNotificationKey: @YES}];
self.selectPeripheral = peripheralInfo.peripheral;
connectState = KING;
[self performSelector:@selector(stopScan)
withObject:nil
afterDelay: 3];
}
/* *
* 连接外设并返回值
*/
-( void)connect:(PeriperalInfo *)peripheralInfo withFinishCB:(eventBlock)callback
{
[self connect:peripheralInfo];
connectBlock = callback;
}
/* *
* 断开连接
*/
-( void)disConnect
{
if(myCenter && self.selectPeripheral){
[myCenter cancelPeripheralConnection:self.selectPeripheral];
}
}
/* *
* 发现设备
*/
-( void)discoverService:(CBService*)service
{
if(self.selectPeripheral){
characteristicState = KING;
self.discoveredSevice = service;
[self.selectPeripheral discoverCharacteristics:nil forService:service];
}
}
/* *
* 读取特征里的值
*/
-( void)readValue:(CBCharacteristic*)characteristic
{
if (readState == KING) {
NSLog( @" BTServer: should wait read over ");
return;
}
if (characteristic != nil) {
self.selectCharacteristic = characteristic;
}
readState = KING;
[self.selectPeripheral readValueForCharacteristic:self.selectCharacteristic];
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals peripheralName:(NSString *)periperalName
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.name isEqualToString:periperalName]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
NSLog( @" 连接成功 ");
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals psUUID:(NSString *)psUUID
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.uuid isEqual:[CBUUID UUIDWithString:psUUID]]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals pcUUID:(CBUUID *)pcUUID
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.uuid isEqual:pcUUID]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral scUUID:(CBUUID *)scUUID ccUUID:(CBUUID *)ccUUID
{
CBCharacteristic *selectCharacter;
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:scUUID]) {
for (CBCharacteristic *character in service.characteristics) {
if ([character.UUID isEqual:ccUUID]) {
selectCharacter = character;
}
}
}
}
return selectCharacter;
}
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral ssUUID:(NSString *)ssUUID csUUID:(NSString *)csUUID
{
CBCharacteristic *selectCharacter;
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:ssUUID]]) {
for (CBCharacteristic *character in service.characteristics) {
if ([character.UUID isEqual:[CBUUID UUIDWithString:csUUID]]) {
selectCharacter = character;
}
}
}
}
return selectCharacter;
}
+( void)writeCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID data:(NSData *)data {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]) {
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
}
}
}
+( void)writeCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID data:(NSData *)data {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID]) {
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
}
}
}
+( void)readCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID {
for ( CBService *service in peripheral.services ) {
if([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]) {
[peripheral readValueForCharacteristic:characteristic];
NSLog( @" characteristic.value = %@ ",characteristic.value);
}
}
}
}
}
+( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID {
for ( CBService *service in peripheral.services ) {
if([service.UUID isEqual:sCBUUID]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID]) {
[peripheral readValueForCharacteristic:characteristic];
}
}
}
}
}
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID enable:(BOOL)enable {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]])
{
[peripheral setNotifyValue:enable forCharacteristic:characteristic];
}
}
}
}
}
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID enable:(BOOL)enable {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID])
{
[peripheral setNotifyValue:enable forCharacteristic:characteristic];
}
}
}
}
}
/* *
* 测试特征值是否可以发送notify
*/
+( bool) isCharacteristicNotifiable:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *) cCBUUID {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID])
{
if (characteristic.properties & CBCharacteristicPropertyNotify) return YES;
else return NO;
}
}
}
}
return NO;
}
#pragma mark CBCentralManagerDelegate
/* *
* 添加设备信息
*/
-( void)addPeripheralInfo:(PeriperalInfo *)peripheralInfo
{
for( int i= 0;i<self.discoveredPeripherals.count;i++){
PeriperalInfo *pi = self.discoveredPeripherals[i];
if([peripheralInfo.uuid isEqualToString:pi.uuid]){
[self.discoveredPeripherals replaceObjectAtIndex:i withObject:peripheralInfo];
return;
}
}
[self.discoveredPeripherals addObject:peripheralInfo];
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didFoundPeripheral)]){
[self. delegate didFoundPeripheral];
}
}
}
/* *
* 添加发现的设备信息
*/
-( void)addPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI
{
PeriperalInfo *pi = [[PeriperalInfo alloc]init];
pi.peripheral = peripheral;
pi.uuid = [peripheral.identifier UUIDString];
pi.name = peripheral.name;
switch (peripheral.state) {
case CBPeripheralStateDisconnected:
pi.state = @" disConnected ";
break;
case CBPeripheralStateConnecting:
pi.state = @" connecting ";
break;
case CBPeripheralStateConnected:
pi.state = @" connected ";
break;
default:
break;
}
if (advertisementData) {
pi.localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
NSArray *array = [advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey];
pi.serviceUUIDS = [array componentsJoinedByString: @" ; "];
}
if (RSSI) {
pi.RSSI = RSSI;
}
[self addPeripheralInfo:pi];
}
/* *
* 当发现设备的时候调用该代理方法
*/
- ( void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
[self stopScan];
[self addPeripheral:peripheral advertisementData:advertisementData RSSI:RSSI];
}
/* *
* 中心设备连接到了外设
*/
- ( void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
[MBProgressHUD hideHUD];
NSLog( @" didconnect to peripheral: %@ ",peripheral.name);
if (connectBlock) {
connectBlock(peripheral, true,nil);
connectBlock = nil;
}
self.selectPeripheral = peripheral;
self.selectPeripheral. delegate = self;
[self.selectPeripheral discoverServices:nil];
}
/* *
* 中心设备和外围断开连接
*/
- ( void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog( @" didDisConnected peripheral: %@ ",peripheral.name);
if (connectBlock) {
connectBlock(peripheral, false,nil);
connectBlock = nil;
}
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didDisconnect)]){
[self. delegate didDisconnect];
}
}
}
/* *
* 中心设备连接外围设备不成功
*/
- ( void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog( @" DidFailToConnectPeripheral ..... ");
}
/* *
* 中心管理设备更新状态
*/
- ( void)centralManagerDidUpdateState:(CBCentralManager *)central
{
// Determine the state of the peripheral
if ([central state] == CBCentralManagerStatePoweredOff) {
NSLog( @" CoreBluetooth BLE hardware is powered off ");
}
else if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog( @" CoreBluetooth BLE hardware is powered on and ready ");
}
else if ([central state] == CBCentralManagerStateUnauthorized) {
NSLog( @" CoreBluetooth BLE state is unauthorized ");
}
else if ([central state] == CBCentralManagerStateUnknown) {
NSLog( @" CoreBluetooth BLE state is unknown ");
}
else if ([central state] == CBCentralManagerStateUnsupported) {
NSLog( @" CoreBluetooth BLE hardware is unsupported on this platform ");
}
}
- ( void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict
{
}
#pragma mark CBPeripheralDelegate
/* *
* 外围设备发现服务
*/
- ( void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (nil == error) {
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString: @" FFF0 "]]) {
self.discoveredSevice = service;
[peripheral discoverCharacteristics:nil forService:self.discoveredSevice];
}
}
} else{
NSLog( @" discover service failed:%@ ",error);
}
}
/* *
* 外围设备发现Service下面的特征
*/
- ( void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (nil == error) {
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString: @" FFF1 "]]) {
self.selectCharacteristic = characteristic;
}
}
} else{
self.discoveredSevice = nil;
}
}
/* *
* 外围设备的特征值更新了
*/
- ( void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error){
NSLog( @" Error updating value for characteristic %@ error: %@ ", characteristic.UUID, [error localizedDescription]);
return;
}
// 收到FF3发来的notify时将FF2的value改成02
if ([[characteristic.UUID UUIDString]isEqualToString: @" FF "]) {
unsigned char data = 0x05;
return;
}
self.selectCharacteristic = characteristic;
if ([[characteristic.UUID UUIDString]isEqualToString: @" FFF1 "]) {
if (self. delegate && [( id)self. delegate respondsToSelector:@selector(didReadvalue)])
[self. delegate didReadvalue];
}
[MBProgressHUD hideHUD];
}
/* *
* 外围设备更改了特征的值
*/
- ( void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) {
NSLog( @" 写入失败 ");
} else{
NSLog( @" 写入成功 ");
NSLog( @" peripheral = %@ ",peripheral);
NSLog( @" characteristic = %@ ",characteristic);
}
}
@end
// BTServer.m
//
#import " BTServer.h "
#import " MBProgressHUD+MJ.h "
@interface BTServer()
@end
@implementation BTServer{
BOOL inited;
CBCentralManager *myCenter;
// state
NSInteger scanState;
NSInteger connectState;
NSInteger serviceState;
NSInteger characteristicState;
NSInteger readState;
eventBlock connectBlock;
}
static BTServer* _defaultBTServer = nil;
-(NSInteger)getScanState
{
return scanState;
}
-(NSInteger)getConnectState
{
return connectState;
}
-(NSInteger)getServiceState
{
return serviceState;
}
-(NSInteger)getCharacteristicState
{
return characteristicState;
}
-(NSInteger)getReadState
{
return readState;
}
+(BTServer*)defaultBTServer
{
if (nil == _defaultBTServer) {
_defaultBTServer = [[BTServer alloc]init];
[_defaultBTServer initBLE];
}
return _defaultBTServer;
}
-( void)initBLE
{
if (inited) {
return;
}
inited = TRUE;
self. delegate = nil;
self.discoveredPeripherals = [NSMutableArray array];
self.selectPeripheral = nil;
connectState = KNOT;
connectBlock = nil;
// NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerOptionShowPowerAlertKey, @"zStrapRestoreIdentifier",CBCentralManagerOptionRestoreIdentifierKey,nil];
myCenter = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
}
-( void)finishBLE
{
}
#pragma mark -- APIs
-( void)startScan
{
[self startScan: 3];
}
/* *
* 开始扫描并设置超时时间
*/
-( void)startScan:(NSInteger)forLastTime
{
[myCenter scanForPeripheralsWithServices:nil options:nil];
if (forLastTime > 0) {
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(stopScan)
object:nil];
[self performSelector:@selector(stopScan)
withObject:nil
afterDelay:forLastTime];
}
}
/* *
* 自动断开连接
*/
-( void)stopScan:(BOOL)withOutEvent
{
if (scanState != KING) {
return;
}
[MBProgressHUD hideHUD];
NSLog( @" stop scan ... ");
scanState = KSUCCESS;
[myCenter stopScan];
if(withOutEvent)
return;
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didStopScan)]){
[self. delegate didStopScan];
}
}
}
/* *
* 停止扫描
*/
-( void)stopScan
{
[MBProgressHUD hideHUD];
[self stopScan:FALSE];
}
/* *
* 去掉连接
*/
-( void)cancelConnect
{
if (myCenter && self.selectPeripheral) {
if(self.selectPeripheral.state == CBPeripheralStateConnecting){
NSLog( @" timeout cancel connect to peripheral:%@ ",self.selectPeripheral.name);
[myCenter cancelPeripheralConnection:self.selectPeripheral];
connectState = KNOT;
}
}
}
/* *
* 连接外设
*/
-( void)connect:(PeriperalInfo *)peripheralInfo
{
NSLog( @" connecting to peripheral:%@ ",peripheralInfo.peripheral.name);
[myCenter connectPeripheral:peripheralInfo.peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey: @YES, CBConnectPeripheralOptionNotifyOnDisconnectionKey: @YES, CBConnectPeripheralOptionNotifyOnNotificationKey: @YES}];
self.selectPeripheral = peripheralInfo.peripheral;
connectState = KING;
[self performSelector:@selector(stopScan)
withObject:nil
afterDelay: 3];
}
/* *
* 连接外设并返回值
*/
-( void)connect:(PeriperalInfo *)peripheralInfo withFinishCB:(eventBlock)callback
{
[self connect:peripheralInfo];
connectBlock = callback;
}
/* *
* 断开连接
*/
-( void)disConnect
{
if(myCenter && self.selectPeripheral){
[myCenter cancelPeripheralConnection:self.selectPeripheral];
}
}
/* *
* 发现设备
*/
-( void)discoverService:(CBService*)service
{
if(self.selectPeripheral){
characteristicState = KING;
self.discoveredSevice = service;
[self.selectPeripheral discoverCharacteristics:nil forService:service];
}
}
/* *
* 读取特征里的值
*/
-( void)readValue:(CBCharacteristic*)characteristic
{
if (readState == KING) {
NSLog( @" BTServer: should wait read over ");
return;
}
if (characteristic != nil) {
self.selectCharacteristic = characteristic;
}
readState = KING;
[self.selectPeripheral readValueForCharacteristic:self.selectCharacteristic];
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals peripheralName:(NSString *)periperalName
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.name isEqualToString:periperalName]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
NSLog( @" 连接成功 ");
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals psUUID:(NSString *)psUUID
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.uuid isEqual:[CBUUID UUIDWithString:psUUID]]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
- ( void)selectPeripheral:(NSMutableArray *)discoveredPeripherals pcUUID:(CBUUID *)pcUUID
{
dispatch_async(dispatch_get_main_queue(), ^{
for (PeriperalInfo *peripheralInfo in self.discoveredPeripherals) {
if ([peripheralInfo.uuid isEqual:pcUUID]) {
[self connect:peripheralInfo withFinishCB:^(CBPeripheral *peripheral, BOOL status, NSError *error) {
if (status) {
self.selectPeripheral = peripheralInfo.peripheral;
} else{
[MBProgressHUD showError: @" 连接失败 "];
}
}];
}
}
});
}
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral scUUID:(CBUUID *)scUUID ccUUID:(CBUUID *)ccUUID
{
CBCharacteristic *selectCharacter;
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:scUUID]) {
for (CBCharacteristic *character in service.characteristics) {
if ([character.UUID isEqual:ccUUID]) {
selectCharacter = character;
}
}
}
}
return selectCharacter;
}
+ (CBCharacteristic *)selectCharacteristic:(CBPeripheral *)peripheral ssUUID:(NSString *)ssUUID csUUID:(NSString *)csUUID
{
CBCharacteristic *selectCharacter;
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:ssUUID]]) {
for (CBCharacteristic *character in service.characteristics) {
if ([character.UUID isEqual:[CBUUID UUIDWithString:csUUID]]) {
selectCharacter = character;
}
}
}
}
return selectCharacter;
}
+( void)writeCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID data:(NSData *)data {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]) {
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
}
}
}
+( void)writeCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID data:(NSData *)data {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID]) {
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
}
}
}
+( void)readCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID {
for ( CBService *service in peripheral.services ) {
if([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]) {
[peripheral readValueForCharacteristic:characteristic];
NSLog( @" characteristic.value = %@ ",characteristic.value);
}
}
}
}
}
+( void)readCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID {
for ( CBService *service in peripheral.services ) {
if([service.UUID isEqual:sCBUUID]) {
for ( CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID]) {
[peripheral readValueForCharacteristic:characteristic];
}
}
}
}
}
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID enable:(BOOL)enable {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]])
{
[peripheral setNotifyValue:enable forCharacteristic:characteristic];
}
}
}
}
}
/* *
* 为特征值设置notify
*/
+( void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *)cCBUUID enable:(BOOL)enable {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID])
{
[peripheral setNotifyValue:enable forCharacteristic:characteristic];
}
}
}
}
}
/* *
* 测试特征值是否可以发送notify
*/
+( bool) isCharacteristicNotifiable:(CBPeripheral *)peripheral sCBUUID:(CBUUID *)sCBUUID cCBUUID:(CBUUID *) cCBUUID {
for ( CBService *service in peripheral.services ) {
if ([service.UUID isEqual:sCBUUID]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:cCBUUID])
{
if (characteristic.properties & CBCharacteristicPropertyNotify) return YES;
else return NO;
}
}
}
}
return NO;
}
#pragma mark CBCentralManagerDelegate
/* *
* 添加设备信息
*/
-( void)addPeripheralInfo:(PeriperalInfo *)peripheralInfo
{
for( int i= 0;i<self.discoveredPeripherals.count;i++){
PeriperalInfo *pi = self.discoveredPeripherals[i];
if([peripheralInfo.uuid isEqualToString:pi.uuid]){
[self.discoveredPeripherals replaceObjectAtIndex:i withObject:peripheralInfo];
return;
}
}
[self.discoveredPeripherals addObject:peripheralInfo];
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didFoundPeripheral)]){
[self. delegate didFoundPeripheral];
}
}
}
/* *
* 添加发现的设备信息
*/
-( void)addPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI
{
PeriperalInfo *pi = [[PeriperalInfo alloc]init];
pi.peripheral = peripheral;
pi.uuid = [peripheral.identifier UUIDString];
pi.name = peripheral.name;
switch (peripheral.state) {
case CBPeripheralStateDisconnected:
pi.state = @" disConnected ";
break;
case CBPeripheralStateConnecting:
pi.state = @" connecting ";
break;
case CBPeripheralStateConnected:
pi.state = @" connected ";
break;
default:
break;
}
if (advertisementData) {
pi.localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
NSArray *array = [advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey];
pi.serviceUUIDS = [array componentsJoinedByString: @" ; "];
}
if (RSSI) {
pi.RSSI = RSSI;
}
[self addPeripheralInfo:pi];
}
/* *
* 当发现设备的时候调用该代理方法
*/
- ( void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
[self stopScan];
[self addPeripheral:peripheral advertisementData:advertisementData RSSI:RSSI];
}
/* *
* 中心设备连接到了外设
*/
- ( void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
[MBProgressHUD hideHUD];
NSLog( @" didconnect to peripheral: %@ ",peripheral.name);
if (connectBlock) {
connectBlock(peripheral, true,nil);
connectBlock = nil;
}
self.selectPeripheral = peripheral;
self.selectPeripheral. delegate = self;
[self.selectPeripheral discoverServices:nil];
}
/* *
* 中心设备和外围断开连接
*/
- ( void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog( @" didDisConnected peripheral: %@ ",peripheral.name);
if (connectBlock) {
connectBlock(peripheral, false,nil);
connectBlock = nil;
}
if (self. delegate) {
if([( id)self. delegate respondsToSelector:@selector(didDisconnect)]){
[self. delegate didDisconnect];
}
}
}
/* *
* 中心设备连接外围设备不成功
*/
- ( void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog( @" DidFailToConnectPeripheral ..... ");
}
/* *
* 中心管理设备更新状态
*/
- ( void)centralManagerDidUpdateState:(CBCentralManager *)central
{
// Determine the state of the peripheral
if ([central state] == CBCentralManagerStatePoweredOff) {
NSLog( @" CoreBluetooth BLE hardware is powered off ");
}
else if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog( @" CoreBluetooth BLE hardware is powered on and ready ");
}
else if ([central state] == CBCentralManagerStateUnauthorized) {
NSLog( @" CoreBluetooth BLE state is unauthorized ");
}
else if ([central state] == CBCentralManagerStateUnknown) {
NSLog( @" CoreBluetooth BLE state is unknown ");
}
else if ([central state] == CBCentralManagerStateUnsupported) {
NSLog( @" CoreBluetooth BLE hardware is unsupported on this platform ");
}
}
- ( void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict
{
}
#pragma mark CBPeripheralDelegate
/* *
* 外围设备发现服务
*/
- ( void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (nil == error) {
for (CBService *service in peripheral.services) {
if ([service.UUID isEqual:[CBUUID UUIDWithString: @" FFF0 "]]) {
self.discoveredSevice = service;
[peripheral discoverCharacteristics:nil forService:self.discoveredSevice];
}
}
} else{
NSLog( @" discover service failed:%@ ",error);
}
}
/* *
* 外围设备发现Service下面的特征
*/
- ( void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (nil == error) {
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString: @" FFF1 "]]) {
self.selectCharacteristic = characteristic;
}
}
} else{
self.discoveredSevice = nil;
}
}
/* *
* 外围设备的特征值更新了
*/
- ( void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error){
NSLog( @" Error updating value for characteristic %@ error: %@ ", characteristic.UUID, [error localizedDescription]);
return;
}
// 收到FF3发来的notify时将FF2的value改成02
if ([[characteristic.UUID UUIDString]isEqualToString: @" FF "]) {
unsigned char data = 0x05;
return;
}
self.selectCharacteristic = characteristic;
if ([[characteristic.UUID UUIDString]isEqualToString: @" FFF1 "]) {
if (self. delegate && [( id)self. delegate respondsToSelector:@selector(didReadvalue)])
[self. delegate didReadvalue];
}
[MBProgressHUD hideHUD];
}
/* *
* 外围设备更改了特征的值
*/
- ( void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) {
NSLog( @" 写入失败 ");
} else{
NSLog( @" 写入成功 ");
NSLog( @" peripheral = %@ ",peripheral);
NSLog( @" characteristic = %@ ",characteristic);
}
}
@end
PeriperalInfo.h
//
// PeriperalInfo.h
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface PeriperalInfo : NSObject
@property (strong,nonatomic)CBPeripheral* peripheral;
@property (strong,nonatomic)NSString* uuid;
@property (strong,nonatomic)NSString* name;
@property (strong,nonatomic)NSString* state;
// advertisement
@property (strong,nonatomic)NSString* channel;
@property (strong,nonatomic)NSString* isConnectable;
@property (strong,nonatomic)NSString* localName;
@property (strong,nonatomic)NSString* manufactureData;
@property (strong,nonatomic)NSString* serviceUUIDS;
// rssi
@property (strong,nonatomic)NSNumber *RSSI;
// PeriperalInfo.h
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface PeriperalInfo : NSObject
@property (strong,nonatomic)CBPeripheral* peripheral;
@property (strong,nonatomic)NSString* uuid;
@property (strong,nonatomic)NSString* name;
@property (strong,nonatomic)NSString* state;
// advertisement
@property (strong,nonatomic)NSString* channel;
@property (strong,nonatomic)NSString* isConnectable;
@property (strong,nonatomic)NSString* localName;
@property (strong,nonatomic)NSString* manufactureData;
@property (strong,nonatomic)NSString* serviceUUIDS;
// rssi
@property (strong,nonatomic)NSNumber *RSSI;
@end
PeriperalInfo.m
#import "PeriperalInfo.h"
@implementation PeriperalInfo
@end