# Path: thingsboard_gateway/connectors/connector.py
# class Connector(ABC):
#     def open(self):
#     def close(self):
#     def get_name(self):
#     def is_connected(self):
#     def on_attributes_update(self, content):
#     def server_side_rpc_handler(self, content):
# 
# Path: thingsboard_gateway/tb_utility/tb_loader.py
# class TBModuleLoader:
#     PATHS = []
#     LOADED_CONNECTORS = {}
# 
#     @staticmethod
#     def find_paths():
#         root_path = path.abspath(path.dirname(path.dirname(__file__)))
#         log.debug("Root path is: " + root_path)
#         if path.exists(DEB_INSTALLATION_EXTENSION_PATH):
#             log.debug("Debian installation extensions folder exists.")
#             TBModuleLoader.PATHS.append(DEB_INSTALLATION_EXTENSION_PATH)
#         TBModuleLoader.PATHS.append(root_path + EXTENSIONS_FOLDER)
#         TBModuleLoader.PATHS.append(root_path + CONNECTORS_FOLDER)
# 
#     @staticmethod
#     def import_module(extension_type, module_name):
#         if len(TBModuleLoader.PATHS) == 0:
#             TBModuleLoader.find_paths()
#         buffered_module_name = extension_type + module_name
#         if TBModuleLoader.LOADED_CONNECTORS.get(buffered_module_name) is not None:
#             return TBModuleLoader.LOADED_CONNECTORS[buffered_module_name]
#         try:
#             for current_path in TBModuleLoader.PATHS:
#                 current_extension_path = current_path + path.sep + extension_type
#                 if path.exists(current_extension_path):
#                     for file in listdir(current_extension_path):
#                         if not file.startswith('__') and file.endswith('.py'):
#                             try:
#                                 module_spec = spec_from_file_location(module_name, current_extension_path + path.sep + file)
#                                 log.debug(module_spec)
# 
#                                 if module_spec is None:
#                                     continue
# 
#                                 module = module_from_spec(module_spec)
#                                 module_spec.loader.exec_module(module)
#                                 for extension_class in getmembers(module, isclass):
#                                     if module_name in extension_class:
#                                         log.info("Import %s from %s.", module_name, current_extension_path)
#                                         TBModuleLoader.LOADED_CONNECTORS[buffered_module_name] = extension_class[1]
#                                         return extension_class[1]
#                             except ImportError:
#                                 continue
#         except Exception as e:
#             log.exception(e)
# 
# Path: thingsboard_gateway/connectors/ble/error_handler.py
# class ErrorHandler:
#     def __init__(self, e):
#         self.e = e
# 
#     def is_char_not_found(self):
#         try:
#             if "could not be found!" in self.e.args[0]:
#                 return True
#         except IndexError:
#             return False
# 
#         return False
# 
#     def is_operation_not_supported(self):
#         try:
#             if 'not permitted' in self.e.args[1] or 'not supported' in self.e.args[1]:
#                 return True
#         except IndexError:
#             return False
# 
#         return False


from threading import Thread
from platform import system
from time import time, sleep
from bleak import BleakClient
from thingsboard_gateway.connectors.connector import log
from thingsboard_gateway.tb_utility.tb_loader import TBModuleLoader
from thingsboard_gateway.connectors.ble.error_handler import ErrorHandler
import asyncio

        self.poll_period = config.get('pollPeriod', 5000) / 1000
        self.config = {
            'extension': config.get('extension', DEFAULT_CONVERTER_CLASS_NAME),
            'telemetry': config.get('telemetry', []),
            'attributes': config.get('attributes', []),
            'attributeUpdates': config.get('attributeUpdates', []),
            'serverSideRpc': config.get('serverSideRpc', [])
        }
        self.callback = config['callback']
        self.last_polled_time = self.poll_period + 1

        self.notifying_chars = []

        self.__converter = None
        self.__load_converter()

        self.start()

    @staticmethod
    def validate_mac_address(mac_address):
        os_name = system()

        if MAC_ADDRESS_FORMAT[os_name if os_name == 'Darwin' else 'other'] not in mac_address:
            raise ValueError(f'Mac-address is invalid for {os_name} os')

        return mac_address.upper()

    def __load_converter(self):
        converter_class_name = self.config['extension']

