Beispiel #1
0
    def addHeaderToMessage(self, message, textLines=None):
        """
        When no WMO header is present in the text part of an AFTN Message, we will create one 
        for each destination address in the message.
        ex: if self.drp.aftnMap['CWAOWXYZ'] == 'SACN32', the header will be 'SACN32 CWAO YYGGgg'
        where YY= day of the month, GG=hours and gg=minutes
        This method is only used at reception.

        textLines is not None for big messages (text is not in the message, but in a supplementary 
        variable.
        """
        import dateLib
        wmoMessages = []
        addresses = message.destAddress
        default = self.drp.aftnMap.get('DEFAULT')
        timestamp = dateLib.getYYGGgg()

        destLine = message.createDestinationAddressLine().strip() 
        originLine = message.createOriginAddressLine().strip() 

        destOriginLines = [destLine, originLine]

        self.logger.debug("Addresses: %s" % addresses)

        for address in addresses:
            header = self.drp.aftnMap.get(address, default) + " " + address[0:4] + " " + timestamp
            headerBlock = [header] + destOriginLines

            #self.logger.info("Header in addHeader: %s" % header)
            if textLines:
                wmoMessages.append('\n'.join(headerBlock + textLines) + '\n')
            else:
                wmoMessages.append('\n'.join(headerBlock + message.textLines) + '\n')
        return wmoMessages
Beispiel #2
0
    def addHeaderToMessage(self, message, textLines=None):
        """
        When no WMO header is present in the text part of an AFTN Message, we will create one 
        for each destination address in the message.
        ex: if self.drp.aftnMap['CWAOWXYZ'] == 'SACN32', the header will be 'SACN32 CWAO YYGGgg'
        where YY= day of the month, GG=hours and gg=minutes
        This method is only used at reception.

        textLines is not None for big messages (text is not in the message, but in a supplementary 
        variable.
        """
        import dateLib
        wmoMessages = []
        addresses = message.destAddress
        default = self.drp.aftnMap.get('DEFAULT')
        timestamp = dateLib.getYYGGgg()

        destLine = message.createDestinationAddressLine().strip()
        originLine = message.createOriginAddressLine().strip()

        destOriginLines = [destLine, originLine]

        self.logger.debug("Addresses: %s" % addresses)

        for address in addresses:
            header = self.drp.aftnMap.get(
                address, default) + " " + address[0:4] + " " + timestamp
            headerBlock = [header] + destOriginLines

            #self.logger.info("Header in addHeader: %s" % header)
            if textLines:
                wmoMessages.append('\n'.join(headerBlock + textLines) + '\n')
            else:
                wmoMessages.append('\n'.join(headerBlock + message.textLines) +
                                   '\n')
        return wmoMessages
