Esempio n. 1
1
class BtServer(object):

    def __init__(self):
        super(BtServer, self).__init__()

        self.socket = BluetoothSocket(RFCOMM)
        self.client = {}

    def start(self):
        # empty host address means this machine
        self.socket.bind(("", PORT_ANY))
        self.socket.listen(config['backlog'])

        self.port = self.socket.getsockname()[1]
        uuid = config['uuid']

        advertise_service(
            self.socket,
            "Rewave Server",
            service_id=uuid,
            service_classes=[uuid, SERIAL_PORT_CLASS],
            profiles=[SERIAL_PORT_PROFILE]
        )

        print('Waiting for connection on RFCOMM channel %d' % self.port)
        self.client['socket'], self.client['info'] = self.socket.accept()
        print("Accepted connection from ", self.client['info'])

    def kill(self):
        self.socket.close()

    def close_connection(self):
        self.client['socket'].close()
Esempio n. 2
0
def main():
    # Setup logging
    setup_logging()
    # We need to wait until Bluetooth init is done
    time.sleep(10)
    # Make device visible
    os.system("hciconfig hci0 piscan")
    # Create a new server socket using RFCOMM protocol
    server_sock = BluetoothSocket(RFCOMM)
    # Bind to any port
    server_sock.bind(("", PORT_ANY))
    # Start listening
    server_sock.listen(1)
    # Get the port the server socket is listening
    port = server_sock.getsockname()[1]
    # The service UUID to advertise
    uuid = "7be1fcb3-5776-42fb-91fd-2ee7b5bbb86d"
    # Start advertising the service
    advertise_service(server_sock,
                      "RaspiBtSrv",
                      service_id=uuid,
                      service_classes=[uuid, SERIAL_PORT_CLASS],
                      profiles=[SERIAL_PORT_PROFILE])
    # These are the operations the service supports
    # Feel free to add more
    operations = ["ping", "example"]
    # Main Bluetooth server loop
    while True:
        print("Waiting for connection on RFCOMM channel %d" % port)
        client_sock = None
        try:
            # This will block until we get a new connection
            client_sock, client_info = server_sock.accept()
            print("Accepted connection from ", client_info)
            # Read the data sent by the client
            data = client_sock.recv(1024)
            if len(data) == 0:
                break
            print("Received [%s]" % data)
            # Handle the request
            if data == "getop":
                response = "op:%s" % ",".join(operations)
            elif data == "ping":
                response = "msg:Pong"
            elif data == "example":
                response = "msg:This is an example"
            # Insert more here
            else:
                response = "msg:Not supported"
            client_sock.send(response)
            print("Sent back [%s]" % response)
        except IOError:
            pass
        except KeyboardInterrupt:
            if client_sock is not None:
                client_sock.close()
            server_sock.close()
            print("Server going down")
            break
Esempio n. 3
0
    def task(self):
        # Waiting until Bluetooth init is done
        time.sleep(self.wakeup_time)

        # Make device visible
        self.scm.set_bluetooth_visible()

        # Create a new server socket using RFCOMM protocol
        server_sock = BluetoothSocket(RFCOMM)

        # Bind to any port
        server_sock.bind(("", PORT_ANY))

        # Start listening
        server_sock.listen(self.max_simultaneous_connections)

        # Get the port the server socket is listening
        port = server_sock.getsockname()[1]

        # Main bluetooth server loop
        while True:

            logger.info(
                'Waiting for bluetooth connection on channel {}'.format(port))

            client_sock = None
            try:
                # Block until we get a new connection
                client_sock, client_info = server_sock.accept()
                logger.info('Accepted connection from {}'.format(client_info))

                # Read the data sent by the client
                command = client_sock.recv(1024)
                if len(command) == 0:
                    continue

                logger.info('Received [{}]'.format(command))

                # Handle the request
                response = self.handle_request(command)

                client_sock.send(response)
                logger.info('Sent back [{}]'.format(response))

            except IOError:
                pass
            except KeyboardInterrupt:

                if client_sock is not None:
                    client_sock.close()

                server_sock.close()

                logger.info('Bluetooth server going down')
                break
