40 lines
2.3 KiB
C
40 lines
2.3 KiB
C
#ifndef GN_UNWRAP_H
|
|||
|
|
#define GN_UNWRAP_H
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <stddef.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
|
||
|
|
// Inverse of geonet_wrap_shb() + dot11p_build_frame(): takes a raw 802.11 frame as delivered by
|
||
|
|
// the WiFi driver's promiscuous RX callback and strips 802.11 header -> LLC/SNAP -> GeoNetworking
|
||
|
|
// Basic/Common/extended header -> BTP-B header, leaving just the ITS payload (CAM UPER bytes)
|
||
|
|
// and the sender's station id (GN_ADDR MID).
|
||
|
|
//
|
||
|
|
// Deliberately narrow, matching what this project actually transmits: only handles the
|
||
|
|
// Single-Hop-Broadcast (TSB, HeaderType=5/Subtype=0) extended header shape, same as
|
||
|
|
// geonet_wrap_shb() builds - the same "best-tested decode path" rationale documented there.
|
||
|
|
// A real receiver would also need GeoBroadcast (HeaderType=4, used by DENM dissemination in
|
||
|
|
// real deployments) and possibly Beacon/GeoUnicast - out of scope for now since nothing this
|
||
|
|
// project talks to sends those. Extend header_type handling here if that changes.
|
||
|
|
//
|
||
|
|
// Only accepts BTP-B destination port 2001 (CAM, per ETSI TS 103 248) - other ports (e.g. 2002
|
||
|
|
// DENM) are silently rejected since the phone-side decoder only understands CAM right now.
|
||
|
|
//
|
||
|
|
// Returns true and fills *out_cam / *out_cam_len (pointing INTO the input frame buffer, not a
|
||
|
|
// copy - valid only as long as `frame` is) if this was a well-formed, CAM-carrying SHB frame
|
||
|
|
// this project can decode. Returns false otherwise (wrong ethertype, wrong header type, wrong
|
||
|
|
// BTP port, truncated, or FCS/promiscuous-capture garbage - all common and expected on an
|
||
|
|
// open-air capture, not logged as errors by the caller).
|
||
|
|
//
|
||
|
|
// No station id is extracted here on purpose: CAM's own ItsPduHeader.stationID (the first real
|
||
|
|
// field inside the UPER payload this function hands back, per cam.c) is already the meaningful
|
||
|
|
// application-level identifier - the Kotlin-side decoder reads it from there. The GN_ADDR MID
|
||
|
|
// this frame also carries is a separate, link-layer-only pseudonym; extracting and forwarding
|
||
|
|
// it too would just be a second, easily-confused "station id" for no benefit here.
|
||
|
|
//
|
||
|
|
// RSSI is NOT extracted here either - it comes from the promiscuous callback's own packet
|
||
|
|
// metadata (wifi_pkt_rx_ctrl_t.rssi in main.c), not from anything inside the frame bytes.
|
||
|
|
bool gn_unwrap_cam(const uint8_t *frame, int frame_len,
|
||
|
|
const uint8_t **out_cam, int *out_cam_len);
|
||
|
|
|
||
|
|
#endif
|