Beispiel #1
0
class enlace(object):
    def __init__(self, name):
        self.fisica = fisica(
            name)  # é o serialName - nome da porta do computador
        self.rx = RX(self.fisica)  #inicializa o RX
        self.tx = TX(self.fisica)  #inicializa o TX
        self.connected = False

    def enable(self):
        self.fisica.open()
        self.rx.threadStart()
        self.tx.threadStart()

    def disable(self):
        self.rx.threadKill()
        self.tx.threadKill()
        time.sleep(1)
        self.fisica.close()

    # Método que recebe os dados em bytes (array) e envia os dados
    #usa a funcao sendBuffer do tx(pino de envio)
    def sendData(self, data):
        self.tx.sendBuffer(data)

    #Método que recebe o tamanho dos dados e retorna os dados e o len dos dados
    def getData(self, size):
        data = self.rx.getNData(size)
        return (data, len(data))

    #Método que recebe o tamanho dos dados e retorna os dados e o len dos dados apos um determinado tempo

    def getDataTime(self, size, t):
        while self.rx.getBufferLen() < size:
            if t <= 0:
                return False
            mins, secs = divmod(t, 60)  #calcula o n de min e seg
            timer = '{:02d}:{:02d}'.format(int(mins), int(secs))
            print(timer, end="\r")  #print q sobrepoe o anterior
            time.sleep(0.05)  #conta 0.05 seg
            t -= 0.05

        return self.rx.getBuffer(size)
