← Docs hub

IotAgent·UpdateAgent 상세 — 클라우드 명령과 OTA

기준: 1398d109c391c4044cae26d0e9aea4d3f08d9670. 지정 커밋의 추적 파일을 직접 확인한 정적 구조 분석이며, 현재 HEAD·후속 TaskManager·SKIX 구현을 포함하지 않는다.

IotAgent: MQTT와 기기 계약의 변환

기준 루트 I/는 apps/IotAgent/app/src/main/java/com/sk/airbot/iotagent/다. IotAgent는 MQTT 연결만 담당하지 않는다. topic별 요청을 제품 command로 변환하고 DeviceAgent 결과를 다시 topic별 응답·보고로 변환한다.

구성 책임 근거
IotAgent Service IIotControl Stub, DeviceControlProxy 연결, network·foreground lifecycle I/IotAgent.java:403, :740, :966
AWSIotMqttHandler 연결 손실 이후 재연결 메시지 처리 같은 파일 :295, :1511
mqtt/ CmdTopic·topic enum·요청/응답 DTO·기능별 데이터 계약 I/mqtt/
WifiMonitor / util Wi-Fi 상태·공통 AWS 연결 지원·설정 보조 I/WifiMonitor.java, I/util/
AWS MQTT manager 인증 material을 사용한 connect·subscribe·publish IotAgent :1497 이후; 외부 SDK

클라우드 → 기기

연결 상태가 Connected가 되면 control·comeback·환경 정보 등 카테고리를 구독한다. subscribeToTopic callback에서 byte payload를 JSON으로 읽고 CmdTopic.setCmdTopic(topic, jsonObject)로 넘긴다. 응답 카테고리는 setCmdTopic_Respones, job 알림은 별도 handleJobMessage 경로다. DTO와 topic 분류를 건너뛰고 모든 MQTT 요청이 같은 method로 전달된다고 단순화하지 않는다.

근거: I/IotAgent.java:1497–1560, :1584–1681, :1331–1360, I/mqtt/.

기기 → 클라우드

DeviceControlProxy의 onModuleCallback은 handleModuleCallback()으로 넘긴다. method별로 CmdTopic.callTopic_Request 또는 publish helper를 선택한다. 반대 방향으로 DeviceAgent가 IIotControl.sendModuleCommand를 호출하는 경로도 있으며, IotAgent의 switch가 topic·상태·응답 기능으로 분기한다.

근거: I/IotAgent.java:403–709, :740–842. DeviceControl callback과 IIotControl은 방향과 수신 역할이 다르다.

생명주기·운영 해석

onCreate에서 foreground notification과 Handler·서비스 연결을 준비한다. MQTT 연결 손실 시 지연 재연결을 예약한다. broker 접속, subscription 설정, payload 수신, DeviceAgent dispatch, 장치 완료, 최종 업무 응답은 각각 관찰해야 한다. publish ACK만으로 마지막 단계가 보장되지 않는다.

Android.mk가 선택하는 것은 IotAgent.apk prebuilt다. 이 소스의 구조를 분석한 결과를 실제 설치 APK 동작으로 승격하지 않는다. 인증서·endpoint·키 값은 문서에 복제하지 않았다.

UpdateAgent: service 알림과 실제 엔진 소유자 구분

기준 루트 U/는 apps/UpdateAgent/java/com/sk/airbot/updateagent/다. 서비스 Binder와 Android UpdateEngine을 직접 같은 노드로 묶으면 중간 UI·준비 계층이 빠진다.

구성 책임 근거
UpdateAgent Service IUpdateControl callback 등록, OTAUpdate 수신, Activity에 broadcast U/UpdateAgent.java:62–163
ui/MainActivity UpdateManager 생성, update config 선택·적용, 진행·완료 UI U/ui/MainActivity.java:91, :593, :917
UpdateManager updater 상태, UpdateEngine bind·apply·cancel·reset·suspend/resume·재동기화 U/UpdateManager.java:44–103, :210–358, :422–535
services/PrepareUpdateService payload 적용 전 준비, 결과 전달 U/services/PrepareUpdateService.java
ui/SelectActivity / UpdateConfig 설정 선택·업데이트 입력 구조 U/ui/SelectActivity.java, 관련 config 모델
UpdateEngine 플랫폼 payload 적용 엔진 Android 외부 프레임워크 경계

두 연결선

DeviceAgent → IUpdateControl(OTAUpdate)
→ UpdateAgent.notifyMainActivity → ACTION_OTA_UPDATE broadcast
→ Activity의 알림·진행 UI

MainActivity.applyUpdate(config)
→ UpdateManager.applyUpdate → PrepareUpdateService
→ 준비 callback → UpdateEngine.applyPayload
→ UpdateEngineCallback → UpdateManager 상태·progress·완료 callback
→ MainActivity

첫 번째 Binder 메시지가 언제나 두 번째 payload 실행을 시작한다고 단정하지 않는다. OTAUpdate 분기는 메시지 type·내용을 Activity에 전달한다. 실제 engine 적용은 MainActivity와 UpdateManager 코드를 기준으로 추적해야 한다.

UpdateAgent의 DeviceControlProxy callback은 method를 읽지만 해당 callback에서 곧바로 UpdateEngine을 실행하는 코드는 보이지 않는다. 알림 서비스의 존재와 payload executor의 소유를 구분한다.

상태와 실패 경계

UpdateManager에는 cancel/reset과 엔진 상태 재동기화가 있다. 엔진 payload 완료, slot 전환 요청, 재부팅, 새 버전 부팅 성공은 서로 다른 증거다. 이 분석에서는 다운로드·payload 검증·A/B slot 적용·재부팅 성공을 실기기로 검증하지 않았다.

Android.mk는 소스 BUILD_PACKAGE와 일부 JAR 의존을 선언하고 기존 updater sample override도 가진다. 전체 업데이트 안전성은 제품 OTA 설정·payload·서명·platform UpdateEngine까지 확인해야 한다.

확대 구조도와 연결별 근거

Connections

전체 목차 · 앱 구성 · DeviceAgent 내부 · IPC · 실행 흐름 · 플랫폼·빌드 · 근거·확인 범위

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date