uecp testing

This commit is contained in:
2026-04-22 17:14:50 +02:00
parent 35bbb2aa99
commit c62b7fde36
11 changed files with 322 additions and 158 deletions
+7
View File
@@ -28,11 +28,18 @@ function dp.reset_rds() end
---@return nil
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
---@return integer
function dp.get_program() end
---Sets the program all of the set/get functions affect
---@param program_idx integer 0 to (max_programs - 1)
function dp.set_writing_program(program_idx) end
---@return integer
function dp.get_writing_program() 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
+110 -5
View File
@@ -1,4 +1,113 @@
local mec_handlers = {}
local function dsn_helper(dsn, write)
if dsn == 0 then write()
elseif dsn == 254 then
local start = dp.get_writing_program()
for i = 1, dp.max_programs do
local p = i - 1
if p ~= start then
dp.set_writing_program(p)
write()
end
end
elseif dsn == 255 then
for i = 1, dp.max_programs do
dp.set_writing_program(i - 1)
write()
end
else
dp.set_writing_program(dsn - 1)
write()
end
end
mec_handlers[1] = function (data)
-- PI
local dsn = string.byte(data, 2)
local psn = string.byte(data, 3)
local pi_msb = string.byte(data, 4)
local pi_lsb = string.byte(data, 5)
dsn_helper(dsn, function ()
rds.set_pi((pi_msb << 8) | pi_lsb)
end)
end
mec_handlers[2] = function (data)
-- PS
local dsn = string.byte(data, 2)
local psn = string.byte(data, 3)
local ps = string.sub(data, 4, 11)
dsn_helper(dsn, function ()
rds.set_ps(ps)
end)
end
mec_handlers[3] = function (data)
-- TP/TA
local dsn = string.byte(data, 2)
local psn = string.byte(data, 3)
local data = string.byte(data, 4)
dsn_helper(dsn, function ()
rds.set_ta((data & 1) ~= 0)
rds.set_ta((data & 2) ~= 0)
end)
end
---@param data string
local function undo_byte_stuff(data)
local output = {}
local i = 1
while i <= #data do
local d0 = string.byte(data, i)
if d0 == 0xFD then
local d1 = string.byte(data, i + 1)
output[#output + 1] = string.char(0xFD + d1)
i = i + 2
else
output[#output + 1] = string.char(d0)
i = i + 1
end
end
return table.concat(output)
end
---@param packet string
local function parse_uecp(packet)
local end_i = string.find(packet, "\xff", 1, true)
if not end_i then return end
local unstuffed = undo_byte_stuff(string.sub(packet, 2, end_i - 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
local sequence_count = string.byte(unstuffed, 3)
local mfl = string.byte(unstuffed, 4)
local data = string.sub(unstuffed, 5, 4 + mfl)
if mfl ~= #data then return end
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
if crc_calculated ~= crc_stored then return end
local mec = string.byte(data, 1)
local handler = mec_handlers[mec]
if handler then
handler(data)
dp.set_writing_program(dp.get_program())
end
end
function data_handle(data)
-- UECP
if string.byte(data, 1) == 0xfe then return parse_uecp(data) end
if string.sub(data, 1, 4):lower() == "lua=" then
local chunk, err = load("return " .. string.sub(data, 5), "udp_chunk") -- skip "lua="
if not chunk then return string.format("-\r\n%s\r\n", err) end
@@ -212,11 +321,6 @@ function data_handle(data)
if not pty then return "-\r\n" end
rds.set_pty(pty)
return "+\r\n"
elseif cmd == "slcd" then
local slc_data = tonumber(value, 16)
if not slc_data then return "-\r\n" end
rds.set_slc_data(slc_data)
return "+\r\n"
elseif cmd == "ct" then
local ct = tonumber(value)
if not ct then return "-\r\n" end
@@ -303,6 +407,7 @@ function data_handle(data)
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_writing_program(program-1)
rds.set_ta(false)
return "+\r\n"
elseif cmd == "dttmout" then
+73 -57
View File
@@ -6,24 +6,25 @@ 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) {
lua_pushlstring(localL, (const char*)&enc->data[enc->program].lua_data, LUA_USER_DATA);
lua_pushlstring(localL, (const char*)&enc->data[writing_program].lua_data, LUA_USER_DATA);
return 1;
}
int lua_get_userdata_offset(lua_State *localL) {
uint16_t offset = luaL_checkinteger(localL, 1);
uint16_t size = luaL_checkinteger(localL, 2);
if((offset+size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
lua_pushlstring(localL, (const char*)&enc->data[enc->program].lua_data[offset], size);
lua_pushlstring(localL, (const char*)&enc->data[writing_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(enc->data[enc->program].lua_data, 0, LUA_USER_DATA);
memcpy(enc->data[enc->program].lua_data, data, len);
memset(enc->data[writing_program].lua_data, 0, LUA_USER_DATA);
memcpy(enc->data[writing_program].lua_data, data, len);
return 0;
}
@@ -34,8 +35,8 @@ int lua_set_userdata_offset(lua_State *localL) {
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(enc->data[enc->program].lua_data + offset, 0, size);
memcpy(enc->data[enc->program].lua_data + offset, data, len);
memset(enc->data[writing_program].lua_data + offset, 0, size);
memcpy(enc->data[writing_program].lua_data + offset, data, len);
return 0;
}
@@ -55,7 +56,7 @@ int lua_set_rds_program_defaults(lua_State *localL) {
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, enc->program);
set_rds_defaults(enc, writing_program);
lua_call_tfunction_nolock("on_init");
lua_call_tfunction_nolock("on_state");
in_set_defaults = 0;
@@ -77,24 +78,24 @@ int lua_reset_rds(lua_State *localL) {
#define BOOL_SETTER(name) \
int lua_set_rds_##name(lua_State *localL) { \
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1)); \
enc->data[enc->program].name = lua_toboolean(localL, 1); \
enc->data[writing_program].name = lua_toboolean(localL, 1); \
return 0; \
}
#define INT_SETTER(name) \
int lua_set_rds_##name(lua_State *localL) { \
enc->data[enc->program].name = luaL_checkinteger(localL, 1); \
enc->data[writing_program].name = luaL_checkinteger(localL, 1); \
return 0; \
}
#define STR_SETTER(name, function) \
int lua_set_rds_##name(lua_State *localL) { \
const char* str = luaL_checklstring(localL, 1, NULL); \
function(enc, convert_to_rdscharset(str)); \
function(enc, convert_to_rdscharset(str), writing_program); \
return 0; \
}
#define STR_RAW_SETTER(name, function) \
int lua_set_rds_##name(lua_State *localL) { \
const char* str = luaL_checklstring(localL, 1, NULL); \
function(enc, str); \
function(enc, str, writing_program); \
return 0; \
}
#define AF_SETTER(name, af_field, af_struct, add_func) \
@@ -103,7 +104,7 @@ int lua_set_rds_##name(lua_State *localL) { \
\
int n = lua_rawlen(localL, 1); \
if (n == 0) { \
memset(&(enc->data[enc->program].af_field), 0, sizeof(af_struct)); \
memset(&(enc->data[writing_program].af_field), 0, sizeof(af_struct)); \
return 0; \
} \
if(n > 25) return luaL_error(localL, "table length over 25"); \
@@ -117,24 +118,24 @@ int lua_set_rds_##name(lua_State *localL) { \
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1)); \
lua_pop(localL, 1); \
} \
memcpy(&(enc->data[enc->program].af_field), &new_af, sizeof(new_af)); \
memcpy(&(enc->data[writing_program].af_field), &new_af, sizeof(new_af)); \
\
return 0; \
}
#define INT_GETTER(name) \
int lua_get_rds_##name(lua_State *localL) { \
lua_pushinteger(localL, enc->data[enc->program].name); \
lua_pushinteger(localL, enc->data[writing_program].name); \
return 1; \
}
#define BOOL_GETTER(name) \
int lua_get_rds_##name(lua_State *localL) { \
lua_pushboolean(localL, enc->data[enc->program].name); \
lua_pushboolean(localL, enc->data[writing_program].name); \
return 1; \
}
#define STR_RAW_GETTER(name, length) \
int lua_get_rds_##name(lua_State *localL) { \
lua_pushlstring(localL, enc->data[enc->program].name, length); \
lua_pushlstring(localL, enc->data[writing_program].name, length); \
return 1; \
}
INT_SETTER(pi)
@@ -195,12 +196,12 @@ int lua_get_rds_streams(lua_State *localL) {
int lua_set_rds_link(lua_State *localL) {
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
enc->state[enc->program].eon_linkage = lua_toboolean(localL, 1);
enc->state[writing_program].eon_linkage = lua_toboolean(localL, 1);
return 0;
}
int lua_get_rds_link(lua_State *localL) {
lua_pushboolean(localL, enc->state[enc->program].eon_linkage);
lua_pushboolean(localL, enc->state[writing_program].eon_linkage);
return 1;
}
@@ -214,6 +215,7 @@ int lua_set_rds_program(lua_State *localL) {
enc->data[enc->program].ta = 0;
enc->data[(uint8_t)program].ta = 0;
enc->program = (uint8_t)program;
writing_program = program;
return 0;
}
@@ -222,34 +224,48 @@ int lua_get_rds_program(lua_State *localL) {
return 1;
}
int lua_set_rds_writing_program(lua_State *localL) {
int program = luaL_checkinteger(localL, 1);
if(program >= PROGRAMS) program = (PROGRAMS-1);
if(program < 0) program = 0;
writing_program = program;
return 0;
}
int lua_get_rds_writing_program(lua_State *localL) {
lua_pushinteger(localL, writing_program);
return 1;
}
int lua_set_rds_rt_switching_period(lua_State *localL) {
enc->data[enc->program].rt_switching_period = luaL_checkinteger(localL, 1);
enc->state[enc->program].rt_switching_period_state = enc->data[enc->program].rt_switching_period;
enc->data[writing_program].rt_switching_period = luaL_checkinteger(localL, 1);
enc->state[writing_program].rt_switching_period_state = enc->data[writing_program].rt_switching_period;
return 0;
}
INT_GETTER(rt_switching_period)
int lua_set_rds_rt_text_timeout(lua_State *localL) {
enc->data[enc->program].rt_text_timeout = luaL_checkinteger(localL, 1);
enc->state[enc->program].rt_text_timeout_state = enc->data[enc->program].rt_text_timeout;
enc->data[writing_program].rt_text_timeout = luaL_checkinteger(localL, 1);
enc->state[writing_program].rt_text_timeout_state = enc->data[writing_program].rt_text_timeout;
return 0;
}
INT_GETTER(rt_text_timeout)
int lua_put_rds_custom_group(lua_State *localL) {
enc->state[enc->program].custom_group[0] = 1;
enc->state[enc->program].custom_group[1] = luaL_checkinteger(localL, 1);
enc->state[enc->program].custom_group[2] = luaL_checkinteger(localL, 2);
enc->state[enc->program].custom_group[3] = luaL_checkinteger(localL, 3);
enc->state[writing_program].custom_group[0] = 1;
enc->state[writing_program].custom_group[1] = luaL_checkinteger(localL, 1);
enc->state[writing_program].custom_group[2] = luaL_checkinteger(localL, 2);
enc->state[writing_program].custom_group[3] = luaL_checkinteger(localL, 3);
return 0;
}
int lua_put_rds2_custom_group(lua_State *localL) {
enc->state[enc->program].custom_group2[0] = 1;
enc->state[enc->program].custom_group2[1] = luaL_checkinteger(localL, 1);
enc->state[enc->program].custom_group2[2] = luaL_checkinteger(localL, 2);
enc->state[enc->program].custom_group2[3] = luaL_checkinteger(localL, 3);
enc->state[enc->program].custom_group2[4] = luaL_checkinteger(localL, 4);
enc->state[writing_program].custom_group2[0] = 1;
enc->state[writing_program].custom_group2[1] = luaL_checkinteger(localL, 1);
enc->state[writing_program].custom_group2[2] = luaL_checkinteger(localL, 2);
enc->state[writing_program].custom_group2[3] = luaL_checkinteger(localL, 3);
enc->state[writing_program].custom_group2[4] = luaL_checkinteger(localL, 4);
return 0;
}
@@ -268,8 +284,8 @@ STR_RAW_GETTER(grp_sqc_rds2, 32)
int lua_set_rds_grp_sqc(lua_State *localL) {
const char* str = luaL_checklstring(localL, 1, NULL);
if(_strnlen(str, 2) < 1) set_rds_grpseq(enc, DEFAULT_GRPSQC);
else set_rds_grpseq(enc, str);
if(_strnlen(str, 2) < 1) set_rds_grpseq(enc, DEFAULT_GRPSQC, writing_program);
else set_rds_grpseq(enc, str, writing_program);
return 0;
}
@@ -284,16 +300,16 @@ int lua_set_rds_eon(lua_State *localL) {
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[enc->program].eon[eon].enabled = lua_toboolean(localL, 2);
enc->data[enc->program].eon[eon].pi = luaL_checkinteger(localL, 3);
enc->data[enc->program].eon[eon].tp = lua_toboolean(localL, 4);
enc->data[enc->program].eon[eon].ta = lua_toboolean(localL, 5);
enc->data[enc->program].eon[eon].pty = luaL_checkinteger(localL, 6);
_strncpy(enc->data[enc->program].eon[eon].ps, luaL_checklstring(localL, 7, NULL), 8);
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 (n == 0) {
memset(&(enc->data[enc->program].eon[eon].af), 0, sizeof(RDSAFs));
memset(&(enc->data[writing_program].eon[eon].af), 0, sizeof(RDSAFs));
return 0;
}
if(n > 25) return luaL_error(localL, "table length over 25");
@@ -307,23 +323,23 @@ int lua_set_rds_eon(lua_State *localL) {
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1));
lua_pop(localL, 1);
}
memcpy(&(enc->data[enc->program].eon[eon].af), &new_af, sizeof(new_af));
memcpy(&(enc->data[writing_program].eon[eon].af), &new_af, sizeof(new_af));
enc->data[enc->program].eon[eon].data = luaL_checkinteger(localL, 9);
enc->data[writing_program].eon[eon].data = luaL_checkinteger(localL, 9);
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_pushboolean(localL, enc->data[enc->program].eon[eon].enabled);
lua_pushinteger(localL, enc->data[enc->program].eon[eon].pi);
lua_pushboolean(localL, enc->data[enc->program].eon[eon].tp);
lua_pushboolean(localL, enc->data[enc->program].eon[eon].ta);
lua_pushinteger(localL, enc->data[enc->program].eon[eon].pty);
lua_pushlstring(localL, enc->data[enc->program].eon[eon].ps, 8);
lua_pushboolean(localL, enc->data[writing_program].eon[eon].enabled);
lua_pushinteger(localL, enc->data[writing_program].eon[eon].pi);
lua_pushboolean(localL, enc->data[writing_program].eon[eon].tp);
lua_pushboolean(localL, enc->data[writing_program].eon[eon].ta);
lua_pushinteger(localL, enc->data[writing_program].eon[eon].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_pushinteger(localL, enc->data[enc->program].eon[eon].data);
lua_pushinteger(localL, enc->data[writing_program].eon[eon].data);
return 8;
}
@@ -353,11 +369,11 @@ int lua_set_rds_udg(lua_State *localL) {
}
if(xy) {
memcpy(&(enc->data[enc->program].udg2), blocks, n * sizeof(uint16_t[3]));
enc->data[enc->program].udg2_len = n;
memcpy(&(enc->data[writing_program].udg2), blocks, n * sizeof(uint16_t[3]));
enc->data[writing_program].udg2_len = n;
} else {
memcpy(&(enc->data[enc->program].udg1), blocks, n * sizeof(uint16_t[3]));
enc->data[enc->program].udg1_len = n;
memcpy(&(enc->data[writing_program].udg1), blocks, n * sizeof(uint16_t[3]));
enc->data[writing_program].udg1_len = n;
}
return 0;
@@ -389,11 +405,11 @@ int lua_set_rds_udg2(lua_State *localL) {
}
if(xy) {
memcpy(&(enc->data[enc->program].udg2_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[enc->program].udg2_len_rds2 = n;
memcpy(&(enc->data[writing_program].udg2_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[writing_program].udg2_len_rds2 = n;
} else {
memcpy(&(enc->data[enc->program].udg1_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[enc->program].udg1_len_rds2 = n;
memcpy(&(enc->data[writing_program].udg1_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[writing_program].udg1_len_rds2 = n;
}
return 0;
+3
View File
@@ -68,6 +68,9 @@ int lua_get_rds_link(lua_State *localL);
int lua_set_rds_program(lua_State *localL);
int lua_get_rds_program(lua_State *localL);
int lua_set_rds_writing_program(lua_State *localL);
int lua_get_rds_writing_program(lua_State *localL);
int lua_set_rds_rt_switching_period(lua_State *localL);
int lua_get_rds_rt_switching_period(lua_State *localL);
+13 -4
View File
@@ -56,6 +56,8 @@ void init_lua(RDSEncoder* _enc) {
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_writing_program", lua_set_rds_writing_program);
lua_registertotable(L, "get_writing_program", lua_get_rds_writing_program);
lua_setglobal(L, "dp");
lua_newtable(L);
@@ -163,16 +165,23 @@ void init_lua(RDSEncoder* _enc) {
}
}
void run_lua(char *str, char *cmd_output, size_t* out_len) {
void run_lua(char *str, size_t str_len, char *cmd_output, size_t *out_len) {
pthread_mutex_lock(&lua_mutex);
lua_getglobal(L, "data_handle");
if (lua_isfunction(L, -1)) {
lua_pushstring(L, str);
lua_pushlstring(L, str, str_len);
if (lua_pcall(L, 1, 1, 0) == LUA_OK) {
if (lua_isstring(L, -1) && cmd_output) _strncpy(cmd_output, lua_tolstring(L, -1, out_len), 254);
if (lua_isstring(L, -1) && cmd_output) {
const char *lua_str = lua_tolstring(L, -1, out_len);
if (*out_len > 254) *out_len = 254;
memcpy(cmd_output, lua_str, *out_len);
}
} else fprintf(stderr, "Lua error: %s at 'data_handle'\n", lua_tostring(L, -1));
} else if (lua_isstring(L, -1) && cmd_output) _strncpy(cmd_output, lua_tolstring(L, -1, out_len), 254);
} else fprintf(stderr, "'data_handle' is not a function\n");
lua_pop(L, 1);
pthread_mutex_unlock(&lua_mutex);
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include <lauxlib.h>
void init_lua(RDSEncoder* _enc);
void run_lua(char *str, char *cmd_output, size_t* out_len);
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);
+8 -8
View File
@@ -329,14 +329,14 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) {
tempCoder.state[program].rt_ab = 1;
tempCoder.state[program].ptyn_ab = 1;
set_rds_rt1(&tempCoder, enc->data[program].rt1);
set_rds_rt2(&tempCoder, enc->data[program].rt2);
set_rds_ps(&tempCoder, enc->data[program].ps);
set_rds_tps(&tempCoder, enc->data[program].tps);
set_rds_ptyn(&tempCoder, enc->data[program].ptyn);
set_rds_lps(&tempCoder, enc->data[program].lps);
set_rds_grpseq(&tempCoder, enc->data[program].grp_sqc);
set_rds_grpseq2(&tempCoder, enc->data[program].grp_sqc_rds2);
set_rds_rt1(&tempCoder, enc->data[program].rt1, program);
set_rds_rt2(&tempCoder, enc->data[program].rt2, program);
set_rds_ps(&tempCoder, enc->data[program].ps), program;
set_rds_tps(&tempCoder, enc->data[program].tps, program);
set_rds_lps(&tempCoder, enc->data[program].lps, program);
set_rds_ptyn(&tempCoder, enc->data[program].ptyn, program);
set_rds_grpseq(&tempCoder, enc->data[program].grp_sqc, program);
set_rds_grpseq2(&tempCoder, enc->data[program].grp_sqc_rds2, program);
struct tm *utc;
time_t now;
+9 -9
View File
@@ -195,12 +195,12 @@ void add_checkwords(RDSGroup *group, uint8_t *bits);
void get_rds_group(RDSEncoder* enc, RDSGroup *group, uint8_t stream);
void get_rds_bits(RDSEncoder* enc, uint8_t *bits, uint8_t stream);
void set_rds_rt1(RDSEncoder* enc, const char *rt1);
void set_rds_rt2(RDSEncoder* enc, const char *rt2);
void set_rds_default_rt(RDSEncoder* enc, const char *rt);
void set_rds_ps(RDSEncoder* enc, const char *ps);
void set_rds_tps(RDSEncoder* enc, const char *tps);
void set_rds_lps(RDSEncoder* enc, const char *lps);
void set_rds_ptyn(RDSEncoder *enc, const char *ptyn);
void set_rds_grpseq(RDSEncoder* enc, const char *grpseq);
void set_rds_grpseq2(RDSEncoder* enc, const char *grpseq2);
void set_rds_rt1(RDSEncoder* enc, const char *rt1, uint8_t program);
void set_rds_rt2(RDSEncoder* enc, const char *rt2, uint8_t program);
void set_rds_default_rt(RDSEncoder* enc, const char *rt, uint8_t program);
void set_rds_ps(RDSEncoder* enc, const char *ps, uint8_t program);
void set_rds_tps(RDSEncoder* enc, const char *tps, uint8_t program);
void set_rds_lps(RDSEncoder* enc, const char *lps, uint8_t program);
void set_rds_ptyn(RDSEncoder *enc, const char *ptyn, uint8_t program);
void set_rds_grpseq(RDSEncoder* enc, const char *grpseq, uint8_t program);
void set_rds_grpseq2(RDSEncoder* enc, const char *grpseq2, uint8_t program);
+63 -63
View File
@@ -1,148 +1,148 @@
#include "rds.h"
void set_rds_rt1(RDSEncoder* enc, const char *rt1) {
void set_rds_rt1(RDSEncoder* enc, const char *rt1, uint8_t program) {
uint8_t i = 0, len = 0;
enc->state[enc->program].rt_text_timeout_state = enc->data[enc->program].rt_text_timeout;
enc->state[program].rt_text_timeout_state = enc->data[program].rt_text_timeout;
enc->state[enc->program].rt_update = 1;
enc->state[program].rt_update = 1;
memset(enc->data[enc->program].rt1, ' ', RT_LENGTH);
while (*rt1 != 0 && len < RT_LENGTH) enc->data[enc->program].rt1[len++] = *rt1++;
memset(enc->data[program].rt1, ' ', RT_LENGTH);
while (*rt1 != 0 && len < RT_LENGTH) enc->data[program].rt1[len++] = *rt1++;
while (len > 0 && enc->data[enc->program].rt1[len - 1] == ' ') len--;
while (len > 0 && enc->data[program].rt1[len - 1] == ' ') len--;
if (len < RT_LENGTH) {
enc->state[enc->program].rt_segments = 0;
enc->data[enc->program].rt1[len++] = '\r';
enc->state[program].rt_segments = 0;
enc->data[program].rt1[len++] = '\r';
while (i < len) {
i += 4;
enc->state[enc->program].rt_segments++;
enc->state[program].rt_segments++;
}
} else enc->state[enc->program].rt_segments = 16;
if(enc->state[enc->program].rt_segments > 16) enc->state[enc->program].rt_segments = 16; //make sure
} else enc->state[program].rt_segments = 16;
if(enc->state[program].rt_segments > 16) enc->state[program].rt_segments = 16; //make sure
}
void set_rds_default_rt(RDSEncoder* enc, const char *rt) {
void set_rds_default_rt(RDSEncoder* enc, const char *rt, uint8_t program) {
uint8_t i = 0, len = 0;
memset(enc->data[enc->program].default_rt, ' ', RT_LENGTH);
while (*rt != 0 && len < RT_LENGTH) enc->data[enc->program].default_rt[len++] = *rt++;
memset(enc->data[program].default_rt, ' ', RT_LENGTH);
while (*rt != 0 && len < RT_LENGTH) enc->data[program].default_rt[len++] = *rt++;
while (len > 0 && enc->data[enc->program].default_rt[len - 1] == ' ') len--;
while (len > 0 && enc->data[program].default_rt[len - 1] == ' ') len--;
if (len < RT_LENGTH) {
enc->state[enc->program].default_rt_segments = 0;
enc->data[enc->program].default_rt[len++] = '\r';
enc->state[program].default_rt_segments = 0;
enc->data[program].default_rt[len++] = '\r';
while (i < len) {
i += 4;
enc->state[enc->program].default_rt_segments++;
enc->state[program].default_rt_segments++;
}
} else enc->state[enc->program].default_rt_segments = 16;
if(enc->state[enc->program].default_rt_segments > 16) enc->state[enc->program].default_rt_segments = 16; //make sure
} else enc->state[program].default_rt_segments = 16;
if(enc->state[program].default_rt_segments > 16) enc->state[program].default_rt_segments = 16; //make sure
}
void set_rds_rt2(RDSEncoder* enc, const char *rt2) {
void set_rds_rt2(RDSEncoder* enc, const char *rt2, uint8_t program) {
uint8_t i = 0, len = 0;
enc->state[enc->program].rt2_update = 1;
enc->state[program].rt2_update = 1;
memset(enc->data[enc->program].rt2, ' ', RT_LENGTH);
while (*rt2 != 0 && len < RT_LENGTH) enc->data[enc->program].rt2[len++] = *rt2++;
memset(enc->data[program].rt2, ' ', RT_LENGTH);
while (*rt2 != 0 && len < RT_LENGTH) enc->data[program].rt2[len++] = *rt2++;
while (len > 0 && enc->data[enc->program].rt2[len - 1] == ' ') len--;
while (len > 0 && enc->data[program].rt2[len - 1] == ' ') len--;
if (len < RT_LENGTH) {
enc->state[enc->program].rt2_segments = 0;
enc->data[enc->program].rt2[len++] = '\r';
enc->state[program].rt2_segments = 0;
enc->data[program].rt2[len++] = '\r';
while (i < len) {
i += 4;
enc->state[enc->program].rt2_segments++;
enc->state[program].rt2_segments++;
}
} else enc->state[enc->program].rt2_segments = 16;
if(enc->state[enc->program].rt2_segments > 16) enc->state[enc->program].rt2_segments = 16; //make sure
} else enc->state[program].rt2_segments = 16;
if(enc->state[program].rt2_segments > 16) enc->state[program].rt2_segments = 16; //make sure
}
void set_rds_ps(RDSEncoder* enc, const char *ps) {
void set_rds_ps(RDSEncoder* enc, const char *ps, uint8_t program) {
uint8_t len = 0;
enc->state[enc->program].ps_update = 1;
memset(enc->data[enc->program].ps, ' ', PS_LENGTH);
while (*ps != 0 && len < PS_LENGTH) enc->data[enc->program].ps[len++] = *ps++;
enc->state[program].ps_update = 1;
memset(enc->data[program].ps, ' ', PS_LENGTH);
while (*ps != 0 && len < PS_LENGTH) enc->data[program].ps[len++] = *ps++;
}
void set_rds_tps(RDSEncoder* enc, const char *tps) {
void set_rds_tps(RDSEncoder* enc, const char *tps, uint8_t program) {
uint8_t len = 0;
enc->state[enc->program].tps_update = 1;
enc->state[program].tps_update = 1;
if(tps[0] == '\0') {
memset(enc->data[enc->program].tps, 0, PS_LENGTH);
memset(enc->data[program].tps, 0, PS_LENGTH);
return;
}
memset(enc->data[enc->program].tps, ' ', PS_LENGTH);
while (*tps != 0 && len < PS_LENGTH) enc->data[enc->program].tps[len++] = *tps++;
memset(enc->data[program].tps, ' ', PS_LENGTH);
while (*tps != 0 && len < PS_LENGTH) enc->data[program].tps[len++] = *tps++;
}
void set_rds_lps(RDSEncoder* enc, const char *lps) {
void set_rds_lps(RDSEncoder* enc, const char *lps, uint8_t program) {
uint8_t i = 0, len = 0;
enc->state[enc->program].lps_update = 1;
enc->state[program].lps_update = 1;
if(lps[0] == '\0') {
memset(enc->data[enc->program].lps, 0, LPS_LENGTH);
memset(enc->data[program].lps, 0, LPS_LENGTH);
return;
}
memset(enc->data[enc->program].lps, ' ', LPS_LENGTH);
while (*lps != 0 && len < LPS_LENGTH) enc->data[enc->program].lps[len++] = *lps++;
memset(enc->data[program].lps, ' ', LPS_LENGTH);
while (*lps != 0 && len < LPS_LENGTH) enc->data[program].lps[len++] = *lps++;
if (len < LPS_LENGTH) {
enc->state[enc->program].lps_segments = 0;
enc->data[enc->program].lps[len++] = '\r';
enc->state[program].lps_segments = 0;
enc->data[program].lps[len++] = '\r';
while (i < len) {
i += 4;
enc->state[enc->program].lps_segments++;
enc->state[program].lps_segments++;
}
} else enc->state[enc->program].lps_segments = 8;
if(enc->state[enc->program].lps_segments > 8) enc->state[enc->program].lps_segments = 8; //make sure
} else enc->state[program].lps_segments = 8;
if(enc->state[program].lps_segments > 8) enc->state[program].lps_segments = 8; //make sure
}
void set_rds_ptyn(RDSEncoder* enc, const char *ptyn) {
void set_rds_ptyn(RDSEncoder* enc, const char *ptyn, uint8_t program) {
uint8_t len = 0;
enc->state[enc->program].ptyn_update = 1;
enc->state[program].ptyn_update = 1;
if(ptyn[0] == '\0') {
memset(enc->data[enc->program].ptyn, 0, PTYN_LENGTH);
memset(enc->data[program].ptyn, 0, PTYN_LENGTH);
return;
}
memset(enc->data[enc->program].ptyn, ' ', PTYN_LENGTH);
while (*ptyn != 0 && len < PTYN_LENGTH) enc->data[enc->program].ptyn[len++] = *ptyn++;
memset(enc->data[program].ptyn, ' ', PTYN_LENGTH);
while (*ptyn != 0 && len < PTYN_LENGTH) enc->data[program].ptyn[len++] = *ptyn++;
}
void set_rds_grpseq(RDSEncoder* enc, const char *grpseq) {
void set_rds_grpseq(RDSEncoder* enc, const char *grpseq, uint8_t program) {
uint8_t len = 0;
if(grpseq[0] == '\0') {
while (DEFAULT_GRPSQC[len] != 0 && len < 32) {
enc->data[enc->program].grp_sqc[len] = DEFAULT_GRPSQC[len];
enc->data[program].grp_sqc[len] = DEFAULT_GRPSQC[len];
len++;
}
return;
}
memset(enc->data[enc->program].grp_sqc, 0, 32);
while (*grpseq != 0 && len < 32) enc->data[enc->program].grp_sqc[len++] = *grpseq++;
memset(enc->data[program].grp_sqc, 0, 32);
while (*grpseq != 0 && len < 32) enc->data[program].grp_sqc[len++] = *grpseq++;
}
void set_rds_grpseq2(RDSEncoder* enc, const char *grpseq2) {
void set_rds_grpseq2(RDSEncoder* enc, const char *grpseq2, uint8_t program) {
uint8_t len = 0;
if(grpseq2[0] == '\0') {
memset(enc->data[enc->program].grp_sqc_rds2, 0, 32);
memcpy(enc->data[enc->program].grp_sqc_rds2, enc->data[enc->program].grp_sqc, 32);
memset(enc->data[program].grp_sqc_rds2, 0, 32);
memcpy(enc->data[program].grp_sqc_rds2, enc->data[program].grp_sqc, 32);
return;
}
memset(enc->data[enc->program].grp_sqc_rds2, 0, 32);
while (*grpseq2 != 0 && len < 32) enc->data[enc->program].grp_sqc_rds2[len++] = *grpseq2++;
memset(enc->data[program].grp_sqc_rds2, 0, 32);
while (*grpseq2 != 0 && len < 32) enc->data[program].grp_sqc_rds2[len++] = *grpseq2++;
}
+35 -11
View File
@@ -44,22 +44,46 @@ void poll_udp_server() {
ssize_t bytes_read = recvfrom(sockfd, buf, BUF_SIZE - 1, 0, (struct sockaddr *)&client_addr, &client_len);
if (bytes_read <= 0) return;
buf[bytes_read] = '\0';
size_t start = 0;
for (ssize_t i = 0; i < bytes_read; i++) {
if (buf[i] == '\n' || (unsigned char)buf[i] == 0xFF) {
size_t len = i - start;
if (len > 0 && len < BUF_SIZE) {
memset(cmd_buf, 0, BUF_SIZE);
memcpy(cmd_buf, buf + start, len);
memset(cmd_output, 0, BUF_SIZE);
size_t out_len = 0;
run_lua(cmd_buf, len, cmd_output, &out_len);
if (out_len > 0 &&
sendto(sockfd, cmd_output, out_len, 0,
(struct sockaddr *)&client_addr, client_len) == -1) {
perror("sendto");
}
}
start = i + 1;
}
}
if (start < bytes_read) {
size_t len = bytes_read - start;
char *token = strtok(buf, "\r\n");
while (token != NULL) {
size_t len = strlen(token);
if (len > 0 && len < BUF_SIZE) {
memset(cmd_buf, 0, BUF_SIZE);
strncpy(cmd_buf, token, BUF_SIZE - 1);
memset(cmd_output, 0, BUF_SIZE);
memcpy(cmd_buf, buf + start, len);
size_t out_len = 0;
run_lua(cmd_buf, cmd_output, &out_len);
if (out_len > 0 && sendto(sockfd, cmd_output, out_len, 0, (struct sockaddr *)&client_addr, client_len) == -1) perror("sendto"); // no walrus
run_lua(cmd_buf, len, cmd_output, &out_len);
if (out_len > 0 &&
sendto(sockfd, cmd_output, out_len, 0,
(struct sockaddr *)&client_addr, client_len) == -1) {
perror("sendto");
}
}
token = strtok(NULL, "\r\n");
}
}
Binary file not shown.