0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 20:33:53 +01:00

user data and rename

This commit is contained in:
2025-12-25 20:38:15 +01:00
parent 597a4a45f0
commit f07e3b70ad
6 changed files with 110 additions and 81 deletions

44
.vscode/settings.json vendored
View File

@@ -22,50 +22,6 @@
"ranges": "c",
"span": "c"
},
"Lua.diagnostics.globals": [
"set_rds_pi",
"set_rds_ecc",
"str",
"cmd",
"set_rds_pty",
"set_rds_slc_data",
"set_rds_ct",
"set_rds_dpty",
"set_rds_tp",
"set_rds_ta",
"set_rds_rt1_enabled",
"set_rds_rt2_enabled",
"set_rds_ptyn_enabled",
"set_rds_rt_type",
"set_rds_rds2mod",
"set_rds_rdsgen",
"set_rds_ptyn",
"set_rds_ps",
"core_version",
"set_rds_tps",
"data",
"set_rds_rt2",
"set_rds_rt1",
"set_rds_lps",
"set_rds_ert",
"set_rds_link",
"set_rds_rt_switching_period",
"set_rds_program",
"set_rds_level",
"set_rds_rt_text_timeout",
"set_rds_program_defaults",
"reset_rds",
"max_programs",
"on_init",
"get_rds_pi",
"get_rds_ecc",
"get_rds_pty",
"get_rds_slc_data",
"get_rds_ct",
"get_rds_dpty",
"get_rds_tp",
"get_rds_ta"
],
"Lua.runtime.plugin": "plugin.lua",
"Lua.runtime.builtin": {
"io": "disable",

View File

@@ -21,27 +21,31 @@ install(TARGETS rds95 DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(CODE
"
# Define the paths for the source and destination files
set(PREFIX_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/.command_prefix.lua\")
set(COMMAND_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/src/command.lua\")
# The $ENV{HOME} variable is evaluated at install time, not configure time
set(DEST_FILE \"$ENV{HOME}/.rds95.command.lua\")
set(PREFIX_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/.script_prefix.lua\")
set(SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/src/script.lua\")
set(DEST_FILE \"/etc/rds95.lua\")
# Check if the optional prefix file exists
if(EXISTS \${PREFIX_FILE})
# If it exists, read the prefix and the main command file
message(STATUS \"Prefix file found. Combining with command.lua.\")
message(STATUS \"Prefix file found. Combining with script.lua.\")
file(READ \${PREFIX_FILE} PREFIX_CONTENT)
file(READ \${COMMAND_FILE} COMMAND_CONTENT)
# Concatenate them, with the prefix content first
set(FINAL_CONTENT \"\${PREFIX_CONTENT}\n\${COMMAND_CONTENT}\")
file(READ \${SCRIPT_FILE} SCRIPT_CONTENT)
set(FINAL_CONTENT \"\${PREFIX_CONTENT}\n\${SCRIPT_CONTENT}\")
else()
# Otherwise, just use the content of the main command file
message(STATUS \"Prefix file not found. Using command.lua directly.\")
file(READ \${COMMAND_FILE} FINAL_CONTENT)
message(STATUS \"Prefix file not found. Using script.lua directly.\")
file(READ \${SCRIPT_FILE} FINAL_CONTENT)
endif()
# Write the resulting content to the destination file
message(STATUS \"Installing command file to \${DEST_FILE}\")
message(STATUS \"Installing script file to \${DEST_FILE}\")
file(WRITE \${DEST_FILE} \"\${FINAL_CONTENT}\")
# Change ownership to the user who invoked sudo (if applicable)
if(DEFINED ENV{SUDO_USER})
message(STATUS \"Changing ownership of \${DEST_FILE} to \$ENV{SUDO_USER}\")
execute_process(COMMAND chown \$ENV{SUDO_USER}:\$ENV{SUDO_USER} \${DEST_FILE})
else()
message(STATUS \"No SUDO_USER detected, skipping chown\")
endif()
"
)

View File

@@ -7,6 +7,8 @@ core_version = ""
eon_count = 0
---@type integer
max_programs = 0
---@type integer
user_data_len = 0
---Starts the initialization sequence, also calls the on_init function
---@return nil
@@ -16,6 +18,10 @@ function set_rds_program_defaults() end
---@return nil
function reset_rds() end
---Forces encoder and modulator data to be saved to disc
---@return nil
function force_save() end
---This function is called by the C core after we reset data, or have no data in general
---It should be defined by the user in the script.
---@return nil
@@ -111,14 +117,14 @@ function get_rds_rt_type() end
-- Modulation & Generation
---@param mode boolean
function set_rds_rds2mod(mode) end
function set_rds2_mode(mode) end
---@return boolean
function get_rds_rds2mod() end
function get_rds2_mode() end
---@param rdsgen integer
function set_rds_rdsgen(rdsgen) end
---@param streams integer
function set_rds_streams(streams) end
---@return integer
function get_rds_rdsgen() end
function get_rds_streams() end
---@param level number
function set_rds_level(level) end
@@ -281,4 +287,22 @@ function register_oda(group, group_version, id, id_data) end
---You are asked to set groups B last 5 bits, leave rest 0
---@param oda_id integer The ID returned by register_oda
---@param fun ODAHandler
function set_oda_handler(oda_id, fun) end
function set_oda_handler(oda_id, fun) end
---Data is allocated in each program's data for lua data, note that this overwrites existing data
---@param data string
function set_userdata(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 data string
function set_userdata_offset(offset, size, data) end
---Returns all of the data saved as user data
---@return string
function get_userdata() end
---Gets data from userdata but at the specified offset
---@param offset integer
---@param size integer
---@return string
function get_userdata_offset(offset, size) end

View File

@@ -6,6 +6,45 @@ static lua_State *L = NULL;
static pthread_mutex_t lua_mutex;
static uint8_t unload_refs[33] = {LUA_REFNIL};
int lua_get_userdata(lua_State *localL) {
lua_pushlstring(localL, &mod->enc->data[mod->enc->program].lua_data, LUA_USER_DATA);
return 1;
}
int lua_get_userdata_offset(lua_State *localL) {
uint8_t offset = luaL_checkinteger(localL, 1);
uint8_t size = luaL_checkinteger(localL, 2);
if((offset+size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
lua_pushlstring(localL, (&mod->enc->data[mod->enc->program].lua_data)+offset, size);
return 1;
}
int lua_set_userdata(lua_State *localL) {
size_t len;
const char *data = luaL_checklstring(localL, 1, &len);
if(len > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
memset(&mod->enc->data[mod->enc->program].lua_data, 0, LUA_USER_DATA);
memcpy(&mod->enc->data[mod->enc->program].lua_data, data, len);
return 0;
}
int lua_set_userdata_offset(lua_State *localL) {
uint8_t offset = luaL_checkinteger(localL, 1);
uint8_t size = luaL_checkinteger(localL, 2);
size_t len;
const char *data = luaL_checklstring(localL, 3, &len);
if(len > size || (offset + size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
memset((&mod->enc->data[mod->enc->program].lua_data)+offset, 0, size);
memcpy((&mod->enc->data[mod->enc->program].lua_data)+offset, data, len);
return 0;
}
int lua_force_save(lua_State *localL) {
encoder_saveToFile(mod->enc);
Modulator_saveToFile(&mod->params);
return 0;
}
int lua_set_rds_program_defaults(lua_State *localL) {
(void)localL;
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
@@ -129,20 +168,20 @@ BOOL_GETTER(ptyn_enabled)
INT_SETTER(rt_type)
INT_GETTER(rt_type)
int lua_set_rds_rds2mod(lua_State *localL) {
int lua_set_rds2_mode(lua_State *localL) {
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
mod->enc->encoder_data.rds2_mode = lua_toboolean(localL, 1);
return 0;
}
int lua_get_rds_rds2mod(lua_State *localL) {
int lua_get_rds2_mode(lua_State *localL) {
lua_pushboolean(localL, mod->enc->encoder_data.rds2_mode);
return 1;
}
int lua_set_rds_rdsgen(lua_State *localL) {
int lua_set_rds_streams(lua_State *localL) {
mod->params.rdsgen = luaL_checkinteger(localL, 1);
return 0;
}
int lua_get_rds_rdsgen(lua_State *localL) {
int lua_get_rds_streams(lua_State *localL) {
lua_pushinteger(localL, mod->params.rdsgen);
return 1;
}
@@ -454,6 +493,7 @@ void init_lua(RDSModulator* rds_mod) {
static int mutex_initialized = 0;
mod = rds_mod;
L = luaL_newstate();
print("Initializing %s\n", LUA_COPYRIGHT);
luaL_requiref(L, "_G", luaopen_base, 1);
luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
@@ -469,9 +509,12 @@ void init_lua(RDSModulator* rds_mod) {
lua_setglobal(L, "max_programs");
lua_pushinteger(L, EONs);
lua_setglobal(L, "eon_count");
lua_pushinteger(L, LUA_USER_DATA);
lua_setglobal(L, "user_data_len");
lua_register(L, "set_rds_program_defaults", lua_set_rds_program_defaults);
lua_register(L, "reset_rds", lua_reset_rds);
lua_register(L, "force_save", lua_force_save);
lua_register(L, "set_rds_pi", lua_set_rds_pi);
lua_register(L, "get_rds_pi", lua_get_rds_pi);
@@ -509,11 +552,11 @@ void init_lua(RDSModulator* rds_mod) {
lua_register(L, "set_rds_rt_type", lua_set_rds_rt_type);
lua_register(L, "get_rds_rt_type", lua_get_rds_rt_type);
lua_register(L, "set_rds_rds2mod", lua_set_rds_rds2mod);
lua_register(L, "get_rds_rds2mod", lua_get_rds_rds2mod);
lua_register(L, "set_rds2_mode", lua_set_rds2_mode);
lua_register(L, "get_rds2_mode", lua_get_rds2_mode);
lua_register(L, "set_rds_rdsgen", lua_set_rds_rdsgen);
lua_register(L, "get_rds_rdsgen", lua_get_rds_rdsgen);
lua_register(L, "set_rds_streams", lua_set_rds_streams);
lua_register(L, "get_rds_streams", lua_get_rds_streams);
lua_register(L, "set_rds_grpseq", lua_set_rds_grp_sqc);
lua_register(L, "get_rds_grpseq", lua_get_rds_grp_sqc);
@@ -570,12 +613,12 @@ void init_lua(RDSModulator* rds_mod) {
lua_register(L, "register_oda", lua_register_oda);
lua_register(L, "set_oda_handler", lua_set_oda_handler);
char path[128];
const char *home = getenv("HOME");
if (!home) return;
snprintf(path, sizeof(path), "%s/.rds95.command.lua", home);
lua_register(L, "set_userdata", lua_set_userdata);
lua_register(L, "set_userdata_offset", lua_set_userdata_offset);
lua_register(L, "get_userdata", lua_get_userdata);
lua_register(L, "get_userdata_offset", lua_get_userdata_offset);
if (luaL_loadfile(L, path) != LUA_OK) {
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);
return;
@@ -585,7 +628,6 @@ void init_lua(RDSModulator* rds_mod) {
lua_pop(L, 1);
}
}
lua_pushvalue(L, 1);
if(mutex_initialized == 0) {
pthread_mutex_init(&lua_mutex, NULL);
mutex_initialized = 1;

View File

@@ -1,5 +1,6 @@
#pragma once
#include "common.h"
#define LUA_USER_DATA 512
/* The RDS error-detection code generator polynomial is
* x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0
@@ -107,6 +108,8 @@ typedef struct {
uint16_t udg2_rds2[8][4];
RDSEON eon[EONs];
uint8_t lua_data[LUA_USER_DATA];
} RDSData;
typedef struct {
uint8_t af_state : 6;

View File

@@ -21,8 +21,8 @@ function data_handle(data)
elseif data == "rt2en" then return string.format("RT2EN=%s\r\n", string.format("%d", (get_rds_rt2_enabled() and 1 or 0)))
elseif data == "ptynen" then return string.format("PTYNEN=%s\r\n", string.format("%d", (get_rds_ptyn_enabled() and 1 or 0)))
elseif data == "rttype" then return string.format("RTTYPE=%s\r\n", string.format("%d", get_rds_rt_type()))
elseif data == "rds2mod" then return string.format("RDS2MOD=%s\r\n", string.format("%d", (get_rds_rds2mod() and 1 or 0)))
elseif data == "rdsgen" then return string.format("RDSGEN=%s\r\n", string.format("%d",get_rds_rdsgen()))
elseif data == "rds2mod" then return string.format("RDS2MOD=%s\r\n", string.format("%d", (get_rds2_mode() and 1 or 0)))
elseif data == "rdsgen" then return string.format("RDSGEN=%s\r\n", string.format("%d", get_rds_streams()))
elseif data == "level" then return string.format("LEVEL=%s\r\n", string.format("%d", get_rds_level() * 255))
elseif data == "link" then return string.format("LINK=%s\r\n", string.format("%d", (get_rds_link() and 1 or 0)))
elseif data == "rtp" then
@@ -225,12 +225,12 @@ function data_handle(data)
elseif cmd == "rds2mod" then
local type = tonumber(value)
if not type then return "-" end
set_rds_rds2mod(type ~= 0)
set_rds2_mode(type ~= 0)
return "+"
elseif cmd == "rdsgen" then
local type = tonumber(value)
if not type then return "-" end
set_rds_rdsgen(type)
set_rds_streams(type)
return "+"
elseif cmd == "ptyn" then
set_rds_ptyn(value)