require "log" require "sys" require "utils" require "patch" require "pack" require "bit" require("dyutils") require("base64") require"shmem" local siganl = require 'posix.signal' local syswait = require 'posix.sys.wait' local unistd = require 'posix.unistd' local lpack=require("lua_pack") local internal_api=require("internal_api") local gw_sn local dev_sn local dev_port local term_addr local shmem_id = 1 local shmem_size = 1280*2 function ex_pack(addr,func,regaddr,regsize,data,error) -- log.info("nil",addr,func,string.format( "0x%04X",regaddr) ,regsize,data and string.toHex(data)) local raw_data=nil if not addr or not func then return nil end if bit.rshift(func, 7) ~= 0 and error then -- 差错寄存器 raw_data = bpack("CCC",addr,func,error) else raw_data = bpack("CCC",addr,func,regsize*2) end -- 有数据增加二进制数据 if data and type(data) == "string" and #data > 0 then if func == 0x01 and #data ~= regsize*2 then log.warn("ex_pack",string.format("buff size and regsize are conflict, size:%d,regsize:%d",#data,regsize)) return nil end for i = 1, #data do raw_data = raw_data .. bpack("C",data:byte(i)) end end raw_data = raw_data .. bpack(">S",dyutils.CRC16(raw_data,#raw_data)) return raw_data end local function ex_unpack(raw_data) --取出入参-- local obj={} local _,addr,func,regaddr,regsize _,addr,func,regaddr,regsize = bunpack(raw_data,"CC>S>S") if (func == 3 or func == 4) and #raw_data ~= 8 then return nil,addr,func,regaddr,regsize end if not addr or not func or not regaddr or not regsize then log.warn("ex_unpack","Invalid param:addr,func,regaddr,regsize=",addr,func,regaddr,regsize) end -- log.info("nil",addr,func,string.format( "0x%04X",regaddr) ,regsize,raw_data and string.toHex(raw_data)) local crc = dyutils.CRC16(raw_data,#raw_data - 2) local _,crc_pack = bunpack(string.sub(raw_data,#raw_data - 1),">S") if (crc ~= crc_pack) then log.warn("ex_unpack",string.format("Data crc check failed cal:0x%04X packet:0x%04X",crc,crc_pack)) return nil,addr,func,regaddr,regsize end return true,addr,func,regaddr,regsize end local function port2pp(topic,payload) local currTime = os.time() -- print("pp2app",topic,payload) local obj = cjson.decode(payload) if not obj.data_b64 then return end local raw_data = base64.decode(obj.data_b64) if not raw_data then return end local result, addr, func, regaddr, regsize = ex_unpack(raw_data) if result then local pkt if addr ~= term_addr then log.warn("ex_unpack",string.format("term_addr cmd:0x%02X recv cmd:0x%02X",term_addr,addr)) return nil end if func == 0x03 or func == 0x04 then -- 读寄存器响应 local out = shmem.shmget(shmem_id,regaddr,regsize*2) if not out or regaddr >= 0x1000 then log.warn("ex_unpack",string.format("fetch data failed, regaddr:0x%02X",term_addr,regaddr)) pkt = ex_pack(addr,bit.bor(func,0x80),nil,nil,nil,2) else local converted="" if #out > 1 then while true do if not out or #out == 0 then break end local swp_h,swp_l = string.sub(out,1,1),string.sub(out,2,2) -- log.info(nil,string.toHex(swp_h),string.toHex(swp_l)) -- converted = string.format("%s%s%s",converted,swp_l,swp_h) -- format 检查入==0直接忽略入参 converted = converted .. swp_l .. swp_h out = string.sub(out,3) end else converted = out end pkt = ex_pack(addr,func,regaddr,regsize,converted) end else pkt = ex_pack(addr,bit.bor(func,0x80),nil,nil,nil,1) end if pkt then log.info("SEND TO UART",string.toHex(pkt)) internal_api.pp2south(gw_sn,dev_sn,dev_port,"NULL",pkt,0,0) end end end local function iot2pp(topic,payload) -- local currTime = os.time() -- print("pp2app",topic,payload) -- local obj = cjson.decode(payload) -- local tags = obj.tag_node and cjson.decode(obj.tag_node) or nil end local function connect_share() -- 读取文件配置表 assert(shmem_id) assert(shmem_size) shmem.connect(shmem_id,shmem_size) end function main(nodes_cfg,sn) log.info("main_loop", "=============== Direct Current RUN 1.1.2 ============") gw_sn = sn if not gw_sn then gw_sn = io.getGatewayID() -- gw_sn = "218800000010" end connect_share() log.info("main_loop", string.format("Try Run At Shell\nsn='%s'\nnodes='%s'\nmain_loop(nodes,sn)",gw_sn or "NOT SN",nodes_cfg or "")) local obj = cjson.decode(nodes_cfg) if obj and #obj then if #obj > 1 then unistd.sleep(10) return -2,"these device the only be one" else nodes = obj end else return -3,"Input param miss word" end -- dev_sn = nodes[1].sn dev_sn = "UNKNOWN" dev_port = nodes[1].connect_port log.info("main_loop", dev_sn,term_addr,dev_port) siganl.signal(siganl.SIGKILL,handler) siganl.signal(siganl.SIGHUP,handler) internal_api.local_mqtt_session({dev_sn},"PP",iot2pp,port2pp) --启动系统框架 sys.init(0, 0) sys.run() end main(arg[1],arg[2]) -- main('[{"connect_port":"RS485_2","depth":0,"product_key":"2860472625","sn":"21880A0002D7_TBOX","template_id":"2860472625","term_addr":"01"}]','21880A0002D7')