mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-07-30 16:59:15 +02:00
change the api and extend lua user data len
This commit is contained in:
+20
-26
@@ -1,11 +1,8 @@
|
|||||||
---@meta
|
---@meta
|
||||||
|
|
||||||
-- Global Variables
|
|
||||||
---@type string
|
---@type string
|
||||||
core_version = ""
|
core_version = ""
|
||||||
|
|
||||||
--#region Functions implemented or used in C
|
|
||||||
|
|
||||||
dp = {}
|
dp = {}
|
||||||
|
|
||||||
---@type integer
|
---@type integer
|
||||||
@@ -30,9 +27,9 @@ function dp.force_save() end
|
|||||||
|
|
||||||
---Set the program which is actually being modulated. Setting this does not affect the writing program
|
---Set the program which is actually being modulated. Setting this does not affect the writing program
|
||||||
---@param program_idx integer 0 to (max_programs - 1)
|
---@param program_idx integer 0 to (max_programs - 1)
|
||||||
function dp.set_program(program_idx) end
|
function dp.set_output_program(program_idx) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function dp.get_program() end
|
function dp.get_output_program() end
|
||||||
|
|
||||||
---Sets the program all of the set/get functions affect
|
---Sets the program all of the set/get functions affect
|
||||||
---@param program_idx integer 0 to (max_programs - 1)
|
---@param program_idx integer 0 to (max_programs - 1)
|
||||||
@@ -179,6 +176,7 @@ function rds.set_tps(tps) end
|
|||||||
---@param rt string Radio Text (max 64 chars)
|
---@param rt string Radio Text (max 64 chars)
|
||||||
function rds.set_rt(rt) end
|
function rds.set_rt(rt) end
|
||||||
|
|
||||||
|
---@return nil
|
||||||
function rds.toggle_rt_ab() end
|
function rds.toggle_rt_ab() end
|
||||||
|
|
||||||
---@param lps string
|
---@param lps string
|
||||||
@@ -213,28 +211,24 @@ function rds.put_rds2_custom_group(a, b, c, d) end
|
|||||||
---@param afs table
|
---@param afs table
|
||||||
function rds.set_af(afs) end
|
function rds.set_af(afs) end
|
||||||
|
|
||||||
|
---@class EON_Data
|
||||||
|
---@field enabled? boolean
|
||||||
|
---@field pi? integer
|
||||||
|
---@field tp? boolean
|
||||||
|
---@field ta? boolean
|
||||||
|
---@field pty? integer
|
||||||
|
---@field ps? string
|
||||||
|
---@field afs? table Empty on the getter - empty table does not mean the same thing as nil
|
||||||
|
---@field data? integer
|
||||||
|
|
||||||
---Sets data about the EON
|
---Sets data about the EON
|
||||||
---@param eon integer Index of the EON we are setting
|
---@param eon integer Index of the EON we are setting
|
||||||
---@param enabled boolean
|
---@param data EON_Data
|
||||||
---@param pi integer
|
function rds.set_eon(eon, data) end
|
||||||
---@param tp boolean
|
|
||||||
---@param ta boolean
|
|
||||||
---@param pty integer
|
|
||||||
---@param ps string
|
|
||||||
---@param afs table
|
|
||||||
---@param data integer
|
|
||||||
function rds.set_eon(eon, enabled, pi, tp, ta, pty, ps, afs, data) end
|
|
||||||
|
|
||||||
---Gets the same data set_rds_eon sets, yes this returns 8 arguments
|
---Gets the same data set_rds_eon sets
|
||||||
---@param eon integer
|
---@param eon integer
|
||||||
---@return boolean enabled
|
---@return EON_Data
|
||||||
---@return integer pi
|
|
||||||
---@return boolean tp
|
|
||||||
---@return boolean ta
|
|
||||||
---@return integer pty
|
|
||||||
---@return string ps
|
|
||||||
---@return table _ this is empty, getting afs is not supported yet
|
|
||||||
---@return integer data
|
|
||||||
function rds.get_eon(eon) end
|
function rds.get_eon(eon) end
|
||||||
|
|
||||||
---Sets the X/Y of the UDG
|
---Sets the X/Y of the UDG
|
||||||
@@ -256,9 +250,9 @@ userdata.len = 0
|
|||||||
function userdata.set(data) end
|
function userdata.set(data) end
|
||||||
---Writes to the userdata at the offset, size does not have to match the length of the string, if the string is less than size then the rest of the string will be padded with zeroes until it is size
|
---Writes to the userdata at the offset, size does not have to match the length of the string, if the string is less than size then the rest of the string will be padded with zeroes until it is size
|
||||||
---@param offset integer
|
---@param offset integer
|
||||||
---@param size integer
|
---@param padded_size integer
|
||||||
---@param data string
|
---@param data string
|
||||||
function userdata.set_offset(offset, size, data) end
|
function userdata.set_offset(offset, padded_size, data) end
|
||||||
|
|
||||||
---Returns all of the data saved as user data
|
---Returns all of the data saved as user data
|
||||||
---@return string
|
---@return string
|
||||||
@@ -314,7 +308,7 @@ function rds.ext.set_af_oda(afs) end
|
|||||||
---@param group_version boolean
|
---@param group_version boolean
|
||||||
---@param aid integer
|
---@param aid integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
---@param temp boolean
|
---@param temp boolean Send AID once (no data) and destroy
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function ext.register_oda(group, group_version, aid, data, temp) end
|
function ext.register_oda(group, group_version, aid, data, temp) end
|
||||||
|
|
||||||
|
|||||||
+95
-10
@@ -1,4 +1,6 @@
|
|||||||
uecp = {}
|
uecp = {}
|
||||||
|
uecp.site_addreses = {}
|
||||||
|
uecp.encoder_addreses = {}
|
||||||
uecp.rt_buffer = {}
|
uecp.rt_buffer = {}
|
||||||
uecp.rt_buffer_index = 1
|
uecp.rt_buffer_index = 1
|
||||||
uecp.rt_tx_remaining = 0
|
uecp.rt_tx_remaining = 0
|
||||||
@@ -21,7 +23,6 @@ hooks.rt_transmission[#hooks.rt_transmission + 1] = function ()
|
|||||||
if entry.toggle_ab then rds.toggle_rt_ab() end
|
if entry.toggle_ab then rds.toggle_rt_ab() end
|
||||||
end
|
end
|
||||||
|
|
||||||
local mec_handlers = {}
|
|
||||||
|
|
||||||
local function dsn_helper(dsn, write)
|
local function dsn_helper(dsn, write)
|
||||||
if dsn == 0 then write()
|
if dsn == 0 then write()
|
||||||
@@ -45,6 +46,7 @@ local function dsn_helper(dsn, write)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local mec_handlers = {}
|
||||||
mec_handlers[1] = function(data)
|
mec_handlers[1] = function(data)
|
||||||
-- PI
|
-- PI
|
||||||
local dsn = string.byte(data, 2)
|
local dsn = string.byte(data, 2)
|
||||||
@@ -99,7 +101,7 @@ mec_handlers[3] = function(data)
|
|||||||
local data = string.byte(data, 4)
|
local data = string.byte(data, 4)
|
||||||
dsn_helper(dsn, function ()
|
dsn_helper(dsn, function ()
|
||||||
rds.set_ta((data & 1) ~= 0)
|
rds.set_ta((data & 1) ~= 0)
|
||||||
rds.set_ta((data & 2) ~= 0)
|
rds.set_tp((data & 2) ~= 0)
|
||||||
end)
|
end)
|
||||||
return 4
|
return 4
|
||||||
end
|
end
|
||||||
@@ -181,7 +183,17 @@ mec_handlers[0x13] = function (data)
|
|||||||
local psn = string.byte(data, 3)
|
local psn = string.byte(data, 3)
|
||||||
local mel = string.sub(data, 4)
|
local mel = string.sub(data, 4)
|
||||||
|
|
||||||
-- TODO: decode
|
-- TODO: decode - i have zero clue what the hell is the meaning of the docs, it might as well be in chinese (traditional)
|
||||||
|
|
||||||
|
return 4+mel
|
||||||
|
end
|
||||||
|
mec_handlers[0x14] = function (data)
|
||||||
|
-- EON-AF
|
||||||
|
local dsn = string.byte(data, 2)
|
||||||
|
local psn = string.byte(data, 3)
|
||||||
|
local mel = string.sub(data, 4)
|
||||||
|
|
||||||
|
-- TODO: decode - haven't read this one
|
||||||
|
|
||||||
return 4+mel
|
return 4+mel
|
||||||
end
|
end
|
||||||
@@ -195,6 +207,7 @@ mec_handlers[0x1A] = function (data)
|
|||||||
local full_data = ((data & 15) << 8) | data_lsb
|
local full_data = ((data & 15) << 8) | data_lsb
|
||||||
local variant = (data >> 4) & 3
|
local variant = (data >> 4) & 3
|
||||||
if variant == 0 then
|
if variant == 0 then
|
||||||
|
-- TODO: maybe make it more than just ecc? idk why but would be cool
|
||||||
dsn_helper(dsn, function ()
|
dsn_helper(dsn, function ()
|
||||||
rds.set_ecc(full_data)
|
rds.set_ecc(full_data)
|
||||||
end)
|
end)
|
||||||
@@ -202,20 +215,59 @@ mec_handlers[0x1A] = function (data)
|
|||||||
|
|
||||||
return 4
|
return 4
|
||||||
end
|
end
|
||||||
|
mec_handlers[0x2E] = function (data)
|
||||||
|
-- Linkage Information
|
||||||
|
-- What? What is the main PSN? Does the server tell me that or am i to fucking guess?
|
||||||
|
return 5
|
||||||
|
end
|
||||||
|
mec_handlers[0x24] = function (data)
|
||||||
|
-- Free-format data in type A or B group
|
||||||
|
-- TODO: figure out the docs
|
||||||
|
return 7
|
||||||
|
end
|
||||||
|
-- Fuck you mean, i have to implement some fucking "spinning wHELLs"? may the lord have mercy
|
||||||
|
-- Also no time setting via UECP - this is linux, just install fucking chrony
|
||||||
mec_handlers[0x19] = function (data)
|
mec_handlers[0x19] = function (data)
|
||||||
-- CT
|
-- CT
|
||||||
local data = string.byte(data, 2)
|
local data = string.byte(data, 2)
|
||||||
rds.set_ct(data ~= 0)
|
dsn_helper(255, function ()
|
||||||
|
rds.set_ct(data ~= 0)
|
||||||
|
end)
|
||||||
return 2
|
return 2
|
||||||
end
|
end
|
||||||
|
mec_handlers[0x23] = function (data)
|
||||||
|
-- Site address
|
||||||
|
local control_bits = string.byte(data, 2)
|
||||||
|
local high = string.byte(data, 3)
|
||||||
|
local low = string.byte(data, 4)
|
||||||
|
local data = high << 8 | low
|
||||||
|
if control_bits == 0 then
|
||||||
|
for i, v in ipairs(uecp.site_addreses) do
|
||||||
|
if v == data then table.remove(uecp.site_addreses, i) end
|
||||||
|
end
|
||||||
|
elseif control_bits == 1 then uecp.site_addreses[#uecp.site_addreses+1] = data
|
||||||
|
elseif control_bits == 2 then uecp.site_addreses = {} end
|
||||||
|
return 4
|
||||||
|
end
|
||||||
|
mec_handlers[0x27] = function (data)
|
||||||
|
-- Encoder address
|
||||||
|
local control_bits = string.byte(data, 2)
|
||||||
|
local data = string.byte(data, 3)
|
||||||
|
if control_bits == 0 then
|
||||||
|
for i, v in ipairs(uecp.encoder_addreses) do
|
||||||
|
if v == data then table.remove(uecp.encoder_addreses, i) end
|
||||||
|
end
|
||||||
|
elseif control_bits == 1 then uecp.encoder_addreses[#uecp.encoder_addreses+1] = data
|
||||||
|
elseif control_bits == 2 then uecp.encoder_addreses = {} end
|
||||||
|
return 3
|
||||||
|
end
|
||||||
mec_handlers[0x1C] = function (data)
|
mec_handlers[0x1C] = function (data)
|
||||||
-- DS select
|
-- DS select
|
||||||
local dsn = string.byte(data, 2)
|
local dsn = string.byte(data, 2)
|
||||||
dp.set_program(dsn)
|
dp.set_output_program(dsn)
|
||||||
dp.set_writing_program(dsn)
|
dp.set_writing_program(dsn)
|
||||||
return 2
|
return 2
|
||||||
end
|
end
|
||||||
|
|
||||||
mec_handlers[0x2D] = function (data)
|
mec_handlers[0x2D] = function (data)
|
||||||
-- Manufacturer
|
-- Manufacturer
|
||||||
local mel = string.byte(data, 2)
|
local mel = string.byte(data, 2)
|
||||||
@@ -246,14 +298,48 @@ local function undo_byte_stuff(data)
|
|||||||
return table.concat(output)
|
return table.concat(output)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param site integer
|
||||||
|
---@param encoder integer
|
||||||
|
---@return boolean
|
||||||
|
local function check_address(site, encoder)
|
||||||
|
if site == 0 and encoder == 0 then return true end
|
||||||
|
|
||||||
|
local site_allowed = false
|
||||||
|
if site ~= 0 then
|
||||||
|
for i, v in ipairs(uecp.site_addreses) do
|
||||||
|
if v == site then
|
||||||
|
site_allowed = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else site_allowed = true end
|
||||||
|
|
||||||
|
local encoder_allowed = false
|
||||||
|
if encoder ~= 0 then
|
||||||
|
for i, v in ipairs(uecp.encoder_addreses) do
|
||||||
|
if v == encoder then
|
||||||
|
encoder_allowed = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else encoder_allowed = true end
|
||||||
|
|
||||||
|
return site_allowed and encoder_allowed
|
||||||
|
end
|
||||||
|
|
||||||
---@param packet string
|
---@param packet string
|
||||||
function uecp.parse_uecp(packet)
|
function uecp.parse_uecp(packet)
|
||||||
|
if not packet or #packet == 0 then return end
|
||||||
|
if string.byte(packet, 1) ~= 0xfe or string.byte(packet, #packet) ~= 0xff then return end
|
||||||
|
|
||||||
local unstuffed = undo_byte_stuff(string.sub(packet, 2, #packet - 1))
|
local unstuffed = undo_byte_stuff(string.sub(packet, 2, #packet - 1))
|
||||||
|
|
||||||
local addr1 = string.byte(unstuffed, 1)
|
local addr1 = string.byte(unstuffed, 1)
|
||||||
local addr2 = string.byte(unstuffed, 2)
|
local addr2 = string.byte(unstuffed, 2)
|
||||||
local site_addr = (addr1 << 2) | (addr2 >> 6)
|
local site_addr = (addr1 << 2) | (addr2 >> 6)
|
||||||
local encoder_addr = addr2 & 0x3F
|
|
||||||
|
if not check_address(site_addr, addr2 & 0x3F) then return end
|
||||||
|
|
||||||
local sequence_count = string.byte(unstuffed, 3)
|
local sequence_count = string.byte(unstuffed, 3)
|
||||||
local mfl = string.byte(unstuffed, 4)
|
local mfl = string.byte(unstuffed, 4)
|
||||||
|
|
||||||
@@ -266,8 +352,7 @@ function uecp.parse_uecp(packet)
|
|||||||
|
|
||||||
local crc_calculated = dp.crc16(string.sub(unstuffed, 1, 4 + mfl))
|
local crc_calculated = dp.crc16(string.sub(unstuffed, 1, 4 + mfl))
|
||||||
local crc_hi = string.byte(unstuffed, 4 + mfl + 1)
|
local crc_hi = string.byte(unstuffed, 4 + mfl + 1)
|
||||||
local crc_lo = string.byte(unstuffed, 4 + mfl + 2)
|
local crc_stored = (crc_hi << 8) | string.byte(unstuffed, 4 + mfl + 2)
|
||||||
local crc_stored = (crc_hi << 8) | crc_lo
|
|
||||||
|
|
||||||
if crc_calculated ~= crc_stored then
|
if crc_calculated ~= crc_stored then
|
||||||
print("bad crc")
|
print("bad crc")
|
||||||
@@ -284,6 +369,6 @@ function uecp.parse_uecp(packet)
|
|||||||
end
|
end
|
||||||
local advance = handler(string.sub(data, consumed))
|
local advance = handler(string.sub(data, consumed))
|
||||||
consumed = consumed + advance
|
consumed = consumed + advance
|
||||||
dp.set_writing_program(dp.get_program())
|
dp.set_writing_program(dp.get_output_program())
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
+22
-23
@@ -1,3 +1,4 @@
|
|||||||
|
---@param data string
|
||||||
function data_handle(data)
|
function data_handle(data)
|
||||||
-- UECP
|
-- UECP
|
||||||
if uecp.parse_uecp and string.byte(data, 1) == 0xfe then return uecp.parse_uecp(data) end
|
if uecp.parse_uecp and string.byte(data, 1) == 0xfe then return uecp.parse_uecp(data) end
|
||||||
@@ -85,15 +86,15 @@ function data_handle(data)
|
|||||||
local eon_idx = tonumber(eon_cmd)
|
local eon_idx = tonumber(eon_cmd)
|
||||||
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
||||||
eon_idx = eon_idx - 1
|
eon_idx = eon_idx - 1
|
||||||
local enabled, pi, tp, ta, pty, ps, afs, data_val = rds.get_eon(eon_idx)
|
local eon_data = rds.get_eon(eon_idx)
|
||||||
|
|
||||||
if eon_num == "en" then return string.format("EON%dEN=%d\r\n", eon_idx + 1, enabled and 1 or 0)
|
if eon_num == "en" then return string.format("EON%dEN=%d\r\n", eon_idx + 1, eon_data.enabled and 1 or 0)
|
||||||
elseif eon_num == "pi" then return string.format("EON%dPI=%x\r\n", eon_idx + 1, pi)
|
elseif eon_num == "pi" then return string.format("EON%dPI=%x\r\n", eon_idx + 1, eon_data.pi)
|
||||||
elseif eon_num == "ps" then return string.format("EON%dPS=%s\r\n", eon_idx + 1, ps)
|
elseif eon_num == "ps" then return string.format("EON%dPS=%s\r\n", eon_idx + 1, eon_data.ps)
|
||||||
elseif eon_num == "pty" then return string.format("EON%dPTY=%d\r\n", eon_idx + 1, pty)
|
elseif eon_num == "pty" then return string.format("EON%dPTY=%d\r\n", eon_idx + 1, eon_data.pty)
|
||||||
elseif eon_num == "ta" then return string.format("EON%dTA=%d\r\n", eon_idx + 1, ta and 1 or 0)
|
elseif eon_num == "ta" then return string.format("EON%dTA=%d\r\n", eon_idx + 1, eon_data.ta and 1 or 0)
|
||||||
elseif eon_num == "tp" then return string.format("EON%dTP=%d\r\n", eon_idx + 1, tp and 1 or 0)
|
elseif eon_num == "tp" then return string.format("EON%dTP=%d\r\n", eon_idx + 1, eon_data.tp and 1 or 0)
|
||||||
elseif eon_num == "dt" then return string.format("EON%dDT=%x\r\n", eon_idx + 1, data_val)
|
elseif eon_num == "dt" then return string.format("EON%dDT=%x\r\n", eon_idx + 1, eon_data.data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return "?\r\n"
|
return "?\r\n"
|
||||||
@@ -109,45 +110,43 @@ function data_handle(data)
|
|||||||
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
||||||
eon_idx = eon_idx - 1
|
eon_idx = eon_idx - 1
|
||||||
|
|
||||||
local enabled, pi, tp, ta, pty, ps, afs, data_val = rds.get_eon(eon_idx)
|
|
||||||
if eon_type == "en" then
|
if eon_type == "en" then
|
||||||
local en_val = tonumber(value)
|
local en_val = tonumber(value)
|
||||||
if not en_val then return "-\r\n" end
|
if not en_val then return "-\r\n" end
|
||||||
enabled = (en_val ~= 0)
|
local enabled = (en_val ~= 0)
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, { enabled = enabled })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "pi" then
|
elseif eon_type == "pi" then
|
||||||
local pi_val = tonumber(value, 16)
|
local pi_val = tonumber(value, 16)
|
||||||
if not pi_val then return "-\r\n" end
|
if not pi_val then return "-\r\n" end
|
||||||
rds.set_eon(eon_idx, enabled, pi_val, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, { pi = pi_val })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "ps" then
|
elseif eon_type == "ps" then
|
||||||
local ps_val = value:sub(1, 24)
|
local ps_val = value:sub(1, 24)
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps_val, afs, data_val)
|
rds.set_eon(eon_idx, { ps = ps_val })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "pty" then
|
elseif eon_type == "pty" then
|
||||||
local pty_val = tonumber(value)
|
local pty_val = tonumber(value)
|
||||||
if not pty_val then return "-\r\n" end
|
if not pty_val then return "-\r\n" end
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty_val, ps, afs, data_val)
|
rds.set_eon(eon_idx, { pty = pty_val })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "ta" then
|
elseif eon_type == "ta" then
|
||||||
if not enabled or not tp then return "-\r\n" end
|
|
||||||
local ta_val = tonumber(value)
|
local ta_val = tonumber(value)
|
||||||
if not ta_val then return "-\r\n" end
|
if not ta_val then return "-\r\n" end
|
||||||
ta = (ta_val ~= 0)
|
local ta = (ta_val ~= 0)
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, { ta = ta })
|
||||||
if ta then rds.set_ta(true) end
|
if ta then rds.set_ta(true) end
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "tp" then
|
elseif eon_type == "tp" then
|
||||||
local tp_val = tonumber(value)
|
local tp_val = tonumber(value)
|
||||||
if not tp_val then return "-\r\n" end
|
if not tp_val then return "-\r\n" end
|
||||||
tp = (tp_val ~= 0)
|
local tp = (tp_val ~= 0)
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, { tp = tp })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "af" then
|
elseif eon_type == "af" then
|
||||||
local af_table = {}
|
local af_table = {}
|
||||||
if value == "" or value == "0" then
|
if value == "" or value == "0" then
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, {}, data_val)
|
rds.set_eon(eon_idx, { afs = {} })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
for freq_str in value:gmatch("([^,]+)") do
|
for freq_str in value:gmatch("([^,]+)") do
|
||||||
@@ -156,12 +155,12 @@ function data_handle(data)
|
|||||||
else return "-\r\n" end
|
else return "-\r\n" end
|
||||||
end
|
end
|
||||||
if #af_table > 25 then return "-\r\n" end
|
if #af_table > 25 then return "-\r\n" end
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, af_table, data_val)
|
rds.set_eon(eon_idx, { afs = af_table })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "dt" then
|
elseif eon_type == "dt" then
|
||||||
local dt_val = tonumber(value, 16)
|
local dt_val = tonumber(value, 16)
|
||||||
if not dt_val then return "-\r\n" end
|
if not dt_val then return "-\r\n" end
|
||||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, dt_val)
|
rds.set_eon(eon_idx, { data = dt_val })
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
else return "?\r\n" end
|
else return "?\r\n" end
|
||||||
end
|
end
|
||||||
@@ -286,7 +285,7 @@ function data_handle(data)
|
|||||||
local program = tonumber(value)
|
local program = tonumber(value)
|
||||||
if not program then return "-\r\n" end
|
if not program then return "-\r\n" end
|
||||||
if program < 1 or program > dp.max_programs then return "-\r\n" end
|
if program < 1 or program > dp.max_programs then return "-\r\n" end
|
||||||
dp.set_program(program-1)
|
dp.set_output_program(program-1)
|
||||||
dp.set_writing_program(program-1)
|
dp.set_writing_program(program-1)
|
||||||
rds.set_ta(false)
|
rds.set_ta(false)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
|
|||||||
+70
-23
@@ -5,7 +5,6 @@ static int in_set_defaults = 0;
|
|||||||
|
|
||||||
extern lua_State *L;
|
extern lua_State *L;
|
||||||
extern RDSEncoder* enc;
|
extern RDSEncoder* enc;
|
||||||
extern uint8_t unload_refs[33];
|
|
||||||
static int writing_program = 0;
|
static int writing_program = 0;
|
||||||
|
|
||||||
int lua_get_userdata(lua_State *localL) {
|
int lua_get_userdata(lua_State *localL) {
|
||||||
@@ -54,8 +53,6 @@ int lua_set_rds_program_defaults(lua_State *localL) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
in_set_defaults = 1;
|
in_set_defaults = 1;
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
|
||||||
unload_refs[0] = 1;
|
|
||||||
set_rds_defaults(enc, writing_program);
|
set_rds_defaults(enc, writing_program);
|
||||||
lua_call_tfunction_nolock("on_init");
|
lua_call_tfunction_nolock("on_init");
|
||||||
lua_call_tfunction_nolock("on_state");
|
lua_call_tfunction_nolock("on_state");
|
||||||
@@ -65,8 +62,6 @@ int lua_set_rds_program_defaults(lua_State *localL) {
|
|||||||
|
|
||||||
int lua_reset_rds(lua_State *localL) {
|
int lua_reset_rds(lua_State *localL) {
|
||||||
(void)localL;
|
(void)localL;
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
|
||||||
unload_refs[0] = 1;
|
|
||||||
encoder_saveToFile(enc);
|
encoder_saveToFile(enc);
|
||||||
|
|
||||||
encoder_loadFromFile(enc);
|
encoder_loadFromFile(enc);
|
||||||
@@ -280,19 +275,58 @@ int lua_toggle_rt_ab(lua_State *localL) {
|
|||||||
int lua_set_rds_eon(lua_State *localL) {
|
int lua_set_rds_eon(lua_State *localL) {
|
||||||
int eon = luaL_checkinteger(localL, 1);
|
int eon = luaL_checkinteger(localL, 1);
|
||||||
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
||||||
if (!lua_isboolean(localL, 2)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 2));
|
|
||||||
if (!lua_isboolean(localL, 4)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 4));
|
|
||||||
if (!lua_isboolean(localL, 5)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 5));
|
|
||||||
luaL_checktype(localL, 8, LUA_TTABLE);
|
|
||||||
enc->data[writing_program].eon[eon].enabled = lua_toboolean(localL, 2);
|
|
||||||
enc->data[writing_program].eon[eon].pi = luaL_checkinteger(localL, 3);
|
|
||||||
enc->data[writing_program].eon[eon].tp = lua_toboolean(localL, 4);
|
|
||||||
enc->data[writing_program].eon[eon].ta = lua_toboolean(localL, 5);
|
|
||||||
enc->data[writing_program].eon[eon].pty = luaL_checkinteger(localL, 6);
|
|
||||||
_strncpy(enc->data[writing_program].eon[eon].ps, luaL_checklstring(localL, 7, NULL), 8);
|
|
||||||
|
|
||||||
int n = lua_rawlen(localL, 8);
|
if(!lua_istable(localL, 2)) return luaL_error(localL, "table expected, got %s", luaL_typename(localL, 2));
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "enabled");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
luaL_checktype(localL, -1, LUA_TBOOLEAN);
|
||||||
|
enc->data[writing_program].eon[eon].enabled = lua_toboolean(localL, -1);
|
||||||
|
} lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "tp");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
luaL_checktype(localL, -1, LUA_TBOOLEAN);
|
||||||
|
enc->data[writing_program].eon[eon].tp = lua_toboolean(localL, -1);
|
||||||
|
} lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "ta");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
luaL_checktype(localL, -1, LUA_TBOOLEAN);
|
||||||
|
enc->data[writing_program].eon[eon].ta = lua_toboolean(localL, -1);
|
||||||
|
} lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "pi");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
lua_Integer pi = luaL_checkinteger(localL, -1);
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
enc->data[writing_program].eon[eon].pi = pi;
|
||||||
|
} else lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "pty");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
lua_Integer pty = luaL_checkinteger(localL, -1);
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
enc->data[writing_program].eon[eon].pty = pty;
|
||||||
|
} else lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "data");
|
||||||
|
if(!lua_isnil(localL, -1)) {
|
||||||
|
lua_Integer data = luaL_checkinteger(localL, -1);
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
enc->data[writing_program].eon[eon].data = data;
|
||||||
|
} else lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "ps");
|
||||||
|
if(!lua_isnil(localL, -1)) _strncpy(enc->data[writing_program].eon[eon].ps, luaL_checklstring(localL, -1, NULL), 8);
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
|
||||||
|
lua_getfield(localL, 2, "afs");
|
||||||
|
luaL_checktype(localL, -1, LUA_TTABLE);
|
||||||
|
|
||||||
|
int n = lua_rawlen(localL, -1);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
lua_pop(localL, 1);
|
||||||
memset(&(enc->data[writing_program].eon[eon].af), 0, sizeof(RDSAFs));
|
memset(&(enc->data[writing_program].eon[eon].af), 0, sizeof(RDSAFs));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -302,29 +336,42 @@ int lua_set_rds_eon(lua_State *localL) {
|
|||||||
memset(&new_af, 0, sizeof(RDSAFs));
|
memset(&new_af, 0, sizeof(RDSAFs));
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
for (int i = 1; i <= n; i++) {
|
||||||
lua_rawgeti(localL, 8, i);
|
lua_rawgeti(localL, -1, i);
|
||||||
if (lua_isnumber(localL, -1)) add_rds_af(&new_af, lua_tonumber(localL, -1));
|
if (!lua_isnumber(localL, -1)) {
|
||||||
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1));
|
const char *type = luaL_typename(localL, -1);
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
return luaL_error(localL, "number expected, got %s", type);
|
||||||
|
}
|
||||||
|
add_rds_af(&new_af, lua_tonumber(localL, -1));
|
||||||
lua_pop(localL, 1);
|
lua_pop(localL, 1);
|
||||||
}
|
}
|
||||||
memcpy(&(enc->data[writing_program].eon[eon].af), &new_af, sizeof(new_af));
|
memcpy(&(enc->data[writing_program].eon[eon].af), &new_af, sizeof(new_af));
|
||||||
|
lua_pop(localL, 1);
|
||||||
enc->data[writing_program].eon[eon].data = luaL_checkinteger(localL, 9);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_get_rds_eon(lua_State *localL) {
|
int lua_get_rds_eon(lua_State *localL) {
|
||||||
int eon = luaL_checkinteger(localL, 1);
|
int eon = luaL_checkinteger(localL, 1);
|
||||||
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
||||||
|
|
||||||
|
lua_newtable(localL);
|
||||||
lua_pushboolean(localL, enc->data[writing_program].eon[eon].enabled);
|
lua_pushboolean(localL, enc->data[writing_program].eon[eon].enabled);
|
||||||
|
lua_setfield(L, -2, "enabled");
|
||||||
lua_pushinteger(localL, enc->data[writing_program].eon[eon].pi);
|
lua_pushinteger(localL, enc->data[writing_program].eon[eon].pi);
|
||||||
|
lua_setfield(L, -2, "pi");
|
||||||
lua_pushboolean(localL, enc->data[writing_program].eon[eon].tp);
|
lua_pushboolean(localL, enc->data[writing_program].eon[eon].tp);
|
||||||
|
lua_setfield(L, -2, "tp");
|
||||||
lua_pushboolean(localL, enc->data[writing_program].eon[eon].ta);
|
lua_pushboolean(localL, enc->data[writing_program].eon[eon].ta);
|
||||||
|
lua_setfield(L, -2, "ta");
|
||||||
lua_pushinteger(localL, enc->data[writing_program].eon[eon].pty);
|
lua_pushinteger(localL, enc->data[writing_program].eon[eon].pty);
|
||||||
|
lua_setfield(L, -2, "pty");
|
||||||
lua_pushlstring(localL, enc->data[writing_program].eon[eon].ps, 8);
|
lua_pushlstring(localL, enc->data[writing_program].eon[eon].ps, 8);
|
||||||
lua_createtable(localL, 0, 0); // don't have decoding for AF, so just return empty table
|
lua_setfield(L, -2, "ps");
|
||||||
|
lua_newtable(localL); // don't have decoding for AF, so just return empty table
|
||||||
|
lua_setfield(L, -2, "afs");
|
||||||
lua_pushinteger(localL, enc->data[writing_program].eon[eon].data);
|
lua_pushinteger(localL, enc->data[writing_program].eon[eon].data);
|
||||||
return 8;
|
lua_setfield(L, -2, "data");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_set_rds_udg(lua_State *localL) {
|
int lua_set_rds_udg(lua_State *localL) {
|
||||||
|
|||||||
+4
-78
@@ -5,7 +5,6 @@
|
|||||||
RDSEncoder* enc = NULL;
|
RDSEncoder* enc = NULL;
|
||||||
lua_State *L = NULL;
|
lua_State *L = NULL;
|
||||||
static pthread_mutex_t lua_mutex;
|
static pthread_mutex_t lua_mutex;
|
||||||
uint8_t unload_refs[33] = {LUA_REFNIL};
|
|
||||||
|
|
||||||
#define lua_registertotable(L,n,f) (lua_pushcfunction(L, (f)), lua_setfield(L, -2, (n)))
|
#define lua_registertotable(L,n,f) (lua_pushcfunction(L, (f)), lua_setfield(L, -2, (n)))
|
||||||
void init_lua(RDSEncoder* _enc) {
|
void init_lua(RDSEncoder* _enc) {
|
||||||
@@ -54,8 +53,8 @@ void init_lua(RDSEncoder* _enc) {
|
|||||||
lua_registertotable(L, "set_program_defaults", lua_set_rds_program_defaults);
|
lua_registertotable(L, "set_program_defaults", lua_set_rds_program_defaults);
|
||||||
lua_pushinteger(L, PROGRAMS);
|
lua_pushinteger(L, PROGRAMS);
|
||||||
lua_setfield(L, -2, "max_programs");
|
lua_setfield(L, -2, "max_programs");
|
||||||
lua_registertotable(L, "set_program", lua_set_rds_program);
|
lua_registertotable(L, "set_output_program", lua_set_rds_program);
|
||||||
lua_registertotable(L, "get_program", lua_get_rds_program);
|
lua_registertotable(L, "get_output_program", lua_get_rds_program);
|
||||||
lua_registertotable(L, "set_writing_program", lua_set_rds_writing_program);
|
lua_registertotable(L, "set_writing_program", lua_set_rds_writing_program);
|
||||||
lua_registertotable(L, "get_writing_program", lua_get_rds_writing_program);
|
lua_registertotable(L, "get_writing_program", lua_get_rds_writing_program);
|
||||||
lua_setglobal(L, "dp");
|
lua_setglobal(L, "dp");
|
||||||
@@ -148,7 +147,6 @@ void init_lua(RDSEncoder* _enc) {
|
|||||||
|
|
||||||
lua_setglobal(L, "rds");
|
lua_setglobal(L, "rds");
|
||||||
|
|
||||||
|
|
||||||
if (luaL_loadfile(L, "/etc/rds95.lua") != LUA_OK) {
|
if (luaL_loadfile(L, "/etc/rds95.lua") != LUA_OK) {
|
||||||
fprintf(stderr, "Lua error loading file: %s\n", lua_tostring(L, -1));
|
fprintf(stderr, "Lua error loading file: %s\n", lua_tostring(L, -1));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@@ -274,39 +272,6 @@ int lua_rds2_group(RDSGroup* group, int stream) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_group_ref(RDSGroup* group, int ref) {
|
|
||||||
pthread_mutex_lock(&lua_mutex);
|
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
|
||||||
|
|
||||||
if (lua_isfunction(L, -1)) {
|
|
||||||
if (lua_pcall(L, 0, 3, 0) == LUA_OK) {
|
|
||||||
if (!lua_isinteger(L, -1)) {
|
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!lua_isinteger(L, -2)) {
|
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!lua_isinteger(L, -3)) {
|
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
group->d = luaL_checkinteger(L, -1);
|
|
||||||
group->c = luaL_checkinteger(L, -2);
|
|
||||||
group->b = luaL_checkinteger(L, -3);
|
|
||||||
lua_pop(L, 3);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Lua error: %s at ref %d\n", lua_tostring(L, -1), ref);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
} else lua_pop(L, 1);
|
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lua_call_function_nolock(const char* function) {
|
void lua_call_function_nolock(const char* function) {
|
||||||
lua_getglobal(L, function);
|
lua_getglobal(L, function);
|
||||||
|
|
||||||
@@ -327,40 +292,6 @@ void lua_call_function(const char* function) {
|
|||||||
pthread_mutex_unlock(&lua_mutex);
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_call_table_nolock(const char *table_name) {
|
|
||||||
lua_getglobal(L, table_name);
|
|
||||||
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_Integer len = lua_rawlen(L, -1);
|
|
||||||
for (lua_Integer i = 1; i <= len; i++) {
|
|
||||||
lua_rawgeti(L, -1, i);
|
|
||||||
if (lua_isfunction(L, -1)) {
|
|
||||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Lua error: %s at '%s[%lld]'\n",
|
|
||||||
lua_tostring(L, -1),
|
|
||||||
table_name,
|
|
||||||
(long long)i);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
} else lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_pop(L, 1); // pop table
|
|
||||||
}
|
|
||||||
void lua_call_table(const char* function) {
|
|
||||||
int need_lock = (pthread_mutex_trylock(&lua_mutex) == 0);
|
|
||||||
if (!need_lock) {
|
|
||||||
fprintf(stderr, "Warning: lua_mutex already locked when table calling %s\n", function);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lua_call_table_nolock(function);
|
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lua_call_tfunction_nolock(const char* name) {
|
void lua_call_tfunction_nolock(const char* name) {
|
||||||
lua_getglobal(L, "hooks");
|
lua_getglobal(L, "hooks");
|
||||||
if (!lua_istable(L, -1)) {
|
if (!lua_istable(L, -1)) {
|
||||||
@@ -380,11 +311,8 @@ void lua_call_tfunction_nolock(const char* name) {
|
|||||||
lua_rawgeti(L, -1, i);
|
lua_rawgeti(L, -1, i);
|
||||||
if (lua_isfunction(L, -1)) {
|
if (lua_isfunction(L, -1)) {
|
||||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Lua error: %s at '%s[%lld]'\n",
|
||||||
"Lua error: %s at '%s[%lld]'\n",
|
lua_tostring(L, -1), name, (long long)i);
|
||||||
lua_tostring(L, -1),
|
|
||||||
name,
|
|
||||||
(long long)i);
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
} else lua_pop(L, 1);
|
} else lua_pop(L, 1);
|
||||||
@@ -404,8 +332,6 @@ void lua_call_tfunction(const char* name) {
|
|||||||
|
|
||||||
void destroy_lua() {
|
void destroy_lua() {
|
||||||
if (L) {
|
if (L) {
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
|
||||||
*unload_refs = 1;
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
L = NULL;
|
L = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ int lua_group(RDSGroup* group, const char grp);
|
|||||||
int lua_rds2_group(RDSGroup* group, int stream);
|
int lua_rds2_group(RDSGroup* group, int stream);
|
||||||
void lua_call_function_nolock(const char* function);
|
void lua_call_function_nolock(const char* function);
|
||||||
void lua_call_function(const char* function);
|
void lua_call_function(const char* function);
|
||||||
void lua_call_table_nolock(const char *table_name);
|
|
||||||
void lua_call_table(const char* function);
|
|
||||||
void lua_call_tfunction_nolock(const char* name);
|
void lua_call_tfunction_nolock(const char* name);
|
||||||
void lua_call_tfunction(const char* name);
|
void lua_call_tfunction(const char* name);
|
||||||
void lua_group_ref(RDSGroup* group, int ref);
|
|
||||||
void destroy_lua();
|
void destroy_lua();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#define LUA_USER_DATA 1152
|
#define LUA_USER_DATA 1280
|
||||||
|
|
||||||
/* The RDS error-detection code generator polynomial is
|
/* The RDS error-detection code generator polynomial is
|
||||||
* x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0
|
* x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0
|
||||||
|
|||||||
Reference in New Issue
Block a user