示例#1
0
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)
示例#2
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
########################################################################################################################