Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple fixes to bring the code to work with latest version of Python3 #1

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
venv/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sudo pip install pybluez`
You've installed the Python 2 version of the bluez bindings. Either run the script using python2 or install the Python 3 bindings. Since they aren't packaged, you would need to install them using pip:

```
sudo python3 -m pip install pybluez`
sudo python3 -m pip install git+https://github.com/pybluez/pybluez.git
```

### Setup your Raspberry Pi
Expand Down
245 changes: 172 additions & 73 deletions bleClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,151 +4,250 @@
# Auth: P Srinivas Rao
# Desc: Bluetooth client application that uses RFCOMM sockets
# intended for use with rfcomm-server
import os
import sys
import os
import time
import logging
import logging.config
import json #Uses JSON package
import cPickle as pickle #Serializing and de-serializing a Python object structure
from bluetooth import * #Python Bluetooth library
import json # Uses JSON package

# import cPickle as pickle # Serializing and de-serializing a Python object structure
import pickle

import bluetooth # Python Bluetooth library

logger = logging.getLogger("bleClientLogger")

logger = logging.getLogger('bleClientLogger')

def startLogging(
default_path='configLogger.json',
default_level=logging.INFO,
env_key='LOG_CFG'
default_path="configLogger.json", default_level=logging.INFO, env_key="LOG_CFG"
):
#Setup logging configuration
"""Init the logging subsystem"""
# Setup logging configuration
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'rt') as f:
config = json.load(f)
with open(path, "rt", encoding="utf-8") as file_handle:
config = json.load(file_handle)
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)


class bleClient:
def __init__(self, clientSocket=None):
if clientSocket is None:
self.clientSocket = clientSocket
self.bleService = None
"""Provide Bluetooth Client interface"""

def __init__(self, client_socket=None):
if client_socket is None:
self.client_socket = client_socket
self.ble_service = None
self.addr = None
self.uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
self.jsonFile ="text.json"
self.jsonObj = None
self.json_file = "text.json"
self.json_obj = None
else:
self.clientSocket = clientSocket
self.client_socket = client_socket

def getBluetoothServices(self):
"""Get BT service"""
try:
logger.info("Searching for Bluetooth services ...")
for reConnect in range(2, 4):
bleService = find_service( uuid = self.uuid, address = self.addr )
if len(bleService) == 0:
logger.info("Re-connecting Bluetooth services : %d attempt", reConnect)
logger.info("Searching for Bluetooth services ...")
for reconnect in range(2, 4):
ble_service = bluetooth.find_service(uuid=self.uuid, address=self.addr)
if len(ble_service) == 0:
logger.info(
"Re-connecting Bluetooth services : %d attempt", reconnect
)
else:
break
if not bleService: raise SystemExit(), KeyboardInterrupt()
if not ble_service:
raise Exception([SystemExit(), KeyboardInterrupt()])
else:
logger.info("Found Bluetooth services ..")
logger.info("Protocol\t: %s", bleService[0]['protocol'])
logger.info("Name\t\t: %s", bleService[0]['name'])
logger.info("Service-id\t: %s", bleService[0]['service-id'])
logger.info("Profiles\t: %s", bleService[0]['profiles'])
logger.info("Service-class\t: %s", bleService[0]['service-classes'])
logger.info("Host\t\t: %s", bleService[0]['host'])
logger.info("Provider\t: %s", bleService[0]['provider'])
logger.info("Port\t\t: %s", bleService[0]['port'])
logger.info("Description\t: %s", bleService[0]['description'])
self.bleService = bleService
except (Exception, BluetoothError, SystemExit, KeyboardInterrupt) as e:
logger.error("Couldn't find the RaspberryPi Bluetooth service : Invalid uuid", exc_info=True)
logger.info("Protocol\t: %s", ble_service[0]["protocol"])
logger.info("Name\t\t: %s", ble_service[0]["name"])
logger.info("Service-id\t: %s", ble_service[0]["service-id"])
logger.info("Profiles\t: %s", ble_service[0]["profiles"])
logger.info("Service-class\t: %s", ble_service[0]["service-classes"])
logger.info("Host\t\t: %s", ble_service[0]["host"])
logger.info("Provider\t: %s", ble_service[0]["provider"])
logger.info("Port\t\t: %s", ble_service[0]["port"])
logger.info("Description\t: %s", ble_service[0]["description"])
self.ble_service = ble_service
except (
Exception,
bluetooth.BluetoothError,
SystemExit,
KeyboardInterrupt,
) as _:
logger.error(
"Couldn't find the RaspberryPi Bluetooth service : Invalid uuid",
exc_info=True,
)
return False

return True

def getBluetoothSocket(self):
"""Get the BT socket"""
try:
self.clientSocket=BluetoothSocket( RFCOMM )
logger.info("Bluetooth client socket successfully created for RFCOMM service ...")
except (Exception, BluetoothError, SystemExit, KeyboardInterrupt) as e:
logger.error("Failed to create the bluetooth client socket for RFCOMM service ... ", exc_info=True)
self.client_socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
logger.info(
"Bluetooth client socket successfully created for RFCOMM service ... "
)
except (
Exception,
bluetooth.BluetoothError,
SystemExit,
KeyboardInterrupt,
) as _:
logger.error(
"Failed to create the bluetooth client socket for RFCOMM service ... ",
exc_info=True,
)

