Я пытаюсь установить sh соединение Bluetooth между raspberry pi и android телефоном. Raspberry pi отправляет данные датчика на телефон.
Я могу отправить стартовое сообщение с телефона на raspberry, и raspberry создаст поток для отправки данных на телефон, используя постоянный UUID с обеих сторон. Все работает нормально, но во время связи по телефону я хочу предотвратить любые попытки связи с другим телефоном. Чтобы предотвратить это, я сохраняю адрес первого подключенного телефона и отменяю попытки подключения, но мне также нужно сообщить об отклоненном телефоне, потому что «устройство используется кем-то другим». Это означает, что мне нужно открыть другое соединение Bluetooth для информирования.
С тем же UUID я не могу отправить данные на второй телефон. Чтобы решить эту проблему, отправьте случайно сгенерированный UUID по предварительно настроенному соединению с постоянным UUID. Получив это сообщение, raspberry открывает второе соединение для отправки данных с UUID, отправленных по телефону. Таким образом, я планирую установить начальное соединение для всех попыток с разными UUID. В то время как первый телефон получает сенсорные данные, другой телефон получает сообщение об отказе. Но при второй попытке подключения все коммуникации прекратились. Там нет ошибки.
Я не уверен, но я думаю, это потому, что все телефоны используют один и тот же UUID для первого подключения.
Итак, я хочу узнать, есть ли способ получить случайно сгенерированный UUID с помощью Bluetooth-сервера (в данном примере малина), а не постоянный UUID для установки первого соединения на стороне android?
Python код на расперри пи:
класс BlueConnServer (threading.Thread):
def __init__(self):
super().__init__()
self.server_sock=BluetoothSocket( RFCOMM )
self.server_sock.bind(("",PORT_ANY))
self.server_sock.listen(1)
self.connectedMAC = None
self.port = self.server_sock.getsockname()[1]
self.uuid_smo2Timeline = "f1614aa6-1592-11ea-8d71-362b9e155667"
advertise_service( self.server_sock, "AquaPiServer",
service_id = self.uuid,
service_classes = [ self.uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
)
def run(self):
while not self.stopped():
self.client_sock, client_info = self.server_sock.accept()
try:
data = self.client_sock.recv(1024)
print("received [%s]" % data)
if self.connectedMAC==None or self.connectedMAC==client_info[0] :
if data[0:4]==self.connPass:
self.connectedMAC = client_info[0]
serverUuid = data[4:].decode()
self.blSmo2Timelile = BlueConnRasp2Andro(1,client_info[0],serverUuid)
self.blSmo2Timelile.start()
elif data==self.connStop:
self.blSmo2Timelile.stoper=True
self.blSmo2Timelile.stop()
self.connectedMAC=None
else :
print("WRONG PASS....")
else:
if data[0:4]==self.connPass:
print("Socket is full. Connection Denied")
serverUuid = data[4:].decode()
self.blSmo2Timelile = BlueConnRasp2Andro(0,client_info[0],serverUuid)
self.blSmo2Timelile.start()
except IOError:
sys.exit(0)
класс BlueConnRasp2Andro (threading.Thread):
def __init__(self,conType ,host,_uuid):
super().__init__()
self._stopper = threading.Event()
self.host=host
self.client_sock=None
self.connectionType = conType
self.service_matches = find_service( uuid = self.uuid, address = self.host )
if len(self.service_matches) == 0:
print("couldn't find the Server service ")
else :
first_match = self.service_matches[0]
_port = first_match["port"]
_name = first_match["name"]
_host = first_match["host"]
self.client_sock=BluetoothSocket( RFCOMM )
self.client_sock.connect((_host,_port))
def sendStroke(self):
if len(self.stroke.strokeDataSendingQueue)>0 :
data=self.getStrokeByte(self.stroke.strokeDataSendingQueue[0])
self.client_sock.send(data)
self.stroke.strokeDataSendingQueue.pop(0)
print(''.join(' {:02X}'.format(x) for x in data)+'. Stroke data sended ')
def sendTimeline(self):
if len(self.eventBus.smo2DataSendingQueue)>0:
data= self.embedTimelineSign(self.eventBus.smo2DataSendingQueue[0])
self.client_sock.send(data)
self.eventBus.smo2DataSendingQueue.pop(0)
def run(self):
if self.connectionType==0:
data = 'denied'
self.client_sock.send(data.encode())
else:
self.stroke.startQueue=True;
self.eventBus.startQueue=True;
while not self.stoper:
if not len(self.service_matches) == 0:
self.sendTimeline()
self.sendStroke()
чтение и запись части Android кода:
частного класса ConnectedThread расширяет поток {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer;
private final int rw;
private Lock lock = new ReentrantLock();
private int connectionType;
public ConnectedThread(BluetoothSocket socket, int rw, int connType) {
mmSocket = socket;
this.rw = rw;
connectionType=connType;
InputStream tmpIn = null;
OutputStream tmpOut = null;
if(rw==MESSAGE_WRITE)
state=MESSAGE_WRITTEN;
if(rw==MESSAGE_READ)
state=MESSAGE_READING;
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
if (lock.tryLock())
{
try
{
if (rw == MESSAGE_READ) {
read();
} else if(rw==MESSAGE_WRITE) {
String pass = connPass + serverUuid.toString();
boolean w = write(pass.getBytes());
} else if(rw==CONNECTION_OFF){
boolean w = write(connStop.getBytes());
}
}
finally
{
lock.unlock();
}
}
cancel();
}
public void read(){
mmBuffer = new byte[255];
int numBytes;
while (state==MESSAGE_READING) {
try {
numBytes = mmInStream.read(mmBuffer);
if (numBytes > 0) {
Message readMsg;
byte[] encodedBytes = new byte[6];
System.arraycopy(mmBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String stringData = new String(encodedBytes, "US-ASCII");
if(stringData.equals("denied")){
readMsg = handler.obtainMessage(MESSAGE_DENIED);
readMsg.sendToTarget();
}
else {
int sign = getSign(mmBuffer);
if (sign == CONNECTION_TIMELINE) {
SmO2Values values = getSmO2Values(mmBuffer);
readMsg = handler.obtainMessage(MESSAGE_READ, values);
} else {
StrokeValues values = getStrokeValues(mmBuffer);
readMsg = handler.obtainMessage(MESSAGE_READ_STROKE, values);
}
readMsg.sendToTarget();
}
}
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
}
}
}
public boolean write(byte[] bytes) {
boolean t=false;
try {
mmOutStream.write(bytes);
t=true;
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
}
return t;
}