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]