mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
526 lines
21 KiB
Python
526 lines
21 KiB
Python
|
from __future__ import division
|
||
|
import time
|
||
|
import threading
|
||
|
import re
|
||
|
import random
|
||
|
import os
|
||
|
import binascii
|
||
|
|
||
|
from TCAction import PerformanceTCBase
|
||
|
from NativeLog import NativeLog
|
||
|
from NativeLog import HTMLGenerator
|
||
|
from comm import MeshPort
|
||
|
from Utility import Encoding
|
||
|
|
||
|
# check frequency in second
|
||
|
CHECK_FREQ = 0.05
|
||
|
# check timeout in seconds
|
||
|
CHECK_TIMEOUT = 30
|
||
|
# multicast group len
|
||
|
MULTICAST_GROUP_LEN = 2
|
||
|
|
||
|
|
||
|
LOG_PATH = os.path.join("..", "log")
|
||
|
|
||
|
def _convert_to_mesh_mac_format(value_in):
|
||
|
value_out = ""
|
||
|
match_list = re.findall("([0-9a-fA-F]+)", value_in)
|
||
|
try:
|
||
|
for i in range(6):
|
||
|
value_out += "%02X" % int(match_list[i], base=16)
|
||
|
pass
|
||
|
except StandardError, e:
|
||
|
NativeLog.add_exception_log(e)
|
||
|
raise e
|
||
|
return value_out
|
||
|
|
||
|
class SendRecvTime(threading.Thread):
|
||
|
def __init__(self):
|
||
|
threading.Thread.__init__(self)
|
||
|
self.setDaemon(True)
|
||
|
self.send_time = dict()
|
||
|
self.recv_time = dict()
|
||
|
self.send_time_lock = threading.Lock()
|
||
|
self.recv_time_lock = threading.Lock()
|
||
|
|
||
|
def add_send_time(self, key, timestamp):
|
||
|
with self.send_time_lock:
|
||
|
self.send_time[key] = timestamp
|
||
|
|
||
|
def add_recv_time(self, key, timestamp):
|
||
|
with self.recv_time_lock:
|
||
|
if key in self.recv_time.keys():
|
||
|
self.recv_time[key].append(timestamp)
|
||
|
else:
|
||
|
self.recv_time[key] = [timestamp]
|
||
|
|
||
|
def calculate(self):
|
||
|
# add compute delay time code here
|
||
|
print 'send dict len:', len(self.send_time)
|
||
|
print 'recv dict len:', len(self.recv_time)
|
||
|
recv_time_keys = self.recv_time.keys()
|
||
|
Max_delay_time = 0.0
|
||
|
Total_delay_time = 0.0
|
||
|
# for i in range(len(recv_time_keys)):
|
||
|
# key = recv_time_keys[i]
|
||
|
for key in recv_time_keys:
|
||
|
Total_delay_time_t = 0.0
|
||
|
if isinstance(self.recv_time[key], list):
|
||
|
for time1 in self.recv_time[key]:
|
||
|
if time1 - self.send_time[key] >= Max_delay_time:
|
||
|
Max_delay_time = time1 - self.send_time[key]
|
||
|
Total_delay_time_t += (time1 - self.send_time[key])
|
||
|
else:
|
||
|
pass
|
||
|
else:
|
||
|
if self.recv_time[key] - self.send_time[key] > Max_delay_time:
|
||
|
Max_delay_time = self.recv_time[key] - self.send_time[key]
|
||
|
Total_delay_time_t += (self.recv_time[key] - self.send_time[key])
|
||
|
Total_delay_time_t += (Total_delay_time_t / len(self.recv_time[key]))
|
||
|
Total_delay_time += Total_delay_time_t
|
||
|
Avg_delay_time = Total_delay_time / len(recv_time_keys)
|
||
|
loss_rate = (len(self.send_time.keys()) - len(self.recv_time.keys())) / len(self.send_time.keys())
|
||
|
return [Max_delay_time, Avg_delay_time, loss_rate]
|
||
|
pass
|
||
|
|
||
|
class EntitySendThread(threading.Thread):
|
||
|
def __init__(self, port, behavior, unicast_addr, send_delay, typ, device_mac_list, server_addr, send_recv_time):
|
||
|
threading.Thread.__init__(self)
|
||
|
self.setDaemon(True)
|
||
|
self.recv_data_cache = ""
|
||
|
self.packets_sent = 0
|
||
|
self.port = port
|
||
|
self.behavior = behavior
|
||
|
self.typ = typ
|
||
|
self.unicast_addr = unicast_addr
|
||
|
self.node_num = len(device_mac_list)
|
||
|
self.device_mac_list = list(device_mac_list)
|
||
|
self.server_addr = server_addr
|
||
|
if typ != "SERVER":
|
||
|
self.device_mac_list.remove(port.device_mac)
|
||
|
self.send_delay = send_delay
|
||
|
self.cache_lock = threading.Lock()
|
||
|
self.exit_event = threading.Event()
|
||
|
self.send_recv_time = send_recv_time
|
||
|
pass
|
||
|
|
||
|
def data_recv_callback(self, data):
|
||
|
with self.cache_lock:
|
||
|
self.recv_data_cache += data
|
||
|
if self.typ == "SSC":
|
||
|
while True:
|
||
|
if self.recv_data_cache is not None:
|
||
|
match = re.compile(".+\+MSEND1:\d+:OK", re.DOTALL)
|
||
|
res = match.search(self.recv_data_cache)
|
||
|
index = re.search("\+MSEND1:(\d+):OK", self.recv_data_cache)
|
||
|
if index is not None:
|
||
|
time1 = time.time()
|
||
|
index1 = int(index.group(1))
|
||
|
self.send_recv_time.add_send_time(index1, time1)
|
||
|
#print 'send index:', index1
|
||
|
process_index = res.group().split("MSEND1")
|
||
|
if len(process_index) > 1:
|
||
|
process_index_t = len(process_index[0]) + len("MSEND1")
|
||
|
self.recv_data_cache = self.recv_data_cache[process_index_t:]
|
||
|
else:
|
||
|
self.recv_data_cache = self.recv_data_cache[len(res.group()):]
|
||
|
else:
|
||
|
break
|
||
|
else:
|
||
|
break
|
||
|
pass
|
||
|
|
||
|
|
||
|
def __server_send_packet(self, dst_addr, option_list=None, group_addr=None):
|
||
|
ver = 0x0
|
||
|
flags = 0x0
|
||
|
proto = 0x0
|
||
|
index = random.randint(10000, 999999999)
|
||
|
if group_addr is not None:
|
||
|
len_t = hex(len(group_addr) * 6).split("0x")
|
||
|
if len(group_addr) <= 2:
|
||
|
option_list = "070" + len_t[1]
|
||
|
else:
|
||
|
option_list = "07" + len_t[1]
|
||
|
group = ""
|
||
|
for addr in group_addr:
|
||
|
group += _convert_to_mesh_mac_format(addr)
|
||
|
option_list += group
|
||
|
else:
|
||
|
option_list = None
|
||
|
if self.behavior == "broadcast":
|
||
|
dst_addr = "00:00:00:00:00:00"
|
||
|
elif self.behavior == "unicast":
|
||
|
if self.unicast_addr == "random":
|
||
|
dst_addr = random.choice(self.device_mac_list)
|
||
|
else:
|
||
|
dst_addr = self.unicast_addr
|
||
|
elif self.behavior == "p2p":
|
||
|
proto = 0x2
|
||
|
if self.unicast_addr == "random":
|
||
|
dst_addr = random.choice(self.device_mac_list)
|
||
|
else:
|
||
|
dst_addr = self.unicast_addr
|
||
|
packet = MeshPort.Packet(ver=ver, flags=flags, proto=proto,
|
||
|
dst_addr=dst_addr, src_addr=self.server_addr, option_list=option_list, data="A" * 100, index=index)
|
||
|
send_data = packet.dumps
|
||
|
try:
|
||
|
self.port.socket.send(send_data)
|
||
|
time2 = time.time()
|
||
|
self.send_recv_time.add_send_time(index, time2)
|
||
|
except StandardError, e:
|
||
|
NativeLog.add_exception_log(e)
|
||
|
return False
|
||
|
|
||
|
def __server_do_send(self):
|
||
|
if self.behavior == "broadcast":
|
||
|
if self.__server_send_packet(dst_addr="00:00:00:00:00:00", group_addr=None) is True:
|
||
|
self.packets_sent += self.node_num
|
||
|
elif self.behavior == "multicast":
|
||
|
random.shuffle(self.device_mac_list)
|
||
|
group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN]
|
||
|
if self.__server_send_packet(dst_addr="01:00:5E:00:00:00", group_addr=group_addr_list) is True:
|
||
|
self.packets_sent += MULTICAST_GROUP_LEN
|
||
|
elif self.behavior == "unicast":
|
||
|
if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True:
|
||
|
self.packets_sent += 1
|
||
|
elif self.behavior == "p2p":
|
||
|
if self.__server_send_packet(dst_addr=random.choice(self.device_mac_list), group_addr=None) is True:
|
||
|
self.packets_sent += 1
|
||
|
else:
|
||
|
NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior)
|
||
|
self.exit()
|
||
|
return
|
||
|
|
||
|
def __node_send_packet(self, dst_addr, group_addr=None):
|
||
|
send_data = ""
|
||
|
ret = False
|
||
|
if group_addr is not None:
|
||
|
len_t = hex(len(group_addr) * 6).split("0x")
|
||
|
if len(group_addr) <= 2:
|
||
|
option_list = "070" + len_t[1]
|
||
|
else:
|
||
|
option_list = "07" + len_t[1]
|
||
|
group = ""
|
||
|
for addr in group_addr:
|
||
|
group += _convert_to_mesh_mac_format(addr)
|
||
|
option_list += group
|
||
|
dst_addr = "01:00:5E:00:00:00"
|
||
|
send_data = "meshsend -S -d %s -o %s -l 100\r\n" % (dst_addr, option_list)
|
||
|
else:
|
||
|
if self.behavior == "broadcast":
|
||
|
dst_addr = "00:00:00:00:00:00"
|
||
|
send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr
|
||
|
elif self.behavior == "unicast":
|
||
|
if self.unicast_addr == "random":
|
||
|
dst_addr = random.choice(self.device_mac_list)
|
||
|
else:
|
||
|
dst_addr = self.unicast_addr
|
||
|
send_data = "meshsend -S -d %s -l 100\r\n" % dst_addr
|
||
|
elif self.behavior == "p2p":
|
||
|
if self.unicast_addr == "random":
|
||
|
dst_addr = random.choice(self.device_mac_list)
|
||
|
else:
|
||
|
dst_addr = self.unicast_addr
|
||
|
send_data = "meshsend -S -d %s -t 1 -l 100\r\n" % dst_addr
|
||
|
try:
|
||
|
self.port.write(send_data)
|
||
|
except StandardError, e:
|
||
|
NativeLog.add_exception_log(e)
|
||
|
pass
|
||
|
for i in range(int(CHECK_TIMEOUT / CHECK_FREQ)):
|
||
|
time.sleep(CHECK_FREQ)
|
||
|
with self.cache_lock:
|
||
|
if self.recv_data_cache.find("+MESHSEND:OK") != -1:
|
||
|
ret = True
|
||
|
break
|
||
|
elif self.recv_data_cache.find("+MESHSEND:ERROR") != -1:
|
||
|
break
|
||
|
return ret
|
||
|
|
||
|
|
||
|
def __node_do_send(self):
|
||
|
if self.behavior == "broadcast":
|
||
|
if self.__node_send_packet("00:00:00:00:00:00", group_addr=None) is True:
|
||
|
self.packets_sent += self.node_num
|
||
|
elif self.behavior == "multicast":
|
||
|
random.shuffle(self.device_mac_list)
|
||
|
group_addr_list = self.device_mac_list[:MULTICAST_GROUP_LEN]
|
||
|
if self.__node_send_packet("01:00:5E:00:00:00", group_addr_list) is True:
|
||
|
self.packets_sent += MULTICAST_GROUP_LEN
|
||
|
elif self.behavior == "unicast":
|
||
|
if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True:
|
||
|
self.packets_sent += 1
|
||
|
elif self.behavior == "p2p":
|
||
|
if self.__node_send_packet(random.choice(self.device_mac_list), group_addr=None) is True:
|
||
|
self.packets_sent += 1
|
||
|
else:
|
||
|
NativeLog.add_trace_critical("unsupported behavior [%s]" % self.behavior)
|
||
|
self.exit()
|
||
|
return
|
||
|
|
||
|
def get_sent_packets(self):
|
||
|
return self.packets_sent
|
||
|
|
||
|
def exit(self):
|
||
|
self.exit_event.set()
|
||
|
pass
|
||
|
|
||
|
def run(self):
|
||
|
while self.exit_event.isSet() is False:
|
||
|
if self.typ == "SSC":
|
||
|
self.__node_do_send()
|
||
|
elif self.typ == "SERVER":
|
||
|
self.__server_do_send()
|
||
|
else:
|
||
|
NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ)
|
||
|
break
|
||
|
time.sleep(self.send_delay)
|
||
|
|
||
|
pass
|
||
|
|
||
|
|
||
|
class EntityRecvThread(threading.Thread):
|
||
|
def __init__(self, port, typ, send_recv_time):
|
||
|
threading.Thread.__init__(self)
|
||
|
self.setDaemon(True)
|
||
|
self.recv_data_cache = ""
|
||
|
self.packets_recv = 0
|
||
|
self.port = port
|
||
|
self.typ = typ
|
||
|
self.cache_lock = threading.Lock()
|
||
|
self.exit_event = threading.Event()
|
||
|
self.send_recv_time = send_recv_time
|
||
|
pass
|
||
|
|
||
|
def data_recv_callback(self, data):
|
||
|
# if self.typ == "SERVER":
|
||
|
# NativeLog.add_prompt_trace("[data_recv_callback] server recv len %d" % len(data))
|
||
|
with self.cache_lock:
|
||
|
self.recv_data_cache += data
|
||
|
pass
|
||
|
|
||
|
def __server_do_recv(self):
|
||
|
while True:
|
||
|
if self.recv_data_cache:
|
||
|
data_cache = self.recv_data_cache
|
||
|
data_cache_hex = binascii.hexlify(data_cache)
|
||
|
packet_len = int(data_cache_hex[2:6], 16)
|
||
|
if len(self.recv_data_cache) >= packet_len:
|
||
|
time3 = time.time()
|
||
|
data_catch_t = self.recv_data_cache[:packet_len]
|
||
|
packet = binascii.hexlify(data_catch_t)
|
||
|
index3 = int(packet[-8:], 16)
|
||
|
self.send_recv_time.add_recv_time(index3, time3)
|
||
|
self.recv_data_cache = self.recv_data_cache[packet_len:]
|
||
|
else:
|
||
|
break
|
||
|
#self.packets_recv += 1
|
||
|
else:
|
||
|
break
|
||
|
|
||
|
def __node_do_recv(self):
|
||
|
with self.cache_lock:
|
||
|
while True:
|
||
|
if self.recv_data_cache:
|
||
|
match = re.search("\+MESHRECV:\d+", self.recv_data_cache)
|
||
|
index = re.search(",(\d+),OK", self.recv_data_cache)
|
||
|
res = re.compile(".+,\d+,OK", re.DOTALL)
|
||
|
res_t = res.search(self.recv_data_cache)
|
||
|
if match is not None:
|
||
|
time4 = time.time()
|
||
|
if index is not None:
|
||
|
index4 = int(index.group(1))
|
||
|
self.send_recv_time.add_recv_time(index4, time4)
|
||
|
if len(res_t.group()) > 1:
|
||
|
process_index = len(res_t.group(0))
|
||
|
self.recv_data_cache = self.recv_data_cache[process_index:]
|
||
|
else:
|
||
|
process_index = len(res_t.group())
|
||
|
self.recv_data_cache = self.recv_data_cache[process_index:]
|
||
|
else:
|
||
|
break
|
||
|
else:
|
||
|
break
|
||
|
# self.packets_recv += 1
|
||
|
else:
|
||
|
break
|
||
|
pass
|
||
|
|
||
|
def get_recv_packets(self):
|
||
|
return self.packets_recv
|
||
|
|
||
|
def exit(self):
|
||
|
self.exit_event.set()
|
||
|
pass
|
||
|
|
||
|
def run(self):
|
||
|
while self.exit_event.isSet() is False:
|
||
|
if self.typ == "SSC":
|
||
|
self.__node_do_recv()
|
||
|
elif self.typ == "SERVER":
|
||
|
self.__server_do_recv()
|
||
|
else:
|
||
|
NativeLog.add_trace_critical("type [%s] is neither SSC nor SERVER" % self.typ)
|
||
|
break
|
||
|
time.sleep(CHECK_FREQ)
|
||
|
|
||
|
pass
|
||
|
|
||
|
|
||
|
class MeshSendRecv(PerformanceTCBase.PerformanceTCBase):
|
||
|
def __init__(self, name, test_env, cmd_set, timeout, log_path):
|
||
|
PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set,
|
||
|
timeout=timeout, log_path=log_path)
|
||
|
self.send_config = []
|
||
|
self.test_time = 0
|
||
|
self.loss_rate_standard = 0.8
|
||
|
# load param from excel
|
||
|
for i in range(1, len(cmd_set)):
|
||
|
if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "":
|
||
|
cmd_string = "self." + cmd_set[i][0]
|
||
|
exec cmd_string
|
||
|
# load node send config
|
||
|
for i in range(1, len(cmd_set)):
|
||
|
for j in range(len(cmd_set[i][1])):
|
||
|
if cmd_set[i][1][j] != "":
|
||
|
cmd_string = "self.send_config.extend([" + cmd_set[i][1][j] + "])"
|
||
|
exec cmd_string
|
||
|
node_num = self.get_parameter("node_num")
|
||
|
self.recv_cb = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"])
|
||
|
self.recv_cb_lock = threading.Lock()
|
||
|
pass
|
||
|
|
||
|
def register_recv_callback(self, port_name, callback):
|
||
|
with self.recv_cb_lock:
|
||
|
if self.recv_cb[port_name] is None:
|
||
|
self.recv_cb[port_name] = [callback]
|
||
|
else:
|
||
|
self.recv_cb[port_name].append(callback)
|
||
|
pass
|
||
|
|
||
|
def process(self):
|
||
|
try:
|
||
|
test_time = self.test_time * 60
|
||
|
send_config = self.send_config
|
||
|
loss_rate_standard = self.loss_rate_standard
|
||
|
node_num = self.get_parameter("node_num")
|
||
|
pc_ip_list = self.get_parameter("pc_ip").split(".")
|
||
|
port = self.get_parameter("test_tcp_port1")
|
||
|
send_recv_time = SendRecvTime()
|
||
|
except StandardError:
|
||
|
return
|
||
|
#create server_addr
|
||
|
server_addr = ""
|
||
|
for i in range(len(pc_ip_list)):
|
||
|
if pc_ip_list[i] in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
|
||
|
server_addr = server_addr + "0" + pc_ip_list[i]
|
||
|
else:
|
||
|
list_t = hex(int(pc_ip_list[i])).split("0x")
|
||
|
server_addr += list_t[1]
|
||
|
port_t = hex(port).split("0x")
|
||
|
port_t_list = list(port_t[1])
|
||
|
server_addr = server_addr + port_t_list[2] + port_t_list[3] + port_t_list[0] + port_t_list[1]
|
||
|
server_port = self.test_env.get_port_by_name("GSOC1")
|
||
|
if server_port is None:
|
||
|
return
|
||
|
|
||
|
# create thread dict
|
||
|
thread_dict = dict.fromkeys(["SSC%s" % (x + 1) for x in range(int(node_num))] + ["GSOC1"])
|
||
|
for port_name in thread_dict:
|
||
|
thread_dict[port_name] = dict(zip(["tx", "rx"], [None, None]))
|
||
|
device_mac_list = []
|
||
|
# init recv thread & register port for SSC
|
||
|
for port_name in ["SSC%s" % (x + 1) for x in range(int(node_num))]:
|
||
|
port = self.test_env.get_port_by_name(port_name)
|
||
|
thread_dict[port_name]["rx"] = EntityRecvThread(port, "SSC", send_recv_time)
|
||
|
self.register_recv_callback(port_name, thread_dict[port_name]["rx"].data_recv_callback)
|
||
|
device_mac_list.append(port.device_mac)
|
||
|
|
||
|
thread_dict["GSOC1"]["rx"] = EntityRecvThread(server_port, "SERVER", send_recv_time)
|
||
|
self.register_recv_callback("GSOC1", thread_dict["GSOC1"]["rx"].data_recv_callback)
|
||
|
|
||
|
# config[0]: target_name; config[1]: behavior; config[2]: destination; config[3]:send_delay;
|
||
|
for config in send_config:
|
||
|
port = self.test_env.get_port_by_name(config[0])
|
||
|
name = port.name
|
||
|
if config[2] == "GSOC1":
|
||
|
dst = server_addr[:2] + ":" + server_addr[2:4] + ":" + server_addr[4:6] + ":" + server_addr[6:8] + \
|
||
|
":" + server_addr[8:10] + ":" + server_addr[10:12]
|
||
|
elif config[2] == "random":
|
||
|
dst = "random"
|
||
|
else:
|
||
|
dst = self.test_env.get_port_by_name(config[2]).device_mac
|
||
|
if name != "GSOC1":
|
||
|
server_addr = None
|
||
|
if config[1] == "broadcast" or config[1] == "multicast":
|
||
|
dst = None
|
||
|
typ = "SSC" if isinstance(port, MeshPort.MeshPort) is False else "SERVER"
|
||
|
thread_dict[name]["tx"] = EntitySendThread(port, config[1], dst, config[3], typ, device_mac_list,
|
||
|
server_addr, send_recv_time)
|
||
|
self.register_recv_callback(name, thread_dict[name]["tx"].data_recv_callback)
|
||
|
pass
|
||
|
|
||
|
# start all thread
|
||
|
for port_name in thread_dict:
|
||
|
if thread_dict[port_name]["rx"] is not None:
|
||
|
thread_dict[port_name]["rx"].start()
|
||
|
if thread_dict[port_name]["tx"] is not None:
|
||
|
thread_dict[port_name]["tx"].start()
|
||
|
|
||
|
# wait test time
|
||
|
time.sleep(test_time)
|
||
|
# close all send thread
|
||
|
for port_name in thread_dict:
|
||
|
if thread_dict[port_name]["tx"] is not None:
|
||
|
thread_dict[port_name]["tx"].exit()
|
||
|
thread_dict[port_name]["tx"].join()
|
||
|
# make sure all packet received before close recv thread
|
||
|
time.sleep(10)
|
||
|
# close all recv thread
|
||
|
for port_name in thread_dict:
|
||
|
if thread_dict[port_name]["rx"] is not None:
|
||
|
thread_dict[port_name]["rx"].exit()
|
||
|
thread_dict[port_name]["rx"].join()
|
||
|
|
||
|
[max_delay_time, avg_delay_time, loss_rate] = send_recv_time.calculate()
|
||
|
|
||
|
NativeLog.add_trace_critical("[Mesh Send Recv Test] MAX Delay Time is %.3f" % max_delay_time)
|
||
|
NativeLog.add_trace_critical("[Mesh Send Recv Test] Avg Delay Time is %.3f" % avg_delay_time)
|
||
|
NativeLog.add_trace_critical("[Mesh Send Recv Test] loss rate is %.2f%%" % (loss_rate * 100))
|
||
|
|
||
|
# set succeed if loss rate higher than required
|
||
|
if loss_rate < loss_rate_standard:
|
||
|
self.set_result("Succeed")
|
||
|
pass
|
||
|
|
||
|
@Encoding.encode_utf8(3)
|
||
|
def result_check(self, port_name, data):
|
||
|
if port_name in self.recv_cb:
|
||
|
# if port_name == "GSOC1":
|
||
|
# NativeLog.add_prompt_trace("[result_check] recv GSOC1 data len %s" % len(data))
|
||
|
with self.recv_cb_lock:
|
||
|
callback_list = self.recv_cb[port_name]
|
||
|
if callback_list is not None:
|
||
|
for callback in callback_list:
|
||
|
callback(data)
|
||
|
|
||
|
# do logging
|
||
|
timestamp = NativeLog.generate_timestamp()
|
||
|
with self.sync_lock:
|
||
|
_formatted_data = HTMLGenerator.process_one_log_item(data, self.log_index, port_name, timestamp)
|
||
|
self.log_index += 1
|
||
|
|
||
|
self.append_to_log_file(_formatted_data)
|
||
|
|
||
|
NativeLog.add_all_tc_log(data, port_name, timestamp)
|
||
|
pass
|
||
|
|
||
|
|
||
|
def main():
|
||
|
pass
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|