mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-07-29 08:19:17 +02:00
move some scripts as modules and also change rds1 group hook
This commit is contained in:
+3
-1
@@ -4,10 +4,12 @@
|
||||
"os": "disable",
|
||||
"jit": "disable",
|
||||
"ffi":"disable",
|
||||
"package": "disable"
|
||||
},
|
||||
"workspace.library": ["context.lua"],
|
||||
"diagnostics.disable": [
|
||||
"duplicate-set-field"
|
||||
],
|
||||
"runtime.path": [
|
||||
"modules/?.lua"
|
||||
]
|
||||
}
|
||||
+12
-33
@@ -93,16 +93,21 @@ hooks.ps_transmission = {}
|
||||
---@return string
|
||||
function hooks.data_handle(data) end
|
||||
|
||||
---This function is called an unknown group is seen in the group sequence. See set_grpseq
|
||||
---This will be also called on recognized groups - if they can't be properly encoded by the core
|
||||
---Please remember that the core always fills in PTY and TP and PI in C if this is an B group
|
||||
---It should be defined by the user in the script.
|
||||
---@param group string group this was called in from the group sequence
|
||||
---@alias group_handler fun(group: string): boolean, integer, integer, integer
|
||||
|
||||
---Called when an unknown group is seen in the group sequence. See set_grpseq.
|
||||
---This is also called on recognized groups if they can't be properly encoded by the core.
|
||||
---The core always fills in PTY, TP, and PI in C if this is a B group.
|
||||
---Should be defined by the user in the script.
|
||||
---@param group string
|
||||
---@return boolean generated
|
||||
---@return integer b
|
||||
---@return integer c
|
||||
---@return integer d
|
||||
function hooks.group(group) end
|
||||
local function group_handler(group) end
|
||||
|
||||
---@type group_handler[]
|
||||
hooks.group = {}
|
||||
|
||||
---This function is called when an RDS2 group. Full control of every RDS2 subcarrier is under this function
|
||||
---If a was returned 0, PTY and TP will be filled in, along with the PI code in C if needed
|
||||
@@ -339,33 +344,7 @@ function ext.set_oda_id_data(oda_id, data) end
|
||||
---@param fun ODAHandler
|
||||
function ext.set_oda_handler(oda_id, fun) end
|
||||
|
||||
---The callback function for an ODA handler
|
||||
---@alias RDS2_ODAHandler fun(integer): (boolean, integer, integer, integer, integer)
|
||||
|
||||
---You are asked to not fill in the channel id in block A, however you are asked to fill in the function number (if you do not know what is that, just OR block A with (1 << 14))
|
||||
---@param oda_id integer
|
||||
---@param func RDS2_ODAHandler
|
||||
function ext.set_oda_handler_rds2(oda_id, func) end
|
||||
|
||||
---@param oda_id integer
|
||||
---@param data integer
|
||||
function ext.set_oda_id_data_rds2(oda_id, data) end
|
||||
|
||||
---@param aid integer
|
||||
---@param data integer
|
||||
---@param file_related boolean
|
||||
---@return integer oda_id
|
||||
function ext.register_oda_rds2(aid, data, file_related) end
|
||||
|
||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function ext.unregister_oda_rds2(oda_id) end
|
||||
|
||||
---@param ert string
|
||||
function RDS.ext.set_ert(ert) end
|
||||
---@return string
|
||||
function RDS.ext.get_ert() end
|
||||
|
||||
---@param designator string
|
||||
---@param handler function
|
||||
function RDS.ext.register_group(designator, handler) end
|
||||
function RDS.ext.get_ert() end
|
||||
@@ -0,0 +1,25 @@
|
||||
local md = {}
|
||||
md.registered_groups = {}
|
||||
|
||||
hooks.group[#hooks.group+1] = function (group)
|
||||
if md.registered_groups[group] then
|
||||
local ok, generated, b, c, d = pcall(md.registered_groups[group], group)
|
||||
if ok then return generated, b, c, d
|
||||
else
|
||||
print(generated)
|
||||
return false, 0, 0, 0
|
||||
end
|
||||
end
|
||||
return false, 0, 0, 0
|
||||
end
|
||||
|
||||
---@param designator string
|
||||
---@param handler function
|
||||
function md.register_group(designator, handler)
|
||||
for i = 1, #designator do
|
||||
local char = designator:sub(i, i)
|
||||
md.registered_groups[char] = handler
|
||||
end
|
||||
end
|
||||
|
||||
return md
|
||||
@@ -1,5 +1,7 @@
|
||||
_RDS2_ODA = { aid = 0, data = 0, handler = false, file_related = false, channel = 0 }
|
||||
_RDS2_next_channel = { normal = 16, file = 0 }
|
||||
local rds2_oda = {}
|
||||
|
||||
local _RDS2_ODA = { aid = 0, data = 0, handler = false, file_related = false, channel = 0 }
|
||||
local _RDS2_next_channel = { normal = 16, file = 0 }
|
||||
|
||||
function _RDS2_ODA.new(aid, data, handler, file_related, channel)
|
||||
local instance = { aid = aid or 0, data = data or 0, handler = handler or false, file_related = file_related or false, channel = channel or 0 }
|
||||
@@ -7,15 +9,15 @@ function _RDS2_ODA.new(aid, data, handler, file_related, channel)
|
||||
return instance
|
||||
end
|
||||
|
||||
_RDS2_ODAs = {}
|
||||
_RDS2_ODA_aid = 0
|
||||
_RDS2_ODA_pointer = 1
|
||||
local _RDS2_ODAs = {}
|
||||
local _RDS2_ODA_aid = 0
|
||||
local _RDS2_ODA_pointer = 1
|
||||
|
||||
---@param aid integer
|
||||
---@param data integer
|
||||
---@param file_related boolean
|
||||
---@return integer oda_id
|
||||
function ext.register_oda_rds2(aid, data, file_related)
|
||||
function rds2_oda.register_oda_rds2(aid, data, file_related)
|
||||
local channel
|
||||
if file_related then
|
||||
channel = _RDS2_next_channel.file
|
||||
@@ -38,7 +40,7 @@ end
|
||||
|
||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function ext.unregister_oda_rds2(oda_id)
|
||||
function rds2_oda.unregister_oda_rds2(oda_id)
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
|
||||
_RDS2_ODAs[oda_id] = false
|
||||
@@ -49,19 +51,23 @@ end
|
||||
|
||||
---@param oda_id integer
|
||||
---@param data integer
|
||||
function ext.set_oda_id_data_rds2(oda_id, data)
|
||||
function rds2_oda.set_oda_id_data_rds2(oda_id, data)
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
_RDS2_ODAs[oda_id].data = data
|
||||
end
|
||||
|
||||
---The callback function for an ODA handler
|
||||
---@alias RDS2_ODAHandler fun(integer): (boolean, integer, integer, integer, integer)
|
||||
|
||||
---You are asked to not fill in the channel id in block A, however you are asked to fill in the function number (if you do not know what is that, just OR block A with (1 << 14))
|
||||
---@param oda_id integer
|
||||
---@param func RDS2_ODAHandler
|
||||
function ext.set_oda_handler_rds2(oda_id, func)
|
||||
function rds2_oda.set_oda_handler_rds2(oda_id, func)
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
_RDS2_ODAs[oda_id].handler = func
|
||||
end
|
||||
|
||||
function hooks.rds2_group(stream)
|
||||
function rds2_oda.rds2_group(stream)
|
||||
if #_RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end
|
||||
|
||||
if _RDS2_ODA_pointer > #_RDS2_ODAs then _RDS2_ODA_pointer = 1 end
|
||||
@@ -106,9 +112,10 @@ function hooks.rds2_group(stream)
|
||||
_RDS2_ODA_aid = _RDS2_ODA_aid + 1
|
||||
if _RDS2_ODA_aid > 8 then _RDS2_ODA_aid = 0 end
|
||||
if oda.handler then
|
||||
generated = false
|
||||
local generated = false
|
||||
checked = 0
|
||||
while generated == false and checked < #_RDS2_ODAs do
|
||||
local ok, a, b, c, d
|
||||
ok, generated, a, b, c, d = pcall(oda.handler, stream)
|
||||
if not (generated and ok) then
|
||||
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
|
||||
@@ -138,4 +145,6 @@ table.insert(hooks.on_state, function ()
|
||||
_RDS2_ODAs = {}
|
||||
_RDS2_ODA_aid = 0
|
||||
_RDS2_ODA_pointer = 1
|
||||
end)
|
||||
end)
|
||||
|
||||
return rds2_oda
|
||||
@@ -1,3 +1,5 @@
|
||||
local scheduler = require("rds2_oda")
|
||||
|
||||
---@class RftInstance
|
||||
---@field oda_id integer|nil The internal ODA registration ID
|
||||
---@field file_data string The raw binary content of the file
|
||||
@@ -43,7 +45,7 @@ end
|
||||
|
||||
function RftInstance:stop()
|
||||
if self.oda_id ~= nil and self.aid ~= 0 then
|
||||
ext.unregister_oda_rds2(self.oda_id)
|
||||
scheduler.unregister_oda_rds2(self.oda_id)
|
||||
self.oda_id = nil
|
||||
end
|
||||
|
||||
@@ -59,9 +61,9 @@ end
|
||||
---@private
|
||||
function RftInstance:start()
|
||||
if self.oda_id == nil and self.aid ~= 0 then
|
||||
self.oda_id = ext.register_oda_rds2(self.aid, 0, true)
|
||||
self.oda_id = scheduler.register_oda_rds2(self.aid, 0, true)
|
||||
|
||||
ext.set_oda_handler_rds2(self.oda_id, function(stream)
|
||||
scheduler.set_oda_handler_rds2(self.oda_id, function(stream)
|
||||
if #self.file_data == 0 or self.paused then
|
||||
return false, 0, 0, 0, 0
|
||||
end
|
||||
@@ -161,8 +163,10 @@ function RftInstance:sendFile(aid, path, id, crc, once)
|
||||
if f_size > (0x3ffff * 5) then error("File too large") end
|
||||
if self.oda_id == nil then self:start() end
|
||||
|
||||
ext.set_oda_id_data_rds2(self.oda_id, f_size | (id & 63) << 18 | (self.version & 7) << 24 | (self.crc_enabled and 1 or 0) << 27)
|
||||
scheduler.set_oda_id_data_rds2(self.oda_id, f_size | (id & 63) << 18 | (self.version & 7) << 24 | (self.crc_enabled and 1 or 0) << 27)
|
||||
self.last_id = id
|
||||
self.paused = false
|
||||
return interrupted
|
||||
end
|
||||
end
|
||||
|
||||
return RftInstance
|
||||
@@ -1,22 +0,0 @@
|
||||
hooks.registered_groups = {}
|
||||
|
||||
function hooks.group(group)
|
||||
if hooks.registered_groups[group] then
|
||||
local ok, generated, b, c, d = pcall(hooks.registered_groups[group], group)
|
||||
if ok then return generated, b, c, d
|
||||
else
|
||||
print(generated)
|
||||
return false, 0, 0, 0
|
||||
end
|
||||
end
|
||||
return false, 0, 0, 0
|
||||
end
|
||||
|
||||
---@param designator string
|
||||
---@param handler function
|
||||
function RDS.ext.register_group(designator, handler)
|
||||
for i = 1, #designator do
|
||||
local char = designator:sub(i, i)
|
||||
hooks.registered_groups[char] = handler
|
||||
end
|
||||
end
|
||||
+1
-1
@@ -119,7 +119,7 @@ local function group_handler(group_type)
|
||||
elseif group_type == "\xff" then return get_data()
|
||||
else return false, 0, 0, 0 end
|
||||
end
|
||||
RDS.ext.register_group("\x06\xff", group_handler)
|
||||
require("group").register_group("\x06\xff", group_handler)
|
||||
|
||||
table.insert(hooks.on_state, function ()
|
||||
_RDS_ODAs = {}
|
||||
|
||||
+36
-27
@@ -204,35 +204,47 @@ void run_lua(char *str, size_t str_len, char *cmd_output, size_t *out_len) {
|
||||
}
|
||||
|
||||
int lua_group(RDSGroup* group, const char grp) {
|
||||
int success = 0;
|
||||
|
||||
pthread_mutex_lock(&lua_mutex);
|
||||
|
||||
lua_rawgeti(globalL, LUA_REGISTRYINDEX, hooks_ref);
|
||||
lua_getfield(globalL, -1, "group");
|
||||
|
||||
if (!lua_isfunction(globalL, -1)) {
|
||||
if (!lua_istable(globalL, -1)) {
|
||||
lua_pop(globalL, 2);
|
||||
pthread_mutex_unlock(&lua_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushlstring(globalL, &grp, 1);
|
||||
lua_Integer len = lua_rawlen(globalL, -1);
|
||||
for (lua_Integer i = 1; i <= len; i++) {
|
||||
lua_rawgeti(globalL, -1, i);
|
||||
|
||||
if (lua_pcall(globalL, 1, 4, 0) != LUA_OK) {
|
||||
fprintf(stderr, "Lua error: %s\n", lua_tostring(globalL, -1));
|
||||
lua_pop(globalL, 2);
|
||||
pthread_mutex_unlock(&lua_mutex);
|
||||
return 0;
|
||||
if (!lua_isfunction(globalL, -1)) {
|
||||
lua_pop(globalL, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
lua_pushlstring(globalL, &grp, 1);
|
||||
|
||||
if (lua_pcall(globalL, 1, 4, 0) != LUA_OK) {
|
||||
fprintf(stderr, "Lua error: %s at 'group[%lld]'\n",
|
||||
lua_tostring(globalL, -1), (long long)i);
|
||||
lua_pop(globalL, 1);
|
||||
continue;
|
||||
}
|
||||
if (lua_isboolean(globalL, -4) && lua_toboolean(globalL, -4) &&
|
||||
lua_isinteger(globalL, -3) && lua_isinteger(globalL, -2) && lua_isinteger(globalL, -1)) {
|
||||
group->b = (uint16_t)lua_tointeger(globalL, -3);
|
||||
group->c = (uint16_t)lua_tointeger(globalL, -2);
|
||||
group->d = (uint16_t)lua_tointeger(globalL, -1);
|
||||
success = 1;
|
||||
}
|
||||
lua_pop(globalL, 4);
|
||||
if (success) break;
|
||||
}
|
||||
|
||||
int success = 0;
|
||||
if (lua_isboolean(globalL, -4) && lua_toboolean(globalL, -4) &&
|
||||
lua_isinteger(globalL, -3) && lua_isinteger(globalL, -2) && lua_isinteger(globalL, -1)) {
|
||||
group->b = (uint16_t)lua_tointeger(globalL, -3);
|
||||
group->c = (uint16_t)lua_tointeger(globalL, -2);
|
||||
group->d = (uint16_t)lua_tointeger(globalL, -1);
|
||||
success = 1;
|
||||
}
|
||||
|
||||
lua_pop(globalL, 5);
|
||||
lua_pop(globalL, 2);
|
||||
pthread_mutex_unlock(&lua_mutex);
|
||||
return success;
|
||||
}
|
||||
@@ -292,7 +304,12 @@ int lua_rds2_group(RDSGroup* group, int stream) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lua_call_function_nolock(const char* function) {
|
||||
oid lua_call_function(const char* function) {
|
||||
int need_lock = (pthread_mutex_trylock(&lua_mutex) == 0);
|
||||
if (!need_lock) {
|
||||
fprintf(stderr, "Warning: lua_mutex already locked when calling %s\n", function);
|
||||
return;
|
||||
}
|
||||
lua_getglobal(globalL, function);
|
||||
|
||||
if (lua_isfunction(globalL, -1)) {
|
||||
@@ -301,14 +318,6 @@ void lua_call_function_nolock(const char* function) {
|
||||
lua_pop(globalL, 1);
|
||||
}
|
||||
} else lua_pop(globalL, 1);
|
||||
}
|
||||
void lua_call_function(const char* function) {
|
||||
int need_lock = (pthread_mutex_trylock(&lua_mutex) == 0);
|
||||
if (!need_lock) {
|
||||
fprintf(stderr, "Warning: lua_mutex already locked when calling %s\n", function);
|
||||
return;
|
||||
}
|
||||
lua_call_function_nolock(function);
|
||||
pthread_mutex_unlock(&lua_mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ uint8_t init_lua(RDSEncoder* _enc);
|
||||
void run_lua(char *str, size_t str_len, char *cmd_output, size_t* out_len);
|
||||
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_tfunction_nolock(const char* name);
|
||||
void lua_call_tfunction(const char* name);
|
||||
|
||||
Reference in New Issue
Block a user