Esempio n. 4
0
class BtServer(object):

    def __init__(self, socket=None):
        super(BtServer, self).__init__()
        self.socket = socket

    def start(self):
        print('start called')
        if not self.socket:
            print('non socket, creating one')
            self.socket = BluetoothSocket(RFCOMM)
            # empty host address means this machine
            self.socket.bind(("", PORT_ANY))
            self.socket.listen(config['backlog'])

            advertise_service(
                self.socket,
                "Rewave Server",
                service_id=config['uuid'],
                service_classes=[config['uuid'], SERIAL_PORT_CLASS],
                profiles=[SERIAL_PORT_PROFILE]
            )

        self.port = self.socket.getsockname()[1] # need port for ref.
        self.accept()

    def stop(self):
        print("server stop called")
        self.socket.close()
        try:
            self.client_socket.close()
        except AttributeError as e:
            # in case if no client is connected
            pass

    def recv(self, buffer=2048):
        print('recv called')
        try:
            return self.client_socket.recv(buffer).decode(encoding='UTF-8')
        except UnicodeDecodeError as e:
            # return raw if unable to unicode decode
            return self.client_socket.recv(buffer)

    def send(self, data):
        self.client_socket.send(data)

    def close_connection(self):
        print("close_connection called")
        self.client_socket.close()

    def accept(self):
        # blocking call
        print("accept Called. Waiting for connection on RFCOMM channel", self.port)
        self.client_socket = self.socket.accept()[0] # returns socket, name
Esempio n. 5
0
def run_bt_server(account):
    """Adapted from: https://github.com/EnableTech/raspberry-bluetooth-demo"""
    import pdb
    pdb.set_trace()
    server_sock = BluetoothSocket(RFCOMM)

    server_sock.bind(("", PORT_ANY))
    server_sock.listen(1)

    port = server_sock.getsockname()[1]
    print ("listening on port %d" % port)

    uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
    advertise_service(
        server_sock,
        "Mock Detector",
        service_id=uuid,
        service_classes=[uuid, SERIAL_PORT_CLASS],
        profiles=[SERIAL_PORT_PROFILE],
        # protocols=[OBEX_UUID],
    )

    print("Waiting for connection on RFCOMM channel %d" % port)

    client_sock, client_info = server_sock.accept()
    print("Accepted connection from ", client_info)

    try:
        while True:
            data = client_sock.recv(1024)
            if len(data) == 0:
                break
            print("received [%s]" % data)
            if data == b'ETH_ADDRESS\r\n':
                client_sock.send(
                    "ETH_ADDRESS::0x{}\r\nEND\r\n".format(account.address())
                )
            elif data.startswith('SIGNED_MESSAGE::'):
                start = len('SIGNED_MESSAGE::')
                user_address = data[start:start+42]
                message = account.create_signed_message(
                    user_address,
                    int(time.time())
                )
                client_sock.send(message)
    except IOError:
        pass

    print("disconnected")

    client_sock.close()
    server_sock.close()
    print("all done")
Esempio n. 6
0
    def start_service(self, port, name, uuid, service_classes,
                      service_profiles, provider, description, protocols):
        socket = BluetoothSocket(RFCOMM)
        socket.bind((self.address, port))
        socket.listen(1)

        advertise_service(socket, name, uuid, service_classes,
                          service_profiles, provider, description, protocols)

        print("Starting server for %s on port %i" % socket.getsockname())
        #self.serve(socket)
        return socket
Esempio n. 7
0
    def _create_server(self):
        server_sock = BluetoothSocket(bt.RFCOMM)
        server_sock.bind(("", bt.PORT_ANY))
        server_sock.listen(1)
        self.channel = server_sock.getsockname()[1]

        bt.advertise_service(server_sock,
                             self.name,
                             service_classes=[self.uuid],
                             profiles=[])

        return server_sock
class BlueComm:
    def __init__(self):

        self.stop = False
        self.exit = False

    def start(self, callback):

        self.stop = False

        self.server_sock = BluetoothSocket(RFCOMM)
        self.server_sock.bind(("", PORT_ANY))
        self.server_sock.listen(1)

        port = self.server_sock.getsockname()[1]

        uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66"

        advertise_service(self.server_sock,
                          "blueCommServer",
                          service_id=uuid,
                          service_classes=[uuid, SERIAL_PORT_CLASS],
                          profiles=[SERIAL_PORT_PROFILE]
                          #  protocols = [ OBEX_UUID ]
                          )

        print("Waiting for connection on RFCOMM channel %d" % port)

        self.client_sock, self.client_info = self.server_sock.accept()
        print("Accepted connection from ", self.client_info)

        try:
            while not self.stop:
                data = self.client_sock.recv(1024)
                if len(data) == 0:
                    break

                callback(self, data)

        except IOError:
            pass

        print("disconnected")

        self.disconnect()

    def disconnect(self):

        self.client_sock.close()
        self.server_sock.close()
from json import loads
# End standard library imports.

# Start third party imports.
from bluetooth import PORT_ANY, RFCOMM, SERIAL_PORT_CLASS, SERIAL_PORT_PROFILE, BluetoothSocket, advertise_service
from socketio import Client
# End third party imports.

# Start project imports.
# End project imports.

