I have got an iPhone problem. Step by step my problem:
I discover, connect and pair (bond) my iPhone to BLE device.
After some characteristic communication I manually leave the app and disconnect.
PROBLEM. When I try to pair and communicate again it is impossible because iPhone shows "connected" or either "not
connected" to device in "my devices" section in settings. When I try
to search for devices in app iPhone can't find anything because
iPhone acts like the device is already found.
How to solve this problem? Because now the only way is to forget the device in settings (delete from "my devices" manually) and only then it is possible to pair and connect..
EDIT:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBCentralManagerStatePoweredOn) {
[self scanForPeripherals];
}
}
- (int)scanForPeripherals {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
nil];
//NSLog(#"%#",#[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]);
[self.centralManager scanForPeripheralsWithServices:nil options:options];
return 0;
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"didConnectPeripheral");
// Clear the data
[self.data setLength:0];
// Discover callbacks
peripheral.delegate = self;
[peripheral discoverServices:#[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]];
}
Related
I have created two iOS apps; one a Bluetooth LE peripheral that advertises a service, and one a Bluetooth LE central that scans for the advertised service. The peripheral is running on my iPhone5s, and the central is running on my iPad Mini. I initially set the central up to scan for the specific advertised service, but later changed it to listen to any service. In either case, the iPad Mini app acting as a central never detects any advertised service. I am uncertain whether its a problem with the way I setup the peripheral manager to advertise, or if its a problem with the way I setup the central manager to scan, or a device configuration problem. Please offer suggestions or tests I can perform to get this working.
The following is the relevant code for the iPhone5s app acting as a peripheral:
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
CBUUID *immediateAlertServiceUUID = [CBUUID UUIDWithString: IMMEDIATE_ALERT_SERVICE_UUID];
CBUUID *alertLevelCharacteristicUUID = [CBUUID UUIDWithString: ALERT_LEVEL_CHARACTERISTIC_UUID];
CBUUID *myCustomCharacteristicUUID = [CBUUID UUIDWithString: MY_CUSTOM_CHARACTERISTIC_UUID];
alertLevelCharacteristic =
[[CBMutableCharacteristic alloc] initWithType:alertLevelCharacteristicUUID
properties:CBCharacteristicPropertyRead
value: nil permissions:CBAttributePermissionsReadable];
myCustomCharacteristic =
[[CBMutableCharacteristic alloc] initWithType:myCustomCharacteristicUUID
properties:CBCharacteristicPropertyRead
value: nil permissions:CBAttributePermissionsReadable];
NSArray *myCharacteristics = #[alertLevelCharacteristic, myCustomCharacteristic];
// Now setup the service
myService = [[CBMutableService alloc] initWithType:immediateAlertServiceUUID primary:YES];
// Finally, associate the characteristic with the service. This is an array of characteristics
myService.characteristics = myCharacteristics;
[peripheralManager addService:myService];
... wait for user to push button to start advertising ...
// Start Advertising
[peripheralManager startAdvertising:#{ CBAdvertisementDataLocalNameKey : #"My Service",
CBAdvertisementDataServiceUUIDsKey : #[myService.UUID] }];
And here are the necessary delegate methods. NOTE: delegate method peripheralManagerDidUpdateState fires and indicates that "CoreBluetooth BLE hardware is powered on and ready" (same is true on the central side). Delegate method peripheralManager:didAddService:error fires without error (see output below). And delegate method peripheralManagerDidStartAdvertising:error fires without an error). Here is the service info printed from didAddService:
<CBMutableService: 0x17008efb0 Primary = YES, UUID = 1802, Included Services = (null), Characteristics = (
"<CBMutableCharacteristic: 0x1702c1500 UUID = 2A06, Value = (null), Properties = 0x2, Permissions = 0x1, Descriptors = (null), SubscribedCentrals = (\n)>",
"<CBMutableCharacteristic: 0x1702c15e0 UUID = 66E613B5-7225-42C6-A9C2-11FADAE62899, Value = (null), Properties = 0x2, Permissions = 0x1, Descriptors = (null), SubscribedCentrals = (\n)>")>
CBPeripheralManager Delegate Methods (sorry for all the code, just trying to be complete.):
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
// Determine the state of the peripheral
if ([peripheral state] == CBPeripheralManagerStatePoweredOff) {
NSLog(#"CoreBluetooth BLE hardware is powered off");
}
else if ([peripheral state] == CBPeripheralManagerStatePoweredOn) {
NSLog(#"CoreBluetooth BLE hardware is powered on and ready");
}
else if ([peripheral state] == CBPeripheralManagerStateUnauthorized) {
NSLog(#"CoreBluetooth BLE state is unauthorized");
}
else if ([peripheral state] == CBPeripheralManagerStateUnknown) {
NSLog(#"CoreBluetooth BLE state is unknown");
}
else if ([peripheral state] == CBPeripheralManagerStateUnsupported) {
NSLog(#"CoreBluetooth BLE hardware is unsupported on this platform");
}
}
- (void)peripheralManager:(CBPeripheralManager *)peripheral
didAddService:(CBService *)service
error:(NSError *)error {
if (error) {
NSLog(#"Error publishing service: %#", [error localizedDescription]);
return;
}
else {
NSLog(#"Hurray! Your Service has been successfully published as: %#", service);
}
}
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
error:(NSError *)error {
if (error == nil) {
NSLog(#"Your service is now advertising");
}
else {
NSLog(#"In peripheralManagerDidStartAdvertising: Your service advertising failed with error: %#", error);
}
}
And here is the relevant central code that runs on the iPad Mini:
// Scan for all available CoreBluetooth LE devices
NSArray *services = #[[CBUUID UUIDWithString:IMMEDIATE_ALERT_SERVICE_UUID]];
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
//[centralManager scanForPeripheralsWithServices:services options:nil];
[centralManager scanForPeripheralsWithServices:nil options:nil];
self.centralManager = centralManager;
And here is one of the Central delegate methods. Except for centralManagerDidUpdateState:, none of the delegate methods fire.
// CBPeripheralDelegate - Invoked when you discover the peripheral's available services.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
NSLog(#"Did Discover Services");
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:service];
}
}
// CBCentralManagerDelegate - This is called with the CBPeripheral class as its main input parameter. This contains most of the information there is to know about a BLE peripheral.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Did Discover Peripheral");
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if (![localName isEqual:#"My Service"]) {
// We found the Device
[self.centralManager stopScan];
self.myPeripheral = peripheral;
peripheral.delegate = self;
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
As a final note, I question whether BLE even works on my devices. I loaded a couple different iBeacon apps on the iPhone and iPad Mini to see if I can get the two devices to recognize iBeacons (one transmits, one receives), but they did not discover iBeacons either. I also tried with two iPhones. I also turned Bluetooth off then on. I also tried powering the devices off/on. Both devices are running in the foreground. Still no luck. Please help.
I'll concatenate all the comments here:
Using apps like LightBlue or BLE Utility can help you to find if your issue is on the peripheral side or central one, since you're developing both sides yourself.
Before looking for CBServices, you have to connect to a CBPeripheral.
Method that you did show before hand, and seems that it wasn't obvious.
Also, before starting a scan with the CBCentralManager you have to check its state, and it has to be CBPeripheralManagerStatePoweredOn.
I have one Bluetooth LE device, I need to scan it only, that I have done with Core Bluetooth Framework in iPhone SDk.
Below is sample code,
manager is object of CBCenterManager which writes in the init method:
manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
scanning process:
- (void)startScan
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
manager.delegate = self;
[manager scanForPeripheralsWithServices:nil options:options];
}
Now I got that device in delegate methods,
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Did discover peripheral. peripheral: %# rssi: %#, UUID: %# advertisementData: %# ", peripheral, RSSI, peripheral.UUID, advertisementData);
}
**Here I have write only few lines of code,
This is not enough data for me to show in interface. Because peripheral.UUID is unique for each device, if I change device to discover BLE, it will be changed.
So I want unique address of Bluetooth LE device which I got same in every iOS devices.
Like peripheral.UUID is 1FE639DB-3C54-B5A8-74A4-3D9FBFCAD074
I had discover same thing in android got address like C8:4D:93:78:98:AE this.
and its unique for all android devices,
So I am searching for the same thing in iPhone SDK.
Is it possible to get same unique address of Bluetooth LE in iPhone SDK?
Thanks for your time to read questions.
I am using Core Bluetooth Framework in my app.
I know how to scan for peripherals and getting values from it.(like Heart Rate Monitor)
But what I want is to retrieve the surrounding iPhone Devices list that supports BLE 4.0 and Bluetooth Enabled ones.
I referred below links..
Uses IOBluetooth Framework
Uses CoreBluetooth For Getting Peripherals not the Devices List
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
// I'm not sure how to make this work
NSLog (#"Discovered peripheral: %#", [peripheral name]);
[self.list addObject:peripheral.name]; // add peripheral name to foundarray
NSLog (#"UUID peripheral: %#", [peripheral UUID]);
NSLog (#"peripheral services before connected: %#", [peripheral services]);
NSLog(#"adversting data %#",[NSString stringWithFormat:#"%#",[advertisementData description]]);
NSLog(#"foundArray is %#", self.list);
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
NSLog(#"Central manager's state is updated to: %#", central);
if(central.state == CBCentralManagerStatePoweredOn)
{
//okay your good to go and can now scan
}
else
{
//Unable to use CentralManager methods so print out the central.state and find out why
}
}
I dont know whether Apple provides this or not..
Any Suggestions or Ideas will be appreciated..
Thank In Advance..
Try below code checkBluetoothAccess and requestBluetoothAccess method
- (void)checkBluetoothAccess {
if(!self.cbManager) {
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
/*
We can ask the bluetooth manager ahead of time what the authorization status is for our bundle and take the appropriate action.
*/
CBCentralManagerState state = [self.cbManager state];
if(state == CBCentralManagerStateUnknown) {
[self alertViewWithDataClass:Bluetooth status:NSLocalizedString(#"UNKNOWN", #"")];
}
else if(state == CBCentralManagerStateUnauthorized) {
[self alertViewWithDataClass:Bluetooth status:NSLocalizedString(#"DENIED", #"")];
}
else {
[self alertViewWithDataClass:Bluetooth status:NSLocalizedString(#"GRANTED", #"")];
}
}
- (void)requestBluetoothAccess {
if(!self.cbManager) {
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
/*
When the application requests to start scanning for bluetooth devices that is when the user is presented with a consent dialog.
*/
[self.cbManager scanForPeripheralsWithServices:nil options:nil];
}
You can only retrieve the surrounding iOS devices that support Bluetooth 4.0 if they are also advertising a specific service to identify them. You can't just see all iOS devices that are powered on and nearby. If they are advertising, you can just scan for nil and that will return the advertisement packets being seen.
Note: if you care about retrieving BLE devices currently connected from other apps, you can use the retrieveConnectedPeripheralsWithServices: method.
As we know, iOS 6 support running devices (iPhone 4s and above, and new iPad) as a BLE peripheral. There is a demo in WWDC 2012 Session 705 called "advanced core bluetooth". I asked for the source code from Apple. They sent me a modified version of source code (BTLE_Transfer_Draft). Then I:
Run the app in iPhone 5 (iOS 6) in "Peripheral Mode" and start "Advertising"
Run the app in new iPad (iOS 5.1.1) in "Central Mode"
The problem is that the peripheral is never been discovered at all. So I use other testing applications including some downloaded from App Store. All failed to discover peripherals. I think the problem should be in BTLE_Transfer_Draft. Because I'm not sure whether I'm allowed to present the whole source code. So I just show the "peripheral mode" part here:
- (void)viewDidLoad {
[super viewDidLoad];
// Start up the CBPeripheralManager
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
}
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
// Opt out from any other state
if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
return;
}
// We're in CBPeripheralManagerStatePoweredOn state...
NSLog(#"self.peripheralManager powered on.");
// ... so build our service.
// Start with the CBMutableCharacteristic
self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]
properties:CBCharacteristicPropertyNotify
value:nil
permissions:CBAttributePermissionsReadable];
// Then the service
CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]
primary:YES];
// Add the characteristic to the service
transferService.characteristics = #[self.transferCharacteristic];
// And add it to the peripheral manager
[self.peripheralManager addService:transferService];
}
/** Start advertising
*/
- (IBAction)switchChanged:(id)sender
{
if (self.advertisingSwitch.on) {
// All we advertise is our service's UUID
[self.peripheralManager startAdvertising:#{ CBAdvertisementDataServiceUUIDsKey : #[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
}
else {
[self.peripheralManager stopAdvertising];
}
}
The BLE is in powered on status and the startAdvertising is called. But the BLE central can never discover it.
Post updated:
According to mttrb's suggestion I added "CBAdvertisementDataLocalNameKey" when I startAdvertising. But my service is still can't be discovered by most of the apps including some apps from app store. The only one app can discover my service is an app from app store called "BLE scanner".
My question is: does this mean my application is working as a peripheral? But why my own code can't discover the service? How am I supposed to debug it ?
My code in Central Mode is like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Start up the CBCentralManager
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
......
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(#"Error discovering services: %#", [error localizedDescription]);
return;
}
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// Deal with errors (if any)
if (error) {
NSLog(#"Error discovering characteristics: %#", [error localizedDescription]);
return;
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(#"Peripheral Disconnected");
self.discoveredPeripheral = nil;
}
The didDiscoverPeripheral and didDiscoverServices are never called. What could be wrong? Any idea? Thanks
There is also a high quality free app called LightBlue that you can use to test your code with. It should be able to pick up all devices advertising in peripheral mode and it can even turn itself into an advertising peripheral if you want to make sure your device is working properly.
I would try moving the startAdvertising: method call up and into the end of your peripheralManagerDidUpdateState: delegate method and see if that helps.
I would also add a CBAdvertisementDataLocalNameKey key-value pair to your startAdvertising: method call. I found things were unreliable when the advertisement didn't have a name.
Finally, I would invest in the BLExplr app available in the App Store to help with scanning for your peripheral. It removes the assumption that your central is working correctly.
This Git hub project also throws some light on the CBPeripheralManager API. Called PeripheralModeTest.
This line is particularly useful for setting the advertising data
NSDictionary *advertisingData = #{CBAdvertisementDataLocalNameKey : #"Device Name", CBAdvertisementDataServiceUUIDsKey : #[[CBUUID UUIDWithString:CBUUIDGenericAccessProfileString]]};
Though I can't see any official documentation in the Apple iOS Developer Library yet. More specifically anything about setting the repeat period for the advertising.
The BTLE Transfer example has this piece of (odd) code, which may cause some troubles:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// Reject any where the value is above reasonable range
if (RSSI.integerValue > -15) {
return;
}
// Reject if the signal strength is too low to be close enough (Close is around -22dB)
if (RSSI.integerValue < -35) {
return;
}
Just remove those two if-statements as it makes no sense!
I have made a simplified version available here that can be used to test high volumes of messages being sent from peripheral to central.
Please note that the CBPeripheralManager class was first introduced in iOS 6.0.
I do not know witch version of BTLE Central Peripheral Transfer you did actually test but current version has iOS 6 as requirement.
So I would suggest to test linkage against iOS 5.1 to see what compatibility issues it shows.
I'm currently creating an iPhone app (Xcode 4.3.1, IOS 5) that could use Bluetooth devices! Main goal of this application is indoor navigation (GPS inside buildings isn't really accurate).
The only solution I see here (to keep my app on AppStore) is to try scan for available bluetooth devices!
I tried to use CoreBluetooth framework, but I don't get list of available devices!
Maybe I don't use these functions correctly
#import <UIKit/UIKit.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface AboutBhyperView : UIViewController <CBPeripheralDelegate, CBCentralManagerDelegate>
{
CBCentralManager *mgr;
}
#property (readwrite, nonatomic) CBCentralManager *mgr;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog([NSString stringWithFormat:#"%#",[advertisementData description]]);
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
NSLog(#"This is it!");
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSString *messtoshow;
switch (central.state) {
case CBCentralManagerStateUnknown:
{
messtoshow=[NSString stringWithFormat:#"State unknown, update imminent."];
break;
}
case CBCentralManagerStateResetting:
{
messtoshow=[NSString stringWithFormat:#"The connection with the system service was momentarily lost, update imminent."];
break;
}
case CBCentralManagerStateUnsupported:
{
messtoshow=[NSString stringWithFormat:#"The platform doesn't support Bluetooth Low Energy"];
break;
}
case CBCentralManagerStateUnauthorized:
{
messtoshow=[NSString stringWithFormat:#"The app is not authorized to use Bluetooth Low Energy"];
break;
}
case CBCentralManagerStatePoweredOff:
{
messtoshow=[NSString stringWithFormat:#"Bluetooth is currently powered off."];
break;
}
case CBCentralManagerStatePoweredOn:
{
messtoshow=[NSString stringWithFormat:#"Bluetooth is currently powered on and available to use."];
[mgr scanForPeripheralsWithServices:nil options:nil];
//[mgr retrieveConnectedPeripherals];
//--- it works, I Do get in this area!
break;
}
}
NSLog(messtoshow);
}
I'm not sure about this line, how to pass correct parameters?
[mgr scanForPeripheralsWithServices:nil options:nil];
I took a look into apple reference .. and I still don't understand what's that CBUUID ???
Every device has some bluetooth id? where can I find it?
- (void)scanForPeripheralsWithServices:(NSArray *)serviceUUIDs options:(NSDictionary *)options;
Parameters
serviceUUIDs - An array of CBUUIDs the app is interested in.
options - A dictionary to customize the scan, see CBCentralManagerScanOptionAllowDuplicatesKey.
Is there any other way to use Bluetooth on IOS? I mean, older frameworks that don't use BLE 4.0!
any advice would be appreciated!
thanks!
This guide looks promising for Bluetooth 3.0. Remember that the CoreBluetooth framework is ONLY for Bluetooth Low Energy (4.0). At bluetooth.com's dev-pages you can see some examples of globally defined services, and as Guan Yang mentionen, you can see that the heart rate service is 0x180D. UUID`s of the unit is defined by the manufacturer.
Here's a code snippet to maybe help you along the way.
// Initialize a private variable with the heart rate service UUID
CBUUID *heartRate = [CBUUID UUIDWithString:#"180D"];
// Create a dictionary for passing down to the scan with service method
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
// Tell the central manager (cm) to scan for the heart rate service
[cm scanForPeripheralsWithServices:[NSArray arrayWithObject:heartRate] options:scanOptions]
in Bluetooth, there are "Services". A device publishes 1..N services, and each service has 1..M characteristics. Each service has an unique identifier, called UUID.
For example, a heart rate Bluetooth Sensor that offers the service "heart rate", publishes a service with UUID 0x180D.
(more services here)
So when you perform a search, you must provide a UUID as the criteria, telling which service to search.
You should take a look at one of the examples. Here’s the relevant line:
[manager scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:#"180D"]] options:nil];
(I know this is a Mac OS X example, but the iOS CoreBluetooth API is very similar.)
CBUUID identifies services you are interested in, not devices. Standard services have a 16-bit UUID, in this case 0x180d for the heart rate monitor or perhaps 0x180a for device information, while proprietary services have a 128-bit UUID (16 bytes).
Most devices implement the device information service, so if you are just looking for any device, you could try [CBUUID UUIDWithString:#"180A"].
Try giving this while you are scanning for devices
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[self.centralManager scanForPeripheralsWithServices:nil options:options];
you will be able to get the list of devices at didDiscoverPeripheral delegate method
Keep calm and use https://github.com/l0gg3r/LGBluetooth
All you need to do
[[LGCentralManager sharedInstance] scanForPeripheralsByInterval:4
completion:^(NSArray *peripherals) {
}];