# Path: thingsboard_gateway/connectors/connector.py
# class Connector(ABC):
#     def open(self):
#     def close(self):
#     def get_name(self):
#     def is_connected(self):
#     def on_attributes_update(self, content):
#     def server_side_rpc_handler(self, content):
# 
# Path: thingsboard_gateway/tb_utility/tb_loader.py
# class TBModuleLoader:
#     PATHS = []
#     LOADED_CONNECTORS = {}
# 
#     @staticmethod
#     def find_paths():
#         root_path = path.abspath(path.dirname(path.dirname(__file__)))
#         log.debug("Root path is: " + root_path)
#         if path.exists(DEB_INSTALLATION_EXTENSION_PATH):
#             log.debug("Debian installation extensions folder exists.")
#             TBModuleLoader.PATHS.append(DEB_INSTALLATION_EXTENSION_PATH)
#         TBModuleLoader.PATHS.append(root_path + EXTENSIONS_FOLDER)
#         TBModuleLoader.PATHS.append(root_path + CONNECTORS_FOLDER)
# 
#     @staticmethod
#     def import_module(extension_type, module_name):
#         if len(TBModuleLoader.PATHS) == 0:
#             TBModuleLoader.find_paths()
#         buffered_module_name = extension_type + module_name
#         if TBModuleLoader.LOADED_CONNECTORS.get(buffered_module_name) is not None:
#             return TBModuleLoader.LOADED_CONNECTORS[buffered_module_name]
#         try:
#             for current_path in TBModuleLoader.PATHS:
#                 current_extension_path = current_path + path.sep + extension_type
#                 if path.exists(current_extension_path):
#                     for file in listdir(current_extension_path):
#                         if not file.startswith('__') and file.endswith('.py'):
#                             try:
#                                 module_spec = spec_from_file_location(module_name, current_extension_path + path.sep + file)
#                                 log.debug(module_spec)
# 
#                                 if module_spec is None:
#                                     continue
# 
#                                 module = module_from_spec(module_spec)
#                                 module_spec.loader.exec_module(module)
#                                 for extension_class in getmembers(module, isclass):
#                                     if module_name in extension_class:
#                                         log.info("Import %s from %s.", module_name, current_extension_path)
#                                         TBModuleLoader.LOADED_CONNECTORS[buffered_module_name] = extension_class[1]
#                                         return extension_class[1]
#                             except ImportError:
#                                 continue
#         except Exception as e:
#             log.exception(e)
# 
# Path: thingsboard_gateway/connectors/ble/error_handler.py
# class ErrorHandler:
#     def __init__(self, e):
#         self.e = e
# 
#     def is_char_not_found(self):
#         try:
#             if "could not be found!" in self.e.args[0]:
#                 return True
#         except IndexError:
#             return False
# 
#         return False
# 
#     def is_operation_not_supported(self):
#         try:
#             if 'not permitted' in self.e.args[1] or 'not supported' in self.e.args[1]:
#                 return True
#         except IndexError:
#             return False
# 
#         return False


# Path: thingsboard_gateway/connectors/ble/device.py
from threading import Thread
from platform import system
from time import time, sleep
from bleak import BleakClient
from thingsboard_gateway.connectors.connector import log
from thingsboard_gateway.tb_utility.tb_loader import TBModuleLoader
from thingsboard_gateway.connectors.ble.error_handler import ErrorHandler
import asyncio


        self.poll_period = config.get('pollPeriod', 5000) / 1000
        self.config = {
            'extension': config.get('extension', DEFAULT_CONVERTER_CLASS_NAME),
            'telemetry': config.get('telemetry', []),
            'attributes': config.get('attributes', []),
            'attributeUpdates': config.get('attributeUpdates', []),
            'serverSideRpc': config.get('serverSideRpc', [])
        }
        self.callback = config['callback']
        self.last_polled_time = self.poll_period + 1

        self.notifying_chars = []

        self.__converter = None
        self.__load_converter()

        self.start()

    @staticmethod
    def validate_mac_address(mac_address):
        os_name = system()

        if MAC_ADDRESS_FORMAT[os_name if os_name == 'Darwin' else 'other'] not in mac_address:
            raise ValueError(f'Mac-address is invalid for {os_name} os')

        return mac_address.upper()

    def __load_converter(self):
        converter_class_name = self.config['extension']

        module = TBModuleLoader.import_module(self.__connector_type, converter_class_name)