Cover radio phone policy, BGP color flags, retries and caller choice timeout
This commit is contained in:
1 parent
4683c98c08
commit
79b4235960
2 files changed
+82
-11
No files matched your search
+73
-8
@@ -20,6 +20,7 @@
|
||||
#include "member_sync.h"
|
||||
#include "../radio/radio.h"
|
||||
#include "../radio/radio_call.h"
|
||||
#include "../call/call.h"
|
||||
#include "../routing_layer/etcp_router.h"
|
||||
#include "../routing_layer/topo_node_sqlite.h"
|
||||
#include "../routing_layer/topo_group.h"
|
||||
@@ -52,7 +53,7 @@
|
||||
#define IDX_C 2
|
||||
|
||||
#define TICK_TB 100 /* 10 ms на такт */
|
||||
#define MAX_TICKS 12000 /* включает минуту ожидания решения по вызову */
|
||||
#define MAX_TICKS 24000 /* включает минутные deadline звонка и выбора продолжения */
|
||||
#define N_FRAMES 5
|
||||
|
||||
enum rad_phase {
|
||||
@@ -111,8 +112,9 @@ static int g_member_radio[3][3];
|
||||
static int g_member_lists[3];
|
||||
static int g_member_event_bad;
|
||||
static int g_talk_on[3], g_talk_starts[3], g_talk_stops[3];
|
||||
static struct { int state, reason, finished, incoming; uint64_t finished_tb; } g_calls[8][3];
|
||||
static int g_call_ready, g_drop_result, g_drop_ack;
|
||||
static struct { int state, reason, finished, incoming; uint64_t finished_tb; } g_calls[20][3];
|
||||
static int g_call_ready, g_drop_result, g_drop_ack, g_drop_force;
|
||||
static int g_member_phone[3][3];
|
||||
static etcp_recv_fn g_call_recv[3];
|
||||
|
||||
/* Потеря приложения после router ACK: восстановить результат обязан сервис, не транспорт. */
|
||||
@@ -122,7 +124,8 @@ static void call_packet_loss(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
if (idx < 0 || !entry) abort();
|
||||
if (entry->len <= ROUTER_SVC_PAYLOAD_OFF) { g_call_recv[idx](conn, entry); return; }
|
||||
int cmd = entry->dgram[ROUTER_SVC_PAYLOAD_OFF];
|
||||
if ((idx == IDX_A && cmd == 3 && g_drop_result-- > 0) || (idx == IDX_C && cmd == 4 && g_drop_ack-- > 0)) {
|
||||
if ((idx == IDX_A && cmd == 3 && g_drop_result-- > 0) || (idx == IDX_C && cmd == 4 && g_drop_ack-- > 0) ||
|
||||
(idx == IDX_C && cmd == 6 && g_drop_force-- > 0)) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "test drops radio result/ACK dst=%d command=%d", idx, cmd);
|
||||
queue_dgram_free(entry); queue_entry_free(entry); return;
|
||||
}
|
||||
@@ -163,7 +166,7 @@ static void member_event(struct UTUN_INSTANCE* inst, int type, const uint8_t* da
|
||||
memcpy(&id, data, 8); memcpy(&group, data + 8, 8); memcpy(&peer, data + 16, 8);
|
||||
int idx = -1;
|
||||
for (int i = 0; i < 3; ++i) if (inst->node_id == g_sh.nid[i]) idx = i;
|
||||
if (idx < 0 || id < 100 || id > 107 || group != strtoull(CH_ID, NULL, 10)) { g_member_event_bad = 1; return; }
|
||||
if (idx < 0 || id < 100 || id > 119 || group != strtoull(CH_ID, NULL, 10)) { g_member_event_bad = 1; return; }
|
||||
g_calls[id - 100][idx].state = data[24]; g_calls[id - 100][idx].reason = data[25];
|
||||
if (data[24] == RADIO_CALL_INCOMING) {
|
||||
++g_calls[id - 100][idx].incoming;
|
||||
@@ -212,8 +215,10 @@ static void member_event(struct UTUN_INSTANCE* inst, int type, const uint8_t* da
|
||||
if (chat_core_deserialize_member(data + off + i * CHAT_MEMBER_DISPLAY_SIZE, &member) < 0) {
|
||||
g_member_event_bad = 1; return;
|
||||
}
|
||||
for (int j = 0; j < 3; j++)
|
||||
if (member.node_id == g_sh.nid[j]) g_member_radio[dst][j] = !!(member.flags & CHAT_MEMBER_FLAG_RADIO);
|
||||
for (int j = 0; j < 3; j++) if (member.node_id == g_sh.nid[j]) {
|
||||
g_member_radio[dst][j] = !!(member.flags & CHAT_MEMBER_FLAG_RADIO);
|
||||
g_member_phone[dst][j] = member.flags & (CHAT_MEMBER_FLAG_PHONE_KNOWN | CHAT_MEMBER_FLAG_PHONE_BUSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,9 +603,69 @@ static void rad_tick(void* arg) {
|
||||
t->result = 2; uasync_stop(t->ua); return;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "test radio calls passed: 2s/60s, accept/decline/cancel/busy, lost result/ACK, idle has no timer");
|
||||
t->phase = P_RADIO_ON;
|
||||
call_set_phone_state(C, 2, CALL_POLICY_WARN_PHONE);
|
||||
radio_action(A, 108, RADIO_CALL_START, nc); ++t->call_step;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (g_calls[8][IDX_A].state != RADIO_CALL_WAIT_DECISION) break;
|
||||
if (g_calls[8][IDX_C].incoming || g_member_phone[IDX_A][IDX_C]) goto phone_failed;
|
||||
call_set_phone_state(C, 1, CALL_POLICY_WARN_PHONE);
|
||||
t->call_started = now; ++t->call_step; break;
|
||||
case 11:
|
||||
if (now - t->call_started < 10000) break;
|
||||
if (g_calls[8][IDX_C].incoming) goto phone_failed; // Освободившийся телефон сам не начинает вызов.
|
||||
g_drop_force = 2;
|
||||
radio_action(A, 108, RADIO_CALL_CONTINUE, 0); ++t->call_step; break;
|
||||
case 12:
|
||||
if (g_calls[8][IDX_A].state != RADIO_CALL_RINGING) break;
|
||||
if (g_calls[8][IDX_C].incoming != 1 || g_drop_force > 0) goto phone_failed;
|
||||
radio_action(C, 108, RADIO_CALL_DECLINE, 0); ++t->call_step; break;
|
||||
case 13:
|
||||
if (!g_calls[8][IDX_A].finished) break;
|
||||
radio_action(A, 108, RADIO_CALL_CONTINUE, 0); // Запоздалое UI-подтверждение не оживляет попытку.
|
||||
call_set_phone_state(C, 2, CALL_POLICY_PUBLISH_PHONE);
|
||||
radio_action(A, 109, RADIO_CALL_START, nc); ++t->call_step; break;
|
||||
case 14:
|
||||
if (g_calls[9][IDX_A].state != RADIO_CALL_RINGING || g_member_phone[IDX_A][IDX_C] != 0xC0) break;
|
||||
if (g_calls[9][IDX_C].incoming != 1 || g_calls[8][IDX_C].incoming != 1) goto phone_failed;
|
||||
{
|
||||
uint8_t member[CHAT_MEMBER_DISPLAY_SIZE];
|
||||
if (chat_core_get_single_member(A, CH_ID, nc, member) || (member[10] & 0xC0) != 0xC0) goto phone_failed;
|
||||
}
|
||||
radio_action(A, 109, RADIO_CALL_CANCEL, 0); ++t->call_step; break;
|
||||
case 15:
|
||||
if (!g_calls[9][IDX_C].finished) break;
|
||||
call_set_phone_state(C, 2, CALL_POLICY_WARN_PHONE | CALL_POLICY_REJECT_PHONE);
|
||||
radio_action(A, 110, RADIO_CALL_START, nc); ++t->call_step; break;
|
||||
case 16:
|
||||
if (!g_calls[10][IDX_A].finished || g_member_phone[IDX_A][IDX_C]) break;
|
||||
if (g_calls[10][IDX_A].reason != RADIO_CALL_PHONE_BUSY || g_calls[10][IDX_C].incoming) goto phone_failed;
|
||||
call_set_phone_state(C, 0, CALL_POLICY_BLOCK_CALLS);
|
||||
radio_action(A, 111, RADIO_CALL_START, nc); ++t->call_step; break;
|
||||
case 17:
|
||||
if (g_calls[11][IDX_A].state != RADIO_CALL_RINGING) break;
|
||||
radio_action(A, 111, RADIO_CALL_CANCEL, 0); ++t->call_step; break;
|
||||
case 18:
|
||||
if (!g_calls[11][IDX_C].finished) break;
|
||||
call_set_phone_state(C, 2, CALL_POLICY_BLOCK_RADIO | CALL_POLICY_WARN_PHONE);
|
||||
radio_action(A, 112, RADIO_CALL_START, nc); ++t->call_step; break;
|
||||
case 19:
|
||||
if (!g_calls[12][IDX_A].finished) break;
|
||||
if (g_calls[12][IDX_A].reason != RADIO_CALL_DECLINED || g_calls[12][IDX_C].incoming) goto phone_failed;
|
||||
call_set_phone_state(C, 2, CALL_POLICY_WARN_PHONE);
|
||||
t->call_started = now;
|
||||
radio_action(A, 113, RADIO_CALL_START, nc); ++t->call_step; break;
|
||||
case 20:
|
||||
if (!g_calls[13][IDX_A].finished) break;
|
||||
if (g_calls[13][IDX_A].reason != RADIO_CALL_NO_ANSWER || g_calls[13][IDX_C].incoming ||
|
||||
now - t->call_started < RADIO_CALL_RING_TB || now - t->call_started > RADIO_CALL_RING_TB + 1000) goto phone_failed;
|
||||
call_set_phone_state(C, 0, 0);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "phone policy passed: hidden/published BGP, warn, override with loss, reject, independent blocks, 60s choice");
|
||||
t->phase = P_RADIO_ON; break;
|
||||
phone_failed:
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "phone policy failed step=%d", t->call_step);
|
||||
t->result = 2; uasync_stop(t->ua); return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user