Bluetooth로 오프라인 화면 설정하기
네트워크에 연결되기 전에도 휴대전화로 Raspberry Pi 사이니지 플레이어를 설정할 수 있도록 Go로 작성한 BLE GATT 서버입니다.
내 역할: 작업 주도. 62개 커밋 중 55개를 작성하고 프로젝트를 유지보수했으며, 팀의 풀 리퀘스트 5개를 모두 리뷰했습니다.
2023년 6월부터 10월까지
- Go
- Raspberry Pi
- BLE GATT
- ARM cross-compilation
네트워크가 없는 상태에서 시작하기
기술자가 화면을 설치할 때는 먼저 로컬 네트워크에 연결해야 합니다. 하지만 Raspberry Pi 플레이어에는 키보드나 설정 페이지가 없습니다. 지금 설정하려는 것이 바로 네트워크이기 때문에, 네트워크를 통해 설정을 받을 수도 없습니다.
그 시점에 사용할 수 있는 연결 수단은 Bluetooth Low Energy뿐이어서, 초기 설정은 기술자의 휴대전화에서 보냅니다.
제가 만든 것
Raspberry Pi 플레이어에서 직접 실행되고 “DoohYouLike Screen”이라는 이름으로 자신을 알리는 BLE GATT 서버를 Go로 만들었습니다. 서비스 5개와 특성 8개가 있으며 모두 비밀번호로 보호됩니다. 기술자는 휴대전화에서 주변 Wi-Fi 네트워크를 검색하고, 접속 정보를 보내고, 현재 설정을 읽고, 네트워크 진단을 실행하고, 플레이어를 재시작하거나 소프트웨어 업데이트를 시작할 수 있습니다.
Wi-Fi 검색은 계획대로 되지 않았습니다. 사용 가능한 Go 라이브러리가 대상 하드웨어에서 동작하지 않아 결국 iwlist를 호출하고 출력을 파싱했습니다. 처음 원했던 구현은 아니었지만, 실제 기기에서는 안정적으로 동작했습니다.
BLE의 한계 안에서 작업하기
약 20바이트 크기의 패킷. SSID와 비밀번호는 사용할 수 있는 BLE MTU 안에 들어가지 않고, 전체 네트워크 검색 결과는 훨씬 큽니다. 그래서 단일 바이트 연산 코드, 길이가 앞에 붙는 문자열, 분할 전송, 0xFF 구분자로 재조립하는 작은 프로토콜을 GATT 위에 만들었습니다. 수신 측은 결과를 사용하기 전에 모든 조각이 올바른 순서로 도착했는지 확인합니다.
동시에 연결된 여러 휴대전화. 두 기술자가 연결했거나, 한 휴대전화에 이전 백그라운드 연결이 남아 있을 수 있습니다. 알림은 뮤텍스로 보호하는 맵에 저장된 기기별 채널로 보내므로, 두 고루틴이 같은 연결 상태에 동시에 쓰지 않습니다.
동시 소프트웨어 업데이트. 업데이트 명령은 동시에 두 번 실행할 수 없는 작업입니다. 이미 업데이트가 진행 중일 때 두 번째 요청이 아무 일도 하지 않도록 재진입 잠금을 추가했습니다. 매장 안에 설치된 Pi에서 업데이트가 일부만 적용되면 보통 기술자가 다시 방문해야 합니다.
실제 화면에 배포하기
개발 환경에서 ARM Linux용으로 교차 컴파일하고, 스크립트로 scp를 사용해 바이너리를 보내고, Wi-Fi 접속 정보가 로그에 남지 않도록 하는 배포 작업도 맡았습니다.
프로젝트 중 팀의 다른 구성원들이 풀 리퀘스트 5개를 열었고, 저는 모두 리뷰하고 병합했습니다.
수치로 보면
첫 커밋부터 출시까지 4개월이 걸렸습니다. 전체 62개 커밋 중 55개를 제가 작성했고, 최종 서버에는 5개 GATT 서비스와 8개 특성에 걸쳐 약 850줄의 운영용 Go 코드가 있습니다.
연락하기
원격 프리랜서 업무가 가능합니다. 이메일로 연락해 주시면 가장 빠르게 답변할 수 있습니다.