<s> import logging <EOL> class NullHandler ( logging . Handler ) : <EOL> def emit ( self , record ) : <EOL> pass <EOL> log = logging . getLogger ( '<STR_LIT>' ) <EOL> log . setLevel ( logging . ERROR ) <EOL> log . addHandler ( NullHandler ( ) ) <EOL> import time <EOL> import threading <EOL> import random <EOL> import coapDefines as d <EOL> import coapException as e <EOL> import coapUtils as u <EOL> import coapMessage as m <EOL> class coapTransmitter ( threading . Thread ) : <EOL> '''<STR_LIT>''' <EOL> STATE_INIT = '<STR_LIT>' <EOL> STATE_TXCON = '<STR_LIT>' <EOL> STATE_TXNON = '<STR_LIT>' <EOL> STATE_WAITFORACK = '<STR_LIT>' <EOL> STATE_ACKRX = '<STR_LIT>' <EOL> STATE_WAITFOREXPIRATIONMID = '<STR_LIT>' <EOL> STATE_WAITFORRESP = '<STR_LIT>' <EOL> STATE_RESPRX = '<STR_LIT>' <EOL> STATE_TXACK = '<STR_LIT>' <EOL> STATE_ALL = [ <EOL> STATE_INIT , <EOL> STATE_TXCON , <EOL> STATE_TXNON , <EOL> STATE_WAITFORACK , <EOL> STATE_WAITFOREXPIRATIONMID , <EOL> STATE_WAITFORRESP , <EOL> STATE_TXACK , <EOL> ] <EOL> def __init__ ( self , sendFunc , srcIp , srcPort , destIp , destPort , confirmable , messageId , code , token , options , payload , ackTimeout , respTimeout ) : <EOL> '''<STR_LIT>''' <EOL> log . debug ( '<STR_LIT>' ) <EOL> self . sendFunc = sendFunc <EOL> self . srcIp = srcIp <EOL> self . srcPort = srcPort <EOL> self . destIp = destIp <EOL> self . destPort = destPort <EOL> self . confirmable = confirmable <EOL> self . messageId = messageId <EOL> self . code = code <EOL> self . token = token <EOL> self . options = options <EOL> self . payload = payload <EOL> self . dataLock = threading . Lock ( ) <EOL> self . fsmSem = threading . Lock ( ) <EOL> self . startLock = threading . Lock ( ) <EOL> self . endLock = threading . Lock ( ) <EOL> self . stateLock = threading . RLock ( ) <EOL> self . rxMsgEvent = threading . Event ( ) <EOL> self . receivedACK = None <EOL> self . receivedResp = None <EOL> self . coapResponse = None <EOL> self . coapError = None <EOL> self . state = self . STATE_INIT <EOL> self . maxRetransmit = d . DFLT_MAX_RETRANSMIT <EOL> self . numTxCON = <NUM_LIT:0> <EOL> self . ackTimeout = ackTimeout <EOL> self . respTimeout = respTimeout <EOL> self . fsmGoOn = True <EOL> self . fsmAction = { <EOL> self . STATE_INIT : self . _action_INIT , <EOL> self . STATE_TXCON : self . _action_TXCON , <EOL> self . STATE_TXNON : self . _action_TXNON , <EOL> self . STATE_WAITFORACK : self . _action_WAITFORACK , <EOL> self . STATE_ACKRX : self . _action_ACKRX , <EOL> self . STATE_WAITFOREXPIRATIONMID : self . _action_WAITFOREXPIRATIONMID , <EOL> self . STATE_WAITFORRESP : self . _action_WAITFORRESP , <EOL> self . STATE_RESPRX : self . _action_RESPRX , <EOL> self . STATE_TXACK : self . _action_TXACK , <EOL> } <EOL> threading . Thread . __init__ ( self ) <EOL> self . name = '<STR_LIT>' . format ( <EOL> self . srcIp , <EOL> self . srcPort , <EOL> self . messageId , <EOL> self . token , <EOL> self . destIp , <EOL> self . destPort , <EOL> ) <EOL> self . startLock . acquire ( ) <EOL> self . endLock . acquire ( ) <EOL> self . start ( ) <EOL> def transmit ( self ) : <EOL> '''<STR_LIT>''' <EOL> log . debug ( '<STR_LIT>' ) <EOL> self . startLock . release ( ) <EOL> self . endLock . acquire ( ) <EOL> with self . dataLock : <EOL> if self . coapError : <EOL> assert not self . coapResponse <EOL> raise self . coapError <EOL> if self . coapResponse : <EOL> assert not self . coapError <EOL> return self . coapResponse <EOL> raise SystemError ( '<STR_LIT>' ) <EOL> def getState ( self ) : <EOL> with self . stateLock : <EOL> return self . state <EOL> def receiveMessage ( self , timestamp , srcIp , srcPort , message ) : <EOL> assert srcIp == self . destIp <EOL> assert srcPort == self . destPort <EOL> assert ( message [ '<STR_LIT>' ] == self . token ) or ( message [ '<STR_LIT>' ] == self . messageId ) <EOL> log . debug ( '<STR_LIT>' . format ( timestamp , srcIp , srcPort , message ) ) <EOL> if message [ '<STR_LIT:code>' ] not in d . METHOD_ALL + d . COAP_RC_ALL_SUCCESS : <EOL> message = e . coapRcFactory ( message [ '<STR_LIT:code>' ] ) <EOL> with self . dataLock : <EOL> self . LastRxPacket = ( timestamp , srcIp , srcPort , message ) <EOL> self . rxMsgEvent . set ( ) <EOL> def run ( self ) : <EOL> try : <EOL> self . startLock . acquire ( ) <EOL> log . debug ( '<STR_LIT>' ) <EOL> while self . fsmGoOn : <EOL> self . fsmSem . acquire ( ) <EOL> log . debug ( '<STR_LIT>' . format ( self . getState ( ) ) ) <EOL> self . fsmAction [ self . getState ( ) ] ( ) <EOL> with self . dataLock : <EOL> if self . coapError or self . coapResponse : <EOL> self . endLock . release ( ) <EOL> self . fsmGoOn = False <EOL> except Exception as err : <EOL> log . critical ( u . formatCrashMessage ( <EOL> threadName = self . name , <EOL> error = err <EOL> ) <EOL> ) <EOL> def _action_INIT ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> if self . confirmable : <EOL> self . _setState ( self . STATE_TXCON ) <EOL> else : <EOL> self . _setState ( self . STATE_TXNON ) <EOL> self . _kickFsm ( ) <EOL> def _action_TXCON ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> if self . numTxCON > self . maxRetransmit + <NUM_LIT:1> : <EOL> self . coapError = e . coapTimeout ( '<STR_LIT>' . format ( <EOL> self . numTxCON , <EOL> self . maxRetransmit + <NUM_LIT:1> , <EOL> ) <EOL> ) <EOL> return <EOL> message = m . buildMessage ( <EOL> msgtype = d . TYPE_CON , <EOL> token = self . token , <EOL> code = self . code , <EOL> messageId = self . messageId , <EOL> options = self . options , <EOL> payload = self . payload , <EOL> ) <EOL> self . sendFunc ( <EOL> destIp = self . destIp , <EOL> destPort = self . destPort , <EOL> msg = message , <EOL> ) <EOL> self . numTxCON += <NUM_LIT:1> <EOL> self . _setState ( self . STATE_WAITFORACK ) <EOL> self . _kickFsm ( ) <EOL> def _action_TXNON ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> message = m . buildMessage ( <EOL> msgtype = d . TYPE_NON , <EOL> token = self . token , <EOL> code = self . code , <EOL> messageId = self . messageId , <EOL> options = self . options , <EOL> payload = self . payload , <EOL> ) <EOL> self . sendFunc ( <EOL> destIp = self . destIp , <EOL> destPort = self . destPort , <EOL> msg = message , <EOL> ) <EOL> self . _setState ( self . STATE_WAITFORRESP ) <EOL> self . _kickFsm ( ) <EOL> def _action_WAITFORACK ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> startTime = time . time ( ) <EOL> ackMaxWait = self . ackTimeout * random . uniform ( <NUM_LIT:1> , d . DFLT_ACK_RANDOM_FACTOR ) <EOL> while True : <EOL> waitTimeLeft = startTime + ackMaxWait - time . time ( ) <EOL> if self . rxMsgEvent . wait ( timeout = waitTimeLeft ) : <EOL> with self . dataLock : <EOL> ( timestamp , srcIp , srcPort , message ) = self . LastRxPacket <EOL> if isinstance ( message , e . coapRc ) : <EOL> with self . dataLock : <EOL> self . coapError = message <EOL> return <EOL> elif ( <EOL> message [ '<STR_LIT:type>' ] == d . TYPE_ACK and <EOL> message [ '<STR_LIT>' ] == self . messageId <EOL> ) : <EOL> with self . dataLock : <EOL> self . receivedACK = ( timestamp , srcIp , srcPort , message ) <EOL> self . _setState ( self . STATE_ACKRX ) <EOL> self . _kickFsm ( ) <EOL> return <EOL> else : <EOL> self . _setState ( self . STATE_TXCON ) <EOL> self . _kickFsm ( ) <EOL> return <EOL> def _action_ACKRX ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> with self . dataLock : <EOL> assert self . receivedACK <EOL> ( timestamp , srcIp , srcPort , message ) = self . receivedACK <EOL> if message [ '<STR_LIT:code>' ] == d . COAP_RC_NONE : <EOL> self . _setState ( self . STATE_WAITFORRESP ) <EOL> self . _kickFsm ( ) <EOL> else : <EOL> with self . dataLock : <EOL> self . coapResponse = message <EOL> def _action_WAITFOREXPIRATIONMID ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> raise NotImplementedError ( ) <EOL> def _action_WAITFORRESP ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> startTime = time . time ( ) <EOL> while True : <EOL> waitTimeLeft = startTime + self . respTimeout - time . time ( ) <EOL> if self . rxMsgEvent . wait ( timeout = waitTimeLeft ) : <EOL> with self . dataLock : <EOL> ( timestamp , srcIp , srcPort , message ) = self . LastRxPacket <EOL> if isinstance ( message , e . coapRc ) : <EOL> with self . dataLock : <EOL> self . coapError = message <EOL> return <EOL> elif ( <EOL> ( <EOL> message [ '<STR_LIT:type>' ] == d . TYPE_CON or <EOL> message [ '<STR_LIT:type>' ] == d . TYPE_NON <EOL> ) and <EOL> message [ '<STR_LIT>' ] == self . token <EOL> ) : <EOL> with self . dataLock : <EOL> self . receivedResp = ( timestamp , srcIp , srcPort , message ) <EOL> self . _setState ( self . STATE_RESPRX ) <EOL> self . _kickFsm ( ) <EOL> return <EOL> else : <EOL> self . coapError = e . coapTimeout ( '<STR_LIT>' . format ( <EOL> self . respTimeout , <EOL> ) <EOL> ) <EOL> return <EOL> def _action_RESPRX ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> with self . dataLock : <EOL> ( timestamp , srcIp , srcPort , message ) = self . receivedResp <EOL> if message [ '<STR_LIT:type>' ] == d . TYPE_CON : <EOL> self . _setState ( self . STATE_TXACK ) <EOL> elif message [ '<STR_LIT:type>' ] == d . TYPE_NON : <EOL> with self . dataLock : <EOL> self . coapResponse = message <EOL> else : <EOL> raise SystemError ( '<STR_LIT>' . format ( message [ '<STR_LIT:type>' ] ) ) <EOL> self . _kickFsm ( ) <EOL> def _action_TXACK ( self ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> with self . dataLock : <EOL> ( timestamp , srcIp , srcPort , message ) = self . receivedResp <EOL> message = m . buildMessage ( <EOL> msgtype = d . TYPE_ACK , <EOL> token = None , <EOL> code = d . COAP_RC_NONE , <EOL> messageId = message [ '<STR_LIT>' ] , <EOL> ) <EOL> self . sendFunc ( <EOL> destIp = message [ '<STR_LIT>' ] , <EOL> destPort = message [ '<STR_LIT>' ] , <EOL> msg = message , <EOL> ) <EOL> with self . dataLock : <EOL> self . coapResponse = message <EOL> self . _kickFsm ( ) <EOL> def _kickFsm ( self ) : <EOL> self . fsmSem . release ( ) <EOL> def _setState ( self , newState ) : <EOL> with self . stateLock : <EOL> self . state = newState <EOL> log . debug ( '<STR_LIT>' . format ( self . name , newState ) ) </s>
