IOS: Sending byte data to an embedded device through bluetooth - ios

I am building an app that connects an iOS device to a smartwatch through bluetooth which returns blood pressure, heart rate, etc.
Once I establish a connection with the watch from an iOS device (using the CoreBluetooth Framework), I should be able to complete the handshake with the watch by sending 7 different byte arrays to the watch in succession for which the watch responds back by sending the corresponding byte data.
For example, the first byte array would contain a command to retrieve firmware version of the watch and the watch responds back with its version and so on. The problem is I'm not able to figure out how to send a byte array to the watch once the bluetooth connection is made and by the way, the watch is BLE 4.0 device.
I built the same app in android where once a bluetooth connection was made, a bluetooth socket was registered and I got input stream and output stream from this socket.
By using these, I was able to send and retrieve byte data to and from the watch.
Is there anyway to achieve the same in iOS?
Thanks for any help in advance!

Related

How can an iOS BLE central receive more than 155 bytes from a peripheral in notify mode?

I have a custom BLE peripheral that can send a notification data packet to a central. The device sends packets of 200 bytes at a time, and the central is expected to register for notification of characteristic updates on the device. Note this device was not designed for read operations and only supports streaming notifications to central.
In android 7 The central software just works with no problems and the phone (central) receives 200 bytes in a single notify event. - this works just fine.
I am porting the code for use on Apple devices using swift. I am using an iPad with iOS 9.3 and core blue tooth to test my software.
The iPad is programmed as a central, to receive notifications, but when the callback didUpdateValueForCharacteristic fires I only ever see the length of the data from the characteristic.value as being 155bytes. This means that 45 bytes are lost somewhere. BTW - The same code was also tested on a mac book air, and in that case the data received by the central was only 101bytes not 200 bytes either.
I dont see any mention in the corebluetooth API documents of a 155byte limitation anywhere. Am I supposed to call some extra function, or should I have set up the notifications a special way to do something to get the remainder of the bytes? If so does anyone know what?

Send image to non ios device

I have to create an application which will detect a non ios device over bluetooth which supports BTLE 4.0.
I have following doubts:
Is it possible to transfer images from iphone app to non ios device using BTLE 4.0
I have searched some tutorial which talks about Central and peripheral. What i understand is in this case iphone app will be peripheral and non ios device will be central? m i right
Will this code will be able to fulfil all my requirements
Yes, an image can be converted to data and data can be sent via bluetooth. To convert a UIImage to NSData you have to decide on what format you want it. You can use UIImageJPEGRepresentation
or
UIImagePNGRepresentation.
Either one will convert a UIImage into NSData.
No you are wrong. The iOS Device has a Central Manager (CBCentralManager) which find other devices (CBPeripheral). Those other devices have many services (CBService) and each service can have many characteristic (CBCharacteristic) which you connect to. Once the connection is created you can send (write) or receive (read) data.
The code looks pretty good. But the main point of SENDING data doesn't seem to be there. You can send to a Bluetooth peripheral from iOS using a WRITE command - which will automatically be split up in to small packets. The size is limited to 64K and can take around a second per kilobyte - so it is pretty slow. Use the function [peripheral writeValue:data forCharacteristic: characterstic type:CBCharacteristicWriteWithResponse]; (you have to keep a reference to the peripheral and the characterstic).

BLE advertising data not received from android device

Using CoreBluetooth I am trying to detect a BLE peripheral which is transmitting the advertisement and scan response packets.
Packet sniffer is able to find the advertisement as well as scan response data but iPhone only detects the scan response. So looks like iOS is rejecting the advertising data.
I am able to receive advertising data from other devices properly.
Any possible debug starting points ?
Note: The periferal device spec indicates that it does not set the 3 optional BLE packet bytes while transmitting the advertising data.
Advertising packets are used only to notify periodically any possible Central devices of the BLE device presence. The Advertising packet can contain information if the device can be connected to or not, and a few other data. Scan response should be the place where you should focus to pack important data.
On iOS you should rely on scan response to deliver the important identification data. On Android you have more flexibility, such as accessing both advertising packet and scan responses. Just to make sure you play along well with both platforms, keep the advertising simple so just the device is visible by any central, and store your data in scan response.

Ios Peripheral Device in BACKGROUND

