mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-07-29 16:29:17 +02:00
change the api and extend lua user data len
This commit is contained in:
+20
-26
@@ -1,11 +1,8 @@
|
||||
---@meta
|
||||
|
||||
-- Global Variables
|
||||
---@type string
|
||||
core_version = ""
|
||||
|
||||
--#region Functions implemented or used in C
|
||||
|
||||
dp = {}
|
||||
|
||||
---@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
|
||||
---@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
|
||||
function dp.get_program() end
|
||||
function dp.get_output_program() end
|
||||
|
||||
---Sets the program all of the set/get functions affect
|
||||
---@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)
|
||||
function rds.set_rt(rt) end
|
||||
|
||||
---@return nil
|
||||
function rds.toggle_rt_ab() end
|
||||
|
||||
---@param lps string
|
||||
@@ -213,28 +211,24 @@ function rds.put_rds2_custom_group(a, b, c, d) end
|
||||
---@param afs table
|
||||
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
|
||||
---@param eon integer Index of the EON we are setting
|
||||
---@param enabled boolean
|
||||
---@param pi integer
|
||||
---@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
|
||||
---@param data EON_Data
|
||||
function rds.set_eon(eon, 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
|
||||
---@return boolean enabled
|
||||
---@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
|
||||
---@return EON_Data
|
||||
function rds.get_eon(eon) end
|
||||
|
||||
---Sets the X/Y of the UDG
|
||||
@@ -256,9 +250,9 @@ userdata.len = 0
|
||||
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
|
||||
---@param offset integer
|
||||
---@param size integer
|
||||
---@param padded_size integer
|
||||
---@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
|
||||
---@return string
|
||||
@@ -314,7 +308,7 @@ function rds.ext.set_af_oda(afs) end
|
||||
---@param group_version boolean
|
||||
---@param aid integer
|
||||
---@param data integer
|
||||
---@param temp boolean
|
||||
---@param temp boolean Send AID once (no data) and destroy
|
||||
---@return integer oda_id
|
||||
function ext.register_oda(group, group_version, aid, data, temp) end
|
||||
|
||||
|
||||
+94
-9
@@ -1,4 +1,6 @@
|
||||
uecp = {}
|
||||
uecp.site_addreses = {}
|
||||
uecp.encoder_addreses = {}
|
||||
uecp.rt_buffer = {}
|
||||
uecp.rt_buffer_index = 1
|
||||
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
|
||||
end
|
||||
|
||||
local mec_handlers = {}
|
||||
|
||||
local function dsn_helper(dsn, write)
|
||||
if dsn == 0 then write()
|
||||
@@ -45,6 +46,7 @@ local function dsn_helper(dsn, write)
|
||||
end
|
||||
end
|
||||
|
||||
local mec_handlers = {}
|
||||
mec_handlers[1] = function(data)
|
||||
-- PI
|
||||
local dsn = string.byte(data, 2)
|
||||
@@ -99,7 +101,7 @@ mec_handlers[3] = function(data)
|
||||
local data = string.byte(data, 4)
|
||||
dsn_helper(dsn, function ()
|
||||
rds.set_ta((data & 1) ~= 0)
|
||||
rds.set_ta((data & 2) ~= 0)
|
||||
rds.set_tp((data & 2) ~= 0)
|
||||
end)
|
||||
return 4
|
||||
end
|
||||
@@ -181,7 +183,17 @@ mec_handlers[0x13] = function (data)
|
||||
local psn = string.byte(data, 3)
|
||||
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
|
||||
end
|
||||
@@ -195,6 +207,7 @@ mec_handlers[0x1A] = function (data)
|
||||
local full_data = ((data & 15) << 8) | data_lsb
|
||||
local variant = (data >> 4) & 3
|
||||
if variant == 0 then
|
||||
-- TODO: maybe make it more than just ecc? idk why but would be cool
|
||||
dsn_helper(dsn, function ()
|
||||
rds.set_ecc(full_data)
|
||||
end)
|
||||
@@ -202,20 +215,59 @@ mec_handlers[0x1A] = function (data)
|
||||
|
||||
return 4
|
||||
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)
|
||||
-- CT
|
||||
local data = string.byte(data, 2)
|
||||
dsn_helper(255, function ()
|
||||
rds.set_ct(data ~= 0)
|
||||
end)
|
||||
return 2
|
||||
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)
|
||||
-- DS select
|
||||
local dsn = string.byte(data, 2)
|
||||
dp.set_program(dsn)
|
||||
dp.set_output_program(dsn)
|
||||
dp.set_writing_program(dsn)
|
||||
return 2
|
||||
end
|
||||
|
||||
mec_handlers[0x2D] = function (data)
|
||||
-- Manufacturer
|
||||
local mel = string.byte(data, 2)
|
||||
@@ -246,14 +298,48 @@ local function undo_byte_stuff(data)
|
||||
return table.concat(output)
|
||||
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
|
||||
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 addr1 = string.byte(unstuffed, 1)
|
||||
local addr2 = string.byte(unstuffed, 2)
|
||||
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 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_hi = string.byte(unstuffed, 4 + mfl + 1)
|
||||
local crc_lo = string.byte(unstuffed, 4 + mfl + 2)
|
||||
local crc_stored = (crc_hi << 8) | crc_lo
|
||||
local crc_stored = (crc_hi << 8) | string.byte(unstuffed, 4 + mfl + 2)
|
||||
|
||||
if crc_calculated ~= crc_stored then
|
||||
print("bad crc")
|
||||
@@ -284,6 +369,6 @@ function uecp.parse_uecp(packet)
|
||||
end
|
||||
local advance = handler(string.sub(data, consumed))
|
||||
consumed = consumed + advance
|
||||
dp.set_writing_program(dp.get_program())
|
||||
dp.set_writing_program(dp.get_output_program())
|
||||
end
|
||||
end
|
||||
+22
-23
@@ -1,3 +1,4 @@
|
||||
---@param data string
|
||||
function data_handle(data)
|
||||
-- UECP
|
||||
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)
|
||||
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
||||
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)
|
||||
elseif eon_num == "pi" then return string.format("EON%dPI=%x\r\n", eon_idx + 1, pi)
|
||||
elseif eon_num == "ps" then return string.format("EON%dPS=%s\r\n", eon_idx + 1, ps)
|
||||
elseif eon_num == "pty" then return string.format("EON%dPTY=%d\r\n", eon_idx + 1, 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 == "tp" then return string.format("EON%dTP=%d\r\n", eon_idx + 1, tp and 1 or 0)
|
||||
elseif eon_num == "dt" then return string.format("EON%dDT=%x\r\n", eon_idx + 1, data_val)
|
||||
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, eon_data.pi)
|
||||
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, eon_data.pty)
|
||||
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, eon_data.tp and 1 or 0)
|
||||
elseif eon_num == "dt" then return string.format("EON%dDT=%x\r\n", eon_idx + 1, eon_data.data)
|
||||
end
|
||||
end
|
||||
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
|
||||
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
|
||||
local en_val = tonumber(value)
|
||||
if not en_val then return "-\r\n" end
|
||||
enabled = (en_val ~= 0)
|
||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||
local enabled = (en_val ~= 0)
|
||||
rds.set_eon(eon_idx, { enabled = enabled })
|
||||
return "+\r\n"
|
||||
elseif eon_type == "pi" then
|
||||
local pi_val = tonumber(value, 16)
|
||||
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"
|
||||
elseif eon_type == "ps" then
|
||||
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"
|
||||
elseif eon_type == "pty" then
|
||||
local pty_val = tonumber(value)
|
||||
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"
|
||||
elseif eon_type == "ta" then
|
||||
if not enabled or not tp then return "-\r\n" end
|
||||
local ta_val = tonumber(value)
|
||||
if not ta_val then return "-\r\n" end
|
||||
ta = (ta_val ~= 0)
|
||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||
local ta = (ta_val ~= 0)
|
||||
rds.set_eon(eon_idx, { ta = ta })
|
||||
if ta then rds.set_ta(true) end
|
||||
return "+\r\n"
|
||||
elseif eon_type == "tp" then
|
||||
local tp_val = tonumber(value)
|
||||
if not tp_val then return "-\r\n" end
|
||||
tp = (tp_val ~= 0)
|
||||
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||
local tp = (tp_val ~= 0)
|
||||
rds.set_eon(eon_idx, { tp = tp })
|
||||
return "+\r\n"
|
||||
elseif eon_type == "af" then
|
||||
local af_table = {}
|
||||
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"
|
||||
end
|
||||
for freq_str in value:gmatch("([^,]+)") do
|
||||
@@ -156,12 +155,12 @@ function data_handle(data)
|
||||
else return "-\r\n" end
|
||||
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"
|
||||
elseif eon_type == "dt" then
|
||||
local dt_val = tonumber(value, 16)
|
||||
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"
|
||||
else return "?\r\n" end
|
||||
end
|
||||
@@ -286,7 +285,7 @@ function data_handle(data)
|
||||
local program = tonumber(value)
|
||||
if not program 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)
|
||||
rds.set_ta(false)
|
||||
return "+\r\n"
|
||||
|
||||
+70
-23
@@ -5,7 +5,6 @@ static int in_set_defaults = 0;
|
||||
|
||||
extern lua_State *L;
|
||||
extern RDSEncoder* enc;
|
||||
extern uint8_t unload_refs[33];
|
||||
static int writing_program = 0;
|
||||
|
||||
int lua_get_userdata(lua_State *localL) {
|
||||
@@ -54,8 +53,6 @@ int lua_set_rds_program_defaults(lua_State *localL) {
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
lua_call_tfunction_nolock("on_init");
|
||||
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) {
|
||||
(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_loadFromFile(enc);
|
||||
@@ -280,19 +275,58 @@ int lua_toggle_rt_ab(lua_State *localL) {
|
||||
int lua_set_rds_eon(lua_State *localL) {
|
||||
int eon = luaL_checkinteger(localL, 1);
|
||||
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) {
|
||||
lua_pop(localL, 1);
|
||||
memset(&(enc->data[writing_program].eon[eon].af), 0, sizeof(RDSAFs));
|
||||
return 0;
|
||||
}
|
||||
@@ -302,29 +336,42 @@ int lua_set_rds_eon(lua_State *localL) {
|
||||
memset(&new_af, 0, sizeof(RDSAFs));
|
||||
|
||||
for (int i = 1; i <= n; i++) {
|
||||
lua_rawgeti(localL, 8, i);
|
||||
if (lua_isnumber(localL, -1)) add_rds_af(&new_af, lua_tonumber(localL, -1));
|
||||
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1));
|
||||
lua_rawgeti(localL, -1, i);
|
||||
if (!lua_isnumber(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);
|
||||
}
|
||||
memcpy(&(enc->data[writing_program].eon[eon].af), &new_af, sizeof(new_af));
|
||||
|
||||
enc->data[writing_program].eon[eon].data = luaL_checkinteger(localL, 9);
|
||||
lua_pop(localL, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_get_rds_eon(lua_State *localL) {
|
||||
int eon = luaL_checkinteger(localL, 1);
|
||||
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
||||
|
||||
lua_newtable(localL);
|
||||
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_setfield(L, -2, "pi");
|
||||
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_setfield(L, -2, "ta");
|
||||
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_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);
|
||||
return 8;
|
||||
lua_setfield(L, -2, "data");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_set_rds_udg(lua_State *localL) {
|
||||
|
||||
+4
-78
@@ -5,7 +5,6 @@
|
||||
RDSEncoder* enc = NULL;
|
||||
lua_State *L = NULL;
|
||||
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)))
|
||||
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_pushinteger(L, PROGRAMS);
|
||||
lua_setfield(L, -2, "max_programs");
|
||||
lua_registertotable(L, "set_program", lua_set_rds_program);
|
||||
lua_registertotable(L, "get_program", lua_get_rds_program);
|
||||
lua_registertotable(L, "set_output_program", lua_set_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, "get_writing_program", lua_get_rds_writing_program);
|
||||
lua_setglobal(L, "dp");
|
||||
@@ -148,7 +147,6 @@ void init_lua(RDSEncoder* _enc) {
|
||||
|
||||
lua_setglobal(L, "rds");
|
||||
|
||||
|
||||
if (luaL_loadfile(L, "/etc/rds95.lua") != LUA_OK) {
|
||||
fprintf(stderr, "Lua error loading file: %s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
@@ -274,39 +272,6 @@ int lua_rds2_group(RDSGroup* group, int stream) {
|
||||
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) {
|
||||
lua_getglobal(L, function);
|
||||
|
||||
@@ -327,40 +292,6 @@ void lua_call_function(const char* function) {
|
||||
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) {
|
||||
lua_getglobal(L, "hooks");
|
||||
if (!lua_istable(L, -1)) {
|
||||
@@ -380,11 +311,8 @@ void lua_call_tfunction_nolock(const char* name) {
|
||||
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),
|
||||
name,
|
||||
(long long)i);
|
||||
fprintf(stderr, "Lua error: %s at '%s[%lld]'\n",
|
||||
lua_tostring(L, -1), name, (long long)i);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else lua_pop(L, 1);
|
||||
@@ -404,8 +332,6 @@ void lua_call_tfunction(const char* name) {
|
||||
|
||||
void destroy_lua() {
|
||||
if (L) {
|
||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||
*unload_refs = 1;
|
||||
lua_close(L);
|
||||
L = NULL;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ int lua_group(RDSGroup* group, const char grp);
|
||||
int lua_rds2_group(RDSGroup* group, int stream);
|
||||
void lua_call_function_nolock(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(const char* name);
|
||||
void lua_group_ref(RDSGroup* group, int ref);
|
||||
void destroy_lua();
|
||||
Reference in New Issue
Block a user