-
Notifications
You must be signed in to change notification settings - Fork 10
/
BluetoothService.py
85 lines (64 loc) · 2.43 KB
/
BluetoothService.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import struct
from threading import Thread
import Crc16
class BluetoothService:
def __init__(self, socket, message_callback=None, debug=False):
# Constants
self.MSG_SIZE_CRC = 2
self.MSG_SIZE_ID = 1
self.MSG_SIZE_MARKER = 1
self.MSG_SIZE_TYPE = 1
self.MSG_SIZE_BYTES = 1
self.MSG_SOM_MARKER = 0xFD
self.MSG_EOM_MARKER = 0xDD
# Member variables
self.message_cb = message_callback
self.debug = debug
self.socket = socket
self.isDisposing = False
self.thread = Thread(target=self.__run)
self.thread.start()
def __run(self):
try:
while not self.isDisposing:
data = self.socket.recv(1024)
if len(data) == 0:
continue
if self.debug:
print(">> INCOMING: " + bytearray(data).hex(sep=' '))
if data[0] != self.MSG_SOM_MARKER:
print("Warning: Invalid SOM received, corrupted message")
continue
if self.message_cb is not None:
self.message_cb(data)
except IOError:
pass
def __size(self, payload_length):
return self.MSG_SIZE_ID + payload_length + self.MSG_SIZE_CRC
def __totalPacketSize(self, payload_length):
return self.__size(payload_length) + (self.MSG_SIZE_MARKER * 2) + self.MSG_SIZE_TYPE + self.MSG_SIZE_BYTES
def close(self):
self.isDisposing = True
self.socket.close()
def sendPacket(self, msg_id, payload, is_response=False, is_fragment=False):
b = bytearray(self.__totalPacketSize(len(payload)))
b[0] = self.MSG_SOM_MARKER
header_b = 0
if is_fragment:
header_b = (header_b | 32)
if is_response:
header_b = (header_b | 16)
b[1] = self.__size(len(payload))
b[2] = header_b
b[3] = msg_id
b[4:4 + len(payload)] = payload
crc_data = bytearray(self.__size(len(payload)) - self.MSG_SIZE_CRC)
crc_data[0] = msg_id
crc_data[1:1 + len(payload)] = payload
crc16 = Crc16.crc16_ccitt(crc_data)
b[len(payload) + 4] = crc16 & 255
b[len(payload) + 5] = (crc16 >> 8) & 255
b[len(payload) + 6] = self.MSG_EOM_MARKER
if self.debug:
print("<< OUTGOING: " + bytearray(b).hex(sep=' '))
self.socket.send(bytes(b))