mesh: add access message builder for segmented (transport) messsages

This commit is contained in:
Matthias Ringwald 2019-04-16 15:34:28 +02:00
parent 8ffbe80d21
commit 668b49bfd4

View File

@ -580,6 +580,78 @@ static void stdin_process(char cmd){
} }
} }
// message builder
static int mesh_access_setup_opcode(uint8_t * buffer, uint32_t opcode){
if (opcode < 0x100){
buffer[0] = opcode;
return 1;
}
if (opcode < 0x10000){
big_endian_store_16(buffer, 0, opcode);
return 2;
}
buffer[0] = opcode >> 16;
little_endian_store_16(buffer, 1, opcode & 0xffff);
return 3;
}
static mesh_transport_pdu_t * mesh_access_transport_init(uint32_t opcode){
mesh_transport_pdu_t * pdu = mesh_transport_pdu_get();
if (!pdu) return NULL;
pdu->len = mesh_access_setup_opcode(pdu->data, opcode);
return pdu;
}
static void mesh_access_transport_add_uint8(mesh_transport_pdu_t * pdu, uint8_t value){
pdu->data[pdu->len++] = value;
}
static void mesh_access_transport_add_uint16(mesh_transport_pdu_t * pdu, uint16_t value){
little_endian_store_16(pdu->data, pdu->len, value);
pdu->len += 2;
}
static void mesh_access_transport_add_uint24(mesh_transport_pdu_t * pdu, uint16_t value){
little_endian_store_24(pdu->data, pdu->len, value);
pdu->len += 3;
}
static void mesh_access_transport_add_uint32(mesh_transport_pdu_t * pdu, uint16_t value){
little_endian_store_32(pdu->data, pdu->len, value);
pdu->len += 4;
}
static int mesh_access_get_opcode(uint8_t * buffer, uint16_t buffer_size, uint32_t * opcode, uint16_t * opcode_size){
switch (buffer[0] >> 6){
case 0:
case 1:
if (buffer[0] == 0x7f) return 0;
*opcode = buffer[0];
*opcode_size = 1;
return 0;
case 2:
if (buffer_size < 2) return 0;
*opcode = big_endian_read_16(buffer, 0);
*opcode_size = 2;
return 1;
case 3:
if (buffer_size < 3) return 0;
*opcode = (buffer[0] << 16) | little_endian_read_16(buffer, 1);
*opcode_size = 3;
return 1;
default:
return 0;
}
}
static int mesh_access_transport_get_opcode(mesh_transport_pdu_t * transport_pdu, uint32_t * opcode, uint16_t * opcode_size){
return mesh_access_get_opcode(transport_pdu->data, transport_pdu->len, opcode, opcode_size);
}
// to sort // to sort
static uint32_t netkey_and_appkey_index; static uint32_t netkey_and_appkey_index;
@ -590,26 +662,32 @@ static uint16_t new_appkey_index;
// Foundation Model Operations // Foundation Model Operations
#define MESH_FOUNDATION_OPERATION_APPKEY_ADD 0x00 #define MESH_FOUNDATION_OPERATION_APPKEY_ADD 0x00
#define MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_GET 0x8008 #define MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS 0x02
#define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_GET 0x8018 #define MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_STATUS 0x06
#define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_STATUS 0x8019 #define MESH_FOUNDATION_OPERATION_APPKEY_DEL 0x8000
#define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET 0x801a #define MESH_FOUNDATION_OPERATION_APPKEY_GET 0x8001
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_ADD 0x801b #define MESH_FOUNDATION_OPERATION_APPKEY_LIST 0x8002
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DEL 0x801c #define MESH_FOUNDATION_OPERATION_APPKEY_STATUS 0x8003
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DEL_ALL 0x801d #define MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_GET 0x8008
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_OVERWRITE 0x801e #define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_GET 0x8018
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_STATUS 0x801f #define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_STATUS 0x8019
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD 0x8020 #define MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET 0x801a
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DEL 0x8021 #define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_ADD 0x801b
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE 0x8022 #define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DEL 0x801c
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DEL_ALL 0x801d
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_OVERWRITE 0x801e
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_STATUS 0x801f
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD 0x8020
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DEL 0x8021
#define MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE 0x8022
#define MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_GET 0x8038 #define MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_GET 0x8038
#define MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_SET 0x8039 #define MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_SET 0x8039
#define MESH_FOUNDATION_OPERATION_HEARTBEAT_SUBSCRIPTION_GET 0x803a #define MESH_FOUNDATION_OPERATION_HEARTBEAT_SUBSCRIPTION_GET 0x803a
#define MESH_FOUNDATION_OPERATION_HEARTBEAT_SUBSCRIPTION_SET 0x803b #define MESH_FOUNDATION_OPERATION_HEARTBEAT_SUBSCRIPTION_SET 0x803b
#define MESH_FOUNDATION_OPERATION_MODEL_APP_BIND 0x803d #define MESH_FOUNDATION_OPERATION_MODEL_APP_BIND 0x803d
#define MESH_FOUNDATION_OPERATION_MODEL_APP_STATUS 0x803e #define MESH_FOUNDATION_OPERATION_MODEL_APP_STATUS 0x803e
#define MESH_FOUNDATION_OPERATION_MODEL_APP_UNBIND 0x803f #define MESH_FOUNDATION_OPERATION_MODEL_APP_UNBIND 0x803f
typedef struct { typedef struct {
btstack_timer_source_t timer; btstack_timer_source_t timer;
@ -645,46 +723,37 @@ static void config_composition_data_status(void){
uint16_t netkey_index = 0; uint16_t netkey_index = 0;
uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
uint8_t access_pdu_data[2 + 10 + 8]; mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS);
int access_pdu_len = sizeof(access_pdu_data); if (!transport_pdu) return;
int pos = 0;
access_pdu_data[pos++] = 0x02; // page 0
access_pdu_data[pos++] = 0x00; mesh_access_transport_add_uint8(transport_pdu, 0);
// CID // CID
little_endian_store_16(access_pdu_data, pos, BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH); mesh_access_transport_add_uint16(transport_pdu, BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH);
pos += 2;
// PID // PID
little_endian_store_16(access_pdu_data, pos, 0); mesh_access_transport_add_uint16(transport_pdu, 0);
pos += 2;
// VID // VID
little_endian_store_16(access_pdu_data, pos, 0); mesh_access_transport_add_uint16(transport_pdu, 0);
pos += 2;
// CRPL - number of protection list entries // CRPL - number of protection list entries
little_endian_store_16(access_pdu_data, pos, 1); mesh_access_transport_add_uint16(transport_pdu, 1);
pos += 2;
// Features - Relay, Proxy, Friend, Lower Power, ... // Features - Relay, Proxy, Friend, Lower Power, ...
little_endian_store_16(access_pdu_data, pos, 0); mesh_access_transport_add_uint16(transport_pdu, 0);
pos += 2;
// Element 1 // Element 1
// Loc - bottom - https://www.bluetooth.com/specifications/assigned-numbers/gatt-namespace-descriptors // Loc - bottom - https://www.bluetooth.com/specifications/assigned-numbers/gatt-namespace-descriptors
little_endian_store_16(access_pdu_data, pos, 0x0103); mesh_access_transport_add_uint16(transport_pdu, 0x0103);
pos += 2;
// NumS - Configuration Server + Health Server // NumS - Configuration Server + Health Server
access_pdu_data[pos++] = 2; mesh_access_transport_add_uint8( transport_pdu, 2);
// NumV // NumV
access_pdu_data[pos++] = 0; mesh_access_transport_add_uint8( transport_pdu, 0);
// SIG Model: Configuration Server 0x0000 // SIG Model: Configuration Server 0x0000
little_endian_store_16(access_pdu_data, pos, 0); mesh_access_transport_add_uint16(transport_pdu, 0);
pos += 2;
// SIG Model: Health Server 0x0002 // SIG Model: Health Server 0x0002
little_endian_store_16(access_pdu_data, pos, 0x0002); mesh_access_transport_add_uint16(transport_pdu, 0x0002);
pos += 2;
// send as segmented access pdu // send as segmented access pdu
mesh_transport_pdu_t * transport_pdu = mesh_transport_pdu_get(); mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, access_pdu_len);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
static void config_composition_data_get_handler(mesh_model_t *mesh_model, mesh_transport_pdu_t *transport_pdu){ static void config_composition_data_get_handler(mesh_model_t *mesh_model, mesh_transport_pdu_t *transport_pdu){
@ -699,18 +768,14 @@ static void config_appkey_status(uint32_t netkey_and_appkey_index, uint8_t statu
uint16_t netkey_index = 0; uint16_t netkey_index = 0;
uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
uint8_t access_pdu_data[2 + 4]; mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_APPKEY_STATUS);
int access_pdu_len = sizeof(access_pdu_data); if (!transport_pdu) return;
int pos = 0;
access_pdu_data[pos++] = 0x80; mesh_access_transport_add_uint8( transport_pdu, status);
access_pdu_data[pos++] = 0x03; mesh_access_transport_add_uint24( transport_pdu, netkey_and_appkey_index);
access_pdu_data[pos++] = status;
little_endian_store_24(access_pdu_data, pos, netkey_and_appkey_index);
pos += 3;
// send as segmented access pdu // send as segmented access pdu
mesh_transport_pdu_t * transport_pdu = mesh_transport_pdu_get(); mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, access_pdu_len);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
@ -748,22 +813,16 @@ static void config_model_subscription_status(uint8_t status, uint16_t element_ad
uint16_t netkey_index = 0; uint16_t netkey_index = 0;
uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
uint8_t access_pdu_data[2 + 7]; mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_STATUS);
int access_pdu_len = sizeof(access_pdu_data); if (!transport_pdu) return;
int pos = 0;
access_pdu_data[pos++] = 0x80; mesh_access_transport_add_uint8(transport_pdu, status);
access_pdu_data[pos++] = 0x1F; mesh_access_transport_add_uint16(transport_pdu, element_address);
access_pdu_data[pos++] = status; mesh_access_transport_add_uint16(transport_pdu, address);
little_endian_store_16(access_pdu_data, pos, element_address); mesh_access_transport_add_uint16(transport_pdu, model_identifier);
pos += 2;
little_endian_store_16(access_pdu_data, pos, address);
pos += 2;
little_endian_store_16(access_pdu_data, pos, model_identifier);
pos += 2;
// send as segmented access pdu // send as segmented access pdu
mesh_transport_pdu_t * transport_pdu = mesh_transport_pdu_get(); mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, access_pdu_len);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
@ -789,22 +848,16 @@ static void config_model_app_status(uint8_t status, uint16_t element_address, ui
uint16_t netkey_index = 0; uint16_t netkey_index = 0;
uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
uint8_t access_pdu_data[2 + 7]; mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_MODEL_APP_STATUS);
int access_pdu_len = sizeof(access_pdu_data); if (!transport_pdu) return;
int pos = 0;
access_pdu_data[pos++] = 0x80; mesh_access_transport_add_uint8(transport_pdu, status);
access_pdu_data[pos++] = 0x3E; mesh_access_transport_add_uint16(transport_pdu, element_address);
access_pdu_data[pos++] = status; mesh_access_transport_add_uint16(transport_pdu, app_key_index);
little_endian_store_16(access_pdu_data, pos, element_address); mesh_access_transport_add_uint16(transport_pdu, model_identifier);
pos += 2;
little_endian_store_16(access_pdu_data, pos, app_key_index);
pos += 2;
little_endian_store_16(access_pdu_data, pos, model_identifier);
pos += 2;
// send as segmented access pdu // send as segmented access pdu
mesh_transport_pdu_t * transport_pdu = mesh_transport_pdu_get(); mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, access_pdu_len);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
@ -817,33 +870,33 @@ static void config_model_app_bind_handler(mesh_model_t *mesh_model, mesh_transpo
} }
static void static void
config_model_publication_virtual_address_add_handler(mesh_model_t *mesh_model, mesh_transport_pdu_t *transport_pdu) { config_model_publication_virtual_address_add_handler(mesh_model_t *mesh_model, mesh_transport_pdu_t *transport_pdu_incoming) {
// ElementAddress - Address of the element - should be us // ElementAddress - Address of the element - should be us
uint16_t element_address = little_endian_read_16(transport_pdu->data, 2); uint16_t element_address = little_endian_read_16(transport_pdu_incoming->data, 2);
// PublishAddress, 128 bit // PublishAddress, 128 bit
// uint8_t * label_uuid = &transport_pdu->data[4]; // uint8_t * label_uuid = &transport_pdu->data[4];
// AppKeyIndex (12), CredentialFlag (1), RFU (3) // AppKeyIndex (12), CredentialFlag (1), RFU (3)
uint16_t temp = little_endian_read_16(transport_pdu->data, 20); uint16_t temp = little_endian_read_16(transport_pdu_incoming->data, 20);
uint16_t app_key_index = temp & 0x0fff; uint16_t app_key_index = temp & 0x0fff;
uint8_t credential_flag = (temp >> 12) & 1; uint8_t credential_flag = (temp >> 12) & 1;
// PublishTTL // PublishTTL
uint8_t publish_ttl = transport_pdu->data[22]; uint8_t publish_ttl = transport_pdu_incoming->data[22];
// PublishPeriod // PublishPeriod
uint8_t publish_period = transport_pdu->data[23]; uint8_t publish_period = transport_pdu_incoming->data[23];
// PublishRetransmitCount(3), PublishRetransmitCount(5) // PublishRetransmitCount(3), PublishRetransmitCount(5)
uint8_t publish_transmit_count = transport_pdu->data[24] & 0x07; uint8_t publish_transmit_count = transport_pdu_incoming->data[24] & 0x07;
uint8_t publish_retransmit_iterval_steps = transport_pdu->data[24] >> 3; uint8_t publish_retransmit_iterval_steps = transport_pdu_incoming->data[24] >> 3;
uint8_t model_id_len; uint8_t model_id_len;
uint32_t model_id; uint32_t model_id;
if (transport_pdu->len == 29){ if (transport_pdu_incoming->len == 29){
// Vendor Model ID // Vendor Model ID
model_id_len = 4; model_id_len = 4;
model_id = little_endian_read_32(transport_pdu->data, 25); model_id = little_endian_read_32(transport_pdu_incoming->data, 25);
} else { } else {
// SIG Model ID // SIG Model ID
model_id_len = 2; model_id_len = 2;
model_id = little_endian_read_16(transport_pdu->data, 25); model_id = little_endian_read_16(transport_pdu_incoming->data, 25);
} }
// TODO: calculate publish address from label uuid // TODO: calculate publish address from label uuid
@ -856,27 +909,25 @@ config_model_publication_virtual_address_add_handler(mesh_model_t *mesh_model, m
uint16_t netkey_index = 0; uint16_t netkey_index = 0;
uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_STATUS);
if (!transport_pdu) return;
uint8_t access_pdu_data[40]; uint8_t status = 0;
// uint16_t access_pdu_len = 1 + transport_pdu->len; mesh_access_transport_add_uint8(transport_pdu, status);
access_pdu_data[0] = 0x80; mesh_access_transport_add_uint16(transport_pdu, element_address);
access_pdu_data[1] = 0x19; mesh_access_transport_add_uint16(transport_pdu, publish_address);
access_pdu_data[2] = 0; mesh_access_transport_add_uint16(transport_pdu, (1<<credential_flag) | app_key_index);
little_endian_store_16(access_pdu_data, 3, element_address); mesh_access_transport_add_uint8(transport_pdu, publish_ttl);
little_endian_store_16(access_pdu_data, 5, publish_address); mesh_access_transport_add_uint8(transport_pdu, publish_period);
little_endian_store_16(access_pdu_data, 7, (1<<credential_flag) | app_key_index); mesh_access_transport_add_uint8(transport_pdu, (publish_retransmit_iterval_steps << 3) | publish_transmit_count);
access_pdu_data[9] = publish_ttl;
access_pdu_data[10] = publish_period;
access_pdu_data[11] = (publish_retransmit_iterval_steps << 3) | publish_transmit_count;
if (model_id_len == 2){ if (model_id_len == 2){
little_endian_store_16(access_pdu_data, 12, model_id); mesh_access_transport_add_uint16(transport_pdu, model_id);
} else { } else {
little_endian_store_32(access_pdu_data, 12, model_id); mesh_access_transport_add_uint32(transport_pdu, model_id);
} }
// send as segmented access pdu // send as segmented access pdu
transport_pdu = mesh_transport_pdu_get(); mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, 12 + model_id_len);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
@ -926,23 +977,23 @@ static void config_heartbeat_publication_status(void){
uint16_t dest = 0x0001; uint16_t dest = 0x0001;
uint8_t ttl = 10; uint8_t ttl = 10;
// setup response mesh_transport_pdu_t * transport_pdu = mesh_access_transport_init(MESH_FOUNDATION_OPERATION_HEARTBEAT_PUBLICATION_STATUS);
uint8_t access_pdu_data[11]; if (!transport_pdu) return;
uint16_t access_pdu_len = 11;
access_pdu_data[0] = 0x06;
access_pdu_data[1] = 0;
little_endian_store_16(access_pdu_data, 2, mesh_heartbeat_publication.destination); uint8_t status = 0;
access_pdu_data[4] = heartbeat_count_log(mesh_heartbeat_publication.count); uint8_t count_log = heartbeat_count_log(mesh_heartbeat_publication.count);
access_pdu_data[5] = mesh_heartbeat_publication.period_log; mesh_access_transport_add_uint8(transport_pdu, status);
access_pdu_data[6] = mesh_heartbeat_publication.ttl; mesh_access_transport_add_uint16(transport_pdu, mesh_heartbeat_publication.destination);
little_endian_store_16(access_pdu_data, 7, mesh_heartbeat_publication.features); mesh_access_transport_add_uint8(transport_pdu, count_log);
little_endian_store_16(access_pdu_data, 9, mesh_heartbeat_publication.netkey_index); mesh_access_transport_add_uint8(transport_pdu, mesh_heartbeat_publication.period_log);
mesh_access_transport_add_uint8(transport_pdu, mesh_heartbeat_publication.ttl);
printf("MESH config_heartbeat_publication_status count = %u => count_log = %u\n", mesh_heartbeat_publication.count, access_pdu_data[4]); mesh_access_transport_add_uint16(transport_pdu, mesh_heartbeat_publication.features);
mesh_access_transport_add_uint16(transport_pdu, mesh_heartbeat_publication.netkey_index);
mesh_transport_pdu_t * transport_pdu = mesh_transport_pdu_get(); printf("MESH config_heartbeat_publication_status count = %u => count_log = %u\n", mesh_heartbeat_publication.count, count_log);
mesh_upper_transport_setup_segmented_access_pdu(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0, access_pdu_data, access_pdu_len);
mesh_upper_transport_setup_segmented_access_pdu_header(transport_pdu, netkey_index, appkey_index, ttl, src, dest, 0);
mesh_upper_transport_send_segmented_access_pdu(transport_pdu); mesh_upper_transport_send_segmented_access_pdu(transport_pdu);
} }
@ -950,7 +1001,6 @@ static void config_heartbeat_publication_set_handler(mesh_model_t *mesh_model, m
// parse // parse
// TODO: validate fields // TODO: validate fields
uint16_t destination =
// Destination address for Heartbeat messages // Destination address for Heartbeat messages
mesh_heartbeat_publication.destination = little_endian_read_16(transport_pdu->data, 2); mesh_heartbeat_publication.destination = little_endian_read_16(transport_pdu->data, 2);
@ -991,29 +1041,6 @@ static void config_heartbeat_publication_get_handler(mesh_model_t *mesh_model, m
// //
static int mesh_access_transport_get_opcode(mesh_transport_pdu_t * transport_pdu, uint32_t * opcode, uint16_t * opcode_size){
switch (transport_pdu->data[0] >> 6){
case 0:
case 1:
if (transport_pdu->data[0] == 0x7f) return -1;
*opcode = transport_pdu->data[0];
*opcode_size = 1;
return 0;
case 2:
if (transport_pdu->len < 2) return -1;
*opcode = big_endian_read_16(transport_pdu->data, 0);
*opcode_size = 2;
return 1;
case 3:
if (transport_pdu->len < 3) return -1;
*opcode = (transport_pdu->data[0] << 16) | big_endian_read_16(transport_pdu->data, 1);
*opcode_size = 3;
return 1;
default:
return 0;
}
}
typedef void (*mesh_operation_handler)(mesh_model_t * mesh_model, mesh_transport_pdu_t * transport_pdu); typedef void (*mesh_operation_handler)(mesh_model_t * mesh_model, mesh_transport_pdu_t * transport_pdu);
typedef struct { typedef struct {