Beispiel #3
0
    def readFromSocket(self):
        replyAFTN = ''
        mm = self.mm
        
        buf = self.socket.recv(32768)

        if len(buf): 
            self.logger.debug('Raw Buffer: %s' % repr(buf))
            message, type = mm.parseReadBuffer(buf) # Only to find if it is an AFTN (SVC included) or Ack message
            while message:
                if type == 'AFTN':
                    ##############################################################################################
                    # An AFTN Message has been read on the socket. It can be a SVC Message or a 
                    # Standard Message.
                    ##############################################################################################
                    self.logger.debug("AFTN Message: %s" % repr(message))
                    mm.messageIn = MessageAFTN(self.logger)
                    mm.messageIn.setMessage(message)
                    if not mm.messageIn.messageToValues():
                        # Here we have a problem because our parser is unable to parse the message. We print the message,
                        # get the next message if present and quit the method (no ack sent, no tid verification)
                        self.logger.error("Method MessageAFTN.messageToValues() has not worked correctly (returned 0)")
                        self.logger.error(mm.messageIn.textLines)
                        message, type = mm.parseReadBuffer("") # Only to find if it is an AFTN (SVC included) or Ack message
                        continue

                    self.logger.debug(mm.messageIn.textLines)

                    self.logger.debug('Message as it has been received:')
                    self.logger.debug('\n' + mm.messageIn.message)

                    status = mm.isItPart(mm.messageIn.textLines)

                    # Not part of a big message, possibly a SVC message
                    if status == 0:
                        suffix = 'NOT_SVC_NOR_AFTN'
                        mp = MessageParser(mm.messageIn.textLines)
                        textType = mp.getType()
                        if textType == "SVC": 
                            ##############################################################################################
                            # A Service  Message has been read on the socket. 
                            ##############################################################################################
                            suffix = 'SVC'
                            self.logger.info("SVC Message Received(%s): %s (%s)" % (mm.messageIn.getTransmitID(), str(mm.messageIn.getTextLines()), MessageParser.names.get(mp.serviceType,
                                              "The service type of this message is unknown. Contact NavCanada")))

                            #if mp.serviceType in [8, 9]:
                            #    self.logger.info("*********************** SERVICE MESSAGE *****************************")
                            #    self.logger.info(str(mm.messageIn.getTextLines()))
                            #    self.logger.info("********************* END SERVICE MESSAGE ***************************")

                        elif textType == "AFTN":
                            suffix = ''
                            if mp.getHeader() in ['SI', 'SM']:
                                # Only one message will be in messages
                                messages = mm.completeHeader(mm.messageIn)

                            elif mp.getHeader(): 
                                # Only one message will be in messages
                                messages = ['\n'.join(mm.messageIn.textLines) + '\n'] 
                            else:
                                # Create headers before ingesting
                                messages = mm.addHeaderToMessage(mm.messageIn)

                            # Ingest in met px
                            for m in messages:
                                mm.ingest(m)

                        elif textType in ['RQ', 'RF']:
                            suffix = textType
                            # request for amis or metser
                            from RequestReplyAFTN import RequestReplyAFTN
                            import dateLib
                            date = dateLib.getYYGGgg()
                            if textType == 'RQ': # amis
                                addOn = 'AACN02 ANIK %s\nATTN %s\n\n' % (date, mm.messageIn.originatorAddress)
                                replyAFTN = 'RQM '
                            elif textType == 'RF': # metser
                                addOn = 'AACN44 CWAO %s\nATTN %s\n\n' % (date, mm.messageIn.originatorAddress)
                                replyAFTN = 'RQF '

                            self.logger.info('AFTN Request Received: Type = %s, Value = %s' % (textType, mp.request))

                            # We want to put the answer on amis or metser.
                            try:
                                rr = RequestReplyAFTN(mp.request, addOn, mp.sendOn, self.logger)
                            except:
                                (type, value, tb) = sys.exc_info()
                                self.logger.error("In RequestReplyAFTN: Type = %s, Value = %s" % (type, value))

                            if rr.bulletin:
                                self.logger.info('Reply is not empty, we will put bulletin in the queue of receiver %s and send an OK message' % rr.receiverName)
                                # bulletin is not empty, put it in queue and create an "OK" message
                                rr.putBulletinInQueue()
                                replyAFTN += 'OK'
                            else:
                                self.logger.info('Request is empty, we will send an UNK message')
                                # bulletin is empty, create an "UNK" message
                                replyAFTN += 'UNK'

                        elif textType in ['RQM_UNK', 'RQM_OK', 'RQF_UNK', 'RQM_OK']:
                        # reply about a request. I think a request never originates from us,
                        # so we should never receive such a reply.
                            suffix = textType
                            self.logger.info("Reply received is: %s" % textType)

                        # We keep one copy of all received messages in a special AFTN directory
                        file = open(self.writePath + mm.messageIn.getName() + suffix, 'w')
                        for line in mm.messageIn.textLines:
                            file.write(line + '\n')
                        file.close()

                    # General part of a big message
                    elif status == 1:
                        self.logger.debug("We are in section 'General part of a big message'")
                        pass
                    # Last part of a big message
                    elif status == -1:
                        file = open(self.writePath + mm.messageIn.getName(), 'w')
                        for line in mm.receivedParts:
                            file.write(line + '\n')
                        file.close()

                        # We must ingest the bulletin contained in the message in the px system
                        lines = [line.strip() for line in mm.receivedParts]
                        mp = MessageParser(lines)

                        if mp.getHeader(): 
                            # Only one message will be in messages
                            messages = ['\n'.join(lines) + '\n'] 
                        else:
                            # Create headers before ingesting
                            messages = mm.addHeaderToMessage(mm.messageIn, lines)

                        # Ingest in met px
                        for m in messages:
                            mm.ingest(m)

                        mm.receivedParts = []

                    # FIXME: The number of bytes include the ones associated to the protocol overhead,
                    # maybe a simple substraction should do the job.
                    self.logger.info("(%i Bytes) Message %s has been received" % (len(mm.messageIn.getTextString()), mm.messageIn.getName()))
                    
                    if mm.ackUsed:
                        self._writeAckToSocket(mm.messageIn.getTransmitID())
                        mm.totAck += 1
                        #if mm.totAck == 5:
                        #    mm.ackUsed = False 

                    ##############################################################################################
                    # Is the CSN Order correct? Maybe Service Message would have to be sent?
                    ##############################################################################################
                    tid = mm.messageIn.getTransmitID()
                    if tid == mm.getWaitedTID():
                        self.logger.debug("The TID received (%s) is in correct order" % tid)
                    elif mm.getWaitedTID() == None:
                        self.logger.debug("Waited TID is None => the received TID (%s) is the first since the program start" % tid)
                    else:
                        self.logger.error("The TID received (%s) is not the one we were waiting for (%s)" % (tid, mm.getWaitedTID()))
                        if int(mm.getWaitedTID()[3:]) - int(tid[3:]) == 1:
                            self.logger.error("Difference is 1 => Probably my ack has been lost (or is late) and the other side has resend")
                        # FIXME: A SVC Message should be sent here. Given the fact that we receive the same message
                        # again, can we conclude that it is a retransmission (because our ack has not been received)
                        # or an error in numbering message?
                        diffCSN = int(tid[3:])- int(mm.getWaitedTID()[3:])
                        if diffCSN < 0:
                            messageText = "SVC LR %s EXP %s" % (tid, mm.getWaitedTID())

                        # FIXME: This implementation is done with only a partial comprehension of how this 
                        # message should work. Should be completed later...
                        elif diffCSN > 0: 
                            if diffCSN == 1:
                                messageText = "SVC QTA MIS %s" % mm.getWaitedTID()
                            else:
                                lastCSN = "%04d" % (int(tid[3:]) - 1)
                                messageText = "SVC QTA MIS %s-%s" % (mm.getWaitedTID(), lastCSN)

                        if not mm.getWaitingForAck():
                            mm.partsToSend = [messageText]
                            mm.completePartsToSend(mm.partsToSend)  
                            mm.setFromDisk(False)
                            self._writeMessageToSocket([mm.partsToSend[0]], False, mm.nextPart)
                            mm.setFromDisk(True)
                        else:
                            # We queue the message to send it after we receive the ack we wait for.
                            self.logger.info("A service message (%s) will be queued" % messageText)
                            mm.serviceQueue.append((messageText, []))
                            
                    mm.calcWaitedTID(tid)

                    ##############################################################################################
                    # Do we have to send a reply to a request?
                    ##############################################################################################
                    if replyAFTN:
                        if not mm.getWaitingForAck():
                            self.logger.debug("A reply (%s) to a request will be sent immediately" % replyAFTN)
                            mm.partsToSend = [replyAFTN]
                            mm.completePartsToSend(mm.partsToSend)  
                            mm.setFromDisk(False)
                            self._writeMessageToSocket([mm.partsToSend[0]], False, mm.nextPart, [mm.messageIn.originatorAddress])
                            mm.setFromDisk(True)
                        else:
                            # We queue the message to send it after we receive the ack we wait for.
                            self.logger.info("A reply (%s) to a request will be queued (because we are waiting for an ack)" % replyAFTN)
                            mm.serviceQueue.append((replyAFTN, [mm.messageIn.originatorAddress]))

                elif type == 'ACK':
                    ##############################################################################################
                    # An Ack Message has been read on the socket. 
                    ##############################################################################################
                    self.logger.debug("Ack Message: %s" % repr(message))
                    strippedMessage = message[2:9]
                    mm.setLastAckReceived(strippedMessage)
                    if mm.getLastAckReceived() == mm.getWaitingForAck():
                        mm.setWaitingForAck(None)
                        mm.resetSendingInfos()
                        mm.updatePartsToSend()
                        self.logger.info("Ack received is the ack we wait for: %s" % strippedMessage)
                    else:
                        # FIXME: When deconnexion occurs, it is possible that we received an ack for a previously sent message???
                        self.logger.error("Ack received (%s) is not the ack we wait for: %s" % (strippedMessage, mm.getWaitingForAck()))
                        if mm.getWaitingForAck() == None:
                            pass
                        elif int(mm.getWaitingForAck()[3:]) - int(strippedMessage[3:]) == 1:
                            self.logger.error("Difference is 1 => Probably my original message + the one I resend have been hacked (Timing problem)")

                # Archive State
                mm.state.fill(mm)
                mm.archiveObject(AFTNPaths.STATE, mm.state)
                self.logger.debug("State has been archived")

                message, type = mm.parseReadBuffer("") # Only to find if it is an AFTN (SVC included) or Ack message
                if not message and type:
                    self.logger.debug("Message (type=%s) uncomplete. It's ok. We will try to complete it in the next pass." % type)

        else:
            # If we are here, it normally means the other side has hung up(not sure in this case, because I use
            # select. Maybe it simply not block and return 0 bytes? Maybe it's correct to do nothing and act 
            # only when the POLLHUP state is captured?
            # FIXME: POLLHUP is never present, I don't know why?
            self.logger.error("Zero byte have been read on the socket (Means the other side has HUNG UP?)")
            raise Exception("Zero byte have been read on the socket (Means the other side has HUNG UP?)")
