0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 12:32:05 +01:00

more error handling

This commit is contained in:
2025-12-28 17:09:38 +01:00
parent 8c7e233b13
commit 1b64cdf091
8 changed files with 55 additions and 48 deletions

2
.gitignore vendored
View File

@@ -55,4 +55,4 @@ build/
*.pyc
__pycache__/
.vscode/
.command_prefix.lua
.script.lua

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
project(rds95 VERSION 1.6)
project(rds95 VERSION 1.7)
add_compile_options(-Wall -Werror -Wextra -pedantic -O2 -std=c18 -march=native -DVERSION=\"${PROJECT_VERSION}\")
@@ -21,7 +21,7 @@ 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}/.script_prefix.lua\")
set(PREFIX_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/.script.lua\")
set(SCRIPTS_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/scripts\")
set(DEST_FILE \"/etc/rds95.lua\")

View File

@@ -29,7 +29,7 @@ end
---@param oda_id integer
---@param data integer
function set_oda_id_data(oda_id, data)
if oda_id > #_RDS_ODAs then return end
if oda_id < 1 or oda_id > #_RDS_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
_RDS_ODAs[oda_id].data = data
end
@@ -41,8 +41,8 @@ end
---@param oda_id integer The ID returned by register_oda
---@param fun ODAHandler
function set_oda_handler(oda_id, fun)
if oda_id > #_RDS_ODAs then return end
if _RDS_ODAs.group == 3 then error("3A ODAs cannot have handlers.") end
if oda_id < 1 or oda_id > #_RDS_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
if _RDS_ODAs[oda_id].group == 3 then error("3A ODAs cannot have handlers.", 2) end
_RDS_ODAs[oda_id].handler = fun
end

View File

@@ -25,7 +25,7 @@ end
---@param oda_id integer
---@param data integer
function set_oda_id_data_rds2(oda_id, data)
if oda_id > #_RDS2_ODAs then return end
if oda_id < 1 or oda_id > #_RDS2_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
_RDS2_ODAs[oda_id].data = data
end
@@ -33,7 +33,7 @@ end
---@param oda_id integer
---@param func RDS2_ODAHandler
function set_oda_handler_rds2(oda_id, func)
if oda_id > #_RDS2_ODAs then return end
if oda_id < 1 or oda_id > #_RDS2_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
_RDS2_ODAs[oda_id].handler = func
end

View File

@@ -3,7 +3,7 @@ _Af_Oda_state = 0
_Af_Oda_len = 0
_Af_Oda_afs = {}
local USERDATA_OFFSET = 270
local USERDATA_ODA_OFFSET = 274
---@param freq number
---@return table
@@ -19,7 +19,7 @@ local function encode_af(freq)
elseif freq >= 531 and freq <= 1602 then
table.insert(out, 250) -- LFMF incoming
table.insert(out, math.tointeger((freq - 531) / 9 + 16))
end
else error(string.format("Invalid AF frequency: %.1f", freq), 2) end
return out
end
@@ -69,7 +69,7 @@ local function save_af_to_userdata(afs)
local payload = string.pack("B", count)
for i = 1, count do payload = payload .. string.pack("f", afs[i]) end
set_userdata_offset(USERDATA_OFFSET, #payload, payload)
set_userdata_offset(USERDATA_ODA_OFFSET, #payload, payload)
end
local function _process_af_list(afs)
@@ -86,13 +86,13 @@ local function _process_af_list(afs)
end
local function load_af_from_userdata()
local header = get_userdata_offset(USERDATA_OFFSET, 1)
local header = get_userdata_offset(USERDATA_ODA_OFFSET, 1)
if header == "" or header == nil then return end
local count = string.unpack("B", header)
if count == 0 or count > 25 then return end
local data = get_userdata_offset(USERDATA_OFFSET + 1, count * 4)
local data = get_userdata_offset(USERDATA_ODA_OFFSET + 1, count * 4)
if #data < (count * 4) then return end
local afs = {}

View File

@@ -1,27 +1,30 @@
_Ert_state = 0
_Ert_oda_id = nil
--- Size: 259 bytes
local USERDATA_ERT_OFFSET = 0
local function init_ert()
if _Ert_oda_id == nil then
_Ert_oda_id = register_oda(13, false, 0x6552, 1)
set_oda_handler(_Ert_oda_id, function ()
if string.byte(get_userdata_offset(258, 1)) == 1 then
local new_data = get_userdata_offset(0, 128)
local new_segments = string.byte(get_userdata_offset(128, 1))
set_userdata_offset(129, 128, new_data)
set_userdata_offset(257, 1, string.char(new_segments))
set_userdata_offset(258, 1, string.char(0))
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+258, 1)) == 1 then
local new_data = get_userdata_offset(USERDATA_ERT_OFFSET, 128)
local new_segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+128, 1))
set_userdata_offset(USERDATA_ERT_OFFSET+129, 128, new_data)
set_userdata_offset(USERDATA_ERT_OFFSET+257, 1, string.char(new_segments))
set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(0))
_Ert_state = 0
end
local segments = string.byte(get_userdata_offset(257, 1))
local segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1))
if segments == 0 then return false, 0, 0, 0 end
if _Ert_state >= segments then _Ert_state = 0 end
local b = _Ert_state & 31
local chunk = get_userdata_offset(129 + _Ert_state * 4, 4)
local chunk = get_userdata_offset(USERDATA_ERT_OFFSET + 129 + _Ert_state * 4, 4)
local c = (string.byte(chunk, 1) << 8) | string.byte(chunk, 2)
local d = (string.byte(chunk, 3) << 8) | string.byte(chunk, 4)
@@ -33,9 +36,9 @@ end
function set_rds_ert(ert)
if #ert == 0 then
set_userdata_offset(0, 128, "")
set_userdata_offset(128, 1, string.char(0))
set_userdata_offset(258, 1, string.char(1))
set_userdata_offset(USERDATA_ERT_OFFSET, 128, "")
set_userdata_offset(USERDATA_ERT_OFFSET+128, 1, string.char(0))
set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1))
return
end
@@ -45,31 +48,31 @@ function set_rds_ert(ert)
local padding = (4 - (#data % 4)) % 4
data = data .. string.rep("\0", padding)
set_userdata_offset(0, 128, data)
set_userdata_offset(USERDATA_ERT_OFFSET, 128, data)
local segments = #data // 4
if segments > 32 then segments = 32 end
set_userdata_offset(128, 1, string.char(segments))
set_userdata_offset(USERDATA_ERT_OFFSET+128, 1, string.char(segments))
if string.byte(get_userdata_offset(257, 1)) == 0 then
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1)) == 0 then
init_ert()
set_userdata_offset(129, 128, data)
set_userdata_offset(257, 1, string.char(segments))
set_userdata_offset(USERDATA_ERT_OFFSET+129, 128, data)
set_userdata_offset(USERDATA_ERT_OFFSET+257, 1, string.char(segments))
_Ert_state = 0
else set_userdata_offset(258, 1, string.char(1)) end
else set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1)) end
end
function get_rds_ert()
local segments = string.byte(get_userdata_offset(128, 1))
local segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+128, 1))
if segments == 0 then return "" end
local data = get_userdata_offset(0, 128)
local data = get_userdata_offset(USERDATA_ERT_OFFSET, 128)
return data:match("^(.-)[\r%z]*") or ""
end
local _old_on_state_ert = on_state
function on_state()
if string.byte(get_userdata_offset(257, 1)) ~= 0 then init_ert() end
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1)) ~= 0 then init_ert() end
if type(_old_on_state_ert) == "function" then _old_on_state_ert() end
end

