제4장 논리 프레임 구조

4.1 프레임의 구성

Logical_Frame(논리 프레임)은 DTP의 애플리케이션 계층 프레임 구조로, 두 부분으로 구성된다:

┌─────────────────────────────────────────┐
│              Logical_Frame               │
├─────────────────────────────────────────┤
│  Header(프레임 헤더)                      │
│  ┌─────────────────────────────────────┐│
│  │ protocolVersion   프로토콜 버전 번호  ││
│  │ frameType         프레임 유형 식별자  ││
│  │ fragmentId        Fragment 고유 식별자││
│  │ agreementId       약정 ID(압축 가능) ││
│  │ originTimestamp   원본 타임스탬프     ││
│  │ dagDependencies   DAG 의존 목록      ││
│  │ encryptionMetadata 암호화 메타데이터  ││
│  │ sequenceNumber    시퀀스 번호        ││
│  └─────────────────────────────────────┘│
├─────────────────────────────────────────┤
│  Payload(페이로드)                        │
│  ┌─────────────────────────────────────┐│
│  │ 암호화된 실제 데이터 내용              ││
│  └─────────────────────────────────────┘│
└─────────────────────────────────────────┘

핵심 설계 결정:

  • 프레임 헤더의 암호화 메타데이터 자체는 암호화하지 않으며, 수신측이 복호화 방식을 결정할 수 있도록 함
  • Logical_Frame은 단말→Fay와 Fay→단말 양방향에서 동일한 프레임 구조 정의를 사용
  • 물리적 전송에서 분할이 필요한 경우, 분할 작업은 하위 Transport_Adapter에 위임하며 Logical_Frame은 완전성을 유지

4.2 프레임 유형

DTP는 네 가지 프레임 유형을 정의한다:

프레임 유형식별자용도
데이터 프레임data실제 Fragment 데이터를 전달
요청 프레임request데이터 요청 발행 또는 전송 약정 조정
응답 프레임response데이터 요청에 회신하며, 수락, 거부 또는 협상 결과를 포함
제어 프레임control오류 알림, 약정 종료 등 제어 정보를 전달

4.3 프레임 헤더 필드 상세

프로토콜 버전 번호(protocolVersion)

{ major: number, minor: number }

현재 프레임이 사용하는 프로토콜 버전을 식별한다. 수신측은 이를 기반으로 호환 여부를 판단한다.

프레임 유형 식별자(frameType)

프레임의 유형을 식별하며, 페이로드의 파싱 방식을 결정한다.

Fragment 고유 식별자(fragmentId)

전역 고유 UUID v4 식별자로, DAG에서 참조 및 추적에 사용된다.

약정 ID(agreementId)

해당 Fragment가 소속된 약정을 식별한다. 압축 전송을 지원한다: 연속된 Fragment가 동일 약정에 속할 때, 해당 배치의 첫 번째 Fragment 헤더에만 완전한 Agreement_ID를 포함하고, 이후 Fragment는 생략(null로 설정)할 수 있다.

수신측 규칙:

  • Agreement_ID가 포함되지 않은 Fragment를 수신하면, 현재 컨텍스트에서 가장 최근에 선언된 Agreement_ID에 연결
  • 알 수 없는 Agreement_ID를 참조하는 Fragment를 수신하면, 해당 Fragment를 폐기하고 "약정 없음" 오류 알림 전송

원본 타임스탬프(originTimestamp)

데이터가 소스에서 실제 생성된 시점으로, UTC 시간대와 밀리초 정밀도를 사용한다. 전송 타임스탬프와 분리 저장되어 전송 지연의 영향을 받지 않는다.

예시: 사용자가 지하철에서 오프라인으로 30분간 심박수 데이터를 기록하고, 역을 나온 후 일괄 업로드할 때 — 각 기록은 업로드 시점이 아닌 실제 측정 시점의 타임스탬프를 보존한다.

DAG 의존 목록(dagDependencies)

다른 Fragment와의 의존 관계를 선언하며, 각 의존은 다음을 포함한다:

  • 대상 Fragment_ID
  • 관계 유형(derived_from / annotates / supersedes)

0개 이상의 의존 관계를 선언할 수 있다.

암호화 메타데이터(encryptionMetadata)

{ algorithm: string, keyVersion: number }
  • algorithm: 암호화 알고리즘 식별자(예: "AES-256-GCM")
  • keyVersion: 키 버전 번호

암호화 메타데이터 자체는 암호화하지 않으며, 수신측이 복호화 전에 복호화 매개변수를 알 수 있도록 한다.

시퀀스 번호(sequenceNumber)

전송 시퀀스 번호로, 단일 세션 내에서 단조 증가하며 재전송 메커니즘에 사용된다. 각 전송 방향은 독립적인 시퀀스 번호 공간을 유지한다.

4.4 직렬화와 역직렬화

DTP_Engine은 Logical_Frame 객체를 바이너리 형식으로 직렬화하여 전송하고, 수신측은 바이너리 데이터를 Logical_Frame 객체로 역직렬화한다.

핵심 보장 — 왕복 일관성: 임의의 유효한 Logical_Frame 객체에 대해, 직렬화 후 역직렬화하면 원본 객체와 동등한 Logical_Frame을 생성해야 한다.

DTP_Engine은 또한 포맷 출력 기능(Pretty Printer)을 제공하여, Logical_Frame 객체를 사람이 읽을 수 있는 텍스트 형식으로 변환하며 디버깅과 로그 기록에 활용된다.

4.5 컨텍스트 메타데이터

각 Fragment는 구조화된 컨텍스트 메타데이터(ContextMetadata)를 포함하며, 다음을 포함한다:

  • 데이터 유형 식별자(dataType): 데이터의 유형을 설명
  • 데이터 출처(source): 하드웨어 출처와 소프트웨어 출처를 구분
  • 사용자 정의 필드(customFields): 확장 가능한 키-값 쌍 구조

하드웨어 출처

데이터가 하드웨어 센서에서 발생한 경우, 메타데이터는 다음을 포함한다:

  • 센서 유형(sensorType)
  • 센서 정밀도(precision)
  • 샘플링 레이트(samplingRate, 단위 Hz)

소프트웨어 출처

데이터가 소프트웨어 공유에서 발생한 경우, 메타데이터는 다음을 포함한다:

  • 출처 애플리케이션 식별자(appIdentifier)
  • 공유 방식 설명(sharingMethod)