Own and bind desktop radio call commands inside the bridge

This commit is contained in:
evgeny committed 2026-10-28 00:59:00 +01:00
1 parent 87b971569e
commit 0f36248d1e
2 files changed
+49

No files matched your search

+11
View File
@@ -102,6 +102,17 @@ enum gui_call_action { GUI_CALL_ACCEPT, GUI_CALL_DECLINE, GUI_CALL_HANGUP, GUI_C
int gui_bridge_call_start(const char* channel, uint64_t peer, uint64_t call_id); // NUL-строка 1..63 байта, peer/id ненулевые.
int gui_bridge_call_action(enum gui_call_action action, uint64_t call_id); // Только перечисленные действия, call_id ненулевой.
/* Приглашение в рацию: GUI передаёт значения без instance/heap-аргументов.
* START требует ненулевые id/group/peer; остальные действия — ненулевой id и group=peer=0.
* Под mutex привязывает копию к текущему running-ядру и передаёт владение очереди.
* 0 — принято, результат приходит через CHAT_EVT_RADIO_CALL; -1 — отказ с логом без оставшейся памяти.
* Detach до исполнения отменяет команду и освобождает её, не вызывая native API. */
enum gui_radio_call_action {
GUI_RADIO_CALL_START, GUI_RADIO_CALL_READY, GUI_RADIO_CALL_ACCEPT, GUI_RADIO_CALL_DECLINE,
GUI_RADIO_CALL_CANCEL, GUI_RADIO_CALL_FAIL, GUI_RADIO_CALL_REJECT_BUSY, GUI_RADIO_CALL_CONTINUE
};
int gui_bridge_radio_call(enum gui_radio_call_action action, uint64_t id, uint64_t group, uint64_t peer);
/* Назначение пары key/value: локальный ui_state SQLite либо live chat_setting ядра. */
enum gui_setting_target { GUI_SETTING_UI_STATE, GUI_SETTING_CHAT };
/* Скопировать NUL-строки key/value в собственный запрос и поставить его текущему ядру под mutex моста.
@@ -26,6 +26,7 @@ extern "C" {
#include "../../../src/chat/chat_join_port.h"
#include "../../../src/dm/dm_core.h"
#include "../../../src/call/call.h"
#include "../../../src/radio/radio_call.h"
}
/* ── Внутренний объект-приёмник в GUI-потоке ── */
@@ -828,6 +829,43 @@ int gui_bridge_call_action(enum gui_call_action action, uint64_t call_id) {
return 0;
}
/* Значения GUI становятся owned native-запросом одной операцией с проверкой ядра и enqueue. */
int gui_bridge_radio_call(enum gui_radio_call_action action, uint64_t id, uint64_t group, uint64_t peer) {
int nativeAction = 0;
const char* name = nullptr;
switch (action) {
case GUI_RADIO_CALL_START: nativeAction = RADIO_CALL_START; name = "start"; break;
case GUI_RADIO_CALL_READY: nativeAction = RADIO_CALL_READY; name = "ready"; break;
case GUI_RADIO_CALL_ACCEPT: nativeAction = RADIO_CALL_ACCEPT; name = "accept"; break;
case GUI_RADIO_CALL_DECLINE: nativeAction = RADIO_CALL_DECLINE; name = "decline"; break;
case GUI_RADIO_CALL_CANCEL: nativeAction = RADIO_CALL_CANCEL; name = "cancel"; break;
case GUI_RADIO_CALL_FAIL: nativeAction = RADIO_CALL_FAIL; name = "fail"; break;
case GUI_RADIO_CALL_REJECT_BUSY: nativeAction = RADIO_CALL_REJECT_BUSY; name = "reject_busy"; break;
case GUI_RADIO_CALL_CONTINUE: nativeAction = RADIO_CALL_CONTINUE; name = "continue"; break;
}
if (!name || !id || (action == GUI_RADIO_CALL_START ? !group || !peer : group || peer)) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio call bridge: invalid command action=%d id=%llu group=%llu peer=%llu",
action, (unsigned long long)id, (unsigned long long)group, (unsigned long long)peer); return -1;
}
std::lock_guard<std::mutex> guard(bridge_mutex);
if (!g_inst || !g_ua || !uasync_is_running(g_ua)) {
DEBUG_WARN(DEBUG_CATEGORY_RADIO, "radio call bridge: core unavailable action=%s id=%llu", name, (unsigned long long)id); return -1;
}
auto* request = static_cast<radio_call_request*>(u_calloc(1, sizeof(radio_call_request)));
if (!request) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio call bridge: request allocation failed action=%s id=%llu", name, (unsigned long long)id);
return -1;
}
request->inst = g_inst; request->id = id; request->group = group; request->peer = peer; request->action = nativeAction;
if (post_command(radio_call_trampoline, request, true) < 0) {
u_free(request);
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "radio call bridge: queue rejected action=%s id=%llu", name, (unsigned long long)id); return -1;
}
DEBUG_DEBUG(DEBUG_CATEGORY_RADIO, "radio call bridge: queued action=%s id=%llu group=%llu peer=%llu",
name, (unsigned long long)id, (unsigned long long)group, (unsigned long long)peer);
return 0;
}
/* Копия команды и её post принимаются одной операцией с привязкой к живому ядру. */
int gui_bridge_member_files_request(uint64_t group, uint64_t server, const struct mf_message* message) {
if (!group || !server || !message || !message->request_id || message->command < MF_LIST || message->command > MF_QUOTA ||