0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 20:33:53 +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 *.pyc
__pycache__/ __pycache__/
.vscode/ .vscode/
.command_prefix.lua .script.lua

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10) 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}\") 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 install(CODE
" "
# Define the paths for the source and destination files # 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(SCRIPTS_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/scripts\")
set(DEST_FILE \"/etc/rds95.lua\") set(DEST_FILE \"/etc/rds95.lua\")

View File

@@ -29,7 +29,7 @@ end
---@param oda_id integer ---@param oda_id integer
---@param data integer ---@param data integer
function set_oda_id_data(oda_id, data) 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 _RDS_ODAs[oda_id].data = data
end end
@@ -41,8 +41,8 @@ end
---@param oda_id integer The ID returned by register_oda ---@param oda_id integer The ID returned by register_oda
---@param fun ODAHandler ---@param fun ODAHandler
function set_oda_handler(oda_id, fun) function set_oda_handler(oda_id, fun)
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
if _RDS_ODAs.group == 3 then error("3A ODAs cannot have handlers.") end if _RDS_ODAs[oda_id].group == 3 then error("3A ODAs cannot have handlers.", 2) end
_RDS_ODAs[oda_id].handler = fun _RDS_ODAs[oda_id].handler = fun
end end

View File

@@ -25,7 +25,7 @@ end
---@param oda_id integer ---@param oda_id integer
---@param data integer ---@param data integer
function set_oda_id_data_rds2(oda_id, data) 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 _RDS2_ODAs[oda_id].data = data
end end
@@ -33,7 +33,7 @@ end
---@param oda_id integer ---@param oda_id integer
---@param func RDS2_ODAHandler ---@param func RDS2_ODAHandler
function set_oda_handler_rds2(oda_id, func) 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 _RDS2_ODAs[oda_id].handler = func
end end

View File

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

View File

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

View File

@@ -37,15 +37,16 @@ end
---@param path string ---@param path string
---@param id integer ---@param id integer
function load_station_logo(path, id) 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 if id == _Rft_last_id then
_Rft_toggle = not _Rft_toggle _Rft_toggle = not _Rft_toggle
_Rft_version = _Rft_version + 1 _Rft_version = _Rft_version + 1
if _Rft_version > 7 then _Rft_version = 0 end if _Rft_version > 7 then _Rft_version = 0 end
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_file > 262143 then error("The file is too large", 2) end
if _Rft_oda_id == nil then start_rft() end if _Rft_oda_id == nil then start_rft() end

View File

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