mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
oda_handler
This commit is contained in:
@@ -264,3 +264,7 @@ function set_rds_udg2(xy, groups) end
|
|||||||
---@param id_data integer
|
---@param id_data integer
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function register_oda(group, group_version, id, id_data) end
|
function register_oda(group, group_version, id, id_data) end
|
||||||
|
---Sets a function to handle the ODA for the oda id we have specified when we get to group "" TODO: which one
|
||||||
|
---@param oda_id integer
|
||||||
|
---@param fun function
|
||||||
|
function set_oda_handler(oda_id, fun) end
|
||||||
@@ -4,9 +4,12 @@
|
|||||||
static RDSModulator* mod = NULL;
|
static RDSModulator* mod = NULL;
|
||||||
static lua_State *L = NULL;
|
static lua_State *L = NULL;
|
||||||
static pthread_mutex_t lua_mutex;
|
static pthread_mutex_t lua_mutex;
|
||||||
|
static uint8_t unload_refs[33] = {LUA_REFNIL};
|
||||||
|
|
||||||
int lua_set_rds_program_defaults(lua_State *localL) {
|
int lua_set_rds_program_defaults(lua_State *localL) {
|
||||||
(void)localL;
|
(void)localL;
|
||||||
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
|
unload_refs[0] = 0;
|
||||||
set_rds_defaults(mod->enc, mod->enc->program);
|
set_rds_defaults(mod->enc, mod->enc->program);
|
||||||
lua_call_function("on_init");
|
lua_call_function("on_init");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -14,6 +17,8 @@ int lua_set_rds_program_defaults(lua_State *localL) {
|
|||||||
|
|
||||||
int lua_reset_rds(lua_State *localL) {
|
int lua_reset_rds(lua_State *localL) {
|
||||||
(void)localL;
|
(void)localL;
|
||||||
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
|
unload_refs[0] = 0;
|
||||||
encoder_saveToFile(mod->enc);
|
encoder_saveToFile(mod->enc);
|
||||||
Modulator_saveToFile(&mod->params);
|
Modulator_saveToFile(&mod->params);
|
||||||
|
|
||||||
@@ -403,8 +408,9 @@ int lua_register_oda(lua_State *localL) {
|
|||||||
if (!lua_isboolean(localL, 2)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 2));
|
if (!lua_isboolean(localL, 2)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 2));
|
||||||
uint8_t id = mod->enc->state[mod->enc->program].user_oda.oda_len++;
|
uint8_t id = mod->enc->state[mod->enc->program].user_oda.oda_len++;
|
||||||
if(mod->enc->state[mod->enc->program].user_oda.oda_len >= 32) return luaL_error(localL, "There can't be more than 32 registered ODAs");
|
if(mod->enc->state[mod->enc->program].user_oda.oda_len >= 32) return luaL_error(localL, "There can't be more than 32 registered ODAs");
|
||||||
mod->enc->state[mod->enc->program].user_oda.odas[id].enabled = 1;
|
if(mod->enc->state[mod->enc->program].user_oda.odas[id].group != 0) return luaL_error(localL, "internal error");
|
||||||
mod->enc->state[mod->enc->program].user_oda.odas[id].group = luaL_checkinteger(localL, 1);
|
mod->enc->state[mod->enc->program].user_oda.odas[id].group = luaL_checkinteger(localL, 1);
|
||||||
|
if(mod->enc->state[mod->enc->program].user_oda.odas[id].group == 0) return luaL_error(localL, "Invalid group")
|
||||||
mod->enc->state[mod->enc->program].user_oda.odas[id].group_version = lua_toboolean(localL, 2);
|
mod->enc->state[mod->enc->program].user_oda.odas[id].group_version = lua_toboolean(localL, 2);
|
||||||
mod->enc->state[mod->enc->program].user_oda.odas[id].id = luaL_checkinteger(localL, 3);
|
mod->enc->state[mod->enc->program].user_oda.odas[id].id = luaL_checkinteger(localL, 3);
|
||||||
mod->enc->state[mod->enc->program].user_oda.odas[id].id_data = luaL_checkinteger(localL, 4);
|
mod->enc->state[mod->enc->program].user_oda.odas[id].id_data = luaL_checkinteger(localL, 4);
|
||||||
@@ -412,6 +418,20 @@ int lua_register_oda(lua_State *localL) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_set_oda_handler(lua_State *localL) {
|
||||||
|
uint8_t idx = luaL_checkinteger(localL, 1);
|
||||||
|
if(idx >= 32) return luaL_error(localL, "There can't be more than 32 registered ODAs");
|
||||||
|
if(mod->enc->state[mod->enc->program].user_oda.odas[idx].group == 0) return luaL_error(localL, "this oda is not registered");
|
||||||
|
luaL_checktype(localL, 2, LUA_TFUNCTION);
|
||||||
|
lua_pushvalue(localL, 2);
|
||||||
|
if(mod->enc->state[mod->enc->program].user_oda.odas[idx].lua_handler != 0) luaL_unref(localL, LUA_REGISTRYINDEX, mod->enc->state[mod->enc->program].user_oda.odas[idx].lua_handler);
|
||||||
|
mod->enc->state[mod->enc->program].user_oda.odas[idx].lua_handler = luaL_ref(localL, LUA_REGISTRYINDEX);
|
||||||
|
int index = *unload_refs;
|
||||||
|
unload_refs[index] = mod->enc->state[mod->enc->program].user_oda.odas[idx].lua_handler;
|
||||||
|
(*unload_refs)++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void init_lua(RDSModulator* rds_mod) {
|
void init_lua(RDSModulator* rds_mod) {
|
||||||
mod = rds_mod;
|
mod = rds_mod;
|
||||||
L = luaL_newstate();
|
L = luaL_newstate();
|
||||||
@@ -529,6 +549,7 @@ void init_lua(RDSModulator* rds_mod) {
|
|||||||
lua_register(L, "set_rds_udg2", lua_set_rds_udg2);
|
lua_register(L, "set_rds_udg2", lua_set_rds_udg2);
|
||||||
|
|
||||||
lua_register(L, "register_oda", lua_register_oda);
|
lua_register(L, "register_oda", lua_register_oda);
|
||||||
|
lua_register(L, "set_oda_handler", lua_set_oda_handler);
|
||||||
|
|
||||||
char path[128];
|
char path[128];
|
||||||
const char *home = getenv("HOME");
|
const char *home = getenv("HOME");
|
||||||
@@ -545,6 +566,7 @@ void init_lua(RDSModulator* rds_mod) {
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
pthread_mutex_init(&lua_mutex, NULL);
|
pthread_mutex_init(&lua_mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,9 +577,9 @@ void run_lua(char *str, char *cmd_output) {
|
|||||||
if (lua_isfunction(L, -1)) {
|
if (lua_isfunction(L, -1)) {
|
||||||
lua_pushstring(L, str);
|
lua_pushstring(L, str);
|
||||||
if (lua_pcall(L, 1, 1, 0) == LUA_OK) {
|
if (lua_pcall(L, 1, 1, 0) == LUA_OK) {
|
||||||
if (lua_isstring(L, -1) && cmd_output) strcpy(cmd_output, lua_tostring(L, -1));
|
if (lua_isstring(L, -1) && cmd_output) _strncpy(cmd_output, lua_tostring(L, -1), 254);
|
||||||
} else fprintf(stderr, "Lua error: %s\n", lua_tostring(L, -1));
|
} else fprintf(stderr, "Lua error: %s\n", lua_tostring(L, -1));
|
||||||
} else if (lua_isstring(L, -1) && cmd_output) strcpy(cmd_output, lua_tostring(L, -1));
|
} else if (lua_isstring(L, -1) && cmd_output) _strncpy(cmd_output, lua_tostring(L, -1), 254);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
}
|
}
|
||||||
@@ -571,6 +593,18 @@ void lua_group(RDSGroup* group) {
|
|||||||
lua_pushinteger(L, group->c);
|
lua_pushinteger(L, group->c);
|
||||||
lua_pushinteger(L, group->d);
|
lua_pushinteger(L, group->d);
|
||||||
if (lua_pcall(L, 3, 3, 0) == LUA_OK) {
|
if (lua_pcall(L, 3, 3, 0) == LUA_OK) {
|
||||||
|
if (!lua_isinteger(localL, -1)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
||||||
|
}
|
||||||
|
if (!lua_isinteger(localL, -2)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -2));
|
||||||
|
}
|
||||||
|
if (!lua_isinteger(localL, -3)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -3));
|
||||||
|
}
|
||||||
group->d = luaL_checkinteger(L, -1);
|
group->d = luaL_checkinteger(L, -1);
|
||||||
group->c = luaL_checkinteger(L, -2);
|
group->c = luaL_checkinteger(L, -2);
|
||||||
group->b = luaL_checkinteger(L, -3);
|
group->b = luaL_checkinteger(L, -3);
|
||||||
@@ -585,6 +619,39 @@ void lua_group(RDSGroup* group) {
|
|||||||
pthread_mutex_unlock(&lua_mutex);
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_group_ref(RDSGroup* group, int ref) {
|
||||||
|
pthread_mutex_lock(&lua_mutex);
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||||
|
|
||||||
|
if (lua_isfunction(L, -1)) {
|
||||||
|
lua_pushinteger(L, group->b);
|
||||||
|
lua_pushinteger(L, group->c);
|
||||||
|
lua_pushinteger(L, group->d);
|
||||||
|
if (lua_pcall(L, 3, 3, 0) == LUA_OK) {
|
||||||
|
if (!lua_isinteger(localL, -1)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
||||||
|
}
|
||||||
|
if (!lua_isinteger(localL, -2)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -2));
|
||||||
|
}
|
||||||
|
if (!lua_isinteger(localL, -3)) {
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -3));
|
||||||
|
}
|
||||||
|
group->d = luaL_checkinteger(L, -1);
|
||||||
|
group->c = luaL_checkinteger(L, -2);
|
||||||
|
group->b = luaL_checkinteger(L, -3);
|
||||||
|
lua_pop(L, 3);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Lua error: %s\n", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
} else lua_pop(L, 1);
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_call_function(const char* function) {
|
void lua_call_function(const char* function) {
|
||||||
pthread_mutex_lock(&lua_mutex);
|
pthread_mutex_lock(&lua_mutex);
|
||||||
lua_getglobal(L, function);
|
lua_getglobal(L, function);
|
||||||
@@ -600,6 +667,7 @@ void lua_call_function(const char* function) {
|
|||||||
|
|
||||||
void destroy_lua(void) {
|
void destroy_lua(void) {
|
||||||
if (L) {
|
if (L) {
|
||||||
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
L = NULL;
|
L = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ void init_lua(RDSModulator* rds_mod);
|
|||||||
void run_lua(char *str, char *cmd_output);
|
void run_lua(char *str, char *cmd_output);
|
||||||
void lua_group(RDSGroup* group);
|
void lua_group(RDSGroup* group);
|
||||||
void lua_call_function(const char* function);
|
void lua_call_function(const char* function);
|
||||||
|
void lua_group_ref(RDSGroup* group, int ref);
|
||||||
void destroy_lua();
|
void destroy_lua();
|
||||||
@@ -30,6 +30,7 @@ uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group);
|
|||||||
uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group);
|
uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rdsp_lua_group(RDSGroup *group);
|
void get_rdsp_lua_group(RDSGroup *group);
|
||||||
void get_rds_user_oda_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_user_oda_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
|
int get_rds_user_oda_group_content(RDSEncoder* enc, RDSGroup *group);
|
||||||
|
|
||||||
#define HANDLE_UDG_STREAM(chan_idx, udg_prefix) \
|
#define HANDLE_UDG_STREAM(chan_idx, udg_prefix) \
|
||||||
do { \
|
do { \
|
||||||
@@ -116,6 +117,9 @@ static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp,
|
|||||||
case 'O':
|
case 'O':
|
||||||
get_rds_user_oda_group(enc, group);
|
get_rds_user_oda_group(enc, group);
|
||||||
break;
|
break;
|
||||||
|
case 'K':
|
||||||
|
if(get_rds_user_oda_group_content(enc, group) == 0) get_rds_ps_group(enc, group);
|
||||||
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
if(enc->state[enc->program].af_oda == 0) get_rds_oda_af_group(enc, group);
|
if(enc->state[enc->program].af_oda == 0) get_rds_oda_af_group(enc, group);
|
||||||
else get_rdsp_oda_af_oda_group(group);
|
else get_rdsp_oda_af_oda_group(group);
|
||||||
@@ -147,6 +151,7 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp) {
|
|||||||
if(*grp == 'T') good_group = 1;
|
if(*grp == 'T') good_group = 1;
|
||||||
if(*grp == 'L') good_group = 1;
|
if(*grp == 'L') good_group = 1;
|
||||||
if(*grp == 'O' && enc->state[enc->program].user_oda.oda_len != 0) good_group = 1;
|
if(*grp == 'O' && enc->state[enc->program].user_oda.oda_len != 0) good_group = 1;
|
||||||
|
if(*grp == 'K') good_group = 1;
|
||||||
if(*grp == 'U' && enc->data[enc->program].af_oda.num_afs) good_group = 1;
|
if(*grp == 'U' && enc->data[enc->program].af_oda.num_afs) good_group = 1;
|
||||||
return good_group;
|
return good_group;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ typedef struct {
|
|||||||
} RDSEONState;
|
} RDSEONState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t enabled : 1;
|
|
||||||
uint8_t group : 4;
|
uint8_t group : 4;
|
||||||
uint8_t group_version : 1;
|
uint8_t group_version : 1;
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
@@ -123,6 +122,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t oda_len;
|
uint8_t oda_len;
|
||||||
uint8_t oda_pointer;
|
uint8_t oda_pointer;
|
||||||
|
uint8_t oda_runner_pointer;
|
||||||
RDSODA odas[32];
|
RDSODA odas[32];
|
||||||
} RDSODAState;
|
} RDSODAState;
|
||||||
|
|
||||||
|
|||||||
@@ -382,3 +382,20 @@ void get_rds_user_oda_group(RDSEncoder* enc, RDSGroup *group) {
|
|||||||
group->c = oda.id_data;
|
group->c = oda.id_data;
|
||||||
group->d = oda.id;
|
group->d = oda.id;
|
||||||
}
|
}
|
||||||
|
int get_rds_user_oda_group_content(RDSEncoder* enc, RDSGroup *group) {
|
||||||
|
RDSODAState *oda_state = &enc->state[enc->program].user_oda;
|
||||||
|
|
||||||
|
if (oda_state->oda_len == 0) return 0;
|
||||||
|
for (uint8_t i = 0; i < oda_state->oda_len; i++) {
|
||||||
|
uint8_t current_idx = oda_state->oda_runner_pointer;
|
||||||
|
|
||||||
|
oda_state->oda_runner_pointer = (oda_state->oda_runner_pointer + 1) % oda_state->oda_len;
|
||||||
|
|
||||||
|
if (oda_state->odas[current_idx].lua_handler != 0) {
|
||||||
|
lua_group_ref(group, oda_state->odas[current_idx].lua_handler);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user