# Path: IoTPy/sfp.py
# def encode_sfp(command, args):
#     """
#     Construct binary SFP command.
# 
#     :param command: SFP command ID.
#     :type command: int
#     :param args: A list of SFP arguments, which can be either an integer or a byte collection (string).
#     :type args: list
#     :return: Binary SFP command.
#     :rtype: str
#     """
#     functions = {
#         binary_type: _encode_bytes,
#         integer_types[0]: _encode_int   # [0] - kinda hack to get class int
#     }
# 
#     sfp_command = pack('B', command) + b''.join(functions[type(arg)](arg) for arg in args)
#     sfp_command = b'\xd4' + pack('>H', len(sfp_command)) + sfp_command
#     return sfp_command
# 
# def decode_sfp(io_buffer):
#     """
#     Decode SFP command from byte buffer.
# 
#     :param io_buffer: A byte buffer which stores SFP command.
#     :type io_buffer: bytes string
#     :return: SFP function ID and arguments list.
#     """
#     if io_buffer[0:1] != b'\xd4':
#         return
#     command_length = unpack('>H', io_buffer[1:3])[0] + 3    # get SFP command length located in two bytes
#     sfp_command = unpack('B', io_buffer[3:4])[0]            # get SFP command code
#     pointer = 4
#     args = []
#     while pointer < command_length:
#         arg_type = ord(io_buffer[pointer:pointer + 1])
#         pointer += 1
#         if arg_type < 64:                    # short int
#             args.append(arg_type)
#         elif arg_type < 128:                    # short str
#             arg_len = arg_type & 0x3f
#             args.append(io_buffer[pointer:pointer + arg_len])
#             pointer += arg_len
#         else:
#             arg_len = arg_type & 0x0f
#             if arg_len < 4:            # decoding integers
#                 if arg_len == 0:
#                     args.append(ord(io_buffer[pointer:pointer + 1]))
#                 elif arg_len == 1:
#                     args.append(unpack('>H', io_buffer[pointer:pointer + 2])[0])
#                 elif arg_len == 2:
#                     args.append(unpack('>I', b'\x00' + io_buffer[pointer:pointer + 3])[0])
#                 elif arg_len == 3:
#                     args.append(unpack('>I', io_buffer[pointer:pointer + 4])[0])
#                 pointer += arg_len + 1
#             else:
#                 if arg_type == 0xc4:        # decoding strings
#                     arg_len = ord(io_buffer[pointer:pointer + 1])
#                 elif arg_type == 0xc5:
#                     arg_len = unpack('>H', io_buffer[pointer:pointer + 2])[0]
#                     pointer += 1
#                 else:
#                     raise IoTPy_APIError("UPER API: Bad parameter type in decodeSFP method.")
#                 pointer += 1
#                 args.append(io_buffer[pointer:pointer + arg_len])
#                 pointer += arg_len
#     return sfp_command, args
# 
# Path: IoTPy/errors.py
# class IoTPy_APIError(Exception):
#     pass


import platform
import glob
import serial
from IoTPy.sfp import encode_sfp, decode_sfp
from IoTPy.errors import IoTPy_APIError
from uuid import UUID
    elif my_platform == "Linux":
        ports_list = glob.glob("/dev/ttyACM*")

    for my_port in ports_list:
        try:
            port_to_try = serial.Serial(
                port=my_port,
                baudrate=230400,  # virtual com port on USB is always max speed
                parity=serial.PARITY_ODD,
                stopbits=serial.STOPBITS_ONE,
                bytesize=serial.EIGHTBITS,
                timeout=1
            )
            komanda_siuntimui = encode_sfp(255, [])
            port_to_try.write(komanda_siuntimui)
            response = port_to_try.read(1)    # read one, blocking
            n = port_to_try.inWaiting()        # look if there is more
            if n:
                response = response + port_to_try.read(n)
                sfp = decode_sfp(response)

                if sfp[0] == 255:  # device info sfp packet
                    dev_uid = UUID(bytes=sfp[1][1])
                    if not uid or uid == dev_uid:
                        return port_to_try

            port_to_try.close()
        except:
            pass


