# !/usr/bin/env python3
# -*- coding:utf-8 -*-
import re
import json
from shuncom_params_init import *
from socketserver import StreamRequestHandler, ThreadingTCPServer
from vbox_cloud import vbox_cloud
import socket
import sz_log
import time
import os
from sz_tftp import sz_tftp_server
import threading
from sz_encrypt_mac import sz_encrypt
from shuncom_fun import get_local_ip
import paramiko
ip = get_local_ip()
host = ip # 监听ip,串口服务器的指向 #host = '0.0.0.0'
tftp_ip = ip # tftp服务器IP
local_firmware_name = "shuncom-juhe4-mt7621-sysupgrade.bin" # 固件文件
uboot_firmware_name = 'u-boot-mt7621-212.bin' # uboot文件
cmd_text = '' # 下发串口服务器命令
client_ip_list = []
mutex = threading.Lock()
class vbox_handle_t():
def __init__(self, product, id, ip, port):
self.id = id
self.vbox_handle = vbox_cloud(product, id, ip, port, self.message_handle)
self.vbox_handle.connect()
def register_mssage_cb(self, process_message_function):
self.process_message_function = process_message_function
def message_handle(self, client, userdata, msg):
print("message handle " + msg.topic + " " + str(msg.payload))
mqtt_msg = json.loads(msg.payload)
if msg.topic[-6:] == "invoke":
print(" invoke ")
firmware_url_para = mqtt_msg["inputs"][0]["value"]
firmware_url_para["ip"] = "122.144.131.26"
firmware_url_para["port"] = 6001
# # linux命令
# os.system("rm /tmp/tftp/" + local_firmware_name)
# update_cmd = "lftp -p " + str(firmware_url_para["port"]) + " -u " \
# + firmware_url_para["username"] + "," \
# + firmware_url_para["password"] + " sftp://" \
# + firmware_url_para["ip"] + ":" + str(firmware_url_para["port"]) \
# + " -e \" set net:max-retries 3; && get download/firmware/" + firmware_url_para["path"] \
# + "/firmware.bin -o %s" % tftp_path + local_firmware_name + " && quit \" &"
# sz_log.info("从平台下载的网关固件命令", update_cmd)
# os.system(update_cmd)
try:
if os.path.isfile(tftp_path + local_firmware_name):
os.remove(tftp_path + local_firmware_name)
sz_log.info('网关固件存在删除文件成功!')
sz_log.info("从平台下载网关新固件中...")
pt = paramiko.Transport(('122.144.131.26', 6001))
pt.connect(username='shuncom', password='shuncomgw')
sftp = paramiko.SFTPClient.from_transport(pt) # sftp = t.open_sftp_client()
sftp.get('download/firmware/%s/firmware.bin' % firmware_url_para["path"],
(tftp_path + local_firmware_name))
sz_log.info("从平台下载网关新固件完成!")
self.vbox_handle.report_properties({"notice": ''}) # 清除下载固件错误提示
pt.close()
except Exception as e:
sz_log.info("*************从平台下载网关新固件失败!!!*********** %s" % e)
self.vbox_handle.report_properties({"notice": '*从平台下载网关新固件失败*【请重新选择固件】%s'% e})
self.vbox_handle.invoke_rsp(mqtt_msg, True)
else:
self.vbox_handle.write_properties_rsp(mqtt_msg, self.process_message_function(mqtt_msg["properties"]))
class productor_t():
global client_ip
def __init__(self, product, id, ip, port):
self.id = id
self.vbox_obj = vbox_handle_t(product, id, ip, port)
self.vbox_obj.register_mssage_cb(self.cloud_msg_cb)
self.refresh_vars()
config_ip_250 = config_init.get('CONFIG_SHUNCOM', 'config_ip_250')
args = "".join(client_ip[0]) # client_ip = ('192.168.31.103', 41358)
ip_ = '.'.join(args.split('.')[:-1])
self.config = {}
self.config["ip_addr"] = ip_ + config_ip_250 # "192.168.31.222" # 网关静态IP地址
sz_log.info('设置的静态ip:',self.config["ip_addr"])
self.config["gatewayip"] = ip_ + '.1' # '192.168.31.1' # 上级路由ip地址
self.config["gwmac"] = "无"
self.config["firmware_version"] = "请选择固件版本"
self.config["bdinfo"] = "请选择bdinfo"
self.bdinfo_value = {}
self.config["running"] = False
# os.system("mkdir -p /tmp/tftp")
self.uboot_v = '2.01.02' # uboot版本
def refresh_vars(self):
self.step = 0 # 生产状态
self.device_status = "" # 设备状态
self.device_uboot_ver = "" # 设备uboot版本
self.firmware_login_step_last_cmd_time = None
self.last_send_time = time.time() # 上次发送时间
self.status = "wait" # WEB状态
self.mac_exist_in_gw = "" # 网关MAC
self.mac_exist_in_gw_cal_passwd = "" # 网关登录密码
self.Request_bdinfo_mac = 0 # 向平台请求bdinfo的Mac地址标志位
try:
self.vbox_obj.vbox_handle.report_properties({"notice": ''}) # 告警提示停止
self.vbox_obj.vbox_handle.report_properties({"info": ''}) # 提示停止
mutex.release()
sz_log.info('重置线程锁解锁完成')
except:
pass
def get_status(self):
return self.status
def get_config(self):
return self.config
def get_step(self):
return self.step
def next_step_test(self):
"""没有使用的功能"""
if self.status == "wait":
self.status = "error"
elif self.status == "error":
self.status = "process"
elif self.status == "process":
self.status = "finish"
elif self.status == "finish":
self.status = "wait"
self.step += 1
if self.step >= 4:
self.step = 0
def get_mac_exist_in_gw(self, splited_str):
try:
for tmp_line in splited_str: # splited_str = ['Login incorrect2c:6a:6f:40:00:05\r', '']
if "2c:6a:6f" in tmp_line or "2C:6A:6F" in tmp_line:
p = re.compile(r'(?:[0-9a-fA-F]:?){12}')
tmp_line = re.findall(p, tmp_line) # 匹配Mac地址
sz_log.info('匹配Mac地址:', tmp_line)
if tmp_line:
tmp_mac_split = tmp_line[0].split(':')
self.mac_exist_in_gw = ""
for tmp_mac_char in tmp_mac_split:
self.mac_exist_in_gw = self.mac_exist_in_gw + tmp_mac_char
self.mac_exist_in_gw_cal_passwd = sz_encrypt(self.mac_exist_in_gw).decode(encoding="utf-8",errors="strict")
sz_log.info("mac_exist_in_gw " + self.mac_exist_in_gw)
sz_log.info("mac_exist_in_gw_password " + self.mac_exist_in_gw_cal_passwd)
self.config["gwmac"] = self.mac_exist_in_gw # 回显原mac地址
return True
else:
sz_log.info('mac地址异常', tmp_line)
return False
elif "00:c0:02:12:35:88" in tmp_line:
sz_log.info('上报Mac:00:c0:02:12:35:88,使用密码 回车')
# self.mac_exist_in_gw_cal_passwd = "5afc1d286cdcb137fcb234a962c19288" # 老板子密码
self.mac_exist_in_gw_cal_passwd = "\r" # 新板子密码是回车
return True
elif "无" in tmp_line:
sz_log.info('上报Mac无,使用默认密码:5554f3ba30a3727c05d66e047c6acbe8')
self.mac_exist_in_gw_cal_passwd = "5554f3ba30a3727c05d66e047c6acbe8"
return True
sz_log.info('获取串口中的mac地址:false')
return False
except Exception as e:
sz_log.info('get_mac_exist_in_gw异常:',e)
return False
def cloud_msg_cb(self, properties):
"""web页面的用户设置"""
global cmd_text
try:
sz_log.info("接收web页面【生产工具-配置参数】")
sz_log.info('接收web页面【properties】 ', properties)
# sz_log.info(self.config.keys())
for obj_name in properties:
sz_log.info('接收web页面【obj_name】 ', obj_name)
sz_log.info('接收web页面【self.config】 ', self.config)
if obj_name in self.config:
if obj_name == "bdinfo":
sz_log.info('接收web页面【进入bdinfo】')
bdinfo_json = json.loads(properties[obj_name])
self.config["bdinfo"] = bdinfo_json["BOARD"] + "_" + bdinfo_json["VARIANT"]
self.bdinfo_value = properties[obj_name]
sz_log.info(" bdinfo " + self.config["bdinfo"])
sz_log.info(self.bdinfo_value)
else:
try:
self.config[obj_name] = properties[obj_name]
except:
sz_log.info('接收web页面【properties[obj_name] 处理错误】')
if obj_name == "running":
self.refresh_vars()
else:
if obj_name == "log":
sz_log.info('读取日志:不支持')
self.vbox_obj.vbox_handle.report_properties({"log": {"日志": '读取日志:不支持'}})
elif obj_name == "cmd":
cmd_text = properties['cmd']
sz_log.info('执行cmd命令:', cmd_text)
self.vbox_obj.vbox_handle.report_properties({"log": {"日志": '执行cmd命令:%s' % cmd_text}})
elif obj_name == "step":
sz_log.info('读取步骤:不支持')
self.vbox_obj.vbox_handle.report_properties({"log": {"日志": '读取步骤:不支持'}})
elif obj_name == "status":
sz_log.info('读取当前状态:不支持')
self.vbox_obj.vbox_handle.report_properties({"log": {"日志": '读取当前状态:不支持'}})
else:
sz_log.info("obj not exist,不存在")
sz_log.info('接收web页面 self.config 修改后 ', self.config)
return True
except Exception as e:
sz_log.info('接收web页面异常%s' % e)
return False
def bdinfo_save(self, mac_str):
"""平台下载bdinfo文件"""
bdinfo_value_split = self.bdinfo_value.split('\n')
last_split_str = ""
tmp_line_num = 0
for tmp_split_str in bdinfo_value_split:
if "\"type\": \"wan\"," in last_split_str and "macaddr" in tmp_split_str:
tmp_i = 0
dst_split_str = " \"macaddr\":\""
sz_log.info('下载bdinfo,遍历出macaddr', tmp_split_str) # 遍历出"macaddr": "2C:6A:6F:00:d4:12"
sz_log.info('下载bdinfo,传入的Mac地址', mac_str)
for tmp_char in mac_str:
tmp_i += 1
print('tmp_i', tmp_i)
if tmp_i < 13:
dst_split_str = dst_split_str + tmp_char
print('dst_split_str数据:', dst_split_str)
print("tmp i : " + str(tmp_i))
print("tmp i / 2: " + str(tmp_i % 2))
if (tmp_i % 2) == 0 and (tmp_i < 12):
dst_split_str += ":"
sz_log.info('下载bdinfo遍历12次,获取出Mac地址: ', dst_split_str)
dst_split_str += "\"" # "macaddr":"无"
bdinfo_value_split[tmp_line_num] = dst_split_str
last_split_str = tmp_split_str # "macaddr": "2C:6A:6F:00:d4:12"
tmp_line_num += 1
self.bdinfo_value = ""
for tmp_split_str in bdinfo_value_split:
self.bdinfo_value = self.bdinfo_value + tmp_split_str + "\n"
sz_log.info('bdinfo_value值:', self.bdinfo_value)
#os.system("mkdir -p /tmp/tftp/" + self.id) # linux 命令
print('判断bdinfo文件夹是否存在',os.path.exists(tftp_path + self.id))
if not os.path.exists(tftp_path + self.id):
sz_log.info('创建bdinfo文件夹')
os.mkdir( tftp_path + self.id)
with open(tftp_path + self.id + '/bdinfo.json', 'w+') as f:
f.write(self.bdinfo_value)
def firmware_login(self):
if self.firmware_login_step == "username":
if self.firmware_login_step_last_cmd_time is None:
self.firmware_login_step_last_cmd_time = time.time()
sz_log.info('发送登录root ')
return "root\r"
else:
if time.time() - self.firmware_login_step_last_cmd_time > 2:
self.firmware_login_step_last_cmd_time = None
self.firmware_login_step = "passwd"
if self.firmware_login_step == "passwd":
if self.firmware_login_step_last_cmd_time is None:
self.firmware_login_step_last_cmd_time = time.time()
sz_log.info('发送ssh登录密码:' + self.mac_exist_in_gw_cal_passwd)
return self.mac_exist_in_gw_cal_passwd + '\r'
else:
if time.time() - self.firmware_login_step_last_cmd_time > 2:
self.firmware_login_step_last_cmd_time = None
self.firmware_login_step = "finish"
def do_step(self):
"""下发数据给串口服务器到网关"""
if self.config["running"] == False:
return None
if self.step == 0:
print('生产状态:检查并更新uboot')
elif self.step == 1:
print('生产状态:固件烧录中')
elif self.step == 2:
print('生产状态:bdinfo写入中')
elif self.step == 3:
print('生产状态:完成中')
else:
print('生产状态:未知%s' % self.step)
if (time.time() - self.last_send_time) < 1:
sz_log.info(" 时间间隔小于1秒不发送串口数据 last send too close")
return None
self.last_send_time = time.time()
# 刷写网关uboot
if self.step == 0:
if self.status == "wait":
if self.device_status == "have_firmware_login":
if self.firmware_login_step is None:
self.firmware_login_step = "username"
elif self.firmware_login_step == "finish":
sz_log.info(" login cmd send finish")
else:
return self.firmware_login()
elif self.device_status == "have_firmware_shell":
return "reboot\n"
else:
return "\n"
elif self.status == "process":
if self.device_status == "break_uboot":
return "0\n"
elif self.device_status == "check_uboot_version":
return "version\n"
elif self.device_status == 'updata_uboot':
sz_log.info('执行设置uboot参数,mtkupgrade')
self.updata_uboot_reset_num = 0
return "setenv gatewayip " + self.config["gatewayip"] + "\n" \
+ "setenv ipaddr " + self.config["ip_addr"] + "\n" \
+ "setenv serverip " + tftp_ip + "\n" \
+ 'setenv bootfile.bootloader ' + uboot_firmware_name + '\n' \
+ 'saveenv\n'
elif self.device_status == 'updata_uboot_2_1' and self.updata_uboot_reset_num ==0:
self.updata_uboot_reset_num = 1
sz_log.info('uboot 设置重启 reset ')
return 'reset\n'
elif self.device_status == 'updata_uboot_2':
return '4\n'
elif self.device_status == 'updata_uboot_3':
return '\n' * 4
elif self.device_status == 'updata_uboot_4':
return 'y\r'
elif self.device_status == 'updata_uboot_5':
sz_log.info('等待网关断电重启网关')
return 'reset\n'
# 刷写网关固件
elif self.step == 1:
if self.status == "wait":
if self.device_status == "firmware_set_ip":
return " setenv gatewayip " + self.config["gatewayip"] + "\n" \
+ "setenv ipaddr " + self.config["ip_addr"] + "\n" \
+ "setenv serverip " + tftp_ip + "\n" \
+ "setenv netmask " + "255.255.255.0\n" \
+ "saveenv\n"
elif self.device_status == "firmware_tftp":
return "szupgradefw\n"
# 刷写网关bdinfo
elif self.step == 2:
if self.status == "process":
if self.device_status == "bdinfo_init_login":
return "\n"
elif self.device_status == "bdinfo_login":
if self.firmware_login_step is None:
self.firmware_login_step = "username"
elif self.firmware_login_step == "finish":
sz_log.info(" login cmd send finish")
sz_log.info(" 登录命令发送完成")
else:
return self.firmware_login()
elif self.device_status == "bdinfo_shell":
return " tftp -g -r " + self.id + "/bdinfo.json " + tftp_ip + " && mv bdinfo.json /bdinfo/ && jffs2reset -y && reboot -f\n"
elif self.status == "finish":
return " tftp -g -r " + self.id + "/bdinfo.json " + tftp_ip + " && mv bdinfo.json /bdinfo/ && rm -f /etc/config/datacenter.db && jffs2reset -y && reboot -f\n"
# 完成中
elif self.step == 3:
if self.device_status == "uboot_error_tftp":
return "szboardboot\n"
if self.device_status == "tty_usb_r":
return "\r"
if self.device_status == 'tty_usb_root':
if self.firmware_login_step == "finish":
sz_log.info("查询usb登录命令发送成功")
else:
return self.firmware_login()
if self.device_status == "tty_usb_shell":
sz_log.info('发送查询USB命令')
#return "uci show shuncom && lspci\r"
return "lspci\r"
if self.device_status =='finish_reboot':
pass
# sz_log.info('发送换行命令')
# return '\n' # 可以修改为恢复出厂设置
def process_uart_data(self, data):
"""根据接收的数据判断网关的状态"""
global mutex
if self.config["running"] == False:
return None
sz_log.info("device status 前:" + self.device_status)
sz_log.info(data.split('\n'))
splited_str = data.split('\n')
# 计算登录密码
gw_mac_key = self.get_mac_exist_in_gw(splited_str)
# 网关检查更新uboot
if self.step == 0:
if self.status == "wait":
print("#########################################################splited_str#############",splited_str)
if "Shuncom login:" in splited_str[-1]:
sz_log.info(" shuncom登录存在 ")
self.device_status = "have_firmware_login"
self.firmware_login_step = None
# elif "-ash: root: not found" in splited_str[-1]:
# if "root@Shuncom:~#" in splited_str[-1]:
if "[\x1b[35;1mroot\x1b[0m@\x1b[31;1mshuncom\x1b[0m:\x1b[32;1m/root\x1b[0m]#" or "root@Shuncom:~#" in splited_str[-1]:
self.device_status = "have_firmware_shell"
self.firmware_login_step = None
self.firmware_login_step_last_cmd_time = None
if "Hit any key to stop autoboot" in data: # 重启网关进入
self.status = "process"
self.device_status = "break_uboot"
self.vbox_obj.vbox_handle.report_properties({"notice": ''})
if "=>" in data:
self.status = "process"
self.device_status = "check_uboot_version"
self.vbox_obj.vbox_handle.report_properties({"notice": ''})
elif self.status == "process":
if self.device_status == 'updata_uboot_5':
self.status = "wait"
self.device_status = ''
if self.device_status == "break_uboot":
if "=>" in data:
self.device_status = "check_uboot_version"
if self.device_status == "check_uboot_version":
for tmp_str in splited_str:
local_idx = tmp_str.find("SHUNCOM-U-BOOT-VERSION")
if local_idx >= 0:
self.device_uboot_ver = tmp_str[local_idx + len("SHUNCOM-U-BOOT-VERSION") + 1:]
sz_log.info("found uboot version:" + self.device_uboot_ver)
if self.device_uboot_ver >= self.uboot_v: # 对比uboot版本 2.01.02
sz_log.info('当前uboot版本不需要升级')
self.status = "wait"
self.step = 1
self.device_status = "firmware_set_ip"
else:
sz_log.info('需要升级uboot版本')
self.device_status = 'updata_uboot'
# self.uboot_v = '2.01.02'# 测试时候使用
if self.device_status == 'updata_uboot':
if "Saving Environment to SPI Flash" in data: # 保存成功
self.device_status = 'updata_uboot_2_1'
if self.device_status == 'updata_uboot_2_1':
if "Upgrade bootloader (advanced mode)" in data:
self.device_status = 'updata_uboot_2' # 选择4 Upgrade bootloader (advanced mode)
if self.device_status == 'updata_uboot_2':
if "Select (enter for default)" in data:
self.device_status = 'updata_uboot_3' # 回车4次
if self.device_status == 'updata_uboot_3':
if "Upgrade Bootblock? (N/y)" in data: # 回复 y
self.device_status = 'updata_uboot_4'
if self.device_status == 'updata_uboot_4': # 表示uboot更新完成。
if "Bootloader upgrade completed!" in data:
sz_log.info('++++ uboot 升级完成 +++++')
self.device_status = 'updata_uboot_5'
self.vbox_obj.vbox_handle.report_properties({"notice": 'uboot升级完成,请把网关断电重启,继续生产!'})
"""
mUpgrade Bootblock? (N/y):[0m y
Whole bootloader will be upgraded
Erasing from 0x0 to 0x2ffff, size 0x30000 ... OK
Writting from 0x80010000 to 0x0, size 0x2fca2 ... OK
[0;33m*** Bootloader upgrade completed! ***[0m
Hit any key to stop reboot: 3
"""
# 刷写网关固件
if self.step == 1:
if self.status == "wait":
if self.device_status == "firmware_set_ip":
if "setenv serverip" in data:
self.device_status = "firmware_tftp"
mutex.acquire()
sz_log.info('线程锁生效')
elif self.device_status == "firmware_tftp":
if "Loading:" in data:
self.device_status = "firmware_tftping"
self.status = "process"
self.start_time = int(time.time())
elif self.status == "process":
if self.device_status == "firmware_tftping":
now_time = int(time.time())
if now_time - self.start_time > 300:
self.vbox_obj.vbox_handle.report_properties({"notice": '固件下载下载超时,请把【控制台-生产状态】重新开始,网关断电重启'})
self.start_time = now_time
sz_log.info(" tftping 固件下载中")
if "Bytes transferred" in data:
sz_log.info("tftp finished ")
mutex.release()
sz_log.info('线程锁解锁')
if "init: Console is alive" in data:
self.device_status = "bdinfo_waiting"
self.status = "wait"
self.step = 2
# 更新刷写bdinfo文件
if self.step == 2:
if self.status == "wait":
if gw_mac_key:
sz_log.info('根据Mac计算出的密码:', self.mac_exist_in_gw_cal_passwd)
self.status = "process"
self.device_status = "bdinfo_init_login"
self.firmware_login_step = None
self.Logintimedout = 0
elif self.status == "process":
if "Login timed" in data or "Login timed out" in data or "timed out" in data:
self.device_status = "bdinfo_init_login"
sz_log.info('****刷写bdinfo文件登录失败超时,尝试重新登录****', data)
self.Logintimedout = 1
if ('Shuncom login:'in data and self.Logintimedout ==1)or('huncom login'in data and self.Logintimedout ==1):
# 发送root重新登录
self.device_status = "bdinfo_login"
self.firmware_login_step_last_cmd_time = None
self.firmware_login_step = "username"
self.Logintimedout = 0
sz_log.info('\n**** 登录超时,重新发送登录 root ****\n')
if self.device_status == "bdinfo_init_login":
if "IPv6: ADDRCONF(NETDEV_UP): br-lan:" in data:
self.device_status = "bdinfo_login"
self.bdinfo_save(self.config["gwmac"])
# if "root@Shuncom:~#" in data:
if "[\x1b[35;1mroot\x1b[0m@\x1b[31;1mshuncom\x1b[0m:\x1b[32;1m/root\x1b[0m]#" or "root@Shuncom:~#" in splited_str[-1]:
self.device_status = "bdinfo_shell"
self.firmware_login_step = None
self.firmware_login_step_last_cmd_time = None
sz_log.info(" bdinfo " + self.config["bdinfo"])
self.status = "finish"
self.step = 2
elif self.status == "finish":
sz_log.info(" finishing")
if "SHUNCOM-U-BOOT" in data:
self.status = "wait"
self.step = 3
# 完成中等待网关重启
if self.step == 3:
if self.status == "wait":
if "=>" in data:
sz_log.info(" 在uboot中错误输入了tftp ")
self.device_status = "uboot_error_tftp"
elif "Linux version" in data:
self.status = "process"
self.tty_usb = False
elif self.status == "process":
if "first boot" in data:
# self.status = "finish"
self.device_status = 'tty_usb_r' # 回车换行登录
self.tty_usb_num = 0
self.tty_usb = True
# 后加的代码++++++++++++++++++++++++++++++++++++++++++++++
if self.tty_usb:
if 'shuncom login:' in data: # 输入root
self.device_status = 'tty_usb_root'
self.firmware_login_step = "username"
self.firmware_login_step_last_cmd_time = None
if "Login timed out" in data or "ogin timed ou" in data:
self.device_status = 'tty_usb_r' # 回车换行登录
self.firmware_login_step = "username"
self.firmware_login_step_last_cmd_time = None
sz_log.info('****查询usb登录失败超时,尝试重新登录****', data)
# if "root@Shuncom:~#" in data:
if "[\x1b[35;1mroot\x1b[0m@\x1b[31;1mshuncom\x1b[0m:\x1b[32;1m/root\x1b[0m]#" or "root@Shuncom:~#" in splited_str[-1]:
self.device_status = "tty_usb_shell"
self.firmware_login_step = None
self.firmware_login_step_last_cmd_time = None
self.tty_usb = 'tty_usb_shell'
if self.tty_usb == 'tty_usb_shell':
"""
root@Shuncom:~# lspci
00:00.0 Class 0604: 0e8d:0801
01:00.0 Class 0c03: 1912:0015
"""
if '1912:0015' in data:
self.status = "finish"
sz_log.info('网关ttyUSB正常')
self.tty_usb_num += 1
print('检查ttyUSB运行次数',self.tty_usb_num)
time.sleep(1)
if self.tty_usb_num > 10:
self.vbox_obj.vbox_handle.report_properties({"notice": 'ttyUSB异常(pcie转usb3.0),请检查硬件问题!'})
elif self.status == "finish":
self.device_status = 'finish_reboot'
sz_log.info('生产完成Mac地址:',self.config["gwmac"])
self.vbox_obj.vbox_handle.report_properties({"info": 'MAC:%s 生产完成,请更换下一台网关!!!'% self.config["gwmac"]})
if "SHUNCOM-U-BOOT" in data: # uboot
self.refresh_vars()
self.status = "process"
self.device_status = "break_uboot"
sz_log.info("device status 后:" + self.device_status)
class rev_tcp(StreamRequestHandler):
""" https:
创建一个继承自 SocketServer.BaseRequestHandler 的类,类中必须定义一个名称为 handle 的方法
"""
def handle(self):
global client_ip
global cmd_text
global gwproductor_id
try:
client_ip = self.client_address
sz_log.info('客户端地址', self.client_address)
config_web_url = config_init.get('CONFIG_SHUNCOM', 'config_web_url')
sz_log.info('生产平台是:',config_web_url)
self.productor = productor_t("PRODUCTOR_GW_1", gwproductor_id, config_web_url, 8027)
self.request.settimeout(1.0)
#client_ip_list.append([self.client_address,self.request,self.wfile,self.rfile,self.productor,time.time()])
client_ip_list.append([self.client_address])
report_seqs = 0
while True:
try:
data = self.request.recv(1024)
except socket.timeout:
pass
else:
if (len(data) == 0):
sz_log.info("客户端自动断开关闭,socket shut down")
self.productor.vbox_obj.vbox_handle.report_properties({"notice": '[串口服务器]自动断开了,【控制台-生产状态】重新开始'})
self.finish()
break
try:
splited_str = data.decode('utf-8').split('\n')
print('接收数据 splited_str: %s' % splited_str)
sz_log.info(splited_str)
print("#########################################################串口接收到的数据splited_str#############",splited_str)
except Exception as e:
splited_str = ''
sz_log.info("data.decode('utf-8')data异常,请检查串口线是否接触不良", e)
# self.productor.vbox_obj.vbox_handle.report_properties({"notice": '串口服务器异常,请检查串口线是否接触不良,【控制台-生产状态】重新开始'})
try:
if len(splited_str) > 0:
if 'gwproductor' in splited_str:
# self.deviceId = splited_str[0]
print('串口服务器的心跳包:', splited_str[0])
for tmp_log_line in splited_str:
if 'MMC init failed' in tmp_log_line:
self.productor.vbox_obj.vbox_handle.report_properties({"notice": 'EMMC初始化失败,【控制台-生产状态】网关重启,重新生产'})
if 'ARP Retry count exceeded; starting again' in tmp_log_line:
sz_log.info('tftp网络不通')
# self.productor.vbox_obj.vbox_handle.report_properties({"notice": 'tftp网络不通,ARP Retry count exceeded; starting again'})
if self.productor.config["running"] == True:
self.productor.vbox_obj.vbox_handle.report_properties({"log": tmp_log_line})
else:
if self.productor.config["running"] == True:
self.productor.vbox_obj.vbox_handle.report_properties({"log": data.decode('utf-8')})
if self.productor.config["running"] == True:
self.productor.process_uart_data(data.decode('utf-8'))
except:
sz_log.info('data数据无法解析')
if len(client_ip_list) > 1:
try:
sz_log.info('删除前客户端列表:', client_ip_list)
for x in range(len(client_ip_list) - 1):
self.finish()
client_ip_list.pop(x)
except:
pass
sz_log.info('删除后客户端列表:', client_ip_list)
break
if (report_seqs > 3):
self.productor.vbox_obj.vbox_handle.report_properties(
{"status": self.productor.get_status(), "step": self.productor.get_step()})
if self.productor.get_status() == "process" and self.productor.get_step() == 2:
if self.productor.Request_bdinfo_mac == 0:
if len(self.productor.mac_exist_in_gw) > 0:
if self.productor.config["gwmac"] == "无":
sz_log.info('检测到mac无 刷写过固件')
self.productor.config["gwmac"] = self.productor.mac_exist_in_gw
else:
if self.productor.config["gwmac"] == "无":
sz_log.info('检测到mac无 没有刷写过固件')
self.productor.vbox_obj.vbox_handle.report_properties(
{"gwmac": "无", "bdinfo": self.productor.config["bdinfo"]})
self.productor.Request_bdinfo_mac = 1 # 请求平台分配bdinfo Mac一次
self.productor.vbox_obj.vbox_handle.report_properties(self.productor.get_config())
print("【主线程线程数量】:", len(threading.enumerate()))
sz_log.info("【主线程线程数量】:", len(threading.enumerate()))
report_seqs = 0
report_seqs += 1
data = self.productor.do_step()
if data:
sz_log.info(" 下发串口数据 write port:\n" + data)
self.request.sendall(data.encode('utf-8'))
if cmd_text:
sz_log.info(" 下发执行cmd命令: " + cmd_text)
if cmd_text == '回车':
self.request.sendall('\r'.encode('utf-8'))
elif cmd_text == '程序重启':
cmd_text = ''
client_ip_list.clear()
self.finish()
break
else:
self.request.sendall(cmd_text.encode('utf-8'))
cmd_text = ''
except Exception as e:
sz_log.info('rev_tcp程序异常', e)
self.finish()
client_ip_list.pop(0)
def finish(self):
""" wfile close,rfile close,mqtt close """
try:
self.request.close()
if not self.wfile.closed:
try:
self.wfile.flush()
except socket.error:
pass
self.wfile.close()
self.rfile.close()
self.productor.vbox_obj.vbox_handle.stop()
except Exception as e:
sz_log.info('finish异常', e)
class ThreadingTCPServerA(ThreadingTCPServer):
"""ThreadingTCPServer从ThreadingMixIn和TCPServer继承
继承SocketServer.ThreadingTCPServer,在init之前设置allow_reuse_address = True(默认为False)
"""
allow_reuse_address = True
sz_log.info('电脑ip地址:', host)
class run_class():
"""运行和停止"""
def run_(self,gw_id):
global gwproductor_id
gwproductor_id = gw_id # 聚盒基地生产ID
self.tftp_server = sz_tftp_server(tftp_path, tftp_ip, 69)
threading.Thread(target=self.tftp_server.sz_tftp_server, args=()).start()
self.rev_tcp = rev_tcp
config_ep = config_init.get('CONFIG_SHUNCOM', 'config_ep')
addr = (host, int(config_ep))
sz_log.info(('ip地址和端口:',addr, self.rev_tcp))
self.TCP_server = ThreadingTCPServerA(addr, self.rev_tcp)
self.TCP_server.serve_forever() # 启动线程 #永久循环执行,可以接受多个客户端连接
def run_stop(self):
sz_log.info('+'*30 + '关闭程序' + '+'*30 + '\n\n')
self.rev_tcp.finish()
self.tftp_server.tftpy_close()
self.TCP_server.server_close()
if __name__ == '__main__':
pass
# t_path = os.path.split(os.path.realpath(__file__))[0]
# if not os.path.exists(t_path + r'\tmp\tftp/'):
# os.mkdir(t_path + r'\tmp\tftp/')
# tftp_path = os.path.split(os.path.realpath(__file__))[0]+ r'\tmp\tftp/'
# tftp_server = sz_tftp_server(tftp_path, tftp_ip, 69)
# threading.Thread(target=tftp_server.sz_tftp_server, args=()).start()
# TCP_server = ThreadingTCPServerA(addr, rev_tcp)
# TCP_server.serve_forever() # 启动线程 #永久循环执行,可以接受多个客户端连接

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823