コード例 #1
0
    def _writeMessageToSocket(self, data, rewrite=False, nextPart=0, destAddresses=None):

        def getWord(type):
            """ Used to create logging text only """
            if type:
                return '(type: %s)' % type
            else:
                return '(type: UNKNOWN)'

            """
            if type == 'SVC':
                return '(type: SVC)'
            elif type == 'AFTN':
                return '(type: AFTN)'
            elif type == 'RF':
                return '(type: RF)'
            elif type == 'RQ':
                return '(type: RQ)'
            elif type == 'RQM_OK':
                return '(type: RQM_OK)'
            elif type == 'RQM_UNK':
                return '(type: RQM_UNK)'
            elif type == 'RQF_OK':
                return '(type: RQF_OK)'
            elif type == 'RQF_UNK':
                return '(type: RQF_UNK)'
            else:
                return '(type: UNKNOWN)'
            """

        mm = self.mm
        if len(data) >= 1:
            if not rewrite:
                self.logger.info("%d new bulletin will be sent" % len(data))
            else:
                self.logger.info("%d new bulletin will be resent (ack not received / reconnexion)" % len(data))

            for index in range(len(data)):
                if nextPart == 0:
                    # We will have access to the first part of the message here (big or not)
                    mp = MessageParser(data[index], mm, self.logger, True)
                    mm.header, mm.type = mp.getHeader(), mp.getType()
                    self.logger.debug("Header: %s, Type: %s" % (mm.header, mm.type))
                if mm.header== None and mm.type==None:
                    self.logger.info(data[index])
                    self.logger.error("Header %s is not in %s" % (mm.header, mm.routingTable))
                    if self.slow:
                        time.sleep(10)
                    os.unlink(self.dataFromFiles[0][1])
                    self.logger.info("%s has been erased", os.path.basename(self.dataFromFiles[0][1]))
                    del self.dataFromFiles[0]
                    mm.clearPartsToSend()
                    continue

                elif mm.header == None and mm.type=='SVC':
                    #FIXME: Is it possible to rewrite Service Message?
                    # If so, the CSN must not change!
                    mm.setFilingTime()
                    mm.nextCSN()
                    messageAFTN = MessageAFTN(self.logger, data[index], mm.stationID, mm.address, MessageAFTN.PRIORITIES[2],
                                              destAddresses or [mm.otherAddress], mm.CSN, mm.filingTime, mm.dateTime)
                    #self.logger.debug('\n' + messageAFTN.message)
                    #messageAFTN.setLogger(None)
                    #mm.archiveObject(self.archivePath + mm.CSN, messageAFTN)

                elif mm.header == None and mm.type in ['RQ', 'RF']:
                    # We will never have to sent such a message, it is only
                    # there for tests purposes
                    mm.setFilingTime()
                    mm.nextCSN()
                    messageAFTN = MessageAFTN(self.logger, data[index], mm.stationID, mm.address, MessageAFTN.PRIORITIES[2],
                                              destAddresses or [mm.otherAddress], mm.CSN, mm.filingTime, mm.dateTime)
                    #self.logger.debug('\n' + messageAFTN.message)
                    #messageAFTN.setLogger(None)
                    #mm.archiveObject(self.archivePath + mm.CSN, messageAFTN)

                elif mm.header == None and mm.type in MessageParser.REPLY_TYPES:
                    mm.setFilingTime()
                    mm.nextCSN()
                    messageAFTN = MessageAFTN(self.logger, data[index], mm.stationID, mm.address, MessageAFTN.PRIORITIES[3],
                                              destAddresses, mm.CSN, mm.filingTime, mm.dateTime)
                    #self.logger.debug('\n' + messageAFTN.message)
                    #messageAFTN.setLogger(None)
                    #mm.archiveObject(self.archivePath + mm.CSN, messageAFTN)

                elif mm.type == 'PRI_DESTADD_TEXT':
                    mm.destAddress = mp.destAddress
                    if mm.destAddress:
                        mm.priority = mp.priority
                        mm.setFilingTime()
                        mm.nextCSN()
                        messageAFTN = MessageAFTN(self.logger, mp.text, mm.stationID, mm.address, mm.priority, mm.destAddress, mm.CSN, mm.filingTime, mm.dateTime)
                    else:
                        if mm.isFromDisk():
                            try:
                                self.logger.warning("%s has been erased (no valid destination address)", os.path.basename(self.dataFromFiles[0][1]))
                                os.unlink(self.dataFromFiles[0][1])
                            except OSError, e:
                                (type, value, tb) = sys.exc_info()
                                self.logger.error("Unable to unlink %s ! Type: %s, Value: %s" % (self.dataFromFiles[0][1], type, value))
                            del self.dataFromFiles[0]
                            mm.clearPartsToSend()
                        continue

                else:
                    # True if mm.header is in the routing table with destination addresses
                    #if mm.header == None: mm.header = 'SACN31 CWAO'
                    if mm.setInfos(mm.header, rewrite):
                        messageAFTN = MessageAFTN(self.logger, data[index], mm.stationID, mm.address, mm.priority,
                                              mm.destAddress, mm.CSN, mm.filingTime, mm.dateTime)
                    else:
                        if mm.isFromDisk():
                            try:
                                self.logger.warning("%s has been erased", os.path.basename(self.dataFromFiles[0][1]))
                                os.unlink(self.dataFromFiles[0][1])
                            except OSError, e:
                                (type, value, tb) = sys.exc_info()
                                self.logger.error("Unable to unlink %s ! Type: %s, Value: %s" % (self.dataFromFiles[0][1], type, value))
                            del self.dataFromFiles[0]
                            mm.clearPartsToSend()

                        continue
                        
                # If it is the first time we sent this message, we archive it.
                #if not rewrite:
                self.logger.debug('Message as it will be sent:')
                self.logger.debug('\n' + messageAFTN.message)
                messageAFTN.setLogger(None)
                mm.archiveObject(self.archivePath + mm.CSN, messageAFTN)

                nbBytesToSend = len(messageAFTN.message)

                while nbBytesToSend > 0:
                    nbBytesSent = self.socket.send(messageAFTN.message)
                    # This sleep is machiavelic! It permits to see many potential problems
                    #if self.subscriber:
                    #    time.sleep(5)
                    messageAFTN.message = messageAFTN.message[nbBytesSent:]
                    nbBytesToSend = len(messageAFTN.message)
                    self.totBytes += nbBytesSent

                mm.setWaitingForAck(messageAFTN.getTransmitID())
                mm.incrementSendingInfos()

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

                # Log the fact that the message has been sent 
                if not rewrite:
                    if mm.isFromDisk():
                        mm.filenameToSend = os.path.basename(self.dataFromFiles[0][1])
                        mm.filenameToErase = self.dataFromFiles[0][1]
                    else:
                        if mp.type == 'SVC':
                            mm.filenameToSend = mp.getServiceName(mp.getServiceType())
                        elif mp.type in MessageParser.REPLY_TYPES:
                            mm.filenameToSend = ''
                        else:
                            # We should never go here
                            self.logger.error("Unknown message type has just been sent. See code!")

                    self.logger.info("(%5d Bytes) Message %s %s (%s/%s) has been sent => delivered" % (self.totBytes, getWord(mm.type), 
                                       mm.filenameToSend, mm.nextPart+1, mm.numberOfParts))
                else:
                    self.logger.info("(%5d Bytes) Message %s %s (%s/%s) has been resent => delivered" % (self.totBytes, getWord(mm.type), 
                                       mm.filenameToSend, mm.nextPart+1, mm.numberOfParts))

                # Reset byte count
                self.totBytes = 0
                
                # If the last part of a message (big or not) has been sent, erase the file.
                # We do this even if we have not yet received the ack. At this point, we have already
                # archived all the parts with their CSN as filename.
                if mm.isLastPart(): 
                    if mm.isFromDisk() and not rewrite:
                        try:
                            os.unlink(self.dataFromFiles[0][1])
                            self.logger.debug("%s has been erased", os.path.basename(self.dataFromFiles[0][1]))
                        except OSError, e:
                            (type, value, tb) = sys.exc_info()
                            self.logger.error("Unable to unlink %s ! Type: %s, Value: %s" % (self.dataFromFiles[0][1], type, value))
                        del self.dataFromFiles[0]