- Firmware: rewrite obu-firmware TX loop to be serial-driven (no on-chip timer), add promiscuous RX + GeoNetworking/BTP unwrap (gn_unwrap.c), add binary UART framing to the phone (serial_link.c/.h). Drop local cam_encode() - CAM is now built on the phone. - Kotlin: byte-exact UPER CAM encoder/decoder ported from cam.c (BitWriter/BitReader/CamUperCodec), matching SerialFrame codec, real UsbSerialTransport (usb-serial-for-android), CamTransmitLoop (1Hz base rate, event/geofence boost, ESP32-C5-only), wired into CamUseCaseRepository for RX and TripRecordingService for TX. - Add V2X message retention: persist all CAM (own+remote) to Room while recording, drop otherwise (DB v2 -> v3 migration). - Add jitpack repo + usb-serial-for-android dependency. Fixes: UsbSerialTransport now uses SerialInputOutputManager.start()/stop() (this lib version manages its own thread internally) instead of manual Runnable/Thread submission, which didn't compile.
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
|