Files
opengd77-uv380-sms/patches/patch_store.py
T
viktor b5a8e92e45 DMR-данные (SMS) на TYT MD-UV380 под OpenGD77
Восстановлено из транскрипта сессии после потери рабочего дерева на сервере сборки.

Что внутри:
- четыре новых модуля прошивки (приём, сборка исходящего, меню Messages);
- правки существующих файлов в виде скриптов, с порядком применения;
- инструменты стенда: снятие экрана рации по USB, дамп кадров, эталонная сборка пакета;
- NOTES.md: что проверено в эфире, что не доделано, где грабли.

Работало в эфире в августе 2026: данные ходят в обе стороны в режиме хотспота,
рация принимает SMS и показывает на экране. Отправка собрана и сверена с эталоном
сервера побайтово, но в эфире не проверялась.

Claude-Session: https://claude.ai/code/session_01GJtvG5WwqYNe1b7s9LLtgy
2026-09-11 02:39:24 +09:00

150 строки
3.6 KiB
Python

#!/usr/bin/env python3
"""Add Inbox/Outbox storage to the SMS module."""
W = "/home/viktor/ogd77rel/uv_src/OpenGD77_MDUV380_DM1701_20260130/MDUV380_firmware/application"
# ------------------------------------------------------------------ header
p = W + "/include/functions/sms.h"
s = open(p).read()
if "smsInboxCount" in s:
print("sms.h: already has storage API")
else:
s = s.replace(
"// Most recently received message, or NULL when nothing has been received yet.\n",
"""// How many messages each folder keeps. Older ones are dropped when full.
#define SMS_INBOX_SIZE 10
#define SMS_OUTBOX_SIZE 10
// Inbox: messages received off air. Newest first.
uint8_t smsInboxCount(void);
const smsMessage_t *smsInboxGet(uint8_t index);
void smsInboxClear(void);
uint8_t smsInboxUnreadCount(void);
// Outbox: messages we sent. Newest first.
uint8_t smsOutboxCount(void);
const smsMessage_t *smsOutboxGet(uint8_t index);
void smsOutboxClear(void);
void smsOutboxAdd(uint32_t dstId, bool isPrivate, const char *text);
// Most recently received message, or NULL when nothing has been received yet.
""", 1)
open(p, "w").write(s)
print("sms.h: storage API declared")
# ------------------------------------------------------------------ source
p = W + "/source/functions/sms.c"
s = open(p).read()
if "smsInboxCount" in s:
print("sms.c: already has storage")
raise SystemExit(0)
a = "static smsMessage_t latest;\n"
assert a in s
s = s.replace(a, a + """
// Message folders. Index 0 is always the newest; adding shifts the rest down.
static smsMessage_t inbox[SMS_INBOX_SIZE];
static uint8_t inboxCount = 0;
static smsMessage_t outbox[SMS_OUTBOX_SIZE];
static uint8_t outboxCount = 0;
""", 1)
# clear folders on init
s = s.replace("\tmemset(&latest, 0, sizeof(latest));\n",
"\tmemset(&latest, 0, sizeof(latest));\n"
"\tinboxCount = 0;\n"
"\toutboxCount = 0;\n", 1)
# store a completed message into the inbox
a = "\thaveMessage = (t > 0);\n"
assert a in s, "completion point not found"
s = s.replace(a, """ if (t > 0)
{
// Newest first: shift the existing entries down, dropping the oldest if full.
for (int8_t i = (int8_t)((inboxCount < SMS_INBOX_SIZE) ? inboxCount : (SMS_INBOX_SIZE - 1)); i > 0; i--)
{
inbox[i] = inbox[i - 1];
}
inbox[0] = latest;
if (inboxCount < SMS_INBOX_SIZE)
{
inboxCount++;
}
}
""" + a, 1)
s += """
uint8_t smsInboxCount(void)
{
return inboxCount;
}
const smsMessage_t *smsInboxGet(uint8_t index)
{
return ((index < inboxCount) ? &inbox[index] : NULL);
}
void smsInboxClear(void)
{
inboxCount = 0;
unread = false;
haveMessage = false;
}
uint8_t smsInboxUnreadCount(void)
{
uint8_t n = 0;
for (uint8_t i = 0; i < inboxCount; i++)
{
if (inbox[i].unread)
{
n++;
}
}
return n;
}
uint8_t smsOutboxCount(void)
{
return outboxCount;
}
const smsMessage_t *smsOutboxGet(uint8_t index)
{
return ((index < outboxCount) ? &outbox[index] : NULL);
}
void smsOutboxClear(void)
{
outboxCount = 0;
}
void smsOutboxAdd(uint32_t dstId, bool isPrivate, const char *text)
{
for (int8_t i = (int8_t)((outboxCount < SMS_OUTBOX_SIZE) ? outboxCount : (SMS_OUTBOX_SIZE - 1)); i > 0; i--)
{
outbox[i] = outbox[i - 1];
}
memset(&outbox[0], 0, sizeof(smsMessage_t));
outbox[0].dstId = dstId;
outbox[0].isPrivate = isPrivate;
outbox[0].unread = false;
strncpy(outbox[0].text, text, SMS_MAX_TEXT_LENGTH);
outbox[0].text[SMS_MAX_TEXT_LENGTH] = '\\0';
if (outboxCount < SMS_OUTBOX_SIZE)
{
outboxCount++;
}
}
"""
open(p, "w").write(s)
print("sms.c: inbox/outbox storage added")