AirPlay 投屏设备发现稳定性:mDNS 缓存一致性问题定位与修复

背景 APlayReceiver 是 APlay 项目里的 Linux AirPlay/RAOP 接收端。Apple 设备发现 AirPlay 接收端依赖 Bonjour,也就是 mDNS + DNS-SD。 这次问题的现象是: 昨天 Apple 设备可以发现 APlayReceiver。 晚上设备自动休眠,没有关机,第二天 Apple 设备的投屏设备列表找不到 APlayReceiver。 重启 Apple 设备后,又可以发现 AP…

Wireshark 分析 AirPlay 投屏

背景 在调试 AirPlay 投屏接收端时,最容易遇到一个反直觉现象:接收端日志里明明已经收到了 SETUP、RECORD、SET_PARAMETER 等 RTSP 请求,但 Wireshark 里使用下面的``rtsp`显示过滤器却是空的: 这很容易让人怀疑: 是不是根本没有抓到 RTSP? 是不是 AirPlay 使用的不是标准 RTSP? 日志中为什么会有多次SETUP请求? 本文基于一次实际 AirPlay 投屏抓包,整理一…

给不能上外网的编译服务器配置 Codex:让 AI 写代码、修 bug

很多公司的编译服务器都不能直接上外网。这很常见:服务器在机房、实验室、内网环境里,能访问代码仓库和构建依赖,但不能直接访问 OpenAI、GitHub、npm、pip 等外部服务。现在多了一个新需求:我们想在这台服务器上跑 Codex,让 AI 直接读代码、改代码、修 bug。 一开始我也尝试过另一种办法:把服务器上的 Android 源码通过 Samba 挂载到本地电脑,然后在本地电脑运行 Codex。这个思路看起来简单,因为本地电脑…

Android DTBO Overlay:远场语音多麦克风多功放动态配置实践

在 Android TV 项目中,同一套系统源码经常要适配多个硬件 BOM。屏、背光、按键、音频通道、麦克风和功放数量等都可能不同。本文以Amlogic T966D5 项目里的远场语音麦克风配置为例,讲清楚如何用 DTBO overlay 在不改基础 DTS 的情况下,生成两套可烧录的设备树 overlay 镜像: 4mic_3amp_10ch_dtbo.img:四麦、三功放、10 通道配置 2mic_2amp_6ch_dtbo.im…

AirPlay mDNS 双栈发现:A 和 AAAA 到底该怎么发

背景 在把 UxPlay 的 DNS-SD/Avahi 依赖替换为内置 mDNS responder 时,PR review 里出现了一个很典型的双栈问题: 使用内置 mdnsd 时,AirPlay 客户端会先建立一个 IPv4 TCP 连接,然后很快又建立一个 IPv6 TCP 连接,前一个 IPv4 连接被替换;使用 Avahi 时,只看到 IPv6 连接。 问题背景来自 UxPlay PR: https://github.c…

一次 Android NDK 链接失败:让 CMake 正确传递 object library 对象文件

一、问题背景 APlay 的 C++ SDK 通过一层 Android.mk 风格的 CMakeHelper 来组织模块。业务侧不用直接写 add_library()、target_link_libraries(),而是用 LOCAL_MODULE、LOCAL_INTERFACE_LIBRARIES、LOCAL_OBJECT_LIBRARIES 这类变量描述 target 关系。 Android SDK 的 JNI 入口目标是 APla…

APlay 为什么不把 mDNS 拆成独立进程

背景 在 UxPlay 的 PR #523 中,我们用内置的 mDNS responder 替换了 Avahi 依赖。PR 的 reviewer 提出了一个架构建议:是否应该把 mDNS 功能拆成独立进程,让用户自己选择用什么 mDNS 实现(Avahi、mDNSResponder 等)? 这个建议本身很合理——桌面场景下确实可以这样分工。但当目标平台变成 Android、HarmonyOS、RTOS 和裸embedded Linux…

AirPlay mDNS Harness:模拟 AirPlay 设备的技术实现

在 APlay 项目中,mDNS 服务发现是 AirPlay/RAOP 设备被发现的基础。本文介绍的 AirPlay mDNS harness 借助一个轻量的验证框架,无需真实硬件,在单机上完成了 mDNS 协议实现的验证。本文从流程、代码到协议细节,完整解析这个"模拟设备"是如何工作的。 背景:为什么需要模拟设备 APlay 是一个支持 AirPlay/RAOP 协议的服务端实现。AirPlay 设备被发现依赖 mDNS(Multic…

用 Android.mk 的写法组织 CMake:让跨平台 C++ 构建更像填表

一、为什么要再封一层 CMake CMake 很强,但刚开始接触时也很容易写乱。 比如我们想做一件很普通的事:写一个 hello object library,再写一个 basic_hello_world 可执行程序去使用它。原生 CMake 可能会这样写: add_library(hello OBJECT hello/src/hello.cpp) target_include_directories(hello PUBLIC hell…

Harness Engineering 入门指南:让 AI 稳定干活

大模型已经很会写代码了,但真正用起来以后,很多人会遇到一个尴尬问题:它能很快生成一大堆东西,却不一定稳定、可维护、符合项目约定。 第一次看起来很惊艳,第二次开始风格漂移,第三次改坏旧逻辑,第四次你发现自己在给 AI 生成的代码收拾现场。于是效率提升没有想象中那么大,问题从“我写代码慢”变成了“我审 AI 代码很累”。 Harness Engineering 要解决的就是这个问题。 它不是一个新框架,也不是某个插件,而是一种使用 AI A…

xdebug:一个面向跨平台 Native 服务的 TCP 调试入口

很多 Native 服务一旦跑起来,最难处理的不是"有没有日志",而是"我现在能不能在不中断进程的情况下问它几个问题"。 比如一个投屏服务、音视频服务或嵌入式后台任务,现场经常需要临时确认: 当前模块是否还活着。 编码器参数是否按预期生效。 某个状态机卡在哪一步。 是否可以临时触发一次 IDR、刷新、重连或 dump。 日志之外的运行时状态能不能直接读出来。 只靠日志不够。日志是被动输出,调试入口是主动查询。xdebug 的目标就…

一切皆文件,epoll 事件驱动编程与实用技巧

epoll 经常被介绍成"高性能网络 I/O 多路复用接口",这句话没错,但它只讲了最常见的一半用法。 在真实工程里,epoll 更像一个统一的事件入口。网络读写、退出通知、信号处理等事件都可以汇入同一个 wait 点,主线程只需要围绕这个 wait 点做分发,而不必在多个阻塞点和轮询逻辑之间来回切换。 这篇文章会围绕 Linux "一切皆文件" 的设计思想,整理几个 epoll 的实用技巧: 用 socketpair 或 signa…

C++ 崩溃栈回溯:从原理到工具,手把手教你看懂 crash

一、问题背景 C++ 程序线上崩溃时,最常见的日志可能只有一句: Segmentation fault (11) 这句话只告诉我们程序收到了 SIGSEGV,也就是访问了不该访问的内存。但它没有告诉我们: 崩溃发生在哪个函数。 这个函数是谁调用的。 对应源码文件和行号是什么。 线上 release 二进制被 strip 后还能不能还原现场。 crashtrace 这个仓库就是为了解决这个问题:它把 C++ 崩溃栈能力拆成一套小型库、…

AirPlay 投屏设备发现

背景:设备发现到底是什么? AirPlay 设备发现不是"手机去扫局域网里所有 IP",而是通过 mDNS/DNS-SD 完成的。 可以把它理解成局域网里的"小广播查询": Apple 设备向 224.0.0.251:5353 或 IPv6 的 ff02::fb:5353 发 UDP 组播查询。 查询内容是"谁提供 _airplay._tcp.local 服务?"以及"谁提供 _raop._tcp.local 服务?"。 Airpl…

Zephyr LVGL 异常显示问题分析

本文记录一次 Zephyr + LVGL + qemu_riscv64 的问题排查过程。表面现象是图形界面显示异常,最开始很像 ramfb 驱动或者像素格式问题;最终定位下来,根因其实是 main() 线程栈太小,导致 LVGL redraw/flush 路径运行时栈溢出。 目标样例是: zephyr/samples/subsys/display/lvgl 最终修复落在: zephyr/samples/subsys/display…

segfault 问题分析

本文结合过往项目经验,介绍了内存分段管理的起源,总结了一下遇到 segmentation fault 问题时如何调试。 关于段 段的含义 A segment, in the 8086/8088 is a 64kb chunk of memory addressable by any particular value in a segment register. Specifically, there are four segment …

OOM 问题分析

最近在开发一款流媒体后视镜产品,发现触摸设备不响应触控事件,画面冻住不动,串口日志提示 Out of memory。而 release 版本看门狗程序未被注释(进入了编译分支),APP 进程因为 OOM 被 kill,无法及时喂狗,导致系统不断重启。 OOM 的主要场景: 开机 OOM。 视频回放时 OOM。 主要现象: Linux App 进程被 kill,无法喂狗,系统重启。 Out of memory: Kill proce…