View File

@@ -37,15 +37,16 @@ end
---@param path string
---@param id integer
function load_station_logo(path, id)
local file = io.open(path, "rb")
if not file then error("Could not open file") end
_Rft_file = file:read("*a")
file:close()
if id == _Rft_last_id then
_Rft_toggle = not _Rft_toggle
_Rft_version = _Rft_version + 1
if _Rft_version > 7 then _Rft_version = 0 end
end
local file = io.open(path, "rb")
if not file then error("Could not open file") end
_Rft_file = file:read("*a")
file:close()
if #_Rft_file > 262143 then error("The file is too large", 2) end
if _Rft_oda_id == nil then start_rft() end

View File

@@ -3,13 +3,16 @@ _Ertp_oda_id = nil
_Rtp_toggle = false
_Ertp_toggle = false
--- Size: 15 bytes
local USERDATA_RTP_OFFSET = 259
local function init_rtp()
if _Rtp_oda_id == nil then
_Rtp_oda_id = register_oda(11, false, 0x4BD7, 0)
set_oda_handler(_Rtp_oda_id, function ()
local b = (_Rtp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(259, 1)) << 3
local data_0 = get_userdata_offset(260, 3)
local data_1 = get_userdata_offset(263, 3)
local b = (_Rtp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(USERDATA_RTP_OFFSET, 1)) << 3
local data_0 = get_userdata_offset(USERDATA_RTP_OFFSET+1, 3)
local data_1 = get_userdata_offset(USERDATA_RTP_OFFSET+4, 3)
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
local c = (string.byte(data_0, 1) & 0x7) << 13
@@ -30,9 +33,9 @@ local function init_ertp()
if _Ertp_oda_id == nil then
_Ertp_oda_id = register_oda(12, false, 0x4BD8, 0)
set_oda_handler(_Ertp_oda_id, function ()
local b = (_Ertp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(266, 1)) << 3
local data_0 = get_userdata_offset(267, 3)
local data_1 = get_userdata_offset(270, 3)
local b = (_Ertp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(USERDATA_RTP_OFFSET+7, 1)) << 3
local data_0 = get_userdata_offset(USERDATA_RTP_OFFSET+8, 3)
local data_1 = get_userdata_offset(USERDATA_RTP_OFFSET+11, 3)
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
local c = (string.byte(data_0, 1) & 0x7) << 13
@@ -52,14 +55,14 @@ end
function set_rds_rtp_meta(ertp, running)
if ertp then
if running and _Ertp_oda_id == nil then init_ertp() end
set_userdata_offset(266, 1, string.char(running and 1 or 0))
set_userdata_offset(USERDATA_RTP_OFFSET+7, 1, string.char(running and 1 or 0))
else
if running and _Rtp_oda_id == nil then init_rtp() end
set_userdata_offset(259, 1, string.char(running and 1 or 0))
set_userdata_offset(USERDATA_RTP_OFFSET, 1, string.char(running and 1 or 0))
end
end
function get_rds_rtp_meta(ertp)
local offset = ertp and 266 or 259
local offset = ertp and (USERDATA_RTP_OFFSET+7) or USERDATA_RTP_OFFSET
return string.byte(get_userdata_offset(offset, 1)) ~= 0
end
function toggle_rds_rtp(ertp)
@@ -70,10 +73,10 @@ end
function set_rds_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2)
set_rds_rtp_meta(ertp, true)
toggle_rds_rtp(ertp)
set_userdata_offset(ertp and 267 or 260, 6, string.char(t1, s1, l1, t2, s2, l2))
set_userdata_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6, string.char(t1, s1, l1, t2, s2, l2))
end
function get_rds_rtplus_tags(ertp)
return string.byte(get_userdata_offset(ertp and 267 or 260, 6), 1, 6)
return string.byte(get_userdata_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6), 1, 6)
end
local _old_on_state_rtp = on_state