Created
March 29, 2013 02:51
-
-
Save t-kashima/5268425 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.h | |
// Bluetooth | |
// | |
#import <UIKit/UIKit.h> | |
#import <CoreBluetooth/CoreBluetooth.h> | |
@interface ViewController : UIViewController <CBCentralManagerDelegate, CBPeripheralManagerDelegate, CBPeripheralDelegate> | |
@property (weak, nonatomic) IBOutlet UITextView *textView; | |
- (IBAction)actionConnect:(id)sender; | |
- (IBAction)actionPeripheral:(id)sender; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// Bluetooth | |
// | |
#import "ViewController.h" | |
@interface ViewController () | |
@property (strong, nonatomic) CBCentralManager *centralManager; | |
@property (strong, nonatomic) CBPeripheralManager *peripheralManager; | |
@property (strong, nonatomic) CBPeripheral *aPeripheral; | |
@property (strong, nonatomic) NSData *dataToSend; | |
@property (nonatomic, readwrite) NSInteger sendDataIndex; | |
@property (strong, nonatomic) CBMutableCharacteristic *transferCharacteristic; | |
@property (strong, nonatomic) NSMutableData *receivedData; | |
@end | |
#define ADVERTISEMENT_NAME @"TestApp" | |
#define SERVICE_ID @"2145B0A7-CC2E-49C2-BCCA-B55A703CD030" | |
#define CHARASTERISTIC_ID @"B4DA0427-EE1D-4D16-8BC8-4B95EA15D0C0" | |
#define MAX_MTU 20 | |
@implementation ViewController | |
@synthesize textView; | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
} | |
- (IBAction)actionConnect:(id)sender | |
{ | |
[self startScan]; | |
} | |
- (IBAction)actionPeripheral:(id)sender | |
{ | |
[self startPeripheral]; | |
} | |
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { | |
switch(peripheral.state) { | |
case CBPeripheralManagerStatePoweredOn: | |
[self setupService]; | |
break; | |
default: | |
NSLog(@"Peripheral Manager did change state"); | |
break; | |
} | |
} | |
- (void)setupService | |
{ | |
CBMutableService *service = [[CBMutableService alloc] | |
initWithType:[CBUUID UUIDWithString:SERVICE_ID] | |
primary:YES]; | |
self.transferCharacteristic = | |
[[CBMutableCharacteristic alloc] | |
initWithType:[CBUUID UUIDWithString:CHARASTERISTIC_ID] | |
properties:CBCharacteristicPropertyNotify | |
value:nil | |
permissions:CBAttributePermissionsReadable]; | |
service.characteristics = @[self.transferCharacteristic]; | |
[self.peripheralManager addService:service]; | |
} | |
- (void)peripheralManager:(CBPeripheralManager *)peripheral | |
central:(CBCentral *)central | |
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic | |
{ | |
self.dataToSend = [@"Hello, world!" dataUsingEncoding:NSUTF8StringEncoding]; | |
self.sendDataIndex = 0; | |
[self sendData]; | |
} | |
- (void)sendData | |
{ | |
static BOOL sendingEOM = NO; | |
if (sendingEOM) { | |
BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] | |
forCharacteristic:self.transferCharacteristic | |
onSubscribedCentrals:nil]; | |
if (didSend) { | |
sendingEOM = NO; | |
NSLog(@"Sent:EOM"); | |
} | |
return; | |
} | |
if (self.sendDataIndex >= self.dataToSend.length) { | |
return; | |
} | |
BOOL didSend = YES; | |
while(didSend) { | |
NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex; | |
if (amountToSend > MAX_MTU) { | |
amountToSend = MAX_MTU; | |
} | |
NSData *chunk = [NSData dataWithBytes:(self.dataToSend.bytes + self.sendDataIndex) length:amountToSend]; | |
didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
if (!didSend) { | |
return; | |
} | |
self.sendDataIndex += amountToSend; | |
NSLog(@"Sending: %d / %d", self.sendDataIndex, self.dataToSend.length); | |
if (self.sendDataIndex >= self.dataToSend.length) { | |
sendingEOM = YES; | |
BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
if (eomSent) { | |
sendingEOM = NO; | |
NSLog(@"Sent: EOM"); | |
} | |
return; | |
} | |
} | |
} | |
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic | |
{ | |
NSLog(@"Central unsubscribed from characteristic"); | |
} | |
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral | |
{ | |
NSLog(@"isReadyRestart"); | |
[self sendData]; | |
} | |
- (void)peripheralManager:(CBPeripheralManager *)peripheral | |
didAddService:(CBService *)service | |
error:(NSError *)error | |
{ | |
if (error != nil) { | |
return; | |
} | |
NSLog(@"Start advertising."); | |
[self.peripheralManager startAdvertising:@{CBAdvertisementDataLocalNameKey: ADVERTISEMENT_NAME, | |
CBAdvertisementDataServiceUUIDsKey: @[[CBUUID UUIDWithString:SERVICE_ID]]}]; | |
} | |
- (void)startPeripheral | |
{ | |
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; | |
} | |
- (void)startScan | |
{ | |
self.receivedData = [[NSMutableData alloc] init]; | |
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; | |
} | |
- (void)centralManager:(CBCentralManager *)central | |
didDiscoverPeripheral:(CBPeripheral *)peripheral | |
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI | |
{ | |
NSLog(@"Peripheral discovered %@ %@ %@", RSSI, peripheral.UUID, advertisementData); | |
if ([[advertisementData objectForKey:@"kCBAdvDataLocalName"] isEqual:ADVERTISEMENT_NAME]) { | |
[self.centralManager stopScan]; | |
self.aPeripheral = peripheral; | |
[self.centralManager connectPeripheral:peripheral options:nil]; | |
} | |
} | |
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral | |
{ | |
NSLog(@"centralManagerDidConnectPeripheral"); | |
[self.aPeripheral setDelegate:self]; | |
[self.aPeripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE_ID]]]; | |
} | |
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error | |
{ | |
NSLog(@"DiscoverService:%d", [peripheral.services count]); | |
if (error) { | |
NSLog(@"Error discovering service: %@", [error localizedDescription]); | |
return; | |
} | |
for (CBService *service in peripheral.services) { | |
NSLog(@"Service found with UUID: %@", service.UUID); | |
if ([service.UUID isEqual:[CBUUID UUIDWithString:SERVICE_ID]]) { | |
[self.aPeripheral discoverCharacteristics:@[[CBUUID UUIDWithString:CHARASTERISTIC_ID]] forService:service]; | |
} | |
} | |
} | |
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { | |
NSLog(@"DiscoverCharacteristics"); | |
if (error) { | |
NSLog(@"Error discovering characteristic: %@", [error localizedDescription]); | |
return; | |
} | |
if ([service.UUID isEqual:[CBUUID UUIDWithString:SERVICE_ID]]) { | |
for (CBCharacteristic *characteristic in service.characteristics) { | |
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:CHARASTERISTIC_ID]]) { | |
[peripheral setNotifyValue:YES forCharacteristic:characteristic]; | |
} | |
} | |
} | |
} | |
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { | |
if (error) { | |
NSLog(@"Error changing notification state: %@", error.localizedDescription); | |
} | |
if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:CHARASTERISTIC_ID]]) { | |
return; | |
} | |
if (characteristic.isNotifying) { | |
NSLog(@"Notification began on %@", characteristic); | |
} else { | |
NSLog(@"Notification stopped on %@. Disconnecting", characteristic); | |
[self.centralManager cancelPeripheralConnection:self.aPeripheral]; | |
} | |
} | |
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error | |
{ | |
if (error) { | |
NSLog(@"Error changing reading request: %@", error.localizedDescription); | |
} | |
NSLog(@"Received response."); | |
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; | |
if ([stringFromData isEqualToString:@"EOM"]) { | |
NSLog(@"EOM"); | |
NSString *string = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding]; | |
textView.text = string; | |
NSLog(@"Loading a data: %@", string); | |
[peripheral setNotifyValue:NO forCharacteristic:characteristic]; | |
[self.centralManager cancelPeripheralConnection:peripheral]; | |
} | |
[self.receivedData appendData:characteristic.value]; | |
NSLog(@"Received data length: %d", [self.receivedData length]); | |
} | |
- (void)centralManagerDidUpdateState:(CBCentralManager *)central | |
{ | |
switch (central.state) { | |
case CBCentralManagerStatePoweredOn: | |
NSLog(@"Scanning..."); | |
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE_ID]] | |
options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)}]; | |
break; | |
default: | |
NSLog(@"Failed getting a Bluetooth."); | |
break; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment