surenyi
7 years ago
4 changed files with 386 additions and 63 deletions
@ -0,0 +1,258 @@ |
|||
constants = { |
|||
IP_INT = "192.168.11.101", |
|||
IP_EXT = "192.168.31.101", |
|||
IP_PRIV = "192.168.9.1", |
|||
|
|||
MSG_MINLEN = 24, |
|||
|
|||
DEV_ID_HOST = 0x0222, |
|||
DEV_TERM_ID_1 = 0x0B02, |
|||
DEV_TERM_ID_2 = 0x0B03, |
|||
DEV_TERM_ID_3 = 0x0B04, |
|||
DEV_TERM_ID_4 = 0x0B05, |
|||
DEV_TERM_ID_5 = 0x0B20, |
|||
DEV_TERM_ID_6 = 0x0B21, |
|||
DEV_PTERM_ID_1 = 0x0210, |
|||
DEV_PTERM_ID_2 = 0x0310, |
|||
DEV_TERM_ALL = 0xffff, |
|||
|
|||
DEV_ID_STORE = 0x0123, |
|||
|
|||
SW_ID_HOST = 0x0110, |
|||
SW_ID_TERM = 0x1009, |
|||
SW_ID_PTERM = 0x0402, |
|||
SW_ID_ADAPTER = 0x1001, |
|||
|
|||
MSG_ID_IPHONE = 0x1101, |
|||
MSG_ID_ALARM = 0x1102, |
|||
MSG_ID_SELFTEST = 0x111E, |
|||
MSG_ID_CFREQ = 0x1103, |
|||
MSG_ID_CFRES = 0x1104, |
|||
MSG_ID_NTP = 0x1125, |
|||
MSG_ID_NTP_STATUS = 0x1128, |
|||
|
|||
CF_ID_VOL = 0x3, |
|||
CF_ID_IPHONE_CHANNEL = 0x0B, |
|||
CF_ID_IPHONE_FREQ = 0x0C, |
|||
CF_ID_STATION_ID = 0x13, |
|||
|
|||
GROUP_IP_ALARM = "225.0.0.22", -- internal or external net segment. |
|||
PORT_ALARM_IN = 7001, |
|||
PORT_ALARM_OUT = 6001, -- iphone, alarm data , config response. |
|||
PORT_ST_IN = 6002, -- selftest, config request. |
|||
|
|||
GROUP_IP_ST = "239.1.11.30", -- selftest [internal net segment]. |
|||
PORT_ST_OUT = 11006, |
|||
|
|||
GROUP_IP_NTP = "239.1.11.30" ,-- ntp [external net segment] |
|||
PORT_NTP_IN = 11004, |
|||
PORT_NTP_OUT = 11005, |
|||
} |
|||
|
|||
local _seq = 0 |
|||
local _station = 0 |
|||
|
|||
function set_station(sid) |
|||
_station = sid |
|||
end |
|||
|
|||
function get_station() |
|||
return _station |
|||
end |
|||
|
|||
function build_header(sdevid, sswid, ddevid, dswid, msgid, msglen) |
|||
msglen = msglen + 2 -- add last reserved 2 bytes |
|||
|
|||
local seq = _seq |
|||
_seq = _seq + 1 |
|||
if _seq > 255 then |
|||
_seq = 0 |
|||
end |
|||
|
|||
local sid = get_station() |
|||
|
|||
local hdr = string.pack('HHHHHHIBBHHH', sid, sdevid, sswid, sid, |
|||
ddevid, dswid, 0, 0, seq, msglen, msgid, 0); |
|||
assert(#hdr == 24) |
|||
return hdr |
|||
end |
|||
|
|||
function build_packet(sdevid, sswid, ddevid, dswid, msgid, data) |
|||
local hdr = build_header(sdevid, sswid, ddevid, dswid, msgid, #data) |
|||
return hdr .. data |
|||
end |
|||
|
|||
function build_alarm_text(termid, mode, data) |
|||
local ctx = string.pack('B', mode) .. data |
|||
return build_packet(0, 0, termid, constants.SW_ID_HOST, constants.MSG_ID_ALARM, ctx) |
|||
end |
|||
|
|||
function build_alarm_data(termid, mode, data) |
|||
local ctx = string.pack('B', mode) .. data |
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
termid, constants.SW_ID_TERM, constants.MSG_ID_ALARM, ctx) |
|||
end |
|||
|
|||
function build_iphone_status(ch, cfreq, rxtx, freqs) |
|||
local m, d = math.modf(cfreq) |
|||
d = math.tointeger(d * 1000) |
|||
local data = string.pack('BHHB', ch, m, d, rxtx) |
|||
|
|||
for _, v in ipairs(freqs) do |
|||
m, d = math.modf(v) |
|||
d = math.tointeger(d * 1000) |
|||
data = data .. string.pack('HH', m, d) |
|||
end |
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
constants.DEV_TERM_ALL, constants.SW_ID_TERM, constants.MSG_ID_IPHONE, data) |
|||
end |
|||
|
|||
function build_iphone_tx(termid, data) |
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
termid, constants.SW_ID_TERM, constants.MSG_ID_IPHONE, data) |
|||
end |
|||
|
|||
function build_iphone_rx(termid, seq, data) |
|||
return build_packet(termid, constants.SW_ID_TERM, constants.SW_ID_TERM, |
|||
constants.DEV_ID_HOST, constants.SW_ID_HOST, constants.MSG_ID_IPHONE, data) |
|||
end |
|||
|
|||
function build_host_selftest(fault, fault_code, version, tdata) |
|||
local tmaps = { |
|||
constants.DEV_TERM_ID_1, |
|||
constants.DEV_TERM_ID_2, |
|||
constants.DEV_TERM_ID_3, |
|||
constants.DEV_TERM_ID_4, |
|||
constants.DEV_TERM_ID_5, |
|||
constants.DEV_TERM_ID_6, |
|||
constants.DEV_PTERM_ID_1, |
|||
constants.DEV_PTERM_ID_2, |
|||
} |
|||
local s = "" |
|||
for _, v in ipairs(tmaps) do |
|||
if tdata[v] ~= nil then |
|||
s = s .. tdata[v] |
|||
else |
|||
s = s .. string.rep("\x00", 10) |
|||
end |
|||
end |
|||
|
|||
local ctx = '\x00' .. string.pack('BII', fault, fault_code, version) .. s |
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
0, constants.SW_ID_ADAPTER, constants.MSG_ID_SELFTEST, ctx) |
|||
end |
|||
|
|||
function build_term_selftest(termid, is_portable, fault, fault_code, version) |
|||
local ctx = '\x00' .. string.pack('BII', fault, fault_code, version) |
|||
|
|||
local sw = constants.SW_ID_TERM |
|||
if is_portable then |
|||
sw = constants.SW_ID_PTERM |
|||
end |
|||
|
|||
return build_packet(termid, sw, constants.DEV_ID_HOST, constants.SW_ID_HOST, constants.MSG_ID_SELFTEST, ctx) |
|||
end |
|||
|
|||
function build_config_req(termid, mode, cfid, cflen, cdata) |
|||
local data = string.pack('BBB', mode, cfid, cflen) |
|||
|
|||
if cflen > 0 then |
|||
data = data .. cdata |
|||
end |
|||
return build_packet(termid, constants.SW_ID_TERM, constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
constants.MSG_ID_CFREQ, data) |
|||
end |
|||
|
|||
function build_config_res(termid, succ, mode, cfid, cflen, cdata) |
|||
local data = string.pack('BBBB', mode, succ, cfid, cflen) |
|||
|
|||
if cflen > 0 then |
|||
data = data .. cdata |
|||
end |
|||
|
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
termid, constants.SW_ID_TERM, constants.MSG_ID_CFRES, data) |
|||
end |
|||
|
|||
function build_ntp_request() |
|||
return build_header(constants.DEV_ID_STORE, constants.SW_ID_ADAPTER, 0xff, 0xff, constants.MSG_ID_NTP, 0) |
|||
end |
|||
|
|||
function build_ntp_status(status) |
|||
local data = string.pack('B', status) |
|||
return build_packet(constants.DEV_ID_HOST, constants.SW_ID_HOST, |
|||
constants.DEV_ID_STORE, constants.SW_ID_ADAPTER, constants.MSG_ID_NTP_STATUS, data) |
|||
end |
|||
|
|||
function parse_msg_id(pkt) |
|||
return string.unpack('H', pkt:sub(21)) |
|||
end |
|||
|
|||
function parse_src_dev(pkt) |
|||
return string.unpack('H', pkt:sub(3)) |
|||
end |
|||
|
|||
function parse_src_sw(pkt) |
|||
return string.unpack('H', pkt:sub(5)) |
|||
end |
|||
|
|||
function parse_dst_dev(pkt) |
|||
return string.unpack('H', pkt:sub(9)) |
|||
end |
|||
|
|||
function parse_dst_sw(pkt) |
|||
return string.unpack('H', pkt:sub(11)) |
|||
end |
|||
|
|||
function parse_alarm(pkt) |
|||
return pkt:byte(25), pkt:sub(26) |
|||
end |
|||
|
|||
function parse_iphone_status(pkt) -- return rxtx, id, cfreq, freqs |
|||
if #pkt ~= 70 then |
|||
error("iphone status packet too short: ", #pkt) |
|||
return nil |
|||
end |
|||
|
|||
local m, d = string.unpack('HH', pkt:sub(26)) |
|||
local cfreq = m + d / 1000.0 |
|||
|
|||
local freqs = {} |
|||
for i = 31, 69, 4 do |
|||
m, d = string.unpack('HH', pkt:sub(i)) |
|||
local cf = m + d / 1000.0 |
|||
table.insert(freqs, cf) |
|||
end |
|||
return pkt:byte(30), pkt:byte(25), cfreq, freqs |
|||
end |
|||
|
|||
function parse_iphone_data(pkt) |
|||
return pkt:sub(25) |
|||
end |
|||
|
|||
function parse_config_req(pkt) |
|||
local cflen = pkt:byte(27) |
|||
if cflen > 0 then |
|||
return pkt:byte(25), pkt:byte(26), pkt:sub(28) |
|||
else |
|||
return pkt:byte(25), pkt:byte(26) |
|||
end |
|||
end |
|||
|
|||
function parse_config_res(pkt) |
|||
local mode = pkt:byte(25) |
|||
local succ = pkt:byte(26) |
|||
local cfid = pkt:byte(27) |
|||
local cflen = pkt:byte(28) |
|||
|
|||
if cflen > 0 then |
|||
return succ, mode, cfid, pkt:sub(29) |
|||
else |
|||
return succ, mode, cfid |
|||
end |
|||
end |
|||
|
|||
function parse_ntp_status(pkt) |
|||
return pkt:byte(25) |
|||
end |
|||
|
@ -0,0 +1,16 @@ |
|||
function loop(n) |
|||
while true do |
|||
print("n = ", n) |
|||
n = coroutine.yield() |
|||
end |
|||
end |
|||
|
|||
local f = coroutine.wrap(loop) |
|||
|
|||
f(1) |
|||
f(2) |
|||
f(3) |
|||
f(4) |
|||
f(5) |
|||
f(6) |
|||
|
Loading…
Reference in new issue