class BLEUART(Consumer): def __init__(self, opc, name="ybb", rxbuf=1024): Consumer.__init__(self) self._ble = BLE() self._ble.active(True) self._ble.irq(self._irq) self._ble.config(gap_name = name[:16]) ((self._tx_handle, self._rx_handle),) = self._ble.gatts_register_services((_UART_SERVICE,)) # Increase the size of the rx buffer and enable append mode. self._ble.gatts_set_buffer(self._rx_handle, rxbuf, True) self._connections = {} self._rx_buffer = bytearray() self._opc = opc # Optionally add services=[_UART_UUID], but this is likely to make the payload too large. self._payload = advertising_payload(name=name[:16], appearance=_ADV_APPEARANCE_GENERIC_COMPUTER) self._advertise() def _parse(self): try: bs = self.read() log.debug("Read data: %s", bs) d = bs.decode().strip() json = loads(d) if ENCRYPTED_INPUT: # 处理加密 st = Sec() json = st.dec_payload(json) if TOKEN not in json: return None, json return json[TOKEN], json except BaseException as e: log.debug("Invalid request: %s" , e) return None, None def send(self, r): try: if not self.is_authed(): log.debug("No authenticated central") return self.write(dumps(r)) except BaseException as e: log.debug("Send failed: %r" , e) def _handle(self): t, d = self._parse() tm = self._opc.tm_auth(t) if tm is not None: self.send(tm) elif not self._opc.auth(t): self.send(AUTH_ERR) else: self._set_auth() create_task(self._call(d)) def _set_auth(self): for conn_handle in self._connections: self._connections[conn_handle] = -1 def _irq(self, event, data): # Track connections so we can send notifications. if event == _IRQ_CENTRAL_CONNECT: conn_handle, _, _ = data self._connections[conn_handle] = 0 log.debug("New connection") elif event == _IRQ_CENTRAL_DISCONNECT: conn_handle, _, _ = data log.debug("Disconnected") if conn_handle in self._connections: del self._connections[conn_handle] # Start advertising again to allow a new connection. self._advertise() elif event == _IRQ_GATTS_WRITE: conn_handle, value_handle = data if conn_handle in self._connections and value_handle == self._rx_handle: self._rx_buffer += self._ble.gatts_read(self._rx_handle) self._handle() def any(self): return len(self._rx_buffer) def read(self, sz=None): if not sz: sz = len(self._rx_buffer) ret = self._rx_buffer[0:sz] self._rx_buffer = self._rx_buffer[sz:] return ret def write(self, data, authed = False): for conn_handle in self._connections: if not authed or self._connections[conn_handle] < 0: log.debug("Send data: %s", data) self._ble.gatts_notify(conn_handle, self._tx_handle, data) def close(self): for conn_handle in self._connections: self._ble.gap_disconnect(conn_handle) self._connections.clear() def disconnect(self, conn_handle): if conn_handle in self._connections: self._ble.gap_disconnect(conn_handle) def _advertise(self, interval_us=500000): self._ble.gap_advertise(interval_us, adv_data=self._payload) log.info("Advertised", ) def is_authed(self): for conn_handle in self._connections: if self._connections[conn_handle] < 0: return True return False def check_auth(self): for conn_handle in self._connections: if self._connections[conn_handle] >= 0: self._connections[conn_handle] = self._connections[conn_handle] + 1 if self._connections[conn_handle] > AUTH_FAILED_COUNT: log.info("Connect is not authenticated: %d, disconnected.", conn_handle) self.disconnect(conn_handle) async def _call(self, data): try: r = await self._opc.op_request(data, False) self.send(r) except BaseException as e: #NOSONAR msg = "Call failed %r" % e log.debug(msg) self.send(result(500, msg)) async def monitor(self): ''' 清理非法连接 ''' log.debug("BLE connection monitor") while True: try: sleep(1) self.check_auth() except: # NOSONAR # pylint: disable=W0702 pass async def consume(self, data: dict): if ENCRYPTED_OUTPUT: st = Sec() self.send(st.enc_paylaod(data)) else: self.send(data) sleep(0)
bluetooth.FLAG_READ, ) _serial_RX_service = ( bluetooth.UUID('72f235e0-fb1c-4772-96f1-d55a445d5c89'), bluetooth.FLAG_WRITE, ) #_my_serial_service = ((_serial_service,(_serial_TX_service, _serial_RX_service,),),) #((_tx_handle, _rx_handle),)= bt.gatts_register_services(_my_serial_service) #start the gatt service # tx_handle is for the TX service to be used for the reads ((tx_handle, rx_handle), ) = bt.gatts_register_services(_my_service) # increase the size of the buffer, default is 20 bytes #need to ensure we pick something that is big enough for file transfers bt.gatts_write(rx_handle, bytes(1024)) #gap_advertise() #params: interval, adv_data bt.gap_advertise(100000, adv_encode_name('MicroTrynkit')) #this function sends to data from esp32 to be read from connected device. Just for testing purposes now. bt.gatts_write(tx_handle, str.encode("hopefully this works")) #adding gatt notify #bt.gatts_notify(conn_handle, 1) #END OF FILE ########################################################################################################################