CLIENT_OBJ = Client()
BLUETOOTH_SOCKET_OBJ = BluetoothSocket(RFCOMM)
BLUETOOTH_SOCKET_OBJ.bind((str(), PORT_ANY))
BLUETOOTH_SOCKET_OBJ.listen(1)
PORT_INT = BLUETOOTH_SOCKET_OBJ.getsockname()[1]
UUID_STR = '94f39d29-7d6d-437d-973b-fba39e49d4ee'


def get_json_from_socket(socketObj) -> dict:
    """"
    """
    receiveBytes = socketObj.recv(1024)
    if len(receiveBytes) == 0:
        print("Received 0 bytes")
        return None
    return loads(receiveBytes.decode('utf-8'))


def main() -> None:
    """
class BluetoothInterface(BaseInterface):
    """The Bluetooth interface definition for communication with wireless client devices."""

    __interface_name__ = 'bluetooth'

    def __init__(self, controller):
        """
        Initializes a bluetooth service that may be consumed by a remote client.

        Arguments
        ---------
            controller : controllers.base.BaseController
                the parent controller that is instantiated this interface

        """
        super(BluetoothInterface, self).__init__()
        self.controller = controller
        self.client_sock = None
        self.client_info = None
        self.rfcomm_channel = None
        self.service_name = self.get_setting('service_name')
        self.service_uuid = self.get_setting('service_uuid')
        self.server_sock = None
        self.thread = None

    def connect(self):
        """Creates a new thread that listens for an incoming bluetooth RFCOMM connection."""
        LOGGER.info('creating thread for bluetooth interface...')
        self.thread = threading.Thread(target=self.listen_for_rfcomm_connection)
        self.thread.daemon = True
        self.thread.start()

    def listen_for_rfcomm_connection(self):
        """
        Starts bluetooth interfaces
        """
        # prepare bluetooth server
        self.server_sock = BluetoothSocket(RFCOMM)
        self.server_sock.bind(("", PORT_ANY))
        self.server_sock.listen(1)
        self.rfcomm_channel = self.server_sock.getsockname()[1]

        # start listening for incoming connections
        try:
            advertise_service(
                sock=self.server_sock,
                name=self.service_name,
                service_id=self.service_uuid,
                service_classes=[self.service_uuid, SERIAL_PORT_CLASS],
                profiles=[SERIAL_PORT_PROFILE]
            )
        except:
            LOGGER.exception("[ERROR] failed to advertise service")
            return

        LOGGER.info('waiting for connection on RFCOMM channel %d', self.rfcomm_channel)

        # accept received connection
        self.client_sock, self.client_info = self.server_sock.accept()
        self.state = self.__states__.STATE_CONNECTED
        LOGGER.info('accepted connection from %r', self.client_info)

        # start listening for data
        self.consume_bus()

    def disconnect(self):
        """
        Closes Bluetooth connection and resets handle
        """
        LOGGER.info('destroying bluetooth interface...')
        self.state = self.__states__.STATE_DISCONNECTING
        if self.client_sock and hasattr(self.client_sock, 'close'):
            self.client_sock.close()
            self.client_sock = None
        if self.server_sock and hasattr(self.server_sock, 'close'):
            self.server_sock.close()
            self.server_sock = None

        # reset the bluetooth interface
        self.thread = None
        self.perform_hci0_reset()
        self.state = self.__states__.STATE_READY

    @staticmethod
    def perform_hci0_reset():
        """Resets the bluetooth hci0 device via hciconfig command line interface."""
        try:
            LOGGER.info('performing hci0 down/up...')
            subprocess.Popen('hciconfig hci0 down', shell=True).communicate()
            subprocess.Popen('hciconfig hci0 up', shell=True).communicate()
            LOGGER.info('hci0 down/up has completed')
        except Exception as exception:
            LOGGER.exception("Failed to restart hci0 - %r", exception)

    def receive(self, data):
        """
        Processes received data from Bluetooth socket

        Arguments
        ---------
            data : basestring
                the data received from the bluetooth connection

        """
        try:
            packet = json.loads(data.decode('utf-8'))
            LOGGER.info('received packet via bluetooth: %r', packet['data'])

            # invoke bound method (if set)
            if self.receive_hook and hasattr(self.receive_hook, '__call__'):
                self.receive_hook(packet['data'])

        except Exception as exception:
            LOGGER.exception('error: %r', exception)

    def send(self, data):
        """
        Sends data via Bluetooth socket connection

        Arguments
        ---------
            data : basestring
                the data to be sent via this interface

        """
        if self.state != self.__states__.STATE_CONNECTED:
            LOGGER.error('error: send() was called but state is not connected')
            return False

        try:
            LOGGER.info('sending IBUSPacket(s)...')
            packets = []
            for packet in data:
                packets.append(packet.as_serializable_dict())

            # encapsulate ibus packets and send
            data = {"data": json.dumps(packets)}  # TODO : is an inner json.dumps necessary?
            LOGGER.info(data)
            self.client_sock.send(json.dumps(data))
        except Exception:
            # socket was closed, graceful restart
            LOGGER.exception('bluetooth send exception')
            self.reconnect()

    def consume_bus(self):
        """
        Start listening for incoming data
        """
        try:
            LOGGER.info('starting to listen for bluetooth data...')
            read_buffer_length = self.get_setting('read_buffer_length', int)

            while self.client_sock:
                data = self.client_sock.recv(read_buffer_length)
                if len(data) > 0:
                    self.receive(data)

        except Exception as exception:
            LOGGER.exception('android device was disconnected - %r', exception)
            self.reconnect()
Esempio n. 11
0
def main():
    """
    Main method of the application.
    Must be run with superuser permissions.
    Params: <user> <network_interface> <hotspot_ssid> <hotspot_password>
    Creates the Bluetooth server and starts listening to clients.
    """
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(29, GPIO.OUT)
    GPIO.output(29, GPIO.HIGH)
    GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    Thread(target=button_thread).start()

    signal.signal(signal.SIGINT, signal_handler)

    global net_interface
    global wifi_on
    global hotspot_enabled
    global hotspot_ssid
    global hotspot_pswd
    global server_sock
    global client_sock
    global username
    global type_pswd
    global indiweb
    global led_thread_run
    global config_file

    if len(sys.argv) == 5:
        username = sys.argv[1]
        print("Username = "******"Network interface = " + net_interface)
        hotspot_ssid = sys.argv[3]
        print("Hotspot SSID = " + hotspot_ssid)
        hotspot_pswd = sys.argv[4]
        print("Hotspot Password = "******"b9029ed0-6d6a-4ff6-b318-215067a6d8b1"
        print("BT service UUID = " + uuid)

        config_file = "{0}.{1}".format("/home" + username + "/", "Telescope-Pi.ini")
        if username == "root":
            if os.path.isdir("/home/pi/"):
                config_file = "/home/pi/.Telescope-Pi.ini"
            else:
                config_file = None
                print("Error! Invalid user!")
                print("Running in emergency mode!")
                emergency_mode_led()
        config = configparser.ConfigParser()
        if os.path.exists(config_file) and os.path.isfile(config_file):
            config.read(config_file)
            if "Wi-Fi" in config and config["Wi-Fi"] == "yes":
                turn_on_wifi()
                try:
                    if len(Cell.all(net_interface)) == 0:
                        print("No Wi-Fi networks found, starting hotspot.")
                        start_hotspot()
                except InterfaceError as e:
                    print("An error occurred while scanning Wi-Fi network!")
                    print(str(e))
            if hotspot_enabled is False and "Hotspot" in config and config["Hotspot"] == "yes":
                start_hotspot()
            if "INDI" in config and config["INDI"] == "yes":
                indiweb_start()
        else:
            turn_on_wifi()
            try:
                if len(list(Cell.all(net_interface))) == 0:
                    print("No Wi-Fi networks found, starting hotspot.")
                    start_hotspot()
            except InterfaceError as e:
                print("An error occurred while scanning Wi-Fi network!")
                print(str(e))
            indiweb_start()

        try:
            server_sock = BluetoothSocket(RFCOMM)
            server_sock.bind(("", PORT_ANY))
            server_sock.listen(1)
            port = server_sock.getsockname()[1]
            advertise_service(server_sock, "Telescope-Pi", service_id=uuid, service_classes=[
                uuid, SERIAL_PORT_CLASS], profiles=[SERIAL_PORT_PROFILE])

            Thread(target=led_thread).start()
            while True:
                print("Waiting for connection on RFCOMM channel %d" % port)
                led_thread_run = True
                client_sock, client_info = server_sock.accept()
                led_thread_run = False
                print("Accepted connection from " + str(client_info))
                bt_send("NetInterface=" + net_interface +
                        "\nWiFi=" + str(wifi_on) +
                        "\nHotspot=" + str(hotspot_enabled) +
                        "\nHotspotSSID=" + hotspot_ssid +
                        "\nHotspotPswdType=WPA\nHotspotPswd=" + hotspot_pswd +
                        "\nINDI=" + str(indiweb is not None))
                send_ip()
                try:
                    while True:
                        data = client_sock.recv(1024)
                        if len(data) == 0:
                            break
                        for line in data.decode().splitlines():
                            parse_rfcomm(line.strip())
                except Exception as e:
                    print(str(e))
                print("Disconnected")
                client_sock.close()
                client_sock = None
                type_pswd = False
        except BluetoothError as e:
            print("No Bluetooth adapter found! Make sure the systemd service has \"Type=idle\".")
            print("Error message: " + str(e))
            print("Running in emergency mode!")
            emergency_mode_led()
    else:
        print("Usage: \"sudo python hotspot-controller-bluetooth.py" +
              "<user> <network_interface> <hotspot_ssid> <hotspot_password>\"")
        print("Running in emergency mode!")
        emergency_mode_led()
Esempio n. 12
0
class BluetoothOffer:
    def __init__(self, key, port=3, size=1024):
        self.key = key
        self.port = port
        self.size = size
        self.server_socket = None
        self.message_def = None
        self.stopped = False
        self.code = None

    @inlineCallbacks
    def start(self):
        self.stopped = False
        message = "Back"
        success = False
        try:
            while not self.stopped and not success:
                # server_socket.accept() is not stoppable. So with select we can call accept()
                # only when we are sure that there is already a waiting connection
                ready_to_read, ready_to_write, in_error = yield threads.deferToThread(
                    select.select, [self.server_socket], [], [], 0.5)
                if ready_to_read:
                    # We are sure that a connection is available, so we can call
                    # accept() without deferring it to a thread
                    client_socket, address = self.server_socket.accept()
                    key_data = get_public_key_data(self.key.fingerprint)
                    kd_decoded = key_data.decode('utf-8')
                    yield threads.deferToThread(client_socket.sendall, kd_decoded)
                    log.info("Key has been sent")
                    client_socket.shutdown(socket.SHUT_RDWR)
                    client_socket.close()
                    success = True
                    message = None
        except Exception as e:
            log.error("An error occurred: %s" % e)
            success = False
            message = e

        returnValue((success, message))

    def allocate_code(self):
        try:
            code = get_local_bt_address().upper()
        except dbus.exceptions.DBusException as e:
            if e.get_dbus_name() == "org.freedesktop.systemd1.NoSuchUnit":
                log.info("No Bluetooth devices found, probably the bluetooth service is not running")
            elif e.get_dbus_name() == "org.freedesktop.DBus.Error.UnknownObject":
                log.info("No Bluetooth devices available")
            else:
                log.error("An unexpected error occurred %s", e.get_dbus_name())
            self.code = None
            return None
        if self.server_socket is None:
            self.server_socket = BluetoothSocket(RFCOMM)
            # We can also bind only the mac found with get_local_bt_address(), anyway
            # even with multiple bt in a single system BDADDR_ANY is not a problem
            self.server_socket.bind((socket.BDADDR_ANY, PORT_ANY))
            # Number of unaccepted connections that the system will allow before refusing new connections
            backlog = 1
            self.server_socket.listen(backlog)
            log.info("sockname: %r", self.server_socket.getsockname())
        port = self.server_socket.getsockname()[1]
        log.info("BT Code: %s %s", code, port)
        bt_data = "BT={0};PT={1}".format(code, port)
        return bt_data

    def stop(self):
        log.debug("Stopping bt receive")
        self.stopped = True
        if self.server_socket:
            self.server_socket.shutdown(socket.SHUT_RDWR)
            self.server_socket.close()
            self.server_socket = None
Esempio n. 13
0
class BluetoothOffer:
    def __init__(self, key, port=3, size=1024):
        self.key = key
        self.port = port
        self.size = size
        self.server_socket = None
        self.message_def = None
        self.stopped = False

    @inlineCallbacks
    def start(self):
        self.stopped = False
        message = "Back"
        success = False
        try:
            while not self.stopped and not success:
                # server_socket.accept() is not stoppable. So with select we can call accept()
                # only when we are sure that there is already a waiting connection
                ready_to_read, ready_to_write, in_error = yield threads.deferToThread(
                    select.select, [self.server_socket], [], [], 0.5)
                if ready_to_read:
                    # We are sure that a connection is available, so we can call
                    # accept() without deferring it to a thread
                    client_socket, address = self.server_socket.accept()
                    key_data = get_public_key_data(self.key.fingerprint)
                    kd_decoded = key_data.decode('utf-8')
                    yield threads.deferToThread(client_socket.sendall,
                                                kd_decoded)
                    log.info("Key has been sent")
                    client_socket.shutdown(socket.SHUT_RDWR)
                    client_socket.close()
                    success = True
                    message = None
        except Exception as e:
            log.error("An error occurred: %s" % e)
            success = False
            message = e

        returnValue((success, message))

    def allocate_code(self):
        """Acquires and returns a string suitable for finding the key via Bluetooth.
        Returns None if no powered on adapter could be found."""
        # TODO: when we have magic-wormhole we should perform this operation in async
        # and show the loading spinning wheel
        bt_data = None
        try:
            code = get_local_bt_address().upper()
        except NoBluezDbus as e:
            log.debug("Bluetooth service seems to be unavailable: %s", e)
        except NoAdapter as e:
            log.debug("Bluetooth adapter is not available: %s", e)
        except UnpoweredAdapter as e:
            log.debug("Bluetooth adapter is turned off: %s", e)
        else:
            if self.server_socket is None:
                self.server_socket = BluetoothSocket(RFCOMM)
                # We create a bind with the Bluetooth address we have in the system
                self.server_socket.bind((code, PORT_ANY))
                # Number of unaccepted connections that the system will allow before refusing new connections
                backlog = 1
                self.server_socket.listen(backlog)
                log.info("sockname: %r", self.server_socket.getsockname())
            port = self.server_socket.getsockname()[1]
            log.info("BT Code: %s %s", code, port)
            bt_data = "BT={0};PT={1}".format(code, port)
        return bt_data

    def stop(self):
        log.debug("Stopping bt receive")
        self.stopped = True
        if self.server_socket:
            self.server_socket.shutdown(socket.SHUT_RDWR)
            self.server_socket.close()
            self.server_socket = None
class BluetoothInterface(BaseInterface):
    """The Bluetooth interface definition for communication with wireless client devices."""

    __interface_name__ = 'bluetooth'

    def __init__(self, controller):
        """
        Initializes a bluetooth service that may be consumed by a remote client.

        Arguments
        ---------
            controller : controllers.base.BaseController
                the parent controller that is instantiated this interface

        """
        super(BluetoothInterface, self).__init__()
        self.controller = controller
        self.client_sock = None
        self.client_info = None
        self.rfcomm_channel = None
        self.service_name = self.get_setting('service_name')
        self.service_uuid = self.get_setting('service_uuid')
        self.server_sock = None
        self.thread = None

    def connect(self):
        """Creates a new thread that listens for an incoming bluetooth RFCOMM connection."""
        LOGGER.info('creating thread for bluetooth interface...')
        self.thread = threading.Thread(
            target=self.listen_for_rfcomm_connection)
        self.thread.daemon = True
        self.thread.start()

    def listen_for_rfcomm_connection(self):
        """
        Starts bluetooth interfaces
        """
        # prepare bluetooth server
        self.server_sock = BluetoothSocket(RFCOMM)
        self.server_sock.bind(("", PORT_ANY))
        self.server_sock.listen(1)
        self.rfcomm_channel = self.server_sock.getsockname()[1]

        # start listening for incoming connections
        advertise_service(
            self.server_sock,
            self.service_name,
            service_id=self.service_uuid,
            service_classes=[self.service_uuid, SERIAL_PORT_CLASS],
            profiles=[SERIAL_PORT_PROFILE])
        LOGGER.info('waiting for connection on RFCOMM channel %d' %
                    self.rfcomm_channel)

        # accept received connection
        self.client_sock, self.client_info = self.server_sock.accept()
        self.state = self.__states__.STATE_CONNECTED
        LOGGER.info('accepted connection from %r', self.client_info)

        # start listening for data
        self.consume_bus()

    def disconnect(self):
        """
        Closes Bluetooth connection and resets handle
        """
        LOGGER.info('destroying bluetooth interface...')
        self.state = self.__states__.STATE_DISCONNECTING
        if self.client_sock and hasattr(self.client_sock, 'close'):
            self.client_sock.close()
            self.client_sock = None
        if self.server_sock and hasattr(self.server_sock, 'close'):
            self.server_sock.close()
            self.server_sock = None

        # reset the bluetooth interface
        self.thread = None
        self.perform_hci0_reset()
        self.state = self.__states__.STATE_READY

    @staticmethod
    def perform_hci0_reset():
        """Resets the bluetooth hci0 device via hciconfig command line interface."""
        try:
            LOGGER.info('performing hci0 down/up...')
            subprocess.Popen('sudo hciconfig hci0 down',
                             shell=True).communicate()
            subprocess.Popen('sudo hciconfig hci0 up',
                             shell=True).communicate()
            LOGGER.info('hci0 down/up has completed')
        except Exception as exception:
            LOGGER.exception("Failed to restart hci0 - %r", exception)

    def receive(self, data):
        """
        Processes received data from Bluetooth socket

        Arguments
        ---------
            data : basestring
                the data received from the bluetooth connection

        """
        try:
            packet = json.loads(data)
            LOGGER.info('received packet via bluetooth: %r', packet['data'])

            # invoke bound method (if set)
            if self.receive_hook and hasattr(self.receive_hook, '__call__'):
                self.receive_hook(packet['data'].decode('hex'))

        except Exception as exception:
            LOGGER.exception('error: %r', exception)

    def send(self, data):
        """
        Sends data via Bluetooth socket connection

        Arguments
        ---------
            data : basestring
                the data to be sent via this interface

        """
        if self.state != self.__states__.STATE_CONNECTED:
            LOGGER.error('error: send() was called but state is not connected')
            return False

        try:
            LOGGER.info('sending IBUSPacket(s)...')
            packets = []
            for packet in data:
                packets.append(packet.as_serializable_dict())

            # encapsulate ibus packets and send
            data = {
                "data": json.dumps(packets)
            }  # TODO : is an inner json.dumps necessary?
            LOGGER.info(data)
            self.client_sock.send(json.dumps(data))
        except Exception as exception:
            # socket was closed, graceful restart
            LOGGER.exception('bt send: %r', exception.message)
            self.reconnect()

    def consume_bus(self):
        """
        Start listening for incoming data
        """
        try:
            LOGGER.info('starting to listen for bluetooth data...')
            read_buffer_length = self.get_setting('read_buffer_length', int)

            while self.client_sock:
                data = self.client_sock.recv(read_buffer_length)
                if len(data) > 0:
                    self.receive(data)

        except Exception as exception:
            LOGGER.exception('android device was disconnected - %r', exception)
            self.reconnect()
Esempio n. 15
0
File: bt.py Progetto: MDP-15/Rasbpi
class BluetoothConn(ServerInterface):
    def __init__(self, config: ProjectConfig):
        self.conn = None
        self.client = None
        self._connected = False

        self.config = config

        self.address = self.config.get('BT_ADDRESS')
        self.port = int(self.config.get('BT_PORT'))

    def get_name(self) -> str:
        return format(
            f'Bluetooth connection on {self.address} port {self.port}')

    def get_tags(self) -> dict:
        return {'ANDROID': True, 'BT': True}

    def is_connected(self) -> bool:
        return self._connected

    def connect(self):
        try:
            self.conn = BluetoothSocket(
                bluetooth.RFCOMM)  # use RFCOMM protocol
            self.conn.bind(
                (self.address,
                 self.port))  # empty address; use any available adapter
            self.address, self.port = self.conn.getsockname()

            self.conn.listen(1)

            uuid = self.config.get('BT_UUID')
            bluetooth.advertise_service(
                sock=self.conn,
                name='MDP-Group-15-Bluetooth-Server',
                service_id=uuid,
                service_classes=[uuid, bluetooth.SERIAL_PORT_CLASS],
                profiles=[bluetooth.SERIAL_PORT_PROFILE],
            )

            print(
                f'Listening for Bluetooth connection on {self.address} port {self.port}'
            )
            self.client, client_info = self.conn.accept()
            print(f'Connected to {client_info}')
            self._connected = True

        except Exception as e:
            print(f'Error with {self.get_name()}: {e}')
            self.disconnect()
            raise ConnectionError

    def read(self):
        try:
            data = self.client.recv(1024)
            # data = data.decode('utf-8')
            if not data:
                raise ConnectionError('No transmission')
            data_dict = json.loads(data)
            print(f'Received from Android device: {data}')
            return self.format_data(data_dict)
        except Exception as e:
            print(f'Error with reading from {self.get_name()}: {e}')
            #print('Reconnecting...')
            #self.disconnect()
            #raise ConnectionError

    def write(self, message):
        try:
            json_str = json.dumps(message)
            byte_msg = bytes(json_str, encoding='utf-8')
            self.client.send(byte_msg)
            print(f'Sent to Android device: {byte_msg}')

        except Exception as e:
            print(f'Error with writing {message} to {self.get_name()}: {e}')
            #print('Reconnecting...')
            #self.disconnect()
            raise ConnectionError

    def disconnect(self):
        if self.conn:
            self.conn.close()
            print('Terminating server socket..')

        if self.client:
            self.client.close()
            print('Terminating client socket..')

        self._connected = False
Esempio n. 16
0
#!/usr/bin/env python3

from bluetooth import BluetoothSocket, RFCOMM, PORT_ANY, advertise_service, SERIAL_PORT_CLASS, SERIAL_PORT_PROFILE

server_sock = BluetoothSocket(RFCOMM)
server_sock.bind(("", PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

uuid = "a140ff7b-6539-40fe-9481-671108c144d6"

advertise_service(server_sock, "PenPi Service", uuid)

print("Waiting for connection on RFCOMM channel %d" % port)

client_sock, client_info = server_sock.accept()

print("Accepted connection from ", client_info)

try:
    while True:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        print("received [%s]" % data)
except IOError:
    pass

print("disconnected")

client_sock.close()
Esempio n. 17
0
def launch_hub_bluetooth_server(config_file_path):
    ''' 
    Launches the Tremium Hub bluetooth server which the Tremium Nodes connect to.

    Parameters
    ----------
    config_file_path (str) : path to the hub configuration file
    '''

    # loading Tremium Hub configurations
    config_manager = HubConfigurationManager(config_file_path)
    log_file_path = os.path.join(
        config_manager.config_data["hub-file-transfer-dir"],
        config_manager.config_data["bluetooth-server-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 container for connection handler handles
    connection_handlers_h = []

    try:

        # creating socket to listen for new connections
        listener_s = BluetoothSocket()
        listener_s.bind(
            (config_manager.config_data["bluetooth-adapter-mac-server"],
             config_manager.config_data["bluetooth-port"]))
        listener_s.listen(1)

        # advertising the listenning connection
        advertise_service(listener_s, config_manager.config_data["hub-id"])

        bind_address = listener_s.getsockname()
        time_str = datetime.datetime.fromtimestamp(
            time.time()).strftime('%Y-%m-%d_%H-%M-%S')
        logging.info(
            "{0} - Hub Bluetooth server listening on address : {1}".format(
                time_str, bind_address))

    except Exception as e:
        time_str = datetime.datetime.fromtimestamp(
            time.time()).strftime('%Y-%m-%d_%H-%M-%S')
        logging.error(
            "{0} - Hub Bluetooth server failed to create listener socket : {1}"
            .format(time_str, e))
        raise

    while True:

        try:

            # blocking until a new connection occurs, then create connection handler
            client_s, remote_address = listener_s.accept()
            client_s.settimeout(
                config_manager.config_data["bluetooth-comm-timeout"])
            connection_handler = HubServerConnectionHandler(
                config_file_path, client_s, remote_address)

            # launching connection handler in a seperate process
            process_h = Process(target=connection_handler.handle_connection,
                                args=())
            process_h.start()
            connection_handlers_h.append(process_h)

            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.info(
                "{0} - Hub Bluetooth server accepted and is handling connection from remote : {1}\
                         ".format(time_str, remote_address))

            #regular check to clear dead handles
            for handler_h in connection_handlers_h:
                if handler_h is not None:
                    connection_handlers_h.remove(handler_h)

        except Exception as e:

            # killing all connection handler processes still running
            for handler_h in connection_handlers_h:
                if handler_h.exitcode is None:
                    handler_h.terminate()

            time_str = datetime.datetime.fromtimestamp(
                time.time()).strftime('%Y-%m-%d_%H-%M-%S')
            logging.error(
                "{0} - Hub Bluetooth server failed to handle incoming connection : {1}"
                .format(time_str, e))
            raise
Esempio n. 18
0
def run_bt_server(end_event, device_name, account):
    """Adapted from: https://github.com/EnableTech/raspberry-bluetooth-demo"""
    server_sock = BluetoothSocket(RFCOMM)

    server_sock.bind(("", PORT_ANY))
    server_sock.listen(1)

    port = server_sock.getsockname()[1]
    print("listening on port %d" % port)

    uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
    try:
        advertise_service(
            server_sock,
            device_name,
            service_id=uuid,
            service_classes=[uuid, SERIAL_PORT_CLASS],
            profiles=[SERIAL_PORT_PROFILE],
            # protocols=[OBEX_UUID],
        )
    except BluetoothError as e:
        print('ERROR: Bluetooth Error:{}.\n Quiting bluetooth server. Is your '
              'bluetooth setup correctly? Do you have sudo privileges?'.format(
                  e))
        return

    print("Waiting for connection on RFCOMM channel %d" % port)

    client_sock, client_info = server_sock.accept()
    print("Accepted connection from ", client_info)
    client_sock.setblocking(0)

    bufferdata = bytearray()
    try:
        while not end_event.is_set():
            ready = select.select([client_sock], [], [], 5)
            if not ready[0]:
                break
            data = client_sock.recv(1024)
            if len(data) == 0:
                break
            print("received [%s]" % data)
            bufferdata = bufferdata + data
            print(bufferdata)
            try:
                end = bufferdata.index(b'\n')
                our_data = bufferdata[0:end].strip(b'\r')
                if len(bufferdata) > end:
                    bufferdata = bufferdata[end + 1:]
                else:
                    bufferdata = bytearray()
                bluetooth_process(our_data, client_sock, account)
            except ValueError:
                pass

    except IOError:
        pass
    print("bluetooth server disconnected")

    client_sock.close()
    server_sock.close()
    print("all done")