UDS: Adding support for Routine ID and Data ID resolution
This commit is contained in:
parent
771872cc7e
commit
9a400118df
|
@ -11,11 +11,15 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <epan/packet.h>
|
#include <epan/packet.h>
|
||||||
|
#include <epan/uat.h>
|
||||||
#include <wsutil/bits_ctz.h>
|
#include <wsutil/bits_ctz.h>
|
||||||
|
|
||||||
void proto_register_uds(void);
|
void proto_register_uds(void);
|
||||||
void proto_reg_handoff_uds(void);
|
void proto_reg_handoff_uds(void);
|
||||||
|
|
||||||
|
#define DATAFILE_UDS_ROUTINE_IDS "UDS_routine_identifiers"
|
||||||
|
#define DATAFILE_UDS_DATA_IDS "UDS_data_identifiers"
|
||||||
|
|
||||||
#define UDS_SERVICES_DSC 0x10
|
#define UDS_SERVICES_DSC 0x10
|
||||||
#define UDS_SERVICES_ER 0x11
|
#define UDS_SERVICES_ER 0x11
|
||||||
#define UDS_SERVICES_CDTCI 0x14
|
#define UDS_SERVICES_CDTCI 0x14
|
||||||
|
@ -376,6 +380,171 @@ static int proto_uds = -1;
|
||||||
|
|
||||||
static dissector_handle_t uds_handle;
|
static dissector_handle_t uds_handle;
|
||||||
|
|
||||||
|
|
||||||
|
/*** Configuration ***/
|
||||||
|
typedef struct _generic_one_id_string {
|
||||||
|
guint id;
|
||||||
|
gchar *name;
|
||||||
|
} generic_one_id_string_t;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
copy_generic_one_id_string_cb(void *n, const void *o, size_t size _U_) {
|
||||||
|
generic_one_id_string_t *new_rec = (generic_one_id_string_t *)n;
|
||||||
|
const generic_one_id_string_t *old_rec = (const generic_one_id_string_t *)o;
|
||||||
|
|
||||||
|
new_rec->name = g_strdup(old_rec->name);
|
||||||
|
new_rec->id = old_rec->id;
|
||||||
|
return new_rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
update_generic_one_identifier_16bit(void *r, char **err) {
|
||||||
|
generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
|
||||||
|
|
||||||
|
if (rec->id > 0xffff) {
|
||||||
|
*err = g_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec->id, rec->name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec->name == NULL || rec->name[0] == 0) {
|
||||||
|
*err = g_strdup("Name cannot be empty");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_generic_one_id_string_cb(void *r) {
|
||||||
|
generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
|
||||||
|
|
||||||
|
/* freeing result of g_strdup */
|
||||||
|
g_free(rec->name);
|
||||||
|
rec->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_update_one_id_string_template_cb(generic_one_id_string_t *data, guint data_num, GHashTable *ht) {
|
||||||
|
guint i;
|
||||||
|
int *key = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < data_num; i++) {
|
||||||
|
key = wmem_new(wmem_epan_scope(), int);
|
||||||
|
*key = data[i].id;
|
||||||
|
|
||||||
|
g_hash_table_insert(ht, key, g_strdup(data[i].name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
generic_lookup_uint16(guint16 id, GHashTable *ht) {
|
||||||
|
guint32 tmp = (guint32)id;
|
||||||
|
|
||||||
|
if (ht == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char *)g_hash_table_lookup(ht, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
simple_free_key(gpointer key) {
|
||||||
|
wmem_free(wmem_epan_scope(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
simple_free(gpointer data) {
|
||||||
|
/* we need to free because of the g_strdup in post_update*/
|
||||||
|
g_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Routine IDs */
|
||||||
|
static generic_one_id_string_t *uds_uat_routine_ids = NULL;
|
||||||
|
static guint uds_uat_routine_id_num = 0;
|
||||||
|
static GHashTable *uds_ht_routine_ids = NULL;
|
||||||
|
|
||||||
|
UAT_HEX_CB_DEF(uds_uat_routine_ids, id, generic_one_id_string_t)
|
||||||
|
UAT_CSTRING_CB_DEF(uds_uat_routine_ids, name, generic_one_id_string_t)
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_update_uds_routine_cb(void) {
|
||||||
|
/* destroy old hash table, if it exists */
|
||||||
|
if (uds_ht_routine_ids) {
|
||||||
|
g_hash_table_destroy(uds_ht_routine_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create new hash table */
|
||||||
|
uds_ht_routine_ids = g_hash_table_new_full(g_int_hash, g_int_equal, &simple_free_key, &simple_free);
|
||||||
|
post_update_one_id_string_template_cb(uds_uat_routine_ids, uds_uat_routine_id_num, uds_ht_routine_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
uds_lookup_routine_name(guint16 id) {
|
||||||
|
return generic_lookup_uint16(id, uds_ht_routine_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
protoitem_append_routine_name(proto_item *ti, guint16 data_identifier) {
|
||||||
|
gchar *routine_name = uds_lookup_routine_name((guint16)data_identifier);
|
||||||
|
if (routine_name != NULL) {
|
||||||
|
proto_item_append_text(ti, " (%s)", routine_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
infocol_append_routine_name(packet_info *pinfo, guint16 routine_identifier) {
|
||||||
|
gchar *routine_name = uds_lookup_routine_name((guint16)routine_identifier);
|
||||||
|
if (routine_name != NULL) {
|
||||||
|
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", routine_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Data IDs */
|
||||||
|
static generic_one_id_string_t *uds_uat_data_ids = NULL;
|
||||||
|
static guint uds_uat_data_id_num = 0;
|
||||||
|
static GHashTable *uds_ht_data_ids = NULL;
|
||||||
|
|
||||||
|
UAT_HEX_CB_DEF(uds_uat_data_ids, id, generic_one_id_string_t)
|
||||||
|
UAT_CSTRING_CB_DEF(uds_uat_data_ids, name, generic_one_id_string_t)
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_update_uds_data_cb(void) {
|
||||||
|
/* destroy old hash table, if it exists */
|
||||||
|
if (uds_ht_data_ids) {
|
||||||
|
g_hash_table_destroy(uds_ht_data_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create new hash table */
|
||||||
|
uds_ht_data_ids = g_hash_table_new_full(g_int_hash, g_int_equal, &simple_free_key, &simple_free);
|
||||||
|
post_update_one_id_string_template_cb(uds_uat_data_ids, uds_uat_data_id_num, uds_ht_data_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
uds_lookup_data_name(guint16 id) {
|
||||||
|
return generic_lookup_uint16(id, uds_ht_data_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
protoitem_append_data_name(proto_item *ti, guint16 data_identifier) {
|
||||||
|
gchar *data_name = uds_lookup_data_name((guint16)data_identifier);
|
||||||
|
if (data_name != NULL) {
|
||||||
|
proto_item_append_text(ti, " (%s)", data_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
infocol_append_data_name(packet_info *pinfo, guint16 data_identifier) {
|
||||||
|
gchar *data_name = uds_lookup_data_name((guint16)data_identifier);
|
||||||
|
if (data_name != NULL) {
|
||||||
|
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", data_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Configuration End ***/
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
guint8 masked_guint8_value(const guint8 value, const guint8 mask)
|
guint8 masked_guint8_value(const guint8 value, const guint8 mask)
|
||||||
{
|
{
|
||||||
|
@ -471,11 +640,16 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
/* Can't know the size of the data for each identifier, Decode like if there is only one idenfifier */
|
/* Can't know the size of the data for each identifier, Decode like if there is only one idenfifier */
|
||||||
guint32 record_length = data_length - UDS_RDBI_DATA_RECORD_OFFSET;
|
guint32 record_length = data_length - UDS_RDBI_DATA_RECORD_OFFSET;
|
||||||
guint32 data_identifier;
|
guint32 data_identifier;
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_rdbi_data_identifier, tvb, UDS_RDBI_DATA_IDENTIFIER_OFFSET,
|
ti = proto_tree_add_item_ret_uint(subtree, hf_uds_rdbi_data_identifier, tvb,
|
||||||
UDS_RDBI_DATA_IDENTIFIER_LEN, ENC_BIG_ENDIAN, &data_identifier);
|
UDS_RDBI_DATA_IDENTIFIER_OFFSET, UDS_RDBI_DATA_IDENTIFIER_LEN,
|
||||||
|
ENC_BIG_ENDIAN, &data_identifier);
|
||||||
|
protoitem_append_data_name(ti, (guint16)data_identifier);
|
||||||
|
|
||||||
proto_tree_add_item(subtree, hf_uds_rdbi_data_record, tvb, UDS_RDBI_DATA_RECORD_OFFSET,
|
proto_tree_add_item(subtree, hf_uds_rdbi_data_record, tvb, UDS_RDBI_DATA_RECORD_OFFSET,
|
||||||
record_length, ENC_NA);
|
record_length, ENC_NA);
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x %s", data_identifier,
|
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", data_identifier);
|
||||||
|
infocol_append_data_name(pinfo, data_identifier);
|
||||||
|
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
|
||||||
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_RDBI_DATA_RECORD_OFFSET,
|
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_RDBI_DATA_RECORD_OFFSET,
|
||||||
record_length, ' '));
|
record_length, ' '));
|
||||||
} else {
|
} else {
|
||||||
|
@ -483,9 +657,12 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
guint32 offset = UDS_RDBI_DATA_IDENTIFIER_OFFSET;
|
guint32 offset = UDS_RDBI_DATA_IDENTIFIER_OFFSET;
|
||||||
while (identifier_length > 0) {
|
while (identifier_length > 0) {
|
||||||
guint32 data_identifier;
|
guint32 data_identifier;
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_rdbi_data_identifier, tvb, offset,
|
ti = proto_tree_add_item_ret_uint(subtree, hf_uds_rdbi_data_identifier, tvb, offset,
|
||||||
UDS_RDBI_DATA_IDENTIFIER_LEN, ENC_BIG_ENDIAN, &data_identifier);
|
UDS_RDBI_DATA_IDENTIFIER_LEN, ENC_BIG_ENDIAN, &data_identifier);
|
||||||
|
protoitem_append_data_name(ti, (guint16)data_identifier);
|
||||||
|
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", data_identifier);
|
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", data_identifier);
|
||||||
|
infocol_append_data_name(pinfo, data_identifier);
|
||||||
offset += UDS_RDBI_DATA_IDENTIFIER_LEN;
|
offset += UDS_RDBI_DATA_IDENTIFIER_LEN;
|
||||||
identifier_length -= UDS_RDBI_DATA_IDENTIFIER_LEN;
|
identifier_length -= UDS_RDBI_DATA_IDENTIFIER_LEN;
|
||||||
}
|
}
|
||||||
|
@ -520,15 +697,20 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
|
|
||||||
case UDS_SERVICES_WDBI:
|
case UDS_SERVICES_WDBI:
|
||||||
subtree = proto_tree_add_subtree(uds_tree, tvb, 0, -1, ett_uds_wdbi, NULL, service_name);
|
subtree = proto_tree_add_subtree(uds_tree, tvb, 0, -1, ett_uds_wdbi, NULL, service_name);
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_wdbi_data_identifier, tvb, UDS_WDBI_DATA_IDENTIFIER_OFFSET,
|
ti = proto_tree_add_item_ret_uint(subtree, hf_uds_wdbi_data_identifier, tvb,
|
||||||
UDS_WDBI_DATA_IDENTIFIER_LEN, ENC_BIG_ENDIAN, &enum_val);
|
UDS_WDBI_DATA_IDENTIFIER_OFFSET, UDS_WDBI_DATA_IDENTIFIER_LEN,
|
||||||
|
ENC_BIG_ENDIAN, &enum_val);
|
||||||
|
protoitem_append_data_name(ti, (guint16)enum_val);
|
||||||
if (sid & UDS_REPLY_MASK) {
|
if (sid & UDS_REPLY_MASK) {
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", enum_val);
|
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", enum_val);
|
||||||
|
infocol_append_data_name(pinfo, enum_val);
|
||||||
} else {
|
} else {
|
||||||
guint32 record_length = data_length - UDS_WDBI_DATA_RECORD_OFFSET;
|
guint32 record_length = data_length - UDS_WDBI_DATA_RECORD_OFFSET;
|
||||||
proto_tree_add_item(subtree, hf_uds_wdbi_data_record, tvb, UDS_WDBI_DATA_RECORD_OFFSET,
|
proto_tree_add_item(subtree, hf_uds_wdbi_data_record, tvb, UDS_WDBI_DATA_RECORD_OFFSET,
|
||||||
record_length, ENC_NA);
|
record_length, ENC_NA);
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x %s", enum_val,
|
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", enum_val);
|
||||||
|
infocol_append_data_name(pinfo, enum_val);
|
||||||
|
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
|
||||||
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_WDBI_DATA_RECORD_OFFSET,
|
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_WDBI_DATA_RECORD_OFFSET,
|
||||||
record_length, ' '));
|
record_length, ' '));
|
||||||
}
|
}
|
||||||
|
@ -539,15 +721,19 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
guint32 state_length = data_length - UDS_IOCBI_STATE_OFFSET;
|
guint32 state_length = data_length - UDS_IOCBI_STATE_OFFSET;
|
||||||
|
|
||||||
subtree = proto_tree_add_subtree(uds_tree, tvb, 0, -1, ett_uds_iocbi, NULL, service_name);
|
subtree = proto_tree_add_subtree(uds_tree, tvb, 0, -1, ett_uds_iocbi, NULL, service_name);
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_iocbi_data_identifier, tvb, UDS_IOCBI_DATA_IDENTIFIER_OFFSET,
|
ti = proto_tree_add_item_ret_uint(subtree, hf_uds_iocbi_data_identifier, tvb,
|
||||||
UDS_IOCBI_DATA_IDENTIFIER_LEN, ENC_BIG_ENDIAN, &data_identifier);
|
UDS_IOCBI_DATA_IDENTIFIER_OFFSET, UDS_IOCBI_DATA_IDENTIFIER_LEN,
|
||||||
|
ENC_BIG_ENDIAN, &data_identifier);
|
||||||
|
protoitem_append_data_name(ti, (guint16)data_identifier);
|
||||||
|
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_iocbi_parameter, tvb, UDS_IOCBI_PARAMETER_OFFSET,
|
proto_tree_add_item_ret_uint(subtree, hf_uds_iocbi_parameter, tvb, UDS_IOCBI_PARAMETER_OFFSET,
|
||||||
UDS_IOCBI_PARAMETER_LEN, ENC_BIG_ENDIAN, &enum_val);
|
UDS_IOCBI_PARAMETER_LEN, ENC_BIG_ENDIAN, &enum_val);
|
||||||
|
|
||||||
proto_tree_add_item(subtree, hf_uds_iocbi_state, tvb, UDS_IOCBI_STATE_OFFSET,
|
proto_tree_add_item(subtree, hf_uds_iocbi_state, tvb, UDS_IOCBI_STATE_OFFSET,
|
||||||
state_length, ENC_NA);
|
state_length, ENC_NA);
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x %s %s", data_identifier,
|
col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", data_identifier);
|
||||||
|
infocol_append_data_name(pinfo, data_identifier);
|
||||||
|
col_append_fstr(pinfo->cinfo, COL_INFO, " %s %s",
|
||||||
val_to_str(enum_val, uds_iocbi_parameters, "Unknown (0x%02x)"),
|
val_to_str(enum_val, uds_iocbi_parameters, "Unknown (0x%02x)"),
|
||||||
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_IOCBI_STATE_OFFSET,
|
tvb_bytes_to_str_punct(wmem_packet_scope(), tvb, UDS_IOCBI_STATE_OFFSET,
|
||||||
state_length, ' '));
|
state_length, ' '));
|
||||||
|
@ -560,11 +746,13 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_rc_type, tvb, UDS_RC_TYPE_OFFSET,
|
proto_tree_add_item_ret_uint(subtree, hf_uds_rc_type, tvb, UDS_RC_TYPE_OFFSET,
|
||||||
UDS_RC_TYPE_LEN, ENC_BIG_ENDIAN, &enum_val);
|
UDS_RC_TYPE_LEN, ENC_BIG_ENDIAN, &enum_val);
|
||||||
|
|
||||||
proto_tree_add_item_ret_uint(subtree, hf_uds_rc_identifier, tvb, UDS_RC_ROUTINE_OFFSET,
|
ti = proto_tree_add_item_ret_uint(subtree, hf_uds_rc_identifier, tvb, UDS_RC_ROUTINE_OFFSET,
|
||||||
UDS_RC_ROUTINE_LEN, ENC_BIG_ENDIAN, &identifier);
|
UDS_RC_ROUTINE_LEN, ENC_BIG_ENDIAN, &identifier);
|
||||||
|
protoitem_append_routine_name(ti, identifier);
|
||||||
|
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " %s 0x%04x",
|
col_append_fstr(pinfo->cinfo, COL_INFO, " %s 0x%04x",
|
||||||
val_to_str(enum_val, uds_rc_types, "Unknown (0x%02x)"), identifier);
|
val_to_str(enum_val, uds_rc_types, "Unknown (0x%02x)"), identifier);
|
||||||
|
infocol_append_routine_name(pinfo, identifier);
|
||||||
if (sid & UDS_REPLY_MASK) {
|
if (sid & UDS_REPLY_MASK) {
|
||||||
guint32 rc_data_len = data_length - UDS_RC_INFO_OFFSET;
|
guint32 rc_data_len = data_length - UDS_RC_INFO_OFFSET;
|
||||||
if (rc_data_len > 0) {
|
if (rc_data_len > 0) {
|
||||||
|
@ -716,9 +904,23 @@ dissect_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data
|
||||||
return tvb_captured_length(tvb);
|
return tvb_captured_length(tvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pref_update_uds(void) {
|
||||||
|
if (uds_ht_routine_ids && uds_uat_routine_id_num == 0) {
|
||||||
|
g_hash_table_destroy(uds_ht_routine_ids);
|
||||||
|
uds_ht_routine_ids = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uds_ht_data_ids && uds_uat_data_id_num == 0) {
|
||||||
|
g_hash_table_destroy(uds_ht_data_ids);
|
||||||
|
uds_ht_data_ids = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
proto_register_uds(void)
|
proto_register_uds(void)
|
||||||
{
|
{
|
||||||
|
module_t* uds_module;
|
||||||
static hf_register_info hf[] = {
|
static hf_register_info hf[] = {
|
||||||
{
|
{
|
||||||
&hf_uds_service,
|
&hf_uds_service,
|
||||||
|
@ -1065,6 +1267,9 @@ proto_register_uds(void)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uat_t* uds_routine_ids_uat;
|
||||||
|
uat_t* uds_data_ids_uat;
|
||||||
|
|
||||||
/* Setup protocol subtree array */
|
/* Setup protocol subtree array */
|
||||||
static gint *ett[] =
|
static gint *ett[] =
|
||||||
{
|
{
|
||||||
|
@ -1094,6 +1299,61 @@ proto_register_uds(void)
|
||||||
proto_register_subtree_array(ett, array_length(ett));
|
proto_register_subtree_array(ett, array_length(ett));
|
||||||
|
|
||||||
uds_handle = register_dissector("uds", dissect_uds, proto_uds);
|
uds_handle = register_dissector("uds", dissect_uds, proto_uds);
|
||||||
|
|
||||||
|
/* Register preferences */
|
||||||
|
uds_module = prefs_register_protocol(proto_uds, &pref_update_uds);
|
||||||
|
|
||||||
|
/* UATs for user_data fields */
|
||||||
|
static uat_field_t uds_routine_id_uat_fields[] = {
|
||||||
|
UAT_FLD_HEX(uds_uat_routine_ids, id, "Routine ID", "Routine Identifier (16bit hex without leading 0x)"),
|
||||||
|
UAT_FLD_CSTRING(uds_uat_routine_ids, name, "Routine Name", "Name of the Routine ID (string)"),
|
||||||
|
UAT_END_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UATs */
|
||||||
|
uds_routine_ids_uat = uat_new("UDS Routine Identifier List",
|
||||||
|
sizeof(generic_one_id_string_t), /* record size */
|
||||||
|
DATAFILE_UDS_ROUTINE_IDS, /* filename */
|
||||||
|
TRUE, /* from profile */
|
||||||
|
(void**)&uds_uat_routine_ids, /* data_ptr */
|
||||||
|
&uds_uat_routine_id_num, /* numitems_ptr */
|
||||||
|
UAT_AFFECTS_DISSECTION, /* but not fields */
|
||||||
|
NULL, /* help */
|
||||||
|
copy_generic_one_id_string_cb, /* copy callback */
|
||||||
|
update_generic_one_identifier_16bit, /* update callback */
|
||||||
|
free_generic_one_id_string_cb, /* free callback */
|
||||||
|
post_update_uds_routine_cb, /* post update callback */
|
||||||
|
NULL, /* reset callback */
|
||||||
|
uds_routine_id_uat_fields /* UAT field definitions */
|
||||||
|
);
|
||||||
|
|
||||||
|
prefs_register_uat_preference(uds_module, "_uds_routine_id_list", "UDS Routine Identifier List",
|
||||||
|
"A table to define names of UDS Routines", uds_routine_ids_uat);
|
||||||
|
|
||||||
|
static uat_field_t uds_data_id_uat_fields[] = {
|
||||||
|
UAT_FLD_HEX(uds_uat_data_ids, id, "Data ID", "Data Identifier (16bit hex without leading 0x)"),
|
||||||
|
UAT_FLD_CSTRING(uds_uat_data_ids, name, "Data Name", "Name of the Data ID (string)"),
|
||||||
|
UAT_END_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
uds_data_ids_uat = uat_new("UDS Data Identifier List",
|
||||||
|
sizeof(generic_one_id_string_t), /* record size */
|
||||||
|
DATAFILE_UDS_DATA_IDS, /* filename */
|
||||||
|
TRUE, /* from profile */
|
||||||
|
(void**)&uds_uat_data_ids, /* data_ptr */
|
||||||
|
&uds_uat_data_id_num, /* numitems_ptr */
|
||||||
|
UAT_AFFECTS_DISSECTION, /* but not fields */
|
||||||
|
NULL, /* help */
|
||||||
|
copy_generic_one_id_string_cb, /* copy callback */
|
||||||
|
update_generic_one_identifier_16bit, /* update callback */
|
||||||
|
free_generic_one_id_string_cb, /* free callback */
|
||||||
|
post_update_uds_data_cb, /* post update callback */
|
||||||
|
NULL, /* reset callback */
|
||||||
|
uds_data_id_uat_fields /* UAT field definitions */
|
||||||
|
);
|
||||||
|
|
||||||
|
prefs_register_uat_preference(uds_module, "_uds_data_id_list", "UDS Data Identifier List",
|
||||||
|
"A table to define names of UDS Data Identifier", uds_data_ids_uat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue