Reputation: 3852
I want two BLE devices to connect to each other, and exchange data bi-directionally.
These devices are exactly equivalent - this is basically a serial cable between two peers.
There is not one 'store of data', or hierarchy between the two.
Both ends basically transmit data to each other (there is no polling for 'read' data), and no acknowledgement is required.
BLE documentation refers to the Characteristic Properties as:
So basically I have just one question:
Can I just have one Characteristic, with two properties
That the Peripheral advertises, and this will enable two-way write behavior?
Upvotes: 1
Views: 1247
Reputation: 18497
First a few things to make everything clear, in case somebody wonders:
BLE has the concept of Central and Peripheral. Peripherals advertise their presence. Centrals scan and discover peripherals which they then connect to. Once the connection is created, these link layer roles do not really matter in terms of GATT and L2CAP Connection oriented channels, which are both used to transfer data.
Every device (including centrals) supporting connections over BLE must have a GATT server. While it is far more common that the peripheral only uses the GATT server role, it can act as GATT client. Centrals can also act as GATT servers. Furthermore, the both GATT roles can be supported simultaneously. Both sides can for example expose an identical GATT server characteristic with the write property. Not sure if this is a common approach though.
Now, back to your question. You can definitely have one characteristic both having the "write" and "notify" capabilities. When you write, I would suggest using "Write without response" since that has better throughput than "Write with response", since it does not require an acknowledgement between every write. Over the link layer, all kinds of packets are still sent "reliably", meaning there will be no packet drops unless the whole connection drops.
I would however suggest you to have one characteristic per direction. The reason is that some Bluetooth stacks can not in a thread-safe way both send and receive data on one single characteristic, due to the API design structure. In particular, Android's API has one method to set data on a characteristic and another method to send the current data of a characteristic. If a notification arrives in between these calls (where the bluetooth stack internally assigns the new data to the characteristic), the write operation will send the data that was just notified, instead of the intended data.
You could also check out L2CAP Connection oriented channels (introduced in Bluetooth v4.2) which is a good way to transfer raw data byte packets, when the GATT structure is not appropriate.
Upvotes: 3