151 lines
5.7 KiB
Plaintext
151 lines
5.7 KiB
Plaintext
/*
|
|
* audi_immobiliser.c
|
|
*
|
|
* Created on: Sep 17, 2025
|
|
* Author: herli
|
|
*/
|
|
|
|
#include "audi_immobiliser.h"
|
|
#include "timeouts.h" // for Timeout_StartIfStopped
|
|
|
|
#include <string.h>
|
|
#include <stddef.h>
|
|
#include "can_db_symbols.h" // MSG_ID_SEND2, MSG_ID_EMPF2
|
|
#include "can_manager.h" // can_manager_register_handler_msg, can_manager_rx_address_request
|
|
#include "can_port.h" // can_port_send_msg_def
|
|
|
|
|
|
extern bool can_manager_empf2_has_pending(void);
|
|
extern void can_manager_empf2_clear_pending(void);
|
|
// Option B (simple flag): uncomment if you used a raw flag in your code
|
|
extern volatile uint8_t s_empf2_pending;
|
|
|
|
volatile uint8_t EMPF2_BYTES[8] = {0};
|
|
|
|
/* === Local storage for the four fields (defaults from your spec/trace) === */
|
|
//static char g_mod_index[8] = "000006"; // full value in storage
|
|
static char g_mod_index[8] = "pelele"; // full value in storage
|
|
|
|
//static char g_client_model[16] = "059 130 106L"; // client model
|
|
static char g_client_model[16] = "tonto el que"; // client model
|
|
|
|
//static char g_serial[16] = "686759"; // serial number
|
|
static char g_serial[16] = "lo lea"; // serial number
|
|
|
|
//static char g_sw[24] = "C150_1.V79"; // software version
|
|
static char g_sw[24] = "kkkvcdskk"; // software version
|
|
|
|
//static char g_pin[8] = "389"; // custom pin
|
|
static char g_pin[8] = " si"; // custom pin
|
|
|
|
/* Full ASCII payload built as: "<client_model> <serial> <sw> <pin>" */
|
|
static char g_full_str[40] = {0};
|
|
static uint16_t g_full_len = 0;
|
|
|
|
/* ---- Public setters ---- */
|
|
void audi_immobiliser_set_client_model(const char *ascii) {
|
|
if (ascii) { strncpy(g_client_model, ascii, sizeof(g_client_model)-1); g_client_model[sizeof(g_client_model)-1] = '\0'; }
|
|
}
|
|
void audi_immobiliser_set_serial(const char *ascii) {
|
|
if (ascii) { strncpy(g_serial, ascii, sizeof(g_serial)-1); g_serial[sizeof(g_serial)-1] = '\0'; }
|
|
}
|
|
void audi_immobiliser_set_sw(const char *ascii) {
|
|
if (ascii) { strncpy(g_sw, ascii, sizeof(g_sw)-1); g_sw[sizeof(g_sw)-1] = '\0'; }
|
|
}
|
|
void audi_immobiliser_set_pin(const char *ascii) {
|
|
if (ascii) { strncpy(g_pin, ascii, sizeof(g_pin)-1); g_pin[sizeof(g_pin)-1] = '\0'; }
|
|
}
|
|
|
|
/* Build the concatenated ASCII */
|
|
void audi_immobiliser_init(void)
|
|
{
|
|
size_t off = 0;
|
|
memset(g_full_str, 0, sizeof(g_full_str));
|
|
|
|
// Trim exactly one leading '0' so "000006" -> "00006"
|
|
const char *mod = g_mod_index;
|
|
if (mod[0] == '0' && mod[1] != '\0') mod++;
|
|
|
|
// Concatenate in the correct order, with NO added spaces between tokens
|
|
// (client model already has its spaces inside, e.g., "059 130 106L")
|
|
const char *parts[] = { mod, g_client_model, g_sw, g_serial, g_pin };
|
|
for (int i = 0; i < (int)(sizeof(parts)/sizeof(parts[0])); ++i) {
|
|
size_t plen = strlen(parts[i]);
|
|
if (off + plen >= sizeof(g_full_str)) plen = sizeof(g_full_str) - 1 - off;
|
|
memcpy(&g_full_str[off], parts[i], plen);
|
|
off += plen;
|
|
if (off >= sizeof(g_full_str) - 1) break;
|
|
}
|
|
g_full_len = (uint16_t)off;
|
|
}
|
|
|
|
/* ---- Immobiliser chunking: index A5..AB maps to 6-byte slices ---- */
|
|
static inline int is_immo_index(uint16_t idx) { return (idx >= 0xA5u) && (idx <= 0xABu); }
|
|
|
|
/* Copy 6 bytes from g_full_str starting at (idx - A5)*6; pad with 0x00 if past end */
|
|
static void immo_slice_fill(uint16_t idx, uint8_t out6[6])
|
|
{
|
|
uint16_t start = (uint16_t)((idx - 0xA5u) * 6u);
|
|
for (uint8_t i = 0; i < 6; ++i) {
|
|
uint16_t pos = (uint16_t)(start + i);
|
|
out6[i] = (pos < g_full_len) ? (uint8_t)g_full_str[pos] : 0x00;
|
|
}
|
|
}
|
|
|
|
/* ---- Wrapper handler for 0x502 (MSG_ID_SEND2) ----
|
|
* If payload is immobiliser request: [FF FF] [idx_hi idx_lo] [.. ..] [.. ..]
|
|
* -> we build EMPF2_BYTES = [idx_hi idx_lo d0 d1 d2 d3 d4 d5] and SEND EMPF2 immediately.
|
|
* Else: forward to the normal address→value handler.
|
|
*/
|
|
static void audi_immo_502_wrapper(const CanMessageDef *msg, const uint8_t in[8], CanTxFn tx)
|
|
{
|
|
(void)tx;
|
|
|
|
const uint16_t word0 = (uint16_t)((in[0] << 8) | in[1]); // must be 0xFFFF
|
|
const uint8_t idx_hi = in[2]; // A5..AB
|
|
const uint8_t idx_lo = in[3]; // must be 0x00
|
|
|
|
if (word0 == 0xFFFFu && idx_lo == 0x00u && is_immo_index(idx_hi)) {
|
|
// Build 6-byte slice from the concatenated immobiliser string
|
|
uint8_t slice[6];
|
|
immo_slice_fill(idx_hi, slice);
|
|
|
|
// Fill the common EMPF2 byte buffer (data-only mapping in can_db.c)
|
|
EMPF2_BYTES[0] = idx_hi; // e.g., A5
|
|
EMPF2_BYTES[1] = 0x00;
|
|
EMPF2_BYTES[2] = slice[0];
|
|
EMPF2_BYTES[3] = slice[1];
|
|
EMPF2_BYTES[4] = slice[2];
|
|
EMPF2_BYTES[5] = slice[3];
|
|
EMPF2_BYTES[6] = slice[4];
|
|
EMPF2_BYTES[7] = slice[5];
|
|
|
|
// Mark pending and start the 60 ms window (index 17) ONLY if not already running
|
|
// Use whichever pending API you kept:
|
|
// Option A (helpers):
|
|
// if (!can_manager_empf2_has_pending()) s_empf2_pending = 1; // or use a setter
|
|
// Option B (simple flag):
|
|
s_empf2_pending = 1;
|
|
|
|
Timeout_StartIfStopped(17, (uint16_t)TIM16->CNT);
|
|
|
|
// Do NOT send now; the 60 ms timeout (or your event path when RPM>250)
|
|
// will transmit EMPF2 and clear the pending flag.
|
|
return;
|
|
}
|
|
|
|
// Not immobiliser → fall back to standard 0x502 address→value handling
|
|
can_manager_rx_address_request(msg, in, tx);
|
|
}
|
|
|
|
|
|
void audi_immobiliser_register(void)
|
|
{
|
|
// Ensure we have a built payload
|
|
if (g_full_len == 0) audi_immobiliser_init();
|
|
|
|
// Hook our wrapper to the 0x502 definition (DB remains data-only)
|
|
can_manager_register_handler_msg(&MSG_ID_SEND2, audi_immo_502_wrapper);
|
|
}
|
|
*/
|