Beispiel #4
0
                    self.bulletin = self.bulletin + header + ' ' + bestHeaderTime + '\n' + theLine.strip(
                    ) + '\n\n'
                    #print repr(theLine)
                    if self.dbs.type == 'SA' and speciLine:
                        speciHeader = header[0] + 'P' + header[2:]
                        speciResult = speciHeader + ' ' + speciHeaderTime + '\n' + speciLine.strip(
                        ) + '\n\n'
                        self.bulletin = speciResult + self.bulletin

        if self.bulletin:
            self.bulletin = self.addOn + self.bulletin

        #print self.bulletin
        return self.bulletin


if __name__ == '__main__':
    import dateLib
    from Logger import *

    logger = Logger('/apps/px/log/RequestReplyAFTN.log.notb', 'DEBUG', 'requ')
    logger = logger.getLogger()

    addOn = 'AACN44 CWAO %s\nATTN %s\n\n' % (dateLib.getYYGGgg(), 'FAKEADDR')
    addOn = 'AACN02 ANIK %s\nATTN %s\n\n' % (dateLib.getYYGGgg(), 'FAKEADDR')

    sendOn = 'amis'

    request = RequestReplyAFTN(' '.join(sys.argv[1:]), addOn, sendOn, logger)
    request.putBulletinInQueue()
