I have been developing an small project which requieres a communication between two Raspberries, the first one acts as a Beacon and the second one tries to connect to that beacon and obtain the RSSI and the small data that had been written into the channel.
The problem is that I have been trying to develope this arquitecture with python through the pygattlib library (https://bitbucket.org/OscarAcena/pygattlib/src/default/) which acts as a wrapper around the GATT protocol implementation of bluez.
This library works prefectly when you want to create a BLE and you want to connect from the other Raspberry, however, I cannot find any information on how to send data from the beacon itself to make the client read it.
Through the small tutorial that Adafruit teaches (https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt) I can understand that the client needs to send a request, however when it comes to answer by the server, there is no information also from the library that helps about that.
I have been searching for other libraries with no result so I cannot procceed to the next steps of my project, but nevertheless I will continue searching for it.
Also I have been looking to make with the gattlib library (https://github.com/labapart/gattlib), but it does not appear hwo to create a BLE.
PD: Sorry for not posting code about the problem I thoguh It would not be require for this type of question. As the library which I used says, to create a beacon on the Raspberry server, you only need to asociate it to a interface and start advertising with a custon UUID
from gattlib import BeaconService
import time
service = BeaconService("hci0")
service.start_advertising("11111111-2222-3333-4444-555555555555",
1, 1, 1, 200)
time.sleep(5)
service.stop_advertising()
print("Done.")
And when you want to read or write into the channel, the library provides you with an easy example (to read you would only need to replace self.requester.write_by_handle(0x2e, str(bytearray([2])))
for
data = self.requester.read_by_handle(0x1)[0]
print("bytes received:", end=' ')
for b in data:
print(hex(ord(b)), end=' ')
print("")
And use it in the next example loaded in the Raspberry Client
from __future__ import print_function
import sys
import time
from gattlib import GATTRequester, GATTResponse
from gattlib import BeaconService
class Writer(object):
def __init__(self, address):
self.requester = GATTRequester(address, False)
self.connect()
self.send_data()
def connect(self):
print("Connecting...", end=' ')
sys.stdout.flush()
self.requester.connect(True)
print("OK!")
def send_data(self):
self.requester.write_by_handle(0x2e, str(bytearray([2])))
class Beacon(object):
def __init__(self, data, address):
self._uuid = data[0]
self._major = data[1]
self._minor = data[2]
self._power = data[3]
self._rssi = data[4]
self._address = address
def __str__(self):
ret = "Beacon: address:{ADDR} uuid:{UUID} major:{MAJOR}"\
" minor:{MINOR} txpower:{POWER} rssi:{RSSI}"\
.format(ADDR=self._address, UUID=self._uuid, MAJOR=self._major,
MINOR=self._minor, POWER=self._power, RSSI=self._rssi)
return ret
service = BeaconService("hci0")
devices = service.scan(2)
for address, data in list(devices.items()):
b = Beacon(data, address)
print(b)
Writer(address)
print("Done.")
The point is, based on the documentation of that library, you can only read (sync and async) and write with a known address what in this case means that the beacon needs to know the address of the client and also make a connection to it which I think it's not possible because the only one that is emitting is the beacon.