About Bluetooth

Bluetooth profile

Bluetooth (Bluetooth) is a kind of wireless technology standard, can realize the short distance data exchange between fixed equipment, mobile equipment and building personal area network (UHF radio ISM band used 2.4, 2.485GHz). Bluetooth technology was originally created by the telecommunications giant Ericsson in 1994, when it was an alternative to the RS232 data line. Bluetooth can connect multiple devices to overcome the problem of data synchronization.
Bluetooth today by the Group (Bluetooth Special Interest, SIG) management. Bluetooth Technology Alliance in the world has more than 25000 member companies, they are distributed in telecommunications, computers, networks, and consumer electronics and other fields. IEEE Bluetooth technology as IEEE 802.15.1, but now no longer maintain the standard. The Bluetooth technology alliance is responsible for overseeing the development of Bluetooth specification, managing certification projects, and safeguarding the rights and interests of trademarks. The manufacturer’s equipment must comply with the standards of the Bluetooth Technology Alliance in order to enter the market in the name of Bluetooth devices. Bluetooth technology has a patented network, can be issued to meet the standard equipment.

Bluetooth development

Bluetooth 1.1 standard

1.1 for the most recent version, the transmission rate of about 748~810kb/s, because it is early design, vulnerable to interference with the same frequency of the product quality of communication.

Bluetooth 1.2 standard

1.2 is also the only 748~810kb/s transmission rate, but with the addition of (improved Software) anti-jamming frequency hopping function.

Bluetooth 2 standard

2 is the 1.2 improving version, transmission rate of about 1.8M/s~2.1M/s, began to support duplex mode — one voice communication, but also can transfer files / high quality pictures, of course, version 2 also supports Stereo operation.
application is the most widely used Bluetooth2.0+EDR standard, the standard has been launched in 2004, support Bluetooth2.0+EDR standard products also appeared in large numbers in 2006.
although the Bluetooth2.0+EDR standard has made a lot of improvements in technology, but the continuation of the configuration process from the 1.X standard complex and large power consumption problems still exist.

Bluetooth 2.1 standard

August 2, 2007, the Bluetooth Technology Alliance today officially approved the 2.1 edition of Bluetooth specification, that is, Bluetooth 2.1+EDR, available for future use of the device. And 2 versions of the same era of products, still occupy a larger share of the Bluetooth market, relative to the 2 version is mainly to improve the standby time of more than 2 times, there is no fundamental change in technical standards.

Bluetooth 3 standard

In April 21, 2009, the Bluetooth Technology Alliance (BluetoothSIG) officially promulgated a new generation standard “BluetoothCoreSpecificationVersion3.0HighSpeed” (Bluetooth core specification version 3), Bluetooth 3 core is “GenericAlternateMAC/PHY” (AMP), which is a whole new alternating RF technology allows Bluetooth protocol stack for any given task dynamically select the correct rf.
Bluetooth 3 data transfer rate increased to about 24Mbps (you can call 802.11WI-FI when needed to achieve high-speed data transmission). In the transmission speed is eight times 3, Bluetooth Bluetooth 2, can be easily used for data transmission between the VCR to high-definition TV, PC to PMP, UMPC to the printer, but both sides need to achieve this standard functions can be achieved.

Bluetooth 4 standard

The Bluetooth 4 specification on July 7, 2010 officially released, the new version of the greatest significance lies in the low power consumption, while strengthening equipment compatibility between different OEM vendors, and reduce the delay, the maximum transmission speed is 24Mbps theory (3MB/s), the effective coverage expanded to 100 meters (the previous version is 10 meters). The standard chip is a large number of mobile phones, tablet, such as apple TheNewiPad Tablet PC, as well as apple iPhone5, Meizu MX4, HTCOneX and other phones with Bluetooth 4 features.

Bluetooth 4.1 standard

Bluetooth 4.1 was released on December 6, 2013, and between the LTE radio signal if the simultaneous transmission of data, transmission of information so Bluetooth 4.1 can automatically reconcile the two, it can reduce the other signal to interference Bluetooth 4.1. The improvement is to enhance the connection speed and more intelligent, such as to reduce the time of re connection between devices, means that if the user out of the Bluetooth 4.1 signal range and disconnection time is not very long, when the user back to the range of signal equipment will be automatically connected again, the reaction time to 4 shorter than bluetooth. The last improvement is to improve the efficiency of transmission, if the user is connected to a very large number of devices, such as the connection of a number of wearable devices, the information between each other can be immediately sent to the receiving device.
in addition, Bluetooth 4.1 also for developers to add more flexibility, this change does not have a big impact on ordinary users, but it is very important for software developers, because in order to wearable devices to rise gradually, so must be able to support multiple Bluetooth devices to connect at the same time.

Bluetooth 4.2 standard