Beispiel #2
0
class enlace(object):
    """ This class implements methods to the interface between Enlace and Application
    """
    def __init__(self, name):
        """ Initializes the enlace class
        """
        self.fisica = fisica(name)
        self.rx = RX(self.fisica)
        self.tx = TX(self.fisica)
        self.connected = False
        self.queuedPck = []
        self.receivedPck = []
        self.meta = None

    def enable(self):
        """ Enable reception and transmission
        """
        self.fisica.open()
        self.rx.threadStart()
        self.tx.threadStart()

    def disable(self):
        """ Disable reception and transmission
        """
        self.rx.threadKill()
        self.tx.threadKill()
        time.sleep(1)
        self.fisica.close()

    ################################
    # Application  interface       #
    ################################

    def listenPacket(self, timeout, size):  #valor -1111 desativa o timeout
        label = 85
        packet = None

        dic = {
            'small': 17,
            'medium':
            544,  #signature + label + thresh + pckAmount + filenameSize + content + checksum + signature : +8 +1 +2 +3 +2 +512 +8 +8
            'big': 14 + 2**10 + 16
        }  #header + payload + eop
        size = dic[size]

        while timeout > 0 or timeout == -1111:
            if (timeout != -1111):
                timeout -= 100
            time.sleep(0.1)
            if (self.rx.getBufferLen() >= size):
                packet = self.rx.getBuffer(size)
                label = packet[8]
                break

        if (packet != None and
            (packet[0:8] != 'F.A.S.T.'.encode() or packet[-8:] !=
             'S.L.O.W.'.encode())):  #confere as assinaturas de header e eop
            label = 170

        if ((label == 0 or label == 131)
                and self.checksum(packet[0:-16]) != packet[-16:-8]
            ):  #confere o checksum de header+payload contra o checksum no eop
            label = 151

        if (label == 0
                and self.getPayloadCounter(packet) != len(self.receivedPck)):
            print(self.getPayloadCounter(packet))
            label = 222

        dic = {
            255: 'SYN',
            240: 'ACK',
            222: 'MISCOUNT',
            170: 'MALFORMED',
            151: 'CORRUPTED',
            131: 'META',
            85: 'TIMEOUT',
            15: 'NACK',
            0: 'DATA'
        }

        label = dic[label]
        print("Resultado do packet ouvido: " + label)
        self.rx.clearBufferUntilSignature('F.A.S.T.'.encode())
        return (label, packet)

    def getMetaName(self, packet):
        trailingfilename = packet[16:16 + 512]
        filenamelength = int.from_bytes(packet[14:16], byteorder='big')
        filename = trailingfilename[0:filenamelength]
        return filename.decode(
            'utf-8'
        )  #torcemos para que não tenhamos que nos preocupar algo que não utf-8

    def getMetaPacketAmount(self, packet):
        return int.from_bytes(packet[11:14], byteorder='big')

    def getMetaThreshold(self, packet):
        return int.from_bytes(packet[9:11], byteorder='big')

    def getPayloadCounter(self, packet):
        return int.from_bytes(packet[11:14], byteorder='little')

    def collapseData(self):
        data = bytes(bytearray())
        i = 0
        while (i != len(self.receivedPck)):
            data += self.receivedPck[i][13:-16]
            print('azul ', self.getPayloadCounter(self.receivedPck[i]))
            i += 1
        self.receivedPck = []
        cut = (2**10 - self.getMetaThreshold(self.meta)) % (2**10)
        return data[:-cut]

    def sendPacket(self, label, number=0):
        time.sleep(
            0.2
        )  #pra dar tempo do outro se preparar pra receber, testar diminuir ou remover este valor depois

        print("Enviando packet tipo ", label)

        dic = {
            'SYN': bytes([255]),
            'ACK': bytes([240]),
            'NACK': bytes([15]),
            'META': bytes([131]),
            'DATA': bytes([0])
        }
        label = dic[label]

        if (label == bytes([255]) or label == bytes([240])
                or label == bytes([15])):

            signature = 'F.A.S.T.'.encode()

            header = signature + label

            signature = 'S.L.O.W.'.encode()

            eop = signature
            packet = header + eop

        elif (label == bytes([131])):
            packet = self.meta

        elif (label == bytes([0])):
            packet = self.queuedPck[number]

        self.tx.sendBuffer(packet)

    def packageData(self, data, filename):

        self.queuedPck = []

        #bytes do payload de cada packet: 2**10
        payloadsize = 2**10
        packetamount = ((len(data) - 1) // payloadsize) + 1

        #TODO: editar o metadata para suportar mais packets por comunicação

        ##Fazer metadata
        #Para suportar o maior número possível de filesystems, suportaremos filenames de até 512 bytes
        #tamanho máximo de um arquivo transferido por uma sprint apenas, 4Gb = 2^32, 4 bytes
        signature = 'F.A.S.T.'.encode()
        label = bytes([131])
        thresh = len(data) % payloadsize
        thresh = bytes([((thresh // 256) % 256), (thresh % 256)])
        content = filename.encode()
        filenameSize = bytes([(((len(content) // 256) % 256)),
                              (len(content) % 256)])
        pckAmount = bytes([((packetamount // (256**2)) % 256),
                           ((packetamount // 256) % 256),
                           (packetamount % 256)])
        header = signature + label + thresh + pckAmount + filenameSize

        content = content + bytes([0]) * (512 - len(content))

        signature = 'S.L.O.W.'.encode()
        eop = self.checksum(header + content) + signature

        self.meta = (header + content + eop)

        #Fazer o packaging

        data += (((2**10) - (len(data) % 2**10)) % 2**10) * bytes([0])  #oh god

        counter = 0
        while (counter != packetamount):
            thisdata = data[counter * (2**10):(counter + 1) * (2**10)]
            self.queuedPck.append(self.createPacket(thisdata, counter))
            counter += 1

    def createPacket(self, payload, counter):

        signature = 'F.A.S.T.'.encode()
        label = bytes([0])
        #size= 2**10 #size do payload, constante para packets com payload
        size = bytes([0, 0])  #TODO: consertar
        counter = bytes([((counter // (256**2)) % 256),
                         ((counter // 256) % 256), (counter % 256)])

        header = signature + label + counter + size
        #14 bytes

        signature = 'S.L.O.W.'.encode()

        eop = self.checksum(header + payload) + signature
        #16 bytes

        return header + payload + eop

    def checksum(self, data):
        #Implementação nossa de um CRC-64 bits

        data = int.from_bytes(data, 'big')
        data = data * (2**64)  #append com zeros
        while (data.bit_length() > 64):
            sumNum = 2**(data.bit_length() - 65)
            key = 18601846741563846107  #um int aleatoriamente selecionado de 65 bits
            powerkey = key * sumNum

            data ^= powerkey

        return bytes([(data // (256**7)) % 256, (data // (256**6)) % 256,
                      (data // (256**5)) % 256, (data // (256**4)) % 256,
                      (data // (256**3)) % 256, (data // (256**2)) % 256,
                      (data // 256) % 256, data % 256])
Beispiel #3
0
class enlace(object):
    """ This class implements methods to the interface between Enlace and Application
    """
    headSTART = 0xFF  # 255 #super clever head start
    headStruct = Struct("start" / Int8ub, "size" / Int16ub, "SYN" / Int8ub,
                        "ACK_NACK" / Int8ub, "P_size" / Int8ub,
                        "P_total" / Int8ub, "CheckSum" / Int16ub,
                        "CheckSum_head" / Int16ub)
    ackCode = 0x9d  # 157
    nackCode = 0x0e  # 14
    synCode = 0x01  # 1

    fakeAck = 0x00
    fakeSyn = 0x00

    maximum_Package = 2048  # determina o tamanho maximo que um pacote pode ter (*8 pois precisa ser em bits)

    def __init__(self, name):
        """ Initializes the enlace class
        """
        self.fisica = fisica(name)
        self.rx = RX(self.fisica)
        self.tx = TX(self.fisica)
        self.connected = False
        self.end = "s.t.o.p.".encode()

    def enable(self):
        """ Enable reception and transmission
        """
        self.fisica.open()
        self.rx.threadStart()
        self.tx.threadStart()

    def disable(self):
        """ Disable reception and transmission
        """
        self.rx.threadKill()
        self.tx.threadKill()
        time.sleep(1)
        self.fisica.close()

    def buildHead(self, dataLen):
        head = self.headStruct.build(
            dict(start=self.headSTART,
                 size=dataLen,
                 SYN=self.fakeSyn,
                 ACK_NACK=self.fakeAck,
                 P_size=0,
                 P_total=0,
                 CheckSum=0,
                 CheckSum_head=0))
        return (head)

    def buildSync(self, dataLen=0):
        head = self.headStruct.build(
            dict(start=self.headSTART,
                 size=dataLen,
                 SYN=self.synCode,
                 ACK_NACK=self.fakeAck,
                 P_size=0,
                 P_total=0,
                 CheckSum=0,
                 CheckSum_head=0))
        return (head)

    def buildACK_NACK(self, dataLen=0, deuCerto=False):
        if deuCerto == True:
            head = self.headStruct.build(
                dict(start=self.headSTART,
                     size=dataLen,
                     SYN=self.synCode,
                     ACK_NACK=self.ackCode,
                     P_size=0,
                     P_total=0,
                     CheckSum=0,
                     CheckSum_head=0))
        if deuCerto == False:
            head = self.headStruct.build(
                dict(start=self.headSTART,
                     size=dataLen,
                     SYN=self.synCode,
                     ACK_NACK=self.nackCode,
                     P_size=0,
                     P_total=0,
                     CheckSum=0,
                     CheckSum_head=0))
        return (head)

    def build_complete(self, dataLen, deuCerto, payload_len, total_payload_len,
                       CheckSum_payload, CheckSum_head):
        head = self.headStruct.build(
            dict(start=self.headSTART,
                 size=dataLen,
                 SYN=self.synCode,
                 ACK_NACK=self.ackCode,
                 P_size=payload_len,
                 P_total=total_payload_len,
                 CheckSum=CheckSum_payload,
                 CheckSum_head=CheckSum_head))
        return (head)

    def getheadStart(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return container["start"]

    def getSize(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return container["size"]

    def getSYN(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return container["SYN"]

    def getACK_NACK(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return container["ACK_NACK"]

    def getP_size_total(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return (container["P_size"], container["P_total"])

    def CRC(self, data):
        # usando crc-16-IBM aka CRC-16
        crc16 = crcmod.predefined.mkCrcFun("crc-16")

        CRC = (crc16(data))
        #'print("CRC: ",CRC)
        return CRC

    def get_CRC(self, file):
        head = file[0:11]
        container = self.headStruct.parse(head)
        return (container["CheckSum"], container["CheckSum_head"])

    def compare_CRC(
        self, file
    ):  # função que retorna True Se o CRChead e CRCpayload estiverem certos
        crc16 = crcmod.predefined.mkCrcFun("crc-16")
        CheckSum, CheckSum_head = self.get_CRC(file)
        half_head = file[0:7]  # parte do head sem CRC

        data, useless_trash = self.openPackage(file)

        if CheckSum == crc16(data) and CheckSum_head == crc16(half_head):
            return True
        else:
            return False

    def Compare_number_package(
            self, file):  # compara se todos os pacotes foram recebidos

        P_size, P_total = self.getP_size_total(file)

        print("Compare debug: ", P_size, " ", P_total)

        if P_size == P_total:
            return True
        else:
            return False

    def DataSender(self, data):

        n = self.maximum_Package  # tamanho maximo do pacote, so mudei de nome

        quantidade_partes = math.ceil(
            len(data) / n
        )  # acha a quantidade minima de partes que o pacote de ser dividido

        timeinit = time.time()

        print("Quantidade de partes necessarias : ", quantidade_partes)
        print("")
        print("Início do envio")
        print("")
        print("-------------------------")

        beginning = 0
        end = n
        Parte_atual = 1

        while Parte_atual <= quantidade_partes:  # roda a quantidade de vezes minima
            #print(a[beginning:end])
            payload = data[beginning:end]

            temp_head = self.build_complete(len(payload), True, Parte_atual,
                                            quantidade_partes, 0, 0)
            head_crc = self.CRC(temp_head[0:7])  # a parte do head sem o CRC
            payload_crc = self.CRC(payload)

            head = self.build_complete(len(payload), True, Parte_atual,
                                       quantidade_partes, payload_crc,
                                       head_crc)

            file = (head + payload + self.end)
            print("- Parte", Parte_atual, "de", quantidade_partes)
            self.tx.sendBuffer(file)

            timeout = time.time()

            while time.time() - timeout <= 1.5:
                ack_esperado = self.rx.getNData()
                if self.getheadStart(ack_esperado) == 255:
                    if self.getACK_NACK(ack_esperado) == 157:
                        print("  - Recebeu ACK")
                        print("")
                        beginning += n
                        end += n
                        Parte_atual += 1
                        break
                    elif self.getACK_NACK(ack_esperado) == 14:
                        print("  - Recebeu NACK")
                        print("  - Reenviando pacote")
                        print("")
                        break
                if time.time() - timeout >= 3.0:
                    print("  - TimeOut")
                    print("  - Reenviando pacote")
                    print("")

                time.sleep(0.05)

        timefim = time.time()
        print("")
        print("Tempo da transmissão:", timefim - timeinit, "segundos")

    def handshake_server(self):
        while True:
            if self.rx.getBufferLen() > 4:
                time_start_getData = time.time()
                data = self.rx.getNData()  # receive syn
                if self.getSYN(data) == 1:
                    print("Syn recebido, send ack + syn")

                    time.sleep(0.1)
                    ack_nack = self.buildACK_NACK(deuCerto=True)
                    self.tx.sendBuffer(ack_nack + self.end)  #ack + syn
                    print(self.getACK_NACK(ack_nack))

                    self.rx.clearBuffer()

                    data = self.rx.getNData()  #receive ack
                    if self.getACK_NACK(data) == 157:
                        print("handshake completo")
                        break

    ################################
    # Application  interface       #
    ################################
    def sendData(self, txLen, data):
        """ Send data over the enlace interface
        """
        sync = (self.buildSync() + self.end)
        head = self.buildHead(txLen)

        time_inicio = time.time()

        while True:

            time.sleep(1)
            self.tx.sendBuffer(sync)
            self.rx.clearBuffer()
            print("Mandei o Sync :3")

            time_now = time.time()
            if (time_now - time_inicio) < 30.0:

                ack_syn = self.rx.getNData()
                if self.getheadStart(ack_syn) == 255:
                    if self.getACK_NACK(ack_syn) == 157 and self.getSYN(
                            ack_syn) == 1:
                        print("Mandei o ACK :3")
                        time.sleep(1)
                        self.tx.sendBuffer(
                            self.buildACK_NACK(deuCerto=True) + self.end)
                        break

            elif (time_now - time_inicio) > 30.0:
                sys.exit()

        time.sleep(1)

        self.DataSender(data)

    def getData(self):
        """ Get n data over the enlace interface
        Return the byte array and the size of the buffer
        """

        self.handshake_server()

        self.rx.clearBuffer()

        Complete_package = b""

        Current_P_size = 1

        while True:  #pega um pacote
            data = self.rx.getNData()
            self.rx.clearBuffer()

            print(data)

            if self.getheadStart(data) == 255:  # se achar o head do pacote
                payload, trash = self.openPackage(data)

                P_size, P_total = self.getP_size_total(data)

                print("P_size,Current_P_size : ", P_size, " ", Current_P_size)

                if self.compare_CRC(data):

                    print("Payload : ", type(payload))

                    Complete_package += payload

                    head = self.buildACK_NACK(deuCerto=True)
                    print("mandei ack", head)
                    self.tx.sendBuffer(head + self.end)

                    Current_P_size += 1

                if self.compare_CRC(data) == False:

                    head = self.buildACK_NACK(deuCerto=False)
                    print("A casa caiu, arquivo corrompido, mandado nack")
                    self.tx.sendBuffer(head + self.end)

                if P_size == P_total:
                    break

        #print("Meu debug: "+str(Complete_package))
        data, head = self.openPackage(data)
        """

        while True: # checa se os sizes batem
            if self.getSize(head) != len(data) :
                print("dataLen:",dataLen,"head size",self.getSize(head))
                self.tx.sendBuffer(self.buildACK_NACK(deuCerto = False) + self.end)
                time.sleep(0.2)

                while True: #pega a data novamente
                    data = self.rx.getNData()
                    #self.rx.clearBuffer()
                    if self.getheadStart(data)==255:
                        break

                print("Meu debug: "+str(data))
                data, head = self.openPackage(data)

            else:
                break
        """

        #print("tempo de trasmição: ",time_start_getData - time.time())

        return (Complete_package, len(Complete_package))

    def addHead(self, txLen, txBuffer):
        return (self.buildHead(txLen) + txBuffer)

    def decrypHead(self, head):
        return (struct.unpack(self.headStruct, head))

    def openPackage(self, file):

        head = file[0:11]
        file = file[11:-8]

        return (file, head)
Beispiel #4
0
class enlace(object):
    """ This class implements methods to the interface between Enlace and Application
    """
    def __init__(self, name):
        """ Initializes the enlace class
        """
        self.fisica = fisica(name)
        self.rx = RX(self.fisica)
        self.tx = TX(self.fisica)
        self.connected = False
        self.endes = endescapsulamento.Empacotamento()

    def enable(self):
        """ Enable reception and transmission
        """
        self.fisica.open()
        self.rx.threadStart()
        self.tx.threadStart()

    def disable(self):
        """ Disable reception and transmission
        """
        self.rx.threadKill()
        self.tx.threadKill()
        time.sleep(1)
        self.fisica.close()

    ################################
    # Application  interface       #
    ################################
    def sendData(self, data):
        """ Send data over the enlace interface
        """
        # endes = endescapsulamento.Empacotamento()
        # packet = endes.buildDataPacket(data)

        self.tx.sendBuffer(data)

    def getData(self):
        """ Get n data over the enlace interface
        Return the byte array and the size of the buffer
        """

        package = self.rx.searchForPacket()
        data = self.endes.unpackage(package)

        return (data)

    def receive(self):
        sync = False
        while sync == False:
            #iniciar timer para esperar um syn
            time.sleep(2)
            if self.rx.getBufferLen() != 0:
                print("recebi algo")
                packet = self.getData()
                packetType = getType.getType(packet)
                if packetType.getPacketType() == 'comando':
                    if packetType.getCommandType() == 'SYN':
                        print("é um syn")
                        self.sendData(self.endes.buildAckPacket())
                        print("Enviando Ack")
                        time.sleep(3)
                        self.sendData(self.endes.buildSynPacket())
                        print("Enviando Syn")
                        #outro timer esprando um ack do client
                        time.sleep(2)
                        packet2 = self.getData()
                        if len(packet2) != 0:
                            packetType2 = getType.getType(packet2)
                            if packetType2.getPacketType() == 'comando':
                                if packetType2.getCommandType() == 'ACK':
                                    print("Recebeu Ack")
                                    sync = True
                                    time.sleep(3)
                                    return True
                                else:
                                    print("nao recebeu ultimo ack do server")
                                    continue
                            else:
                                print("server nao mandou ack")
                                continue
                        else:
                            print(
                                "nao recebeu nenhum ack do server, reiniciando"
                            )
                            continue
                    else:
                        print("server nao mandou syn")
                        continue
                else:
                    print("nao recebeu")
                    continue
            else:
                print("pacote vazio, procurar novamente")
                continue

    def conecta(self):
        sync = False
        while sync == False:
            time.sleep(1)
            synPacket = self.endes.buildSynPacket()
            self.sendData(synPacket)
            print("Mandando Syn")

            # start_receiving_time = time.time()
            # finished_receiving_time = time.time() - start_receiving_time

            time.sleep(2)
            # print("lenBuffer" + str(self.tx.getBufferLen()))
            #inicia timer esperando um ack e um syn
            bufferLen = self.rx.getBufferLen()

            if bufferLen != 0:
                packet = self.getData()
                packetType = getType.getType(packet)
                if packetType.getPacketType() == 'comando':
                    if packetType.getCommandType() == 'ACK':
                        print("Recebendo Ack")

                        time.sleep(3)
                        packet = self.getData()
                        packetType = getType.getType(packet)
                        if packetType.getPacketType() == 'comando':
                            if packetType.getCommandType() == 'SYN':
                                print('Recebendo Syn')
                                #iniciar timer para esperar um SYN do server
                                ackPacket = self.endes.buildAckPacket()
                                # print(self.rx.buffer)
                                self.sendData(ackPacket)
                                print("Mandando Ack")
                                # print(self.rx.buffer)
                                sync = True
                                time.sleep(2)
                                return True
                            else:
                                print("nao recebeu SYN do server")
                                continue

                    else:
                        print("nao recebeu ACK do server")
                        continue
                else:
                    print("nao é um comando")
                    continue
            else:
                print("pacote vazio, reiniciando")

    def confirm_client(self):
        time.sleep(2)
        if self.rx.getBufferLen() != 0:
            packet = self.getData()
            if packet != 0:
                packetType = getType.getType(packet)
                if packetType.getPacketType() == 'comando':
                    if packetType.getCommandType() == 'ACK':
                        return True
                    elif packetType.getCommandType() == 'NACK':
                        print("Pacote não recebido, reenviando")
                        # endes = endescapsulamento.Empacotamento()
                        # packet = endes.buildDataPacket(txBuffer)
                        # self.sendData(packet)
                        return False
        else:
            print('Aguardando confirmação de recebimento de pacote')

        # sent = False
        # return True

    def confirm_server(self):
        received = False
        # while received == False:
        if self.rx.getBufferLen == 0:
            nackPacket = self.endes.buildNackPacket()
            self.sendData(nackPacket)
            return False
        else:
            # rxBuffer = self.getData()
            print("recebi pacote")
            ackPacket = self.endes.buildAckPacket()
            self.sendData(ackPacket)
            # received = True
            return True
            # break
        # received = False
        # return rxBuffer

    def parsePacket(self, payload):
        offset = 0
        nPacotes = math.ceil(len(payload) / 2048)
        packetCounter = 0
        while packetCounter < nPacotes:
            if (len(payload) - offset) >= 2048:
                pacote = self.endes.buildDataPacket(
                    (payload[offset:offset + 2048]), packetCounter, nPacotes)
                print("Enviando pacote: " + str(packetCounter + 1) + "/" +
                      str(nPacotes))
                self.sendData(pacote)
                confirmacao = self.confirm_client()
                if confirmacao == True:
                    print("Pacote: " + str(packetCounter + 1) + " de " +
                          str(len(pacote) - 40) + " recebido")
                    print("--------------------------")
                    offset += 2048
                    packetCounter += 1
                    # time.sleep(2)
                else:
                    continue
            else:
                pacote = self.endes.buildDataPacket((payload[offset:]),
                                                    packetCounter, nPacotes)
                self.sendData(pacote)
                print("Enviando pacote: " + str(packetCounter + 1) + "/" +
                      str(nPacotes))
                confirmacao = self.confirm_client()
                if confirmacao == True:
                    # print("confirmado")
                    print("Pacote: " + str(packetCounter + 1) + " de " +
                          str(len(pacote) - 40) + " bytes " + "recebido")
                    print("--------------------------")
                    # print(len(pacote))

                    packetCounter += 1
                    # time.sleep(2)
                else:
                    continue

    def receive_packets(self):
        imagem = bytearray()
        n = 0
        total = 1

        while n < total:

            if self.rx.getBufferLen() != 0:
                pacote = self.rx.searchForPacket()
                # print("lenPacote " + str(len(pacote)))
                headParameters = self.endes.getHeadParameters(pacote)
                new_n = headParameters[0] + 1
                total = headParameters[1]
                print("Recebendo pacote: " + str(new_n) + "/" + str(total))
                # print("new_n " + str(new_n))
                # print("Total " + str(total))
                payload = self.endes.unpackage(pacote)
                data = payload[8:len(payload) - 8]
                crcClient = payload[0:8]
                # crcClient = self.endes.unpackage(pacote)[0:8]
                # crcClientPayload = self.endes.unpackage(pacote)[-8:0]
                crcClientPayload = payload[len(payload) - 8:]

                # pacotePayload = self.endes.unpackage(pacote)[14:len(pacote) - 8]
                # print("lenPacotePayload: " + str(len(pacotePayload)))

                key = self.endes.getKey()

                crcServer = self.endes.encodeData(str(pacote[0:6]), key)
                hexCrc = self.endes.stringToHex(crcServer)

                crcServerPayload = self.endes.encodeData(str(data), key)

                hexCrcPayload = self.endes.stringToHex(crcServerPayload)

                if hexCrc == crcClient:
                    if hexCrcPayload == crcClientPayload:
                        if (new_n != n):
                            print("Pacote: " + str(new_n) + "/" + str(total) +
                                  " de " + str(len(payload) - 16) + " bytes " +
                                  "recebido")
                            print("--------------------------")
                            n = new_n
                            ackPacket = self.endes.buildAckPacket()
                            self.sendData(ackPacket)

                            imagem += data
                            time.sleep(2)
                        else:
                            print(
                                "Pacote: " + str(new_n) + "/" + str(total) +
                                " já foi recebido, aguardando próximo pacote")
                            time.sleep(2)
                            continue
                    else:
                        print("crc Payload não confere, mandar novamente")
                        nackPacket = self.endes.buildNackPacket()
                        self.sendData(nackPacket)
                        time.sleep(2)
                        continue

                else:
                    print("crc Head não confere, mandar novamente")
                    nackPacket = self.endes.buildNackPacket()
                    self.sendData(nackPacket)
                    time.sleep(2)
                    continue

            else:
                nackPacket = self.endes.buildNackPacket()
                self.sendData(nackPacket)
                continue

        return imagem
Beispiel #5
0
class enlace(object):
    """ This class implements methods to the interface between Enlace and Application
	"""
    def __init__(self, name):
        """ Initializes the enlace class
		"""
        self.fisica = fisica(name)
        self.rx = RX(self.fisica)
        self.tx = TX(self.fisica)
        self.connected = False

    def enable(self):
        """ Enable reception and transmission
		"""
        self.fisica.open()
        self.rx.threadStart()
        self.tx.threadStart()

    def disable(self):
        """ Disable reception and transmission
		"""
        self.rx.threadKill()
        self.tx.threadKill()
        time.sleep(1)
        self.fisica.close()

    ################################
    # Application  interface       #
    ################################

    def comunicacao(self, data, user):
        data_null = (0).to_bytes(4, byteorder="big")
        while True:

            if user == "client":

                print("Enviada mensagem do tipo 1")
                self.sendData(data_null, 0, 0, 0, 1, 0)

                start_time1 = time.time()

                size = self.waitLoop(2, 1)

                if size != 0:
                    print('...')
                    rxBuffer = self.getData(size)
                    tipo_msg = self.getType(rxBuffer)

                    if tipo_msg == 2:
                        print("Mensagem tipo 2 recebida")
                        print('----------------------')
                        time.sleep(2.5)
                        print("Enviada mensagem do tipo 3")
                        self.sendData(data_null, 0, 0, 0, 3, 0)
                        time.sleep(1)

                        self.sendPackages(data)
                        print("Transmissao Concluida")
                        print("Enviando Mensagem de tipo 7 (encerramento)")
                        time.sleep(5)
                        self.sendData(data_null, 0, 0, 0, 7, 0)
                        break
                    elif tipo_msg == 7:
                        print("Mensagem de encerramento recebida - encerrando")
                        break
                    else:
                        print('--------------------')
                        print("Erro de mensagem recebida1")
                        print('--------------------')

                else:
                    print('--------------------')
                    print("Mensagem tipo 2 não recebida")
                    print('--------------------')

            if user == "server":
                while True:

                    size = self.waitLoop(2, 0)

                    rxBuffer = self.getData(size)
                    tipo_msg = self.getType(rxBuffer)
                    print('tipo', tipo_msg)

                    if tipo_msg == 1:
                        print('--------------------')
                        print("Mensagem de tipo 1 recebida")

                        while True:
                            print("Enviada mensagem do tipo 2")
                            self.sendData(data_null, 0, 0, 0, 2, 0)
                            self.rx.clearBuffer()

                            size = self.waitLoop(3, 1)
                            #rxBuffer = self.getData(size)

                            if size == 0:
                                print('--------------------')
                                print("Mensagem de tipo 3 não recebida")
                                print('--------------------')
                            else:
                                rxBuffer = self.getData(size)
                                tipo_msg = self.getType(rxBuffer)

                                if tipo_msg == 3:
                                    print('--------------------')
                                    print(
                                        "Recebida mensagem de tipo 3, esperando pacote de informações"
                                    )
                                    print('--------------------')
                                    while True:
                                        time.sleep(0.3)
                                        size = self.waitLoop(4, 0)

                                        rxBuffer = self.getData(size)
                                        tipo_msg = self.getType(rxBuffer)

                                        if tipo_msg == 7:  #mensagem do tipo 7 (dados)
                                            print(
                                                "Mensagem de encerramento recebida - encerrando"
                                            )
                                            return data_null

                                        elif tipo_msg == 4:  #mensagem do tipo 4 (dados)

                                            full_data = self.receivePackages()
                                            print('Em Espera')
                                            size = self.waitLoop(9, 0)

                                            rxBuffer = self.getData(size)
                                            tipo_msg = self.getType(rxBuffer)

                                            if tipo_msg == 7:  #mensagem do tipo 7 (dados)
                                                print('--------------------')
                                                print(
                                                    "Mensagem de tipo 7 recebida"
                                                )
                                                print('--------------------')
                                                print("Conexao encerrando")
                                                return full_data
                                        else:
                                            print('--------------------')
                                            print("Erro de Mensagem recebida4")
                                            print('--------------------')
                                elif tipo_msg == 7:
                                    print(
                                        "Mensagem de encerramento recebida - encerrando"
                                    )
                                    return data_null

                                else:
                                    print('--------------------')
                                    print("Erro de Mensagem recebida2")
                                    print('--------------------')
                    elif tipo_msg == 7:
                        print("Mensagem de encerramento recebida - encerrando")
                        return data_null
                    else:
                        print("Erro de mensagem recebida3")

    def sendData(self, data, numero_pacote, pacotes_totais, erro_pacote,
                 tipo_msg, crc):
        """ Send data over the enlace interface
		(self, payload, package_number, total_packages, package_error, message_type)
		"""
        pacote, lenPayload = self.tx.criaPackage(data, numero_pacote,
                                                 pacotes_totais, erro_pacote,
                                                 tipo_msg, crc)
        self.tx.sendBuffer(pacote)
        return lenPayload

    def sendPackages(self, data):
        print("...Inicio da transmissao dos pacotes de dados...")
        total_packages = int((len(data) / 128) + 1)
        lista_packages = []
        i = 0
        idx = 0
        info = data

        while len(info) > 128:
            pay = info[:128]
            info = info[128:]
            lista_packages.append(pay)
        lista_packages.append(info)

        #while i<(len(data)-128):
        #	lista_packages.append(data[i:i+127])
        #	i+=128
        #lista_packages.append(data[i:])
        print('Pacotes totais:', total_packages)
        print("{0} pacotes a serem enviados".format(len(lista_packages)))

        while idx < len(lista_packages):
            time.sleep(1)
            val = lista_packages[idx]
            while True:
                print("------------------------------")
                print("Pacote {0} enviado".format(idx))
                print("Tamanho:", len(val))
                print(self.crc16(val))
                self.sendData(val, idx, total_packages, 0, 4,
                              self.crc16(val) + 1)
                size = self.waitLoop(5, 1)
                if size != 0:
                    break
                else:
                    print("Resposta nao recebida")
            rxBuffer = self.getData(size)
            tipo_msg = self.getType(rxBuffer)

            if tipo_msg == 5:
                print("Mensagem tipo 5 recebida")
                idx += 1
            elif tipo_msg == 6:
                print("Mensagem tipo 6 recebida")
            elif tipo_msg == 8:
                print("Mensagem tipo 8 recebida")
                if self.getExpectedPackage(rxBuffer) == -1:
                    print("Erro de Mensagem")
                else:
                    idx = self.getExpectedPackage(rxBuffer)
            elif tipo_msg == 7:
                print("Mensagem de encerramento recebida - encerrando tudo")
                return
            else:
                print("Erro de Mensagem")
        print("Transmissao dos pacotes concluida")
        return

    def receivePackages(self):
        print("...Inicio da recepcao dos pacotes de dados...")
        pacote_esperado = 0
        lista_packages = bytes(0)
        data_null = (0).to_bytes(4, byteorder="big")

        while True:
            size = self.waitLoop(9, 0)
            rxBuffer = self.getData(size)
            if rxBuffer == 51:
                print("Erro de mensagem")
                self.sendData(data_null, 0, 0, 0, 6, 0)
            else:

                pacotes_totais = rxBuffer[1]
                tipo_msg = self.getType(rxBuffer)

                if tipo_msg == 4:

                    if self.getPackageNumber(rxBuffer) == pacote_esperado:
                        if self.crcIsCorrect(rxBuffer):
                            print('_____________________')
                            print("Pacote recebido: {0}".format(
                                self.getPackageNumber(rxBuffer)))
                            print(
                                "Pacote esperado: {0}".format(pacote_esperado))
                            print("Correto! - Mensagem de tipo 5 enviada")
                            self.sendData(data_null, 0, 0, 0, 5, 0)
                            package = self.getPackage(rxBuffer)
                            print(self.crc16(package))
                            lista_packages += package
                            pacote_esperado += 1
                            print('Pacotes a serem recebidos:',
                                  (pacotes_totais - pacote_esperado))
                            if pacotes_totais - pacote_esperado == 0:
                                print("Todos os {0} pacotes recebidos".format(
                                    pacote_esperado))
                                full_data = lista_packages
                                print(
                                    "Os dados recebidos tem {0} bytes".format(
                                        len(full_data)))
                                break
                        else:
                            print("Pacote corrompido - CRC incorreto")
                            time.sleep(1)
                            print("Enviada mensagem de tipo 6")
                            self.sendData(data_null, 0, 0, 0, 6, 0)

                    else:
                        print('_____________________')
                        print("Pacote recebido: {0}".format(
                            self.getPackageNumber(rxBuffer)))
                        print("Pacote esperado: {0}".format(pacote_esperado))
                        print("Incorreto! - Mensagem de tipo 8 enviada")
                        time.sleep(1)
                        self.sendData(data_null, 0, 0, pacote_esperado, 8, 0)

                elif tipo_msg == 7:
                    print(
                        'Mensagem de tipo 7 recebida - comunicacao encerrando')
                    break
        print('Transmissao dos pacotes encerrada')
        return full_data

    def getData(self, size):
        """ Get n data over the enlace interface
		Return the byte array and the size of the buffer
		"""
        buffer_data = self.rx.getNData(size)
        data = self.rx.desfaz_package(buffer_data)

        return (data)

    def getType(self, data):
        #null, tipo_msg = self.rx.desfaz_package(package)
        if data == 51:
            return data
        tipo_msg = data[9]
        return tipo_msg

    def getPackage(self, data):
        if data == 51:
            return data
        package = data[10:]
        return package

    def getPackageNumber(self, data):
        if data == -1:
            return data
        package_number = data[0]
        return package_number

    def getExpectedPackage(self, data):
        if data == -1:
            return data
        expected_type = data[2]
        return expected_type

    def crcIsCorrect(self, data):
        expected_crc = int.from_bytes(data[6:9], byteorder="big")
        true_crc = self.crc16(self.getPackage(data))
        if expected_crc == true_crc:
            return True
        else:
            return False

    def waitLoop(self, type, timed):
        size = 10
        start_time1 = time.time()
        if timed == 1:
            while (self.rx.getBufferLen() == 0 or self.rx.getBufferLen() > size
                   ) and (time.time() - start_time1) < 5:
                if (type == 9):
                    print('.')
                else:
                    print("Esperando tipo {0}".format(type))
                time.sleep(0.5)
                size = self.rx.getBufferLen()
        if timed == 0:
            while self.rx.getBufferLen() == 0 or self.rx.getBufferLen() > size:
                print("Recebendo")
                time.sleep(0.3)
                size = self.rx.getBufferLen()
        return size

    def crc16(self, data: bytes):

        return crc16.crc16xmodem(data)