'''
Bluetooth socket support

Copyright 2018  <NAME>, <NAME>, <NAME>, <NAME>, <NAME>

MIT License
'''

import os

import bluetooth as bt

class BluetoothServer(object):
    '''
    Provides an abstract class for serving sockets over Bluetooth.  You call the constructor and the start()
    method.  You must implement the method handleMessage(self, message) to handle messages from the client.
    '''

    def __init__(self):
        '''
        Constructor
        '''

        # Arbitrary service UUID to advertise
        self.uuid = "7be1fcb3-5776-42fb-91fd-2ee7b5bbb86d"

        self.client_sock = None

    def start(self):
        '''
        Serves a socket on the default port, listening for clients.  Upon client connection, runs a loop to 
        that receives period-delimited messages from the client and calls the sub-class's 
        handleMessage(self, message) method.   Sub-class can call send(self, message) to send a 
        message back to the client.   Begins listening again after client disconnects.
        '''

        # Make device visible
        os.system("hciconfig hci0 piscan")

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

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

        # Start listening
        server_sock.listen(1)

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

        # Start advertising the service
        bt.advertise_service(server_sock, "RaspiBtSrv",
                           service_id=self.uuid,
                           service_classes=[self.uuid, bt.SERIAL_PORT_CLASS],
                           profiles=[bt.SERIAL_PORT_PROFILE])

        # Outer loop: listen for connections from client
        while True:

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

            try:

                # This will block until we get a new connection
                self.client_sock, client_info = server_sock.accept()
                print("Accepted connection from " +  str(client_info))

                # Track strings delimited by '.'
                s = ''

                while True:

                    c = self.client_sock.recv(1).decode('utf-8')

                    if c == '.' and len(s) > 0:
                        self.handleMessage(s)
                        s = ''
                    else:
                        s += c

            except IOError:
                pass

            except KeyboardInterrupt:

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

                server_sock.close()

                print("Server going down")
                break

    def send(self, message):
        '''
        Appends a period to your message and sends the message back to the client.
        '''
        
        self.client_sock.send((message+'.').encode('utf-8'))

'''
Bluetooth socket support

Copyright 2018  <NAME>, <NAME>, <NAME>, <NAME>, <NAME>

MIT License
'''

import os

import bluetooth as bt

class BluetoothServer(object):
    '''
    Provides an abstract class for serving sockets over Bluetooth.  You call the constructor and the start()
    method.  You must implement the method handleMessage(self, message) to handle messages from the client.
    '''

    def __init__(self):
        '''
        Constructor
        '''

        # Arbitrary service UUID to advertise
        self.uuid = "7be1fcb3-5776-42fb-91fd-2ee7b5bbb86d"

        self.client_sock = None

    def start(self):
        '''
        Serves a socket on the default port, listening for clients.  Upon client connection, runs a loop to 
        that receives period-delimited messages from the client and calls the sub-class's 
        handleMessage(self, message) method.   Sub-class can call send(self, message) to send a 
        message back to the client.   Begins listening again after client disconnects.
        '''

        # Make device visible
        os.system("hciconfig hci0 piscan")

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

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

        # Start listening
        server_sock.listen(1)

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

        # Start advertising the service
        bt.advertise_service(server_sock, "RaspiBtSrv",
                           service_id=self.uuid,
                           service_classes=[self.uuid, bt.SERIAL_PORT_CLASS],
                           profiles=[bt.SERIAL_PORT_PROFILE])

        # Outer loop: listen for connections from client
        while True:

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

            try:

                # This will block until we get a new connection
                self.client_sock, client_info = server_sock.accept()
                print("Accepted connection from " +  str(client_info))

                # Track strings delimited by '.'
                s = ''

                while True:

                    c = self.client_sock.recv(1).decode('utf-8')

                    if c == '.' and len(s) > 0:
                        self.handleMessage(s)
                        s = ''
                    else:
                        s += c

            except IOError:
                pass

            except KeyboardInterrupt:

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

                server_sock.close()

                print("Server going down")
                break

    def send(self, message):
        '''
        Appends a period to your message and sends the message back to the client.
        '''
        
        self.client_sock.send((message+'.').encode('utf-8'))

Bluetooth socket support  Copyright 2018  <NAME>, <NAME>, <NAME>, <NAME>, <NAME>  MIT License Provides an abstract class for serving sockets over Bluetooth.  You call the constructor and the start()     method.  You must implement the method handleMessage(self, message) to handle messages from the client. Constructor # Arbitrary service UUID to advertise Serves a socket on the default port, listening for clients.  Upon client connection, runs a loop to          that receives period-delimited messages from the client and calls the sub-class's          handleMessage(self, message) method.   Sub-class can call send(self, message) to send a          message back to the client.   Begins listening again after client disconnects. # Make device visible # Create a new server socket using RFCOMM protocol # Bind to any port # Start listening # Get the port the server socket is listening # Start advertising the service # Outer loop: listen for connections from client # This will block until we get a new connection # Track strings delimited by '.' Appends a period to your message and sends the message back to the client.