We need in our project to detect the proximity of an iPhone that is running a custom APP that is using Bluetooth LE.
The detector (Scanner, Central...) will be implemented using a BLE Integrated Circuit (from Texas or Nordic). I mean that the scanner is not another IOS device... running Core Bluetooth as a Central..
For the detector to guess the proximity, the idea is very simple, just advertise a service with an UUID proprietary.
While in foreground all works OK, and the UUID and a Local name are advertised (The UUID in the main advertise packet, and the Local Name in the SCAN Response packet....), and our scanner is able to decide if this iOS device is running our App.
The problem arises when going to background .....
The iOS stops broadcasting UUID and Local Name. (As the documentation of Core Bluetooth Explains... I Know...)
At this moment (Background), IOS begin to broadcast a SPECIAL MANUFACTURER DATA in the main advertise packet, and nothing in the SCAN Response packet)
The data packet we see using a Bluetooth Sniffer is :
0x14 (length of packet not including this byte).
0xFF (Manufacturer specific data AD Type).
And then :
0x4C, 0x00 (this data is the manufacturer identifier, if the packet is compliant with BLE 4.0 specification).
0x01, 0x00,0x00, 0x00, 0x00,0x00,0x80, and ten 0x00 more....
I know Apple says that while in background ONLY ANOTHER IOS DEVICE SEARCHING FOR A SPECIFIC SERVICE CAN DISCOVER IT. (Really I do not know how they can achieve that, unless they connect to the peripheral and retrieve the services, or if the peripheral knows about other IOS device is scanning because of it´s Address in the SCAN REQUEST and then changes the advertisement data in background).
The main questions are :
Is there any documentation or knowledge of what this manufacturer data means....Perhaps it would be possible to the scanner to know based on this info that this is an iOS device advertising in background and then connect to look if the custom service is there. (Not a quick and clean solution...but I do not see any other workaround....)
Does anybody worked with this scenario...and found a clean solution .....
I have heard from people that forces the application not to go to background.
This limitation, will stop a lot of possible projects.

Transmitting data with CoreBluetooth

I'm developing an iOS app with an accompanying Bluetooth LE peripheral. The one step I don't seem to be able to solve is how to actually transmit the data from my app to the peripheral or vice versa.
What I've built so far is a test app that can connect to my sample Bluetooth peripheral, and read all of its services/characteristics/descriptors. It can toggle notifications for a given characteristic, and write to given characteristics. It is just this last step of "transmit n bytes to the peripheral, and receive m bytes from the peripheral" that I can't seem to figure out.
Looking at the External Accessory Framework (what I would use if Apple would actually give me MFi approval for this project), they give you input and output streams on a given session to communicate with the accessory, but no such object exists for CoreBluetooth.
Is this simply an oversight on Apple's part on the functionality of CoreBluetooth? Or do I simply need to develop my own Bluetooth service profile to handle the inflow/outflow of data to and from the peripheral?
LE is fundamentally designed to work with these GATT based profiles, which are suited for monitoring sensors, not for data streams. While LE does allow for additional L2CAP streams to be opened for custom protocols, Apple's CoreBluetooth doesn't provide access to do so.
You can build a custom profile with private services and characteristics and have it work kind of like SSP; that's the way I'm using my BLE module to get data from some sensors to my app. The module I bought (Microchip's RN-4020) already has a custom profile made specifically for this known as MLDP (Microchip Low-energy Data Profile).
The way I get the data in my iOS app is by subscribing to the private characteristic, thus being notified when the values are updated. So far it has been working great, and the data rate can go up to 20 kbps according to Microchip (I haven't tested its limits, since I don't need much speed). Here's a link to Microchip's product page: http://www.microchip.com/wwwproducts/Devices.aspx?product=RN4020
Good luck!
You can use the bluetooth.org 'Immediate Alert Service' uuid=1802 with characteristic uuid=2A06 with property=write_no_response to send one byte values to your peripheral device from your iPhone. The peripheral device must be programmed to act on the data that is sent. For example, you might use a button on an iPhone app to send a hex address that causes one or more port pins to turn on or off on the peripheral. While this is not using the Alert Service as it was intended, it does provide an easy way to test out data transfer to a peripheral device. The same process could be used to send sequential data bytes similar to a serial data stream. I have not yet tried sending more complex data streams. The write_no_response does not provide any feedback to the app as to whether the data was received by the peripheral.
The IOS TemperatureSensor.xproj is an example of code for reading temperature data from a peripheral. The OSX HealthThermometerClient.xproj has the code needed to decode the somewhat complex thermometer data structure. The IOS TI-BLE-Demo.xproj TIBLECBKeyfob.m has code for reading and writing characteristic values, such as, reading temperature or battery levels from a peripheral device.

Resources