Beispiel #5
0
                       self.logger.warning("%s has been excluded of reply for %s" % (new_header, self.sendOn))
                       continue
   
                   self.bulletin =  self.bulletin + header + ' ' + bestHeaderTime + '\n' + theLine.strip() + '\n\n'
                   #print repr(theLine)
                   if self.dbs.type == 'SA' and speciLine:
                       speciHeader = header[0] + 'P' + header[2:]
                       speciResult = speciHeader + ' ' + speciHeaderTime + '\n' + speciLine.strip() + '\n\n'
                       self.bulletin = speciResult + self.bulletin
            
        if self.bulletin:
            self.bulletin = self.addOn + self.bulletin

        #print self.bulletin
        return self.bulletin

if __name__ == '__main__':
    import dateLib
    from Logger import *

    logger = Logger('/apps/px/log/RequestReplyAFTN.log.notb', 'DEBUG', 'requ')
    logger = logger.getLogger()

    addOn = 'AACN44 CWAO %s\nATTN %s\n\n' % (dateLib.getYYGGgg(), 'FAKEADDR')
    addOn = 'AACN02 ANIK %s\nATTN %s\n\n' % (dateLib.getYYGGgg(), 'FAKEADDR')
    
    sendOn = 'amis'

    request = RequestReplyAFTN(' '.join(sys.argv[1:]), addOn, sendOn, logger)
    request.putBulletinInQueue()