December 4, 2014, the latest Bluetooth 4.2 standard promulgated. Bluetooth 4.2 standard announcement, not only improved the speed of data transmission and privacy protection, but also access to the device will be able to directly access the Internet through IPv6 and 6LoWPAN.
is the first speed is getting faster. Although the Bluetooth version 4.1 has been on the basis of the previous upgrade a lot, but far from meeting the needs of users, compared with Wi-Fi, appears to be less competitive. Bluetooth 4.2 standard (Bluetooth Smart) via Bluetooth smart packets to improve its capacity, can accommodate the amount of data is equivalent to about 10 times previously, the speed of data transmission between two Bluetooth devices increased by 2.5 times.
secondly, the degree of privacy protection has also been enhanced by many users. As we all know, Bluetooth 4.1 and its previous version in the privacy of security there is a certain risk – after a connection will no longer need to confirm automatically connect, easy to cause privacy leaks. Under the new Bluetooth 4.2 standard, the Bluetooth signal to connect or track user equipment must be approved by the user, otherwise the Bluetooth signal will not be able to connect and track user equipment.
of course, the most anticipated or new version of the Internet access through IPv6 and 6LoWPAN features. As early as the Bluetooth version 4.1, Bluetooth technology alliance has begun to try to access, but because of the limitations of the previous version of the transmission rate and the network is not compatible with the new chip, did not fully achieve this feature. According to the Bluetooth technology alliance, said the new Bluetooth 4.2 standard has been directly through the IPv6 and 6LoWPAN access to the internet. Believe that on this basis, once IPv6 and 6LoWPAN can be widely used, this feature will attract more attention.
also have to mention is that the older Bluetooth adapter, Bluetooth 4.2 part of the function can be obtained by way of software upgrades, but not all features are available. Bluetooth technology alliance, said: “the privacy function can be obtained by firmware upgrade, but depending on the manufacturer’s installation enabled. Speed and data packet expansion will require hardware upgrades to do.” And so far, Bluetooth 4 is still the most commonly used standard consumer devices, but Android Lollipop and other mobile platforms have begun to add to the Bluetooth 4.1 standard and Bluetooth 4.2 standard of native support.

Bluetooth 5 standard

The United States on June 16, 2016, the Bluetooth Technology Alliance (SIG) has released the fifth generation of Bluetooth technology in Washington (officially referred to as Bluetooth 5), not only speed up to 2 times, 4 times farther, but also optimize the IoT network bottom function. The performance of
, Bluetooth 5 standard transmission speed is two times before the 4.2LE version, the effective distance is 4 times the previous version, namely between Bluetooth transmitting and receiving equipment to work effectively theoretical distance to 300 meters. In addition to the
, Bluetooth 5 also allows you to receive data from the beacon, such as advertising, Beacon, location information, etc., the transmission rate increased by 8 times. At the same time, Bluetooth 5 standard also for the bottom of the IoT Internet of things optimization, faster and more energy-efficient, and strive to lower power consumption and higher performance for smart home services.
Bluetooth technology alliance, said the current global Bluetooth devices have exceeded 8 billion 200 million. And expect the Bluetooth 5 standard will be formally launched in late 2016 or early 2017, equipped with Bluetooth 5 chip flagship mobile phone will be available in 2017, said Apple will become one of the first to use the technology vendors.

CoreBluetooth

Central and Peripheral

The role of Bluetooth communication

In BLE communications, there are two main roles: Central and Peripheral. Similar to the traditional client server architecture, a Peripheral terminal is provided on one side of the data (equivalent to server); while the Central is using Peripheral port data provided by the specific task Party (or client). A Peripheral device that can scan and monitor any broadcast information of interest to the Central terminal. Data broadcast and reception needs to be represented by a certain data structure. The service is such a data structure. The Peripheral side may contain one or more services or provide useful information about the strength of the connection signal. A service is a collection of data and data related operations of a device. And the service itself is composed of the characteristics or services contained. A feature provides more detailed information about the service. After a successful connection between the Central and the Peripheral side, the Central can discover the full set of services and features provided by the Peripheral side. A Central can also read and write the value of the Peripheral side of the service characteristics.

Representation of Central, Peripherals and Peripheral data

When we use the local Central to interact with the Peripheral side, we will perform the operation on the Central side of the BLE communication. Unless we set up a local Peripheral device, most of the Bluetooth interaction is carried out on the Central side. (below will also talk about the basic operation of the Peripheral side). On the Central side, the local Central device is represented by the CBCentralManager object. This object is used to manage the discovery and connection of Peripheral devices (CBPeripheral objects), including scanning, searching and connecting. When interacting with a peripheral device, we are primarily dealing with its services and features. In the Core Bluetooth framework, the service is a CBService object, the property is a CBCharacteristic object, the following figure shows the Central side of the basic characteristics of services and features:

About Bluetooth
serves the characteristic relationship.Png

apple OS X 10.9 and iOS version 6, provides a BLE peripheral (Peripheral) function, you can use the device as a Peripheral to deal with. On the Peripheral side, the local Peripheral device is represented as a CBPeripheralManager object. These objects are used to manage services and features to the local Peripheral device database and to advertise these services to the Central device. The Peripheral manager is also used to respond to read and write requests from the Central side. The following figure shows a Peripheral end role:

