Exemplo n.º 1
0
    def find_bluetooth_adapter(self, tty_port=None):
        if tty_port is None:
            tty_port = self.find_tty()
        if tty_port is None:
            raise ValueError('Bluetooth adapter not found!')

        self.bluetooth = BLE(tty_port)
Exemplo n.º 2
0
 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()
Exemplo n.º 3
0
        raise EventTimeoutError()


def wait_for_event(irq, key, timeout_ms):
    start_time = time.ticks_ms()

    event_queue = _events[irq][key]

    while not event_queue:
        _maybe_raise_timeout(timeout_ms, start_time)
        machine.idle()

    return event_queue.popleft()


_ble = BLE()

gap_advertise = _ble.gap_advertise
gatts_register_services = _ble.gatts_register_services
gatts_read = _ble.gatts_read
gatts_write = _ble.gatts_write
gatts_set_buffer = _ble.gatts_set_buffer
gap_disconnect = _ble.gap_disconnect


def gap_scan(duration_ms, interval_us=None, window_us=None, timeout_ms=None):
    assert not (interval_us is None and window_us is not None), \
        "Argument window_us has to be specified if interval_us is specified"

    start_time = time.ticks_ms()
Exemplo n.º 4
0
class Myo(object):
    def __init__(self):
        self.bluetooth = None
        self.connection = None

    def connect(self, tty_port=None):
        self.safely_disconnect()
        self.find_bluetooth_adapter(tty_port)

        address = self.find_myo_device()
        connection_packet = self.bluetooth.connect(address)
        self.connection = multiord(connection_packet.payload)[-1]
        self.bluetooth.wait_event(3, 0)
        print('Connected.')

        is_fw_valid = self.valid_firmware_version()

        if is_fw_valid:
            device_name = self.read_attribute(0x03)
            print('Device name: %s' % device_name.payload[5:])
            self.write_attribute(0x1d, b'\x01\x00')
            self.write_attribute(0x24, b'\x02\x00')
            self.initialize()
        else:
            raise ValueError('The firmware version must be v1.x or greater.')

    def find_bluetooth_adapter(self, tty_port=None):
        if tty_port is None:
            tty_port = self.find_tty()
        if tty_port is None:
            raise ValueError('Bluetooth adapter not found!')

        self.bluetooth = BLE(tty_port)

    def find_tty(self):
        for port in comports():
            if re.search(r'PID=2458:0*1', port[2]):
                return port[0]

        return None

    def run(self, timeout=None):
        if self.connection is not None:
            self.bluetooth.receive_packet(timeout)
        else:
            raise ValueError('Myo device not paired.')

    def valid_firmware_version(self):
        firmware = self.read_attribute(0x17)
        _, _, _, _, major, minor, patch, build = unpack(
            'BHBBHHHH', firmware.payload)

        print('Firmware version: %d.%d.%d.%d' % (major, minor, patch, build))

        return major > 0

    def add_listener(self, listener):
        if self.bluetooth is not None:
            self.bluetooth.add_listener(listener)
        else:
            print('Connect function must be called before adding a listener.')

    def vibrate(self, duration):
        cmd = b'\x03\x01'
        if duration == VibrationType.LONG:
            cmd = cmd + b'\x03'
        elif duration == VibrationType.MEDIUM:
            cmd = cmd + b'\x02'
        elif duration == VibrationType.SHORT:
            cmd = cmd + b'\x01'
        else:
            cmd = cmd + b'\x00'

        self.write_attribute(0x19, cmd)

    def initialize(self):
        self.write_attribute(0x28, b'\x01\x00')
        self.write_attribute(0x19, b'\x01\x03\x01\x01\x00')
        self.write_attribute(0x19, b'\x01\x03\x01\x01\x01')

    def find_myo_device(self):
        print('Find Myo device...')
        address = None
        self.bluetooth.start_scan()
        while True:
            packet = self.bluetooth.receive_packet()

            if packet.payload.endswith(
                    b'\x06\x42\x48\x12\x4A\x7F\x2C\x48\x47\xB9\xDE\x04\xA9\x01\x00\x06\xD5'
            ):
                address = list(multiord(packet.payload[2:8]))
                break

        self.bluetooth.end_scan()
        return address

    def write_attribute(self, attribute, value):
        if self.connection is not None:
            self.bluetooth.write_attribute(self.connection, attribute, value)

    def read_attribute(self, attribute):
        if self.connection is not None:
            return self.bluetooth.read_attribute(self.connection, attribute)
        return None

    def safely_disconnect(self):
        if self.bluetooth is not None:
            self.bluetooth.end_scan()
            self.bluetooth.disconnect(0)
            self.bluetooth.disconnect(1)
            self.bluetooth.disconnect(2)
            self.disconnect()

    def disconnect(self):
        if self.connection is not None:
            self.bluetooth.disconnect(self.connection)
Exemplo n.º 5
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)
Exemplo n.º 6
0
_IRQ_GATTC_SERVICE_RESULT = const(1 << 8)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(1 << 9)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(1 << 10)
_IRQ_GATTC_READ_RESULT = const(1 << 11)
_IRQ_GATTC_WRITE_STATUS = const(1 << 12)
_IRQ_GATTC_NOTIFY = const(1 << 13)
_IRQ_GATTC_INDICATE = const(1 << 14)

#Global functions for the timer
time_after = time.time()
time_before = time.time()
timeCheck = False
global conn_handle

# create BLE variable
bt = BLE()

# set active to True initializing the bluetooth module
bt.active(1)

#adc for the battery level check
adc = machine.ADC(Pin(32))
val = adc.read()

# adding banner message to the device
print("****************************************************")
print("* SER 402 - Project 5 Trynkit                      *")
print("* Micropython on ESP32                             *")
print("* Battery Voltage:" + str(val))
print("****************************************************")
Exemplo n.º 7
0
def create_battery_service():
    service = BatteryService(BLE())
    service.register_services()
    service.start()
    return service