# Path: IoTPy/sfp.py
# def encode_sfp(command, args):
#     """
#     Construct binary SFP command.
# 
#     :param command: SFP command ID.
#     :type command: int
#     :param args: A list of SFP arguments, which can be either an integer or a byte collection (string).
#     :type args: list
#     :return: Binary SFP command.
#     :rtype: str
#     """
#     functions = {
#         binary_type: _encode_bytes,
#         integer_types[0]: _encode_int   # [0] - kinda hack to get class int
#     }
# 
#     sfp_command = pack('B', command) + b''.join(functions[type(arg)](arg) for arg in args)
#     sfp_command = b'\xd4' + pack('>H', len(sfp_command)) + sfp_command
#     return sfp_command
# 
# def decode_sfp(io_buffer):
#     """
#     Decode SFP command from byte buffer.
# 
#     :param io_buffer: A byte buffer which stores SFP command.
#     :type io_buffer: bytes string
#     :return: SFP function ID and arguments list.
#     """
#     if io_buffer[0:1] != b'\xd4':
#         return
#     command_length = unpack('>H', io_buffer[1:3])[0] + 3    # get SFP command length located in two bytes
#     sfp_command = unpack('B', io_buffer[3:4])[0]            # get SFP command code
#     pointer = 4
#     args = []
#     while pointer < command_length:
#         arg_type = ord(io_buffer[pointer:pointer + 1])
#         pointer += 1
#         if arg_type < 64:                    # short int
#             args.append(arg_type)
#         elif arg_type < 128:                    # short str
#             arg_len = arg_type & 0x3f
#             args.append(io_buffer[pointer:pointer + arg_len])
#             pointer += arg_len
#         else:
#             arg_len = arg_type & 0x0f
#             if arg_len < 4:            # decoding integers
#                 if arg_len == 0:
#                     args.append(ord(io_buffer[pointer:pointer + 1]))
#                 elif arg_len == 1:
#                     args.append(unpack('>H', io_buffer[pointer:pointer + 2])[0])
#                 elif arg_len == 2:
#                     args.append(unpack('>I', b'\x00' + io_buffer[pointer:pointer + 3])[0])
#                 elif arg_len == 3:
#                     args.append(unpack('>I', io_buffer[pointer:pointer + 4])[0])
#                 pointer += arg_len + 1
#             else:
#                 if arg_type == 0xc4:        # decoding strings
#                     arg_len = ord(io_buffer[pointer:pointer + 1])
#                 elif arg_type == 0xc5:
#                     arg_len = unpack('>H', io_buffer[pointer:pointer + 2])[0]
#                     pointer += 1
#                 else:
#                     raise IoTPy_APIError("UPER API: Bad parameter type in decodeSFP method.")
#                 pointer += 1
#                 args.append(io_buffer[pointer:pointer + arg_len])
#                 pointer += arg_len
#     return sfp_command, args
# 
# Path: IoTPy/errors.py
# class IoTPy_APIError(Exception):
#     pass


# Path: IoTPy/detect_sfp_serial.py
import platform
import glob
import serial
from IoTPy.sfp import encode_sfp, decode_sfp
from IoTPy.errors import IoTPy_APIError
from uuid import UUID

    elif my_platform == "Linux":
        ports_list = glob.glob("/dev/ttyACM*")

    for my_port in ports_list:
        try:
            port_to_try = serial.Serial(
                port=my_port,
                baudrate=230400,  # virtual com port on USB is always max speed
                parity=serial.PARITY_ODD,
                stopbits=serial.STOPBITS_ONE,
                bytesize=serial.EIGHTBITS,
                timeout=1
            )
            komanda_siuntimui = encode_sfp(255, [])
            port_to_try.write(komanda_siuntimui)
            response = port_to_try.read(1)    # read one, blocking
            n = port_to_try.inWaiting()        # look if there is more
            if n:
                response = response + port_to_try.read(n)
                sfp = decode_sfp(response)

                if sfp[0] == 255:  # device info sfp packet
                    dev_uid = UUID(bytes=sfp[1][1])
                    if not uid or uid == dev_uid:
                        return port_to_try

            port_to_try.close()
        except:
            pass


    raise IoTPy_APIError("No SFP device was found on serial ports.")