에어갭 환경 파일 전송 아이디어, 32+ Mbps 달성
Had an idea for air-gapped file transfer, got 32+ Mbps
핵심 요약
광학 파일 전송 기술을 개선하여 32Mbps 이상의 속도를 구현한 에어갭 전송 시스템 개발기입니다.
- 광학 전송 시스템 — QR 코드 대신 OFDM 기반의 링 시스템을 설계함
- GPU 가속 활용 — 3계층 CNN을 학습시켜 1.5ms 만에 코드 위치를 탐색함
- 동기화 문제 해결 — Camera2 API의 프레임 지연 제어와 파일럿 신호를 활용함
- 성능 최적화 — ISP 보정 비활성화 및 2:1 멀티플렉싱으로 전송 속도를 극대화함
다들 안녕! 광학 파일 전송 방식을 좀 살펴보다가 Decimen이 생각보다 영 별로라는 걸 알게 됐어. 일단 그 QR 기반 시스템은 종이 출력용으로 설계된 것 같더라고. 종이에서는 잉크 번짐을 막으려고 이진법 디자인이 필수거든. 근데 화면에서는 이진법이 비효율적이야. 휘도를 활용하는 게 훨씬 합리적이지. 논문을 엄청 찾아보다가 결국 이걸 발견했어:
OFDM이 QR 코드에서 논리적으로 한 단계 발전한 방식이라는 걸 알게 됐지. 흑백 QR 코드 대신 실제 신호 처리와 휘도를 사용하니까. 그래서 내 시스템을 FOCUS 기반으로 만들기로 했어. 빠른 디코딩을 위해 CPU가 아니라 GPU를 활용하고 싶었고, 프레임 비동기화 문제도 잘 해결하고 싶었거든. https://vs.inf.ethz.ch/publ/papers/soeroesg-mobisys2016-Focus.pdf
그다음엔 FOCUS의 파인더(원래 파인더는 너무 못생겼고 공간도 엄청 잡아먹더라)를 다 뜯어고쳐서 나만의 콤팩트한 링 디자인을 만들었어. 이 링은 리드 솔로몬 부호로 거대한 링 전체에 약 15비트의 정보를 분산시켜 놨지. GPU로 32,768개의 가능한 코드워드 확률을 브루트 포스로 돌리면 아주 쉽게 디코딩이 가능해. 엄청나게 병렬적인 구조라 아주 깔끔하지.
내가 결정한 링 시스템이야. 보기에도 좋고 효율적이며 밴드에 오류 수정 기능도 많이 들어갔어.
전송 거리와 속도 사이에서 균형을 맞추려고 32, 64, 128, 256 이렇게 4가지 링 사이즈를 만들었어. 처음엔 브라우저 기반으로 가려고 했는데, 웹캠 성능이 진짜 처참하더라고. 설정을 최대로 올려도 700 KB/s밖에 안 나왔어. Decimen보다는 낫지만, 그렇다고 압도적인 수준은 아니었지. 60fps로 올리려니까 위상이 안 맞을 때 1.3 MB/s에서 0 MB/s까지 미친 듯이 널뛰기를 하더라고. 그래서 그냥 안드로이드 네이티브 앱으로 방향을 틀었어. LIZARD는 하나의 포맷일 뿐이고, 디코딩 방식은 디코더가 정하기 나름이니까. 웹 디코더가 좀 약하다고 해서 네이티브 디코더까지 덩달아 구려질 이유는 없잖아.
처음엔 Claude 녀석이 멍청하게 OpenCV 기반 파인더를 Vulkan으로 포팅하려고 하더라. GPU에서 분기문(Branchy work)은 진짜 쓰레기거든. 워프 다이버전스 때문에 렉만 엄청 걸리니까. 근데 나한테는 RTX 4090이 있잖아? 그래서 그냥 AI한테 제너레이터를 만들고 PyTorch를 켜서, 그레이스케일 이미지를 보고 네 귀퉁이를 찾아내는 5만 파라미터짜리 커스텀 AI 파인더를 학습시키라고 시켰어. CPU 기반 OpenCV 파인더로 GPU 학습용 프레임 솔루션을 만들었는데, 폰 카메라 환경을 현실적으로 구현하려고 노이즈랑 원근 왜곡을 엄청나게 섞었지. GPU 버전이 인식 정확도에서 CPU를 이길 때까지 계속 학습시켰어. 몇 시간 뒤에 3계층 CNN 모델이 완성됐는데, GPU에서 1.5ms 만에 코드를 아주 쉽게 찾아내더라.
그다음엔 마지막 골칫거리인 비동기화(desync) 문제가 남았어. 이게 광학 카메라 통신의 최대 난제인데, 수많은 논문이 바코드로 이걸 해결하려고 끙끙대더라고. 근데 안드로이드의 Camera2 API에는 이 문제를 완전히 박살 낼 수 있는 비밀이 하나 있어. 프레임 간의 지연 시간을 제어할 수 있거든. 그래서 신호에 파일럿 신호를 심기로 했어. 4프레임마다 이 4가지 파일럿을 순환시키는 거지.