About Bluetooth
Peripheral role.Png

when we set the data on a local Peripheral device, we are actually dealing with a variable version of the service and features. In the Core Bluetooth framework, the local Peripheral service represented by the CBMutableService object, and the characteristics expressed by CBMutableCharacteristic objects, the following diagram shows the basic structure and characteristics of the local Peripheral service:

About Bluetooth
Peripheral terminal services and characteristics.Png
Peripheral (Server) end operation

A Peripheral end operation has the following steps:

Start a Peripheral management object
in the local Peripheral service and
service will set the properties and characteristics of release to the local database of
advertising equipment of our service for
Central is connected to the read and write requests to send updates to
response value to subscribe to the Central end
we will combine the code for each step respectively. Explain in the following

Start a Peripheral Manager

To implement a Peripheral on a local device, we need to assign and initialize an instance of the Peripheral manager, as shown in the following code

/ / create a Peripheral Manager / / we will peripheralManager as the current class, it must implement the CBPeripheralManagerDelegate / / second if the parameters are specified as nil, using the default peripheralManager = [[CBPeripheralManager alloc] initWithDelegate: self column queue:nil];

After the Peripheral manager is created, the Peripheral manager calls the peripheralManagerDidUpdateState: method of the proxy object. We need to implement this method to ensure that local devices support BLE.

- (void) peripheralManagerDidUpdateState: (CBPeripheralManager * peripheral) {NSLog ("Peripheral Manager Did Update @ State"); switch (peripheral.state) {case CBPeripheralManagerStatePoweredOn: NSLog (@ CBPeripheralManagerStatePoweredOn); break case; CBPeripheralManagerStatePoweredOff: NSLog (@ CBPeripheralManagerStatePoweredOff); break case; CBPeripheralManagerStateUnsupported: NSLog (@ CBPeripheralManagerStateUnsupported); break; default: break;}}
Set up services and features

A local Peripheral database organizes services and features in a tree like structure. So, when we set up the services and features, we organize them into a tree structure.

A Peripheral service and features are identified by a 128 bit Bluetooth specified UUID, which is a CBUUID object. Although the SIG organization does not define all the services and features of the UUID, but SIG has defined and published some of the adopted UUID, these UUID is simplified into 16 bit to facilitate the use of. For example, SIG defines a 16 bit UUID as the heartbeat service identifier (180D).

The CBUUID class provides a method to generate a CBUUID object from a string. When the note string using a 16 bit UUID predefined, Core Bluetooth will automatically use it into a 128 bit identifier completion.

CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString:@ "180D"];

Of course, we can also generate a 128 bit UUID to identify our services and features. Using the uuidgen command in the command line generates a 128 bit UUID string, and then we can use it to generate a CBUUID object.

After generating the UUID object, we can use this object to create our services and features, and then organize them into a tree structure.

The code for creating the features is shown below:

CBUUID *characteristicUUID1 [CBUUID UUIDWithString:@ = "C22D1ECA-0F78-463B-8C21-688A517D7D2B"]; CBUUID *characteristicUUID2 = [CBUUID UUIDWithString:@ "632FB3C9-2078-419B-83AA-DBC64B5B685A"]; CBMutableCharacteristic *character1 = "CBMutableCharacteristic alloc] initWithType:characteristicUUID1 properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable]; CBMutableCharacteristic *character2 = [[CBMutableCharacteristic alloc] initWithType: characteristicUUID2 properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsWriteable];

We need to set properties, values, and permissions. Property and permission values determine whether the value of the property is readable or writable, and whether the Central side of the connection can subscribe to a value. In addition, if we specify the value of the property, the value is cached and its properties and permissions are set to be readable. If we want the value of the property to be writable, or if the value of the service in the life of the desired attribute can be modified, the value must be nil.

After creating the features, we can create a service that is associated with the feature, and then associate the features to the service, as shown in the following code:

CBUUID *serviceUUID [CBUUID UUIDWithString:@ = "3655296F-96CE-44D4-912D-CD83F06E7E7E"]; CBMutableService *service = [[CBMutableService alloc] initWithType:serviceUUID primary:YES]; service.characteristics = character2]; / / @[character1, organized into a tree structure

In this example, the primary parameter passed to YES, said this is a main service, which describes the main functions of a device and can be referenced for other services. In contrast to the secondary service (secondary service), it describes a service only in the context of another service that references it.

Publishing services and features

After creating the service and the characteristics of the post to organize it into a tree structure, we need to publish these services to the device’s local database. We can use the CBPeripheralManager addService: method to complete this work. The following code shows:

[peripheralManager addService:service];

When you call a method to publish a service, the CBPeripheralManager object will call the peripheralManager:didAddService:error: method of its agent. If there is an error in the publication process that cannot be used as a cloth, the agent method can be implemented to handle the error, as shown in the following code:

- (void) peripheralManager: (CBPeripheralManager * peripheral) didAddService: (CBService * service) error: (NSError * error) {NSLog (@ "Add Service"); if (error) {NSLog (@ Error publishing service:, [error localizedDescription]% @ ");}}

After publishing services and features to the device database, the service will be cached, and we can no longer modify the service.

Advertising service

After the above steps, we will be able to advertise these services to the Central side of the interest in services. We can do this by calling the startAdvertising: method of the CBPeripheralManager instance, as shown in the following code:

[peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey: @[service.UUID]}];

The startAdvertising: argument is a dictionary, Peripheral manager supports and supports only two key values: CBAdvertisementDataLocalNameKey and CBAdvertisementDataServiceUUIDsKey. These two values describe the details of the data. The value expectation corresponding to the key value is an array representing multiple services.

When the ad service, the CBPeripheralManager object will call the peripheralManagerDidStartAdvertising:error: method of the code object, we can do the corresponding processing, as shown in the following code:

- (void) peripheralManagerDidStartAdvertising: (CBPeripheralManager * peripheral) error: (NSError * error) {NSLog (@ "Start Advertising"); if (error) {NSLog (@ Error advertising:, [error localizedDescription]% @ ");}}

After the ad service, the Central side can discover the device and initialize a connection.

Respond to read and write requests on the Central side

After connecting with the Central side, you may need to receive a read and write request from it, we need to respond in an appropriate manner.

When the Central is connected with a request to read the value of a feature, the CBPeripheralManager object peripheralManager:didReceiveReadRequest: method invokes the proxy object, the proxy method provides a CBATTRequest object to represent the Central end of the request, we can use it to fill the request attribute. The following code shows a simple process:

- (void) peripheralManager: (CBPeripheralManager * peripheral) didReceiveReadRequest: (CBATTRequest * request) is characteristic of view {/ / request is specified by the if property ([request.characteristic.UUID isEqual:cha1.UUID]) {NSLog (@ "Request character 1"); / / ensure offset read request the requested offset position does not exceed the length range of if / value of our the characteristics of the offset property specifies the request to read values (request.offset > cha1.value.length) {[peripheralManager respondToRequest:request withResult:CBATTErrorInvalidOffset]; return;} / / if the reading position will not cross the characteristics of the values in the specified range assigned to the request of the value attribute. Request.value = [cha1.value subdataWithRange: (NSRange) {request.offset, cha1.value.length - request.offset}] [peripheralManager respondToRequest:request; / / make a successful response to the withResult:CBATTErrorSuccess] request;}}

The respondToRequest:withResult: method is called to respond to the request when calling the peripheralManager:didReceiveReadRequest: of the proxy object.

Processing a write request is similar to the above procedure, which calls the peripheralManager:didReceiveWriteRequests: method of the proxy object. The difference is that the proxy method gives us an array of one or more CBATTRequest objects, each representing a write request. We can use the value property of the request object to assign our characteristic properties, as shown in the following code:

- (void) peripheralManager: (CBPeripheralManager * peripheral) didReceiveWriteRequests: (NSArray * requests) {CBATTRequest *request = requests[0]; cha1.value = request.value; [peripheralManager respondToRequest:request withResult: CBATTErrorSuccess];}

Response processing is similar to request.

Send the updated value to the Central end of the subscription

If there are one or more Central clients that subscribe to the characteristics of our services, we need to notify the Central when the features change. To do this, the proxy object needs to implement the peripheralManager:central:didSubscribeToCharacteristic: method. As shown below:

- (void) peripheralManager: (CBPeripheralManager * peripheral) central: (CBCentral * central) didUnsubscribeFromCharacteristic: (CBCharacteristic * characteristic) {NSLog (@ Central subscribed to characteristic, characteristic NSData% @ "); *updatedData = characteristic.value; / / get the attribute update values and invoking the following methods to send it to the Central end / / the last parameter specified we want to modify the Central which sent to the end, if nil, will be sent to all connected Central / / method returns a BOOL value that is modified successfully sent, if used to transfer the updated value queue to be filled, then the method returns NO BOOL didSendValue = [peripheralManager updateValue:updatedData forCharacteristic: (CBMutableCharacteristic * charac) Teristic onSubscribedCentrals:nil]; NSLog ("Send @ Success?% @, (@ didSendValue @?" YES ":" NO "));}

In the above code, the CBPeripheralManager object calls the peripheralManagerIsReadyToUpdateSubscribers: method of the code object when there is available space in the transmission queue. We can call updateValue:forCharacteristic:onSubscribedCentrals: to resend the value in this method.

We use notifications to send a single packet to a subscription Central. When we update the subscription to the Central, we should call the updateValue:forCharacteristic:onSubscribedCentrals: method to place the value of the update in a notification.

Because the value of the property is not the same, not all values will be notified. If this happens, you need to call the CBPeripheral instance at the Central end of the readValueForCharacteristic: method to deal with, this method can get the entire value.

Central (Client) end operation

A Central client mainly includes the following operations:

Start a Central terminal manager object
search and advertising are connected Peripheral devices
query
data sent in connection to the Peripheral terminal after a characteristic value of read and write requests to the Peripheral terminal
terminal characteristics when the Peripheral values changed when we will receive notification of
according to the code for each step were explained in the the following

Start a Central Manager

The CBCentralManager object represents a local Central device in Core Bluetooth, which we must allocate and initialize a Central manager object when performing any BLE interaction. Create code as shown below:

Specify the current class / / proxy object, so the need to implement the CBCentralManagerDelegate protocol / / if queue is nil, the Central manager uses the column to send the event centralManager alloc] initWithDelegate:self = [[CBCentralManager queue:nil options:nil];

For some initial property management center set up
NSString const CBCentralManagerOptionShowPowerAlertKey NSNumber corresponds to a type of bool value in the options dictionary, for setting whether in turn off Bluetooth pop-up prompt the user
NSString const CBCentralManagerOptionRestoreIdentifierKey corresponding to a NSString object, set the ID identifier management center

When you create a Central manager, the manager object invokes the centralManagerDidUpdateState: method of the proxy object. We need to implement this method to ensure that local devices support BLE.

- (void) centralManagerDidUpdateState: (CBCentralManager * central) {NSLog (@ "Central Update State"); switch (central.state) {case CBCentralManagerStatePoweredOn: NSLog (@ CBCentralManagerStatePoweredOn); break case; CBCentralManagerStatePoweredOff: NSLog (@ CBCentralManagerStatePoweredOff); break case; CBCentralManagerStateUnsupported: NSLog (@ CBCentralManagerStateUnsupported); break; default: break}};
Peripheral devices found in advertising

The primary task of the Central side is to find the Peripheral device being advertised for subsequent connection. We can call the CBCentralManager instance of the scanForPeripheralsWithServices:options: method to discover the advertised Peripheral device. The following code shows:

Find the Peripheral / / equipment / / if the first parameter nil, then the manager will return all Peripheral equipment. We usually specify / / an array of UUID objects, to find the equipment [centralManager scanForPeripheralsWithServices:nil specific options:nil];

ServiceUUIDs is used to scan a ID peripheral options is used to set the following
attribute key scanning whether to allow repeated scanning of corresponding NSNumber bool value, the default is NO,
NSString const will automatically go to CBCentralManagerScanOptionAllowDuplicatesKey;
to UUID array scanning equipment corresponding to the NSArray hovertree.com
NSString const CBCentralManagerScanOptionSolicitedServiceUUIDsKey;

After calling the above method, the CBCentralManager object calls the centralManager:didDiscoverPeripheral:advertisementData:RSSI: method of the proxy object every time the device is found.

- (void) centralManager: (CBCentralManager * central) didDiscoverPeripheral: (CBPeripheral * peripheral) advertisementData: (NSDictionary * advertisementData) RSSI: (NSNumber * RSSI) {NSLog ("Discover @ Name:% @", peripheral.name); / / when we find the Peripheral side, we can stop the search for other equipment, to save power [centralManager stopScan]; NSLog (@ "Scanning stop");}
Connecting Peripheral devices

After finding the Peripheral device, we can call the CBCentralManager instance of the connectPeripheral:options: method to connect to the Peripheral device. The following code shows

[centralManager connectPeripheral:peripheral options:nil];

You can set the initial connection device attribute key follows
corresponding to the NSNumber bool value of options, when the peripheral connection is set up a warning
NSString const CBConnectPeripheralOptionNotifyOnConnectionKey;
NSNumber corresponding to the bool value, set up a warning if
NSString const CBConnectPeripheralOptionNotifyOnDisconnectionKey peripherals is disconnected;
corresponds to the NSNumber value of bool when the peripheral, setting up a warning or suspension of
NSString *const CBConnectPeripheralOptionNotifyOnNotificationKey connection;

If the connection is successful, it will call the centralManager:didConnectPeripheral: method of the proxy object, we can implement the method to do the corresponding processing. In addition, before starting to interact with the Peripheral device, we need to set up a proxy for the peripheral object to ensure that the appropriate callback is received.

- (void) centralManager: (CBCentralManager *) Central didConnectPeripheral: (CBPeripheral *) peripheral {NSLog (@ "Peripheral Connected"); peripheral.delegate = self;}
Find the service for the connected Peripheral device

After establishing the connection to the Peripheral device, we can begin to query the data. First we need to find the services available in the Peripheral device. Due to the limited data available to the Peripheral device, the actual service of the Peripheral device may be more than that of the advertised service. We can call the discoverServices: method of the peripheral object to find all services. The following code shows:

[peripheral discoverServices:nil];

Parameter passing nil can find all services, but in general we will specify the services that are of interest.

When the above method is called, peripheral calls the peripheral:didDiscoverServices: method of the proxy object. Core Bluetooth creates an array of CBService objects, the elements in the array are found in the peripheral service.

- (void) peripheral: (CBPeripheral * peripheral) didDiscoverServices: (NSError * error) {NSLog (@ "Discover Service"); for (CBService *service in peripheral.services NSLog (Discovered) {@ service% @ ", service);}}
Find the characteristics of the service

Assuming that we have found the service that is of interest, the next step is the query service. In order to find the characteristics of the service, we only need to call the discoverCharacteristics:forService: method of the CBPeripheral class, as shown below:

NSLog (@ Discovering characteristics for, service service% @ "); [peripheral discoverCharacteristics:nil forService:service];

When the characteristics of a particular service are found, the peripheral object invokes the peripheral:didDiscoverCharacteristicsForService:error: method of the proxy object. In this method, the Core Bluetooth creates an array of CBCharacteristic objects, each representing an object that is found. The following code shows:

- (void) peripheral: (CBPeripheral * peripheral) didDiscoverCharacteristicsForService: (CBService * service) error: (NSError * error) {NSLog (@ "Discover Characteristics"); for (CBCharacteristic *characteristic in service.characteristics NSLog (Discovered) {@ characteristic% @ ", characteristic);}}
Gets the value of the characteristic

A feature contains a single value that contains information about the Peripheral service. After getting to the feature, we can get the value from the feature. Just call the readValueForCharacteristic: method of the CBPeripheral instance. As shown below:

NSLog (@ Reading value for, characteristic characteristic% @ "); [peripheral readValueForCharacteristic:characteristic];

When we read the value in the feature, the peripheral object calls the peripheral:didUpdateValueForCharacteristic:error: method of the proxy object to obtain the value. If successful, we can access it through the value property of the attribute, as shown below:

- (void) peripheral: (CBPeripheral * peripheral) didUpdateValueForCharacteristic: (CBCharacteristic * characteristic) error: (NSError * error) {NSData *data = characteristic.value; NSLog (Data = @% @ ", data);}
Subscription value

Although the use of the readValueForCharacteristic: method to read the value of the characteristics of some of the use of the scene is very effective, but for the value of the change is not very effective. For most of the value of the change, we need to get them by subscribing. When we subscribe to the value of the feature, we receive the notification from the peripheral object when the value changes.

We can call the setNotifyValue:forCharacteristic: method of the CBPeripheral class to subscribe to the values of the characteristics of interest. As shown below:

[peripheral setNotifyValue:YES forCharacteristic:characteristic];

When we try to subscribe to the value of the property, we call the peripheral:didUpdateNotificationStateForCharacteristic:error: method of the peripheral object’s proxy object. If the subscription fails, we can implement the proxy method to access the error, as shown below:

- (void) peripheral: (CBPeripheral * peripheral) didUpdateValueForCharacteristic: (CBCharacteristic * characteristic) error: (NSError * error) {... If (error) {NSLog (@ Error changing notification state:, [error localizedDescription]% @ ");}}

After the value of a successful subscription feature, the peripheral device notifies us of the application when the characteristic value changes.

Write value

Some scenarios, we need to write the value of the characteristics. For example, when we need to interact with the BLE digital thermostat, it may be necessary to provide a value for the thermostat to set the room temperature. If the value of the feature is writable, we can write the value by calling the writeValue:forCharacteristic:type: method of the CBPeripheral instance.

NSData *data = [NSData dataWithBytes:[@ "UTF8String]" length:@ ".Length]"; [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse] test "test";

When attempting to write a characteristic value, we need to specify the type of writing to execute. This example specifies the write type is CBCharacteristicWriteWithResponse, peripheral let us know whether to write the successful application.

Specifies that the peripheral object of the CBCharacteristicWriteWithResponse type is written to call the peripheral:didWriteValueForCharacteristic:error: method of the proxy object in response to a request. If the write fails, we can handle the error message in this method.

Background processing

In the development of BLE related applications, due to the application in the background will have a lot of resource constraints, the need to consider the application of the background processing. By default, most common Core Bluetooth tasks cannot be used when the program is in the background or suspended, whether it is Central or Peripheral. But we can declare that our application supports the Core Bluetooth background execution mode to allow the program to be awakened from the pending state to deal with Bluetooth related events.

However, even if our application supports both ends of the Core Bluetooth background execution mode, it can’t always run. In some cases, the system may shut down our applications to free up memory to provide more memory space for the current foreground application. In iOS7 and later versions, Core Bluetooth supports the status information of the Central and Peripheral manager objects, and restores the information when the program starts. We can use this feature to support long – term tasks associated with Bluetooth devices.

Below we will discuss these issues in detail.

Applications that support foreground only (Foreground-Only)

Most applications will go into a suspended state in a short time after entering the background, unless we request to perform some specific background tasks. When processing pending state, our application cannot continue to perform Bluetooth related tasks.

On the Central side, the Foreground-Only application is unable to scan and find the Peripheral device in the advertisement when it enters the background or hangs. In the Peripheral side, can not advertise themselves, while the Central side of any of its access operations will return an error.

When Foreground-Only application hangs, all Bluetooth related events will be put into a queue by the system. When the application is in the foreground, the system will send them to us. That is, when certain events occur, Core Bluetooth provides a way to prompt the user. Users can use these tips to decide whether to put the application in the foreground. In Central and Peripheral we introduced the connectPeripheral:options: method, in the call to this method, we can set the device options parameters to these tips:

CBConnectPeripheralOptionNotifyOnConnectionKey: if the connection is successful, if we want the system to display a prompt for the specified peripheral, use the key value.
CBConnectPeripheralOptionNotifyOnDisconnectionKey: when the application is suspended, if the connection is disconnected, if we want the system to the specified peripheral display a disconnect when prompted to use this key value.
CBConnectPeripheralOptionNotifyOnNotificationKey: when the application is suspended, use the key value to indicate that a notification is displayed as long as the notification is received from the given peripheral.

Core Bluetooth background execution mode

We can set up the Core Bluetooth background execution mode in the Info.plist file to allow the application to support the implementation of some Bluetooth related tasks in the background. When the application declares this function, the system wakes up the application to allow it to handle Bluetooth related tasks. This feature is very useful for the application of BLE interaction with the timing of sending data.

There are two kinds of Core Bluetooth background execution mode, a Peripheral for the realization of the Central operation, a used to achieve the end of the operation. If our application implements both ends of the function at the same time, it is necessary to declare support for the two models. We need to add the UIBackgroundModes key in the Info.plist file and add the following two values or one of them:

Bluetooth-central (App communicates using CoreBluetooth)
bluetooth-peripheral (App shares data using CoreBluetooth)

  • Bluetooth-central mode

If you set the bluetooth-central value, then our application in the background, you can still find and connect to the Peripheral device, and find the corresponding data. In addition, the system wakes up our application when the CBCentralManagerDelegate or CBPeripheralDelegate proxy method is invoked, allowing applications to handle events, such as establishing a connection or disconnection, etc..

Although the application in the background, we can perform a lot of Bluetooth related tasks, but need to remember that the application before and after the Peripheral device is not the same. When our application scans the Peripheral device in the background,

The CBCentralManagerScanOptionAllowDuplicatesKey scan option is ignored, and multiple discovery events on the same Peripheral side are aggregated into a discovery event.
if scanning multiple applications of Peripheral devices are in the background, the time interval for the Central device to scan the advertising data will increase. As a result, it is likely to take a long time to find an advertised Peripheral device.
these processes are very useful in minimizing the use of radio and improving battery life in iOS devices.

  • Bluetooth-peripheral mode

If you set the bluetooth-peripheral value, we used in the background, the application will be awakened to treatment from the Central is connected to the read and write and subscribe request, Core Bluetooth also allows us to advertise in the background. Similar to the Central side, but also need to pay attention to the operation of the background difference. Especially in advertising, there are several differences:

CBAdvertisementDataLocalNameKey key advertising value will be ignored, not local name Peripheral end advertising
CBAdvertisementDataServiceUUIDsKey key all the service UUID is placed in a “overflow” in the region, they can only be shown to those who find it scanning network equipment.
if more than one application is in the background, the time interval for the Peripheral device to send the ad will be longer.

Perform long (Long-Term) tasks in the background

Although it is recommended to complete the background task as soon as possible, but some still need to use Core Bluetooth to perform a long task. At this point, it involves the preservation and recovery of the state.

State save and restore

Because the state of preservation and restoration is built in Core Bluetooth, we can choose the program characteristics, let the system save Central and Peripheral management for the state and continues to perform some Bluetooth related tasks, even if the program is no longer running. When one of these tasks is complete, the system restarts the program in the background, which can restore the previous state to handle the event. Core Bluetooth support Central side, Peripheral side of the state of preservation and recovery, you can also support both.

On the Central side, the system will save the state of the Central manager object when the program is closed, and if there are multiple Central managers, we can choose which manager to follow. For a given CBCentralManager object, the system tracks the following information:

Central Service Manager Central manager scanning attempt or connected to Peripheral
Central manager subscription properties of
in the Peripheral end, for a given CBPeripheralManager object, the system will follow the following information:

Central
Peripheral manager
Peripheral manager advertising data released to the characteristics of equipment database service and the characteristics of
Peripheral subscription manager value when the system will restart the program to the background, we can re re initialize our program Central and Peripheral manager and restore state. We will then describe in detail how to save and restore the state.

Add state save and restore support

State preservation and recovery in Core Bluetooth is an optional feature that requires the support of the program to work. We can follow these steps to add support for this feature:

(necessary steps) when adding and initializing Central or Peripheral manager objects, add state preservation and recovery.
(required) in the system to restart the program, re initialization of Central or Peripheral manager object
(required) to achieve appropriate recovery agent
(optional) method to update the Central or Peripheral manager
initialization process selectively added state saving and restoring

In order to selectively add state saving and recovery features, a unique recovery identifier is provided in the allocation and initialization of the Central or Peripheral manager. The recovery identifier is a string of notes that are used to make the Core Bluetooth and program identify Central or Peripheral manager. The value of a string is meaningful only in its own code, but the string tells Core Bluetooth that we need to save the state of the object. Core Bluetooth only those objects that have a recovery flag.

For example, in the realization of the Central side, in order to join the state selective preservation and recovery characteristics, while initializing the CBCentralManager object, you can specify the CBCentralManagerOptionRestoreIdentifierKey initialization options, and provides a recovery logo, as shown in the following code:

CentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionRestoreIdentifierKey: @ "restoreIdentifier"}];

Peripheral side to achieve the operation is similar, but we use the option CBPeripheralManagerOptionRestoreIdentifierKey key.

Because the program can have multiple Central or Peripheral managers, it is necessary to ensure that the recovery identifier is unique, so that the system can distinguish between these manager objects.

Initializing Central or Peripheral manager objects

The first thing we need to do when the system restarts the program is to use the restore flag to re initialize the objects. If our application has only one Central manager or Peripheral manager, and the manager exists throughout the life cycle of the program, then we do not need to do more processing. But if we have multiple managers, or the manager does not exist in the entire life cycle of the program, the system restarts the application, we need to know which manager to re initialize. We can use the application:didFinishLaunchingWithOptions: method in the program proxy object in the list using the appropriate key startup options to access the object manager (the list is closed for the program is program system preservation).

The following code shows that when the program is restarted, we get the recovery identifier for all Central manager objects:

- (BOOL) application: (UIApplication * application) didFinishLaunchingWithOptions: (NSDictionary *) launchOptions point for customization {/ / Override after application launch. NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey]; TODO: return YES;} / /...

With this list of recovery tags, we can re initialize the manager object we need.

Implement appropriate recovery proxy methods

After the Central or Peripheral manager object is initialized, we restore the status of these objects by using the state of the Bluetooth system. At this point, we need to implement some recovery proxy methods. For the Central manager, we implement the centralManager:willRestoreState: proxy method; for the Peripheral Manager Manager, we implement the peripheralManager:willRestoreState: proxy method.

These methods are the first method for the application to start the background to complete some Bluetooth related tasks for the application of the selective preservation and recovery features. As for the application of non selective join, the centralManagerDidUpdateState: and peripheralManagerDidUpdateState: proxy methods will be called first.

In the above two proxy methods, the last argument is a dictionary that contains information about the manager when the program is closed. As shown in the following code, we can use the CBCentralManagerRestoredStatePeripheralsKey key to get a list of all Peripheral devices that have been connected to the Central manager or try to connect:

- (void) centralManager: (CBCentralManager * central) willRestoreState: (NSDictionary * state) {NSArray *peripherals = state[CBCentralManagerRestoredStatePeripheralsKey];} / / TODO:...

After getting to this list, we can do it as needed.

Update initialization process

After implementing the first three steps, we may want to update the initialization process of our manager. Although this step is optional, it is useful if you want to make sure that the task is running properly. For example, our program may be shut down in parsing the data of the connected Peripheral device. When the program uses the Peripheral device for recovery, it is impossible to know where the data is processed. We need to make sure that the program starts from the position where the data operation is stopped.

Also, as the following code shows how to initialize the program operation in the centralManagerDidUpdateState: proxy method, we can find out whether the specified service for the recovered Peripheral device has been found:

NSUInteger serviceUUIDIndex = [peripheral.services indexOfObjectPassingTest:^BOOL (CBService *obj, NSUInteger index, BOOL *stop) {return [obj.UUID isEqual:myServiceUUIDString];}]; if (serviceUUIDIndex = = NSNotFound) {[peripheral discoverServices:@[myServiceUUIDString]];}...

Shown above, if the system in the program to complete the search service application is closed, to parse Peripheral data recovery at that point closed by calling the discoverServices: method. If the program successfully searches for the service, we can confirm whether the search has the correct characteristics. By updating the initialization process, we can ensure that the correct method is called at the right time.

Although we may need to declare that the application supports Core Bluetooth background execution mode to accomplish a specific task, it should always be careful to consider the implementation of the background operation. Because too many Bluetooth related tasks require the use of the built-in radio of the iOS device, and the use of radio will affect the life of the battery, so as to minimize the tasks performed in the background. Any application that will be woken up by Bluetooth related tasks should handle the task as soon as possible and hang it up again when it is finished.

Here are some basic guidelines:

Applications should be session based and provide interfaces to allow the user to decide when to start and end the distribution of Bluetooth related events. Once
is awakened, an application may have about 10s of the time to complete the task. Ideally, the application should finish the task as soon as possible and hang it up again. The system can limit the execution time and even kill the background task. When a
application is awakened, it should not perform some insignificant operations.