feat: M6.44+M6.45 收编 — 真机 0.8.45 现场保全(reader章节/key_router按键路由/WiFi连接修复/ncm bench+IME修复)
脏工作区现场收编:devdocs/local/m6_44_45_dirty_tracked.patch(46 个已跟踪文本文件,
+3090/-585, 已对 M6.43 基线干净适配) + m6_44_45_untracked_src.tar.gz 中 patch_v2/ 下
13 个新增源文件, 合成单个提交, 内容与容器工作树(R3ProII/patch_v2)逐字节一致。
- reader 章节: 新增 core/rdchapter.{h,c} — TXT 章节规范解析器, 扫描 512KB 码位对齐段文件
逐段流式识别标题行(行首缩进≤4/显示宽≤40/行内标点≤1 三重约束防误判), 输出标题+全书字符
偏移+段号/段内偏移+阿拉伯章号(中文数字归一), 首章前内容归"卷首"; book/reader/rdenc/
rdlayout/settings 接入章节跳转与进度锚点, 附 chapter_smoke/turn_repro/build_turn_repro.sh
- key_router 按键路由: 新增 meow_launcherd/key_router.{h,c} — launcher-UI 页物理键统一路由
(P1 仅音量键), 把读取边沿+防抖+长按 held+ramp 推进从 5 个会话收敛为进程内单开;
各页每圈 key_router_pump() 取防抖后边沿, 动作(调音量/光标导航)仍由调用页决定,
保留 run_menu 的 meow_mode 分支; App 前台 volume_page 武装时边沿抑制;
main_menu/now_playing/notif_center/settings_page/subpage 接入, 附 test_key_router_vol/test_np_keys
- WiFi 连接修复: meow_netmgrd connect 有界等待 wpa_state=COMPLETED(普通 10s/隐藏网络 15s,
env 可调)修设置页连接无响应; list_networks/scan_results 的 \xNN 转义还原始字节, 修中文 SSID
永不命中致新建同名 open 记录顶影; launcher netmgr_ipc 配读超时; 附 test_wifi_connect(桩
wpa_cli 驱动 static wifi_connect_ex), test_netmgrd.sh 补用例; wifi_page 同步
- ncm bench: 新增 bench/lyric_sim.c、bench/plpage_sim.c, vol_sync_sim 与 ncm core/app 同步
- SDK IME 修复: shift 大小写、K_ENTER 只提交不关、阻塞 IME 循环喂 on_tick 不被遮挡、
IME 打开 ~200ms TAP 冷却窗吞 stray-TAP; 附 sdk/test_ime_fix.c
- 同期: meow_audiod 音量异步 ACK 线程(代际防 fd/槽复用竞态)、watchdog 音量收编(首选 audiod
权威, settings.conf 覆盖路径)、panel 文件搜索(F1-④)与蓝牙只读详情(F1-③)、各类 build 脚本同步
范围红线: third_party/legado-E-main 原开发者未跟踪, 本次不入库(保留 devdocs/local tar 参考);
二进制不入库(后续重编); devdocs/ 不入库。59 文件全部在 patch_v2/ 下, 无 third_party/devdocs。
验证: git apply --check 干净; 59 文件 md5 与容器 patch_v2 逐一比对 59/59 一致(含
key_router.c/rdchapter.c/meow_ui_ime.c/test_wifi_connect.c 抽查); 可执行位保守
(check_lgpl_release.sh 100755, build_turn_repro.sh 100644 与容器一致)。
This commit is contained in:
1 parent
e87ccdf061
commit
7c7d891570
59 files changed
+5305
-590
No files matched your search
@@ -15,6 +15,14 @@
|
||||
#define NETMGR_SOCK_DEFAULT "/usr/data/meow_net.sock"
|
||||
/* NETMGR_UNREACH 定义在 meow_launcher_internal.h(测试/调用方共用) */
|
||||
|
||||
/* IPC 读超时(ms)。netmgrd 单线程 poll,connect/connecth 会阻塞 ~10s/~15s 有界等待
|
||||
* wpa_state=COMPLETED(bug1),scan 内含 1.5s 触发等待(P3)——客户端 per-command 超时需
|
||||
* 覆盖这些同步等待,其余读级子命令维持 1.5s 不被卡死。 */
|
||||
#define NM_TMO_DFL 1500
|
||||
#define NM_TMO_SCAN 5000
|
||||
#define NM_TMO_CONNECT 12000
|
||||
#define NM_TMO_CONNECTH 17000
|
||||
|
||||
/* 可达性缓存:netmgrd 不可达时每次 connect 都秒回 ECONNREFUSED,无成本;缓存约 1s 防热循环。 */
|
||||
static int g_nm_ok = -1; /* -1 未知 / 0 down / 1 up */
|
||||
static time_t g_nm_ok_ts = 0;
|
||||
@@ -50,7 +58,7 @@ static int nm_r_all(int fd, uint8_t *b, size_t n)
|
||||
return 0;
|
||||
}
|
||||
static int nm_xchg(int fd, uint16_t type, uint32_t req, const void *pl, uint32_t len,
|
||||
uint8_t *rbuf, uint32_t rcap, uint16_t *rtype)
|
||||
uint8_t *rbuf, uint32_t rcap, uint16_t *rtype, int tmo_ms)
|
||||
{
|
||||
uint8_t hdr[MEOW_IPC_HDR_LEN];
|
||||
uint32_t magic = MEOW_IPC_MAGIC, rlen = len;
|
||||
@@ -60,7 +68,7 @@ static int nm_xchg(int fd, uint16_t type, uint32_t req, const void *pl, uint32_t
|
||||
if (nm_w_all(fd, hdr, sizeof hdr) < 0) return -1;
|
||||
if (len && pl && nm_w_all(fd, pl, len) < 0) return -1;
|
||||
struct pollfd pf = { fd, POLLIN, 0 };
|
||||
int pr = poll(&pf, 1, 1500);
|
||||
int pr = poll(&pf, 1, tmo_ms);
|
||||
if (pr <= 0) return -1;
|
||||
uint8_t rhdr[MEOW_IPC_HDR_LEN];
|
||||
if (nm_r_all(fd, rhdr, sizeof rhdr) < 0) return -1;
|
||||
@@ -81,15 +89,16 @@ static int nm_hello(int fd)
|
||||
snprintf(h.app_id, sizeof h.app_id, "%s", "os.meow.launcher");
|
||||
h.version = 1;
|
||||
uint8_t rbuf[256]; uint16_t rtype = 0;
|
||||
if (nm_xchg(fd, MSG_HELLO, 0x100, &h, sizeof h, rbuf, sizeof rbuf, &rtype) < 0 || rtype != MSG_ACK)
|
||||
if (nm_xchg(fd, MSG_HELLO, 0x100, &h, sizeof h, rbuf, sizeof rbuf, &rtype, NM_TMO_DFL) < 0 || rtype != MSG_ACK)
|
||||
return -1;
|
||||
m_ack_t ak; memcpy(&ak, rbuf, sizeof ak);
|
||||
return (ak.code == MEOW_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
/* 发一条 WIFI_CTL/BT_CTL 子命令,收 RESULT。返回 netmgrd 业务 code;NETMGR_UNREACH=不可达。 */
|
||||
/* 发一条 WIFI_CTL/BT_CTL 子命令,收 RESULT。返回 netmgrd 业务 code;NETMGR_UNREACH=不可达。
|
||||
* tmo_ms:读超时(connect/connecth/scan 需覆盖 netmgrd 同步等待,见 NM_TMO_*)。 */
|
||||
static int nm_cmd(uint16_t ctl_type, uint16_t res_type, const char *cmd, const char *arg,
|
||||
char *text, int tlen)
|
||||
char *text, int tlen, int tmo_ms)
|
||||
{
|
||||
m_net_cmd_t q;
|
||||
memset(&q, 0, sizeof q);
|
||||
@@ -100,7 +109,7 @@ static int nm_cmd(uint16_t ctl_type, uint16_t res_type, const char *cmd, const c
|
||||
if (nm_hello(fd) < 0) { close(fd); nm_cache(0); return NETMGR_UNREACH; }
|
||||
uint8_t rbuf[MEOW_IPC_MAX]; uint16_t rtype = 0;
|
||||
memset(rbuf, 0, sizeof rbuf);
|
||||
if (nm_xchg(fd, ctl_type, 0x101, &q, sizeof q, rbuf, sizeof rbuf, &rtype) < 0 || rtype != res_type) {
|
||||
if (nm_xchg(fd, ctl_type, 0x101, &q, sizeof q, rbuf, sizeof rbuf, &rtype, tmo_ms) < 0 || rtype != res_type) {
|
||||
close(fd); nm_cache(0); return NETMGR_UNREACH;
|
||||
}
|
||||
m_net_cmd_result_t res; memcpy(&res, rbuf, sizeof res);
|
||||
@@ -112,11 +121,14 @@ static int nm_cmd(uint16_t ctl_type, uint16_t res_type, const char *cmd, const c
|
||||
return (int)res.code;
|
||||
}
|
||||
|
||||
int netmgr_wifi_tmo(const char *cmd, const char *arg, char *text, int tlen, int tmo_ms)
|
||||
{ return nm_cmd(MSG_NET_WIFI_CTL, MSG_NET_WIFI_RESULT, cmd, arg, text, tlen, tmo_ms); }
|
||||
|
||||
int netmgr_wifi(const char *cmd, const char *arg, char *text, int tlen)
|
||||
{ return nm_cmd(MSG_NET_WIFI_CTL, MSG_NET_WIFI_RESULT, cmd, arg, text, tlen); }
|
||||
{ return netmgr_wifi_tmo(cmd, arg, text, tlen, NM_TMO_DFL); }
|
||||
|
||||
int netmgr_bt(const char *cmd, const char *arg, char *text, int tlen)
|
||||
{ return nm_cmd(MSG_NET_BT_CTL, MSG_NET_BT_RESULT, cmd, arg, text, tlen); }
|
||||
{ return nm_cmd(MSG_NET_BT_CTL, MSG_NET_BT_RESULT, cmd, arg, text, tlen, NM_TMO_DFL); }
|
||||
|
||||
int netmgr_ok(void)
|
||||
{
|
||||
@@ -361,7 +373,7 @@ int nm_wifi_saved(meow_net_t *out, int max)
|
||||
int nm_wifi_scan(meow_net_t *out, int max)
|
||||
{
|
||||
char text[MEOW_IPC_MAX - 32];
|
||||
int rc = netmgr_wifi("scan", NULL, text, sizeof text); /* netmgrd 内含触发+有界等待+读结果 */
|
||||
int rc = netmgr_wifi_tmo("scan", NULL, text, sizeof text, NM_TMO_SCAN); /* netmgrd 内含触发+有界等待+读结果 */
|
||||
if (rc == NETMGR_UNREACH) return net_wifi_scan(out, max);
|
||||
if (rc != MEOW_OK) return 0;
|
||||
return nm_parse_scan(text, out, max);
|
||||
@@ -374,49 +386,133 @@ void nm_wifi_scan_trigger(void)
|
||||
if (!netmgr_ok()) net_wifi_scan_trigger();
|
||||
}
|
||||
|
||||
/* —— 直连回退:wpa_cli add/set/enable/select 新网络(复刻 netmgrd wifi_connect 逻辑)—— */
|
||||
static int nm_direct_connect(const char *ssid, const char *psk, char *err, int elen)
|
||||
/* —— 直连回退:与 netmgrd wifi_connect/connecth 对齐(bug1/bug2/bug4)。
|
||||
* 匹配既有(\xNN 还原同表示)→ 新建或(命中且带新 psk)更新凭据 → hidden 补 scan_ssid=1 →
|
||||
* enable+select → 有界等待 wpa_state=COMPLETED → 成功 enable_network all + save_config(校验重试);
|
||||
* 失败时本次新建的网络回收,报文明示原因。仅在 netmgrd 不可达时走此路径。 */
|
||||
static const char NM_WPA_PREFIX[] = "PATH=/bin:/sbin:/usr/bin:/usr/sbin wpa_cli -i wlan0";
|
||||
|
||||
static int nm_direct_wpa(char *out, int cap, const char *args, int tmo)
|
||||
{
|
||||
const char *wpa = "PATH=/bin:/sbin:/usr/bin:/usr/sbin wpa_cli -i wlan0";
|
||||
char cmd[256];
|
||||
snprintf(cmd, sizeof cmd, "%s add_network 2>/dev/null", wpa);
|
||||
char *o = popen_read_tmo(1200, cmd);
|
||||
int id = o ? atoi(o) : -1;
|
||||
if (o) free(o);
|
||||
if (id < 0) { if (err) snprintf(err, elen, "add_network 无 id"); return MEOW_ERR_INVAL; }
|
||||
{
|
||||
char *r;
|
||||
snprintf(cmd, sizeof cmd, "%s set_network %d ssid '\"%s\"' 2>/dev/null", wpa, id, ssid);
|
||||
if ((r = popen_read_tmo(1200, cmd))) free(r);
|
||||
if (psk && psk[0]) {
|
||||
snprintf(cmd, sizeof cmd, "%s set_network %d psk '\"%s\"' 2>/dev/null", wpa, id, psk);
|
||||
if ((r = popen_read_tmo(1200, cmd))) free(r);
|
||||
} else {
|
||||
snprintf(cmd, sizeof cmd, "%s set_network %d key_mgmt NONE 2>/dev/null", wpa, id);
|
||||
if ((r = popen_read_tmo(1200, cmd))) free(r);
|
||||
char cmd[384];
|
||||
snprintf(cmd, sizeof cmd, "%s %s 2>/dev/null", NM_WPA_PREFIX, args);
|
||||
char *o = popen_read_tmo(tmo, cmd);
|
||||
if (!o) { out[0] = 0; return -1; }
|
||||
int l = (int)strlen(o);
|
||||
if (l >= cap) l = cap - 1;
|
||||
memcpy(out, o, (size_t)l); out[l] = 0;
|
||||
free(o);
|
||||
return l;
|
||||
}
|
||||
|
||||
static int nm_direct_save_config(void)
|
||||
{
|
||||
char out[128];
|
||||
if (nm_direct_wpa(out, sizeof out, "save_config", 1500) > 0 && strstr(out, "OK")) return 1;
|
||||
nm_direct_wpa(out, sizeof out, "set update_config 1", 1500);
|
||||
if (nm_direct_wpa(out, sizeof out, "save_config", 1500) > 0 && strstr(out, "OK")) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nm_direct_connect_ex(const char *ssid, const char *psk, int hidden, char *err, int elen)
|
||||
{
|
||||
char out[1024]; char args[256];
|
||||
int id = -1;
|
||||
if (nm_direct_wpa(out, sizeof out, "list_networks", 1500) > 0) {
|
||||
char *ln = strtok(out, "\n");
|
||||
while (ln) {
|
||||
char *tab0 = strchr(ln, '\t');
|
||||
if (tab0) {
|
||||
int this_id = atoi(ln);
|
||||
char *ss = tab0 + 1;
|
||||
char *tab1 = strchr(ss, '\t');
|
||||
if (tab1) *tab1 = 0;
|
||||
char clean[128], unesc[160], norm[128];
|
||||
size_t cl = strlen(ss);
|
||||
if (cl >= 2 && ss[0] == '"' && ss[cl - 1] == '"') {
|
||||
memcpy(clean, ss + 1, cl - 2); clean[cl - 2] = 0;
|
||||
} else {
|
||||
snprintf(clean, sizeof clean, "%s", ss);
|
||||
}
|
||||
nm_decode_ssid(clean, unesc, sizeof unesc);
|
||||
char *p = unesc; while (*p == ' ' || *p == '\t') p++;
|
||||
snprintf(norm, sizeof norm, "%s", p);
|
||||
size_t nl = strlen(norm);
|
||||
while (nl > 0 && (norm[nl - 1] == ' ' || norm[nl - 1] == '\t')) norm[--nl] = 0;
|
||||
if (strcmp(norm, ssid) == 0) { id = this_id; break; }
|
||||
}
|
||||
ln = strtok(NULL, "\n");
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s enable_network %d 2>/dev/null", wpa, id);
|
||||
if ((r = popen_read_tmo(1200, cmd))) free(r);
|
||||
snprintf(cmd, sizeof cmd, "%s select_network %d 2>/dev/null", wpa, id);
|
||||
if ((r = popen_read_tmo(1200, cmd))) free(r);
|
||||
}
|
||||
if (err) snprintf(err, elen, "connect: ssid=%s network_id=%d", ssid, id);
|
||||
logmsg("netmgr_ipc: [direct-fallback] wifi connect ssid=%s id=%d", ssid, id);
|
||||
int created = 0;
|
||||
if (id < 0) {
|
||||
if (nm_direct_wpa(out, sizeof out, "add_network", 1500) <= 0) {
|
||||
if (err) snprintf(err, elen, "add_network 无 id");
|
||||
return MEOW_ERR_INVAL;
|
||||
}
|
||||
id = atoi(out);
|
||||
if (id < 0) { if (err) snprintf(err, elen, "add_network 无 id"); return MEOW_ERR_INVAL; }
|
||||
created = 1;
|
||||
snprintf(args, sizeof args, "set_network %d ssid '\"%s\"'", id, ssid);
|
||||
nm_direct_wpa(out, sizeof out, args, 1500);
|
||||
if (psk && psk[0]) { snprintf(args, sizeof args, "set_network %d psk '\"%s\"'", id, psk); nm_direct_wpa(out, sizeof out, args, 1500); }
|
||||
else { snprintf(args, sizeof args, "set_network %d key_mgmt NONE", id); nm_direct_wpa(out, sizeof out, args, 1500); }
|
||||
} else if (psk && psk[0]) {
|
||||
snprintf(args, sizeof args, "set_network %d psk '\"%s\"'", id, psk);
|
||||
nm_direct_wpa(out, sizeof out, args, 1500);
|
||||
}
|
||||
if (hidden) { snprintf(args, sizeof args, "set_network %d scan_ssid 1", id); nm_direct_wpa(out, sizeof out, args, 1500); }
|
||||
snprintf(args, sizeof args, "enable_network %d", id); nm_direct_wpa(out, sizeof out, args, 1500);
|
||||
snprintf(args, sizeof args, "select_network %d", id); nm_direct_wpa(out, sizeof out, args, 1500);
|
||||
|
||||
int wait_ms = hidden ? 15000 : 10000;
|
||||
int waited = 0, ok = 0; char ip[40] = "";
|
||||
for (;;) {
|
||||
char st[512];
|
||||
if (nm_direct_wpa(st, sizeof st, "status", 1500) > 0) {
|
||||
char *ws = strstr(st, "wpa_state=");
|
||||
if (ws && !strncmp(ws + 10, "COMPLETED", 9)) {
|
||||
ok = 1;
|
||||
char *ib = strstr(st, "ip_address=");
|
||||
if (ib) { ib += 11; char *ie = ib; while (*ie && *ie != '\n' && *ie != '\r') ie++;
|
||||
int il = (int)(ie - ib); if (il >= (int)sizeof ip) il = (int)sizeof ip - 1;
|
||||
memcpy(ip, ib, (size_t)il); ip[il] = 0; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (waited >= wait_ms) break;
|
||||
usleep(200000);
|
||||
waited += 200;
|
||||
}
|
||||
if (!ok) {
|
||||
if (created) { snprintf(args, sizeof args, "remove_network %d", id); nm_direct_wpa(out, sizeof out, args, 1500); nm_direct_save_config(); }
|
||||
if (err) snprintf(err, elen, "连接失败:密码错误或信号不佳(超时未关联)");
|
||||
logmsg("netmgr_ipc: [direct-fallback] wifi connect ssid=%s hidden=%d id=%d timeout", ssid, hidden, id);
|
||||
return MEOW_ERR_NODEV;
|
||||
}
|
||||
nm_direct_wpa(out, sizeof out, "enable_network all", 1500);
|
||||
int persisted = nm_direct_save_config();
|
||||
if (err) snprintf(err, elen, "已连接:%s ip=%s%s", ssid, ip[0] ? ip : "-", persisted ? "" : "(记录未持久化)");
|
||||
logmsg("netmgr_ipc: [direct-fallback] wifi connect ssid=%s hidden=%d id=%d ip=%s", ssid, hidden, id, ip[0] ? ip : "-");
|
||||
return MEOW_OK;
|
||||
}
|
||||
|
||||
int nm_wifi_connect(const char *ssid, const char *psk, char *err, int elen)
|
||||
int nm_wifi_connect_ex(const char *ssid, const char *psk, int hidden, char *err, int elen)
|
||||
{
|
||||
if (!ssid || !ssid[0]) { if (err) snprintf(err, elen, "ssid 缺失"); return MEOW_ERR_INVAL; }
|
||||
char arg[132];
|
||||
snprintf(arg, sizeof arg, "%s,%s", ssid, psk ? psk : ""); /* connect 带空 psk → netmgrd 复用既有网络 */
|
||||
snprintf(arg, sizeof arg, "%s,%s", ssid, psk ? psk : ""); /* 带空 psk → netmgrd 复用既有网络 */
|
||||
char text[192];
|
||||
int rc = netmgr_wifi("connect", arg, text, sizeof text);
|
||||
if (rc == NETMGR_UNREACH) return nm_direct_connect(ssid, psk, err, elen);
|
||||
int rc = netmgr_wifi_tmo(hidden ? "connecth" : "connect", arg, text, sizeof text,
|
||||
hidden ? NM_TMO_CONNECTH : NM_TMO_CONNECT);
|
||||
if (rc == NETMGR_UNREACH) return nm_direct_connect_ex(ssid, psk, hidden, err, elen);
|
||||
if (err && elen > 0) snprintf(err, elen, "%s", text);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int nm_wifi_connect(const char *ssid, const char *psk, char *err, int elen)
|
||||
{ return nm_wifi_connect_ex(ssid, psk, 0, err, elen); }
|
||||
|
||||
int nm_wifi_disconnect(char *err, int elen)
|
||||
{
|
||||
char text[128];
|
||||
|
||||
Reference in new issue
Block a user