def getBluetoothConnection(self):
try:
bleServiceInfo = self.bleService[0]
logger.info("Connecting to \"%s\" on %s with port %s" % (bleServiceInfo['name'], bleServiceInfo['host'], bleServiceInfo['port']))
self.clientSocket.connect((bleServiceInfo['host'], bleServiceInfo['port']))
logger.info("Connected successfully to %s "% (bleServiceInfo['name']))
except (Exception, BluetoothError, SystemExit, KeyboardInterrupt) as e:
logger.error("Failed to connect to \"%s\" on address %s with port %s" % (bleServiceInfo['name'], bleServiceInfo['host'], bleServiceInfo['port']), exc_info=True)
"""Get the BT connection"""
ble_service_info = self.ble_service[0]
msg = (
f'Connecting to "{ble_service_info["name"]}" on '
f'{ble_service_info["host"]} with port {ble_service_info["port"]}'
)
logger.info(msg)

attempt = 0
# Retry a few times
while True:
attempt += 1

try:
self.client_socket.connect(
(ble_service_info["host"], ble_service_info["port"])
)
msg = f"Connected successfully to {ble_service_info['name']}"
logger.info(msg)
break
except (
Exception,
bluetooth.BluetoothError,
SystemExit,
KeyboardInterrupt,
) as _:
msg = (
f'Failed to connect to "{ble_service_info["name"]}" on '
f'address {ble_service_info["host"]} with port {ble_service_info["port"]}'
)
logger.error(
msg,
exc_info=True,
)

time.sleep(1)
if attempt > 5:
return False

return True

def readJsonFile(self):
"""Read JSON file"""
try:
jsonFileObj = open(self.lsonFile,"r")
logger.info("File successfully uploaded to %s" % (jsonFileObj))
self.jsonObj = json.load(jsonFileObj)
logger.info("Content loaded successfully from the %s file" %(self.jsonFile))
jsonFileObj.close()
except (Exception, IOError) as e:
logger.error("Failed to load content from the %s" % (self.jsonFile), exc_info=True)
json_file_obj = open(self.json_file, "r", encoding="utf-8")
msg = "File successfully uploaded to %s" % (json_file_obj)
logger.info(msg)
self.json_obj = json.load(json_file_obj)
msg = "Content loaded successfully from the %s file" % (self.json_file)
logger.info(msg)
json_file_obj.close()
except (Exception, IOError) as _:
msg = "Failed to load content from the %s" % (self.json_file)
logger.error(msg, exc_info=True)

def serializeData(self):
"""Serialize the data"""
try:
serializedData = pickle.dumps(self.jsonObj)
serialized_data = pickle.dumps(self.json_obj)
logger.info("Object successfully converted to a serialized string")
return serializedData
except (Exception, pickle.PicklingError) as e:
logger.error("Failed to convert json object to serialized string", exc_info=True)
return serialized_data
except (Exception, pickle.PicklingError) as _:
logger.error(
"Failed to convert json object to serialized string", exc_info=True
)

def sendData(self, _serializedData):
def sendData(self, serialized_data):
"""Send data via BT"""
try:
logger.info("Sending data over bluetooth connection")
_serializedData =str(len(_serializedData))+ ":"+_serializedData
self.clientSocket.send(_serializedData)
_serialized_data = b""
_serialized_data += len(serialized_data).to_bytes(2, "little")
_serialized_data += b":"
_serialized_data += serialized_data
self.client_socket.send(_serialized_data)
time.sleep(0.5)
while True:
dataRecv= self.clientSocket.recv(1024)
if dataRecv in ['EmptyBufferResend', 'CorruptedBufferResend', 'DelimiterMissingBufferResend']:
self.clientSocket.send(_serializedData)
data_recv = self.client_socket.recv(1024)
if data_recv in [
"EmptyBufferResend",
"CorruptedBufferResend",
"DelimiterMissingBufferResend",
]:
self.client_socket.send(_serialized_data)
time.sleep(0.5)
logger.info("%s : Re-sending data over bluetooth connection" %(dataRecv))
msg = f"{data_recv} : Re-sending data over bluetooth connection"
logger.info(msg)
else:
break
logger.info("Data sent successfully over bluetooth connection")
except (Exception, IOError) as e:
except (Exception, IOError) as _:
logger.error("Failed to send data over bluetooth connection", exc_info=True)

def closeBluetoothSocket(self):
"""Close BT socket"""
try:
self.clientSocket.close()
self.client_socket.close()
logger.info("Bluetooth client socket successfully closed ...")
except (Exception, BluetoothError, SystemExit, KeyboardInterrupt) as e:
except (
Exception,
bluetooth.BluetoothError,
SystemExit,
KeyboardInterrupt,
) as _:
logger.error("Failed to close the bluetooth client socket ", exc_info=True)

def start(self):
"""Start the BT interface"""
# Search for the RaspberryPi Bluetooth service
self.getBluetoothServices()
res = self.getBluetoothServices()
if not res:
logger.error("Failed to get bluetooth services")
sys.exit(0)
# Create the client socket
self.getBluetoothSocket()
# Connect to bluetooth service
self.getBluetoothConnection()
res = self.getBluetoothConnection()
if not res:
logger.error("Failed to get bluetooth connection")
sys.exit(0)

def send(self):
"""Send content"""

# Load the contents from the file, which creates a new json object
self.readJsonFile()
# Convert the json object to a serialized string
serializedData = self.serializeData()
serialized_data = self.serializeData()
# Sending data over bluetooth connection
self.sendData(serializedData)
self.sendData(serialized_data)

def stop(self):
"""Stop the BT interface"""

# Disconnecting bluetooth service
self.closeBluetoothSocket()

if __name__ == '__main__':

if __name__ == "__main__":
startLogging()
logger.info("Setup logging configuration")
bleClnt = bleClient()
Expand Down
Loading