def disassemble_ipv6(self,ipv6): ''' Turn byte array representing IPv6 packets into into dictionary of fields. See http://tools.ietf.org/html/rfc2460#page-4. :param ipv6: [in] Byte array representing an IPv6 packet. :raises: ValueError when some part of the process is not defined in the standard. :raises: NotImplementedError when some part of the process is defined in the standard, but not implemented in this module. :returns: A dictionary of fields. ''' if len(ipv6)<self.IPv6_HEADER_LEN: raise ValueError('Packet too small ({0} bytes) no space for IPv6 header'.format(len(ipv6))) returnVal = {} returnVal['version'] = ipv6[0] >> 4 if returnVal['version']!=6: raise ValueError('Not an IPv6 packet, version=={0}'.format(returnVal['version'])) returnVal['traffic_class'] = ((ipv6[0] & 0x0F) << 4) + (ipv6[1] >> 4) returnVal['flow_label'] = ((ipv6[1] & 0x0F) << 16) + (ipv6[2] << 8) + ipv6[3] returnVal['payload_length'] = u.buf2int(ipv6[4:6]) returnVal['next_header'] = ipv6[6] returnVal['hop_limit'] = ipv6[7] returnVal['src_addr'] = ipv6[8:8+16] returnVal['dst_addr'] = ipv6[24:24+16] returnVal['payload'] = ipv6[40:] return returnVal
def _meshToV6_notif(self, sender, signal, data): ''' Converts a 6LowPAN packet into a IPv6 packet. This function dispatches the IPv6 packet with signal 'according to the destination address, protocol_type and port'. ''' try: ipv6dic = {} #build lowpan dictionary from the data ipv6dic = self.lowpan_to_ipv6(data) success = True dispatchSignal = None #read next header if ipv6dic['next_header'] == self.IANA_IPv6HOPHEADER: #hop by hop header present, check flags and parse if (ipv6dic['hop_flags'] & self.O_FLAG) == self.O_FLAG: #error -- this packet has gone downstream somewhere. log.error( "detected possible downstream link on upstream route from {0}" .format(",".join(str(c) for c in ipv6dic['src_addr']))) if (ipv6dic['hop_flags'] & self.R_FLAG) == self.R_FLAG: #error -- loop in the route log.error( "detected possible loop on upstream route from {0}". format(",".join(str(c) for c in ipv6dic['src_addr']))) #skip the header and process the rest of the message. ipv6dic['next_header'] = ipv6dic['hop_next_header'] #=================================================================== if ipv6dic['next_header'] == self.IPV6_HEADER: #ipv6 header (inner) ipv6dic_inner = {} # prasing the iphc inner header and get the next_header ipv6dic_inner = self.lowpan_to_ipv6( [ipv6dic['pre_hop'], ipv6dic['payload']]) ipv6dic['next_header'] = ipv6dic_inner['next_header'] ipv6dic['payload'] = ipv6dic_inner['payload'] ipv6dic['payload_length'] = ipv6dic_inner['payload_length'] ipv6dic['src_addr'] = ipv6dic_inner['src_addr'] if not ipv6dic.has_key('hop_limit'): ipv6dic['hop_limit'] = ipv6dic_inner['hop_limit'] ipv6dic['dst_addr'] = ipv6dic_inner['dst_addr'] ipv6dic['flow_label'] = ipv6dic_inner['flow_label'] if ipv6dic['next_header'] == self.IANA_ICMPv6: #icmp header if len(ipv6dic['payload']) < 5: log.critical( "wrong payload lenght on ICMPv6 packet {0}".format( ",".join(str(c) for c in data))) print "wrong payload lenght on ICMPv6 packet {0}".format( ",".join(str(c) for c in data)) return ipv6dic['icmpv6_type'] = ipv6dic['payload'][0] ipv6dic['icmpv6_code'] = ipv6dic['payload'][1] ipv6dic['icmpv6_checksum'] = ipv6dic['payload'][2:4] ipv6dic['app_payload'] = ipv6dic['payload'][4:] #this function does the job dispatchSignal = (tuple(ipv6dic['dst_addr']), self.PROTO_ICMPv6, ipv6dic['icmpv6_type']) elif ipv6dic['next_header'] == self.IANA_UDP: #udp header -- can be compressed.. assume first it is not compressed. if len(ipv6dic['payload']) < 5: log.critical( "wrong payload lenght on UDP packet {0}".format( ",".join(str(c) for c in data))) print "wrong payload lenght on UDP packet {0}".format( ",".join(str(c) for c in data)) return if ipv6dic['payload'][0] & self.NHC_UDP_MASK == self.NHC_UDP_ID: lowpan_nhc = ipv6dic['payload'][0] udp_header_length = 0 newUdp = [] newUdp_header_length = 0 if lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_INLINE: src_port = u.buf2int(ipv6dic['payload'][1:3]) dest_port = u.buf2int(ipv6dic['payload'][3:5]) udp_header_length = 5 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_16S_8D: src_port = u.buf2int(ipv6dic['payload'][1:3]) dest_port = 0xf000 + ipv6dic['payload'][3] udp_header_length = 4 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_8S_16D: src_port = 0xf000 + ipv6dic['payload'][1] dest_port = u.buf2int(ipv6dic['payload'][2:4]) udp_header_length = 4 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_4S_4D: src_port = 0xf0b0 + ( (ipv6dic['payload'][1] >> 4) & 0x0f) dest_port = 0xf0b0 + ( (ipv6dic['payload'][1] >> 0) & 0x0f) udp_header_length = 2 newUdp = [src_port >> 8, src_port & 0x00ff] newUdp += [dest_port >> 8, dest_port & 0x00ff] idxLen = len(newUdp) # remember index of payload length newUdp += [0x00, 0x00] # length (placeholder) newUdp_header_length += 2 udp_header_length += 2 # skip two bytes checksum following idxCS = len(newUdp) # remember index of checksum newUdp += [0x00, 0x00] # Checksum (placeholder) newUdp_header_length += 2 #append payload to compute crc again newUdp += ipv6dic['payload'][ udp_header_length:] # data octets udp_len = [ 0, len(ipv6dic['payload'][udp_header_length:]) + 8 ] newUdp[idxLen] = udp_len[0] newUdp[idxLen + 1] = udp_len[1] checksum = u.calculatePseudoHeaderCRC( ipv6dic['src_addr'], ipv6dic['dst_addr'], udp_len, [0, ipv6dic['next_header']], newUdp) #fill crc with the right value. newUdp[idxCS] = checksum[0] newUdp[idxCS + 1] = checksum[1] #keep fields for later processing if needed ipv6dic['udp_src_port'] = u.buf2int(newUdp[0:2]) ipv6dic['udp_dest_port'] = u.buf2int(newUdp[2:4]) ipv6dic['udp_length'] = newUdp[4:6] ipv6dic['udp_checksum'] = newUdp[6:8] ipv6dic['app_payload'] = newUdp[8:] #substitute udp header by the uncompressed header. ipv6dic['payload'] = newUdp ipv6dic['payload_length'] = len(newUdp) else: #No UDP header compressed ipv6dic['udp_src_port'] = u.buf2int(ipv6dic['payload'][:2]) ipv6dic['udp_dest_port'] = u.buf2int( ipv6dic['payload'][2:4]) ipv6dic['udp_length'] = ipv6dic['payload'][4:6] ipv6dic['udp_checksum'] = ipv6dic['payload'][6:8] ipv6dic['app_payload'] = ipv6dic['payload'][8:] dispatchSignal = (tuple(ipv6dic['dst_addr']), self.PROTO_UDP, ipv6dic['udp_dest_port']) #keep payload and app_payload in case we want to assemble the message later. #as source address is being retrieved from the IPHC header, the signal includes it in case #receiver such as RPL DAO processing needs to know the source. success = self._dispatchProtocol( dispatchSignal, (ipv6dic['src_addr'], ipv6dic['app_payload'])) if success: return # assemble the packet and dispatch it again as nobody answer ipv6pkt = self.reassemble_ipv6_packet(ipv6dic) self.dispatch('v6ToInternet', ipv6pkt) except (ValueError, NotImplementedError) as err: log.error(err) pass
def _meshToV6_notif(self,sender,signal,data): ''' Converts a 6LowPAN packet into a IPv6 packet. This function dispatches the IPv6 packet with signal 'according to the destination address, protocol_type and port'. ''' try: ipv6dic={} #build lowpan dictionary from the data ipv6dic = self.lowpan_to_ipv6(data) success = True dispatchSignal = None hopbyhop_header_present = False #read next header if ipv6dic['next_header']==self.IANA_IPv6HOPHEADER: # mark hop by hop header present, check hop_flags after obtaining src_addr in IPV6 header. hopbyhop_header_present = True #skip the header and process the rest of the message. ipv6dic['next_header'] = ipv6dic['hop_next_header'] #=================================================================== if ipv6dic['next_header']==self.IPV6_HEADER: #ipv6 header (inner) ipv6dic_inner = {} # parsing the iphc inner header and get the next_header ipv6dic_inner = self.lowpan_to_ipv6([ipv6dic['pre_hop'],ipv6dic['payload']]) ipv6dic['next_header'] = ipv6dic_inner['next_header'] ipv6dic['payload'] = ipv6dic_inner['payload'] ipv6dic['payload_length'] = ipv6dic_inner['payload_length'] ipv6dic['src_addr'] = ipv6dic_inner['src_addr'] if not ipv6dic.has_key('hop_limit'): ipv6dic['hop_limit'] = ipv6dic_inner['hop_limit'] ipv6dic['dst_addr'] = ipv6dic_inner['dst_addr'] ipv6dic['flow_label'] = ipv6dic_inner['flow_label'] if hopbyhop_header_present: #hop by hop header present, check hop_flags if (ipv6dic['hop_flags'] & self.O_FLAG) == self.O_FLAG: #error -- this packet has gone downstream somewhere. log.error("detected possible downstream link on upstream route from {0}".format(",".join(str(c) for c in ipv6dic['src_addr']))) if (ipv6dic['hop_flags'] & self.R_FLAG) == self.R_FLAG: #error -- loop in the route log.error("detected possible loop on upstream route from {0}".format(",".join(str(c) for c in ipv6dic['src_addr']))) if ipv6dic['next_header']==self.IANA_ICMPv6: #icmp header if len(ipv6dic['payload'])<5: log.critical("wrong payload lenght on ICMPv6 packet {0}".format(",".join(str(c) for c in data))) print "wrong payload lenght on ICMPv6 packet {0}".format(",".join(str(c) for c in data)) return ipv6dic['icmpv6_type']=ipv6dic['payload'][0] ipv6dic['icmpv6_code']=ipv6dic['payload'][1] ipv6dic['icmpv6_checksum']=ipv6dic['payload'][2:4] ipv6dic['app_payload']=ipv6dic['payload'][4:] #this function does the job dispatchSignal=(tuple(ipv6dic['dst_addr']),self.PROTO_ICMPv6,ipv6dic['icmpv6_type']) elif ipv6dic['next_header']==self.IANA_UDP: #udp header -- can be compressed.. assume first it is not compressed. if len(ipv6dic['payload'])<5: log.critical("wrong payload lenght on UDP packet {0}".format(",".join(str(c) for c in data))) print "wrong payload lenght on UDP packet {0}".format(",".join(str(c) for c in data)) return if ipv6dic['payload'][0] & self.NHC_UDP_MASK==self.NHC_UDP_ID: lowpan_nhc = ipv6dic['payload'][0] udp_header_length = 0 newUdp = [] newUdp_header_length = 0 if lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_INLINE: src_port = u.buf2int(ipv6dic['payload'][1:3]) dest_port = u.buf2int(ipv6dic['payload'][3:5]) udp_header_length = 5 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_16S_8D: src_port = u.buf2int(ipv6dic['payload'][1:3]) dest_port = 0xf000 + ipv6dic['payload'][3] udp_header_length = 4 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_8S_16D: src_port = 0xf000 + ipv6dic['payload'][1] dest_port = u.buf2int(ipv6dic['payload'][2:4]) udp_header_length = 4 elif lowpan_nhc & self.NHC_UDP_PORTS_MASK == self.NHC_UDP_PORTS_4S_4D: src_port = 0xf0b0 +((ipv6dic['payload'][1] >> 4) & 0x0f) dest_port = 0xf0b0 +((ipv6dic['payload'][1] >> 0) & 0x0f) udp_header_length = 2 newUdp = [src_port >>8 , src_port & 0x00ff] newUdp += [dest_port >>8 , dest_port & 0x00ff] idxLen = len(newUdp) # remember index of payload length newUdp += [0x00,0x00] # length (placeholder) newUdp_header_length += 2 udp_header_length += 2 # skip two bytes checksum following idxCS = len(newUdp) # remember index of checksum newUdp += [0x00,0x00] # Checksum (placeholder) newUdp_header_length += 2 #append payload to compute crc again newUdp += ipv6dic['payload'][udp_header_length:] # data octets udp_len = [0, len(ipv6dic['payload'][udp_header_length:])+8] newUdp[idxLen] = udp_len[0] newUdp[idxLen+1] = udp_len[1] checksum = u.calculatePseudoHeaderCRC(ipv6dic['src_addr'],ipv6dic['dst_addr'],udp_len,[0,ipv6dic['next_header']],newUdp) #fill crc with the right value. newUdp[idxCS] = checksum[0] newUdp[idxCS+1] = checksum[1] #keep fields for later processing if needed ipv6dic['udp_src_port'] = u.buf2int(newUdp[0:2]) ipv6dic['udp_dest_port'] = u.buf2int(newUdp[2:4]) ipv6dic['udp_length'] = newUdp[4:6] ipv6dic['udp_checksum'] = newUdp[6:8] ipv6dic['app_payload'] = newUdp[8:] #substitute udp header by the uncompressed header. ipv6dic['payload'] = newUdp ipv6dic['payload_length'] = len(newUdp) else: #No UDP header compressed ipv6dic['udp_src_port']=u.buf2int(ipv6dic['payload'][:2]) ipv6dic['udp_dest_port']=u.buf2int(ipv6dic['payload'][2:4]) ipv6dic['udp_length']=ipv6dic['payload'][4:6] ipv6dic['udp_checksum']=ipv6dic['payload'][6:8] ipv6dic['app_payload']=ipv6dic['payload'][8:] dispatchSignal=(tuple(ipv6dic['dst_addr']),self.PROTO_UDP,ipv6dic['udp_dest_port']) #keep payload and app_payload in case we want to assemble the message later. #as source address is being retrieved from the IPHC header, the signal includes it in case #receiver such as RPL DAO processing needs to know the source. success = self._dispatchProtocol(dispatchSignal,(ipv6dic['src_addr'],ipv6dic['app_payload'])) if success: return # assemble the packet and dispatch it again as nobody answer ipv6pkt=self.reassemble_ipv6_packet(ipv6dic) self.dispatch('v6ToInternet',ipv6pkt) except (ValueError,IndexError,NotImplementedError) as err: log.error(err) pass
def _latency_notif(self, sender, signal, data): ''' This method is invoked whenever a UDP packet is send from a mote from UDPLatency application. This application listens at port 61001 and computes the latency of a packet. Note that this app is crosslayer since the mote sends the data within a UDP packet and OpenVisualizer (ParserData) handles that packet and reads UDP payload to compute time difference. At the bridge module on the DAGroot, the ASN of the DAGroot is appended to the serial port to be able to know what is the ASN at reception side. Calculate latency values are in ms[SUPERFRAMELENGTH]. ''' address = ",".join(hex(c) for c in data[0]) latency = data[1] parent = ",".join(hex(c) for c in data[2]) SN = u.buf2int(data[3]) stats = {} # dictionary of stats if (self.latencyStats.get(str(address)) is None): # none for this node... create initial stats stats.update({'min': latency}) stats.update({'max': latency}) stats.update({'avg': latency}) stats.update({'pktRcvd': 1}) stats.update({'pktSent': (SN + 1)}) stats.update({'DUP': 0}) # changes of parent stats.update({'parentSwitch': 1}) else: # get and update stats = self.latencyStats.get(str(address)) if (stats.get('min') > latency): stats.update({'min': latency}) if (stats.get('max') < latency): stats.update({'max': latency}) stats.update({ 'avg': ((stats.get('avg') * stats.get('pktRcvd')) + latency) / (stats.get('pktRcvd') + 1) }) stats.update({'pktRcvd': (stats.get('pktRcvd') + 1)}) if (stats.get('prefParent') != parent): stats.update({'parentSwitch': (stats.get('parentSwitch') + 1) }) # record parent change since last message # check if packet is a duplicate if (SN == stats.get('SN')): # increment duplicated stats.update({'DUP': (stats.get('DUP') + 1)}) # update pktSent if (SN > stats.get('pktSent')): stats.update({'pktSent': SN + 1}) # these fields are common stats.update({'SN': SN}) # calculate PLR PLR = self._calculatePLR(stats.get('pktRcvd'), stats.get('pktSent')) stats.update({'PLR': PLR}) stats.update({'lastVal': latency}) stats.update({'prefParent': parent}) stats.update({'lastMsg': datetime.now()}) # add to dictionary and compute stats... self.stateLock.acquire() self.latencyStats.update({str(address): stats}) self.stateLock.release() # log stats if log.isEnabledFor(logging.DEBUG): log.debug( self._formatUDPLatencyStat(self.latencyStats.get(str(address)), str(address)))
def _meshToV6_notif(self,sender,signal,data): ''' Converts a 6LowPAN packet into a IPv6 packet. This function dispatches the IPv6 packet with signal 'according to the destination address, protocol_type and port'. ''' try: ipv6dic={} #build lowpan dictionary from the data ipv6dic = self.lowpan_to_ipv6(data) success = True dispatchSignal = None #read next header if (ipv6dic['next_header']==self.IANA_IPv6HOPHEADER): #hop by hop header present, check flags and parse if ((ipv6dic['hop_flags'] & self.O_FLAG) == self.O_FLAG): #error -- this packet has gone downstream somewhere. log.error("detected possible downstream link on upstream route from {0}".format(",".join(str(c) for c in ipv6dic['src_addr']))) if ((ipv6dic['hop_flags'] & self.R_FLAG) == self.R_FLAG): #error -- loop in the route log.error("detected possible loop on upstream route from {0}".format(",".join(str(c) for c in ipv6dic['src_addr']))) #skip the header and process the rest of the message. ipv6dic['next_header'] = ipv6dic['hop_next_header'] #=================================================================== if (ipv6dic['next_header']==self.IPV6_HEADER): #ipv6 header (inner) ipv6dic_inner = {} # prasing the iphc inner header and get the next_header ipv6dic_inner = self.lowpan_to_ipv6([ipv6dic['pre_hop'],ipv6dic['payload']]) ipv6dic['next_header'] = ipv6dic_inner['next_header'] ipv6dic['payload'] = ipv6dic_inner['payload'] ipv6dic['payload_length'] = ipv6dic_inner['payload_length'] ipv6dic['src_addr'] = ipv6dic_inner['src_addr'] if not ipv6dic.has_key('hop_limit'): ipv6dic['hop_limit'] = ipv6dic_inner['hop_limit'] ipv6dic['dst_addr'] = ipv6dic_inner['dst_addr'] ipv6dic['flow_label'] = ipv6dic_inner['flow_label'] if (ipv6dic['next_header']==self.IANA_ICMPv6): #icmp header if (len(ipv6dic['payload'])<5): log.critical("wrong payload lenght on ICMPv6 packet {0}".format(",".join(str(c) for c in data))) print "wrong payload lenght on ICMPv6 packet {0}".format(",".join(str(c) for c in data)) return ipv6dic['icmpv6_type']=ipv6dic['payload'][0] ipv6dic['icmpv6_code']=ipv6dic['payload'][1] ipv6dic['icmpv6_checksum']=ipv6dic['payload'][2:4] ipv6dic['app_payload']=ipv6dic['payload'][4:] #this function does the job dispatchSignal=(tuple(ipv6dic['dst_addr']),self.PROTO_ICMPv6,ipv6dic['icmpv6_type']) elif(ipv6dic['next_header']==self.IANA_UDP): #udp header -- can be compressed.. assume first it is not compressed. if (len(ipv6dic['payload'])<5): log.critical("wrong payload lenght on UDP packet {0}".format(",".join(str(c) for c in data))) print "wrong payload lenght on UDP packet {0}".format(",".join(str(c) for c in data)) return if (ipv6dic['payload'][0] & self.NHC_UDP_MASK==self.NHC_UDP_ID): oldUdp=ipv6dic['payload'][:5] #re-arrange fields and inflate newUdp = [] newUdp += oldUdp[1:3] # Source Port newUdp += oldUdp[3:5] # Destination Port length = 8+len(pkt[5:]) newUdp += [(length & 0xFF00) >> 8] # Length newUdp += [(length & 0x00FF) >> 0] idxCS = len(newUdp) # remember index of checksum newUdp += [0x00,0x00] # Checksum (placeholder) #append payload to compute crc again newUdp += ipv6dic['payload'][5:] # data octets checksum = u.calculateCRC(newUdp) #fill crc with the right value. newUdp[idxCS] = checksum[0] newUdp[idxCS+1] = checksum[1] #keep fields for later processing if needed ipv6dic['udp_src_port']=newUdp[:2] ipv6dic['udp_dest_port']=newUdp[2:4] ipv6dic['udp_length']=newUdp[4:6] ipv6dic['udp_checksum']=newUdp[6:8] ipv6dic['app_payload']=newUdp[8:] #substitute udp header by the uncompressed header. ipv6dic['payload'] =newUdp[:8] + ipv6dic['payload'][5:] else: #No UDP header compressed ipv6dic['udp_src_port']=ipv6dic['payload'][:2] ipv6dic['udp_dest_port']=ipv6dic['payload'][2:4] ipv6dic['udp_length']=ipv6dic['payload'][4:6] ipv6dic['udp_checksum']=ipv6dic['payload'][6:8] ipv6dic['app_payload']=ipv6dic['payload'][8:] dispatchSignal=(tuple(ipv6dic['dst_addr']),self.PROTO_UDP,u.buf2int(ipv6dic['udp_dest_port'])) #keep payload and app_payload in case we want to assemble the message later. #ass source address is being retrieved from the IPHC header, the signal includes it in case #receiver such as RPL DAO processing needs to know the source. success = self._dispatchProtocol(dispatchSignal,(ipv6dic['src_addr'],ipv6dic['app_payload'])) if success == True: return # assemble the packet and dispatch it again as nobody answer ipv6pkt=self.reassemble_ipv6_packet(ipv6dic) self.dispatch('v6ToInternet',ipv6pkt) except (ValueError,NotImplementedError) as err: log.error(err) pass
def _latency_notif(self,sender,signal,data): ''' This method is invoked whenever a UDP packet is send from a mote from UDPLatency application. This application listens at port 61001 and computes the latency of a packet. Note that this app is crosslayer since the mote sends the data within a UDP packet and OpenVisualizer (ParserData) handles that packet and reads UDP payload to compute time difference. At the bridge module on the DAGroot, the ASN of the DAGroot is appended to the serial port to be able to know what is the ASN at reception side. Calculate latency values are in ms[SUPERFRAMELENGTH]. ''' address = ",".join(hex(c) for c in data[0]) latency = data[1] parent = ",".join(hex(c) for c in data[2]) SN = u.buf2int(data[3]) stats = {} # dictionary of stats if (self.latencyStats.get(str(address)) is None): # none for this node... create initial stats stats.update({'min':latency}) stats.update({'max':latency}) stats.update({'avg':latency}) stats.update({'pktRcvd':1}) stats.update({'pktSent':(SN + 1)}) stats.update({'DUP':0}) # changes of parent stats.update({'parentSwitch':1}) else: # get and update stats = self.latencyStats.get(str(address)) if (stats.get('min') > latency): stats.update({'min':latency}) if (stats.get('max') < latency): stats.update({'max':latency}) stats.update({'avg':((stats.get('avg') * stats.get('pktRcvd')) + latency) / (stats.get('pktRcvd') + 1)}) stats.update({'pktRcvd':(stats.get('pktRcvd') + 1)}) if (stats.get('prefParent') != parent): stats.update({'parentSwitch':(stats.get('parentSwitch')+1)})# record parent change since last message # check if packet is a duplicate if (SN == stats.get('SN')): # increment duplicated stats.update({'DUP':(stats.get('DUP') + 1)}) # update pktSent if (SN > stats.get('pktSent')): stats.update({'pktSent':SN + 1}) # these fields are common stats.update({'SN':SN}) # calculate PLR PLR = self._calculatePLR(stats.get('pktRcvd'), stats.get('pktSent')) stats.update({'PLR':PLR}) stats.update({'lastVal':latency}) stats.update({'prefParent':parent}) stats.update({'lastMsg':datetime.now()}) # add to dictionary and compute stats... self.stateLock.acquire() self.latencyStats.update({str(address):stats}) self.stateLock.release() # log stats if log.isEnabledFor(logging.DEBUG): log.debug(self._formatUDPLatencyStat(self.latencyStats.get(str(address)), str(address)))
def test_buf2int(expectedBuf2int): (expBuf, expInt) = json.loads(expectedBuf2int) assert u.buf2int(expBuf) == expInt