Z-Wave Protocol Controller Reference
zwave_s0_transport.c File Reference
#include "zwave_s0_internal.h"
#include "zwave_s0_transport.h"
#include "zwave_s0_network.h"
#include "zwave_s0_sm.h"
#include <stdint.h>
#include <string.h>
#include <ctimer.h>
#include <assert.h>
#include "zwave_command_class_indices.h"
#include "ZW_classcmd.h"
#include "zwave_helper_macros.h"
#include "zwave_controller_internal.h"
#include "zwave_controller_transport_internal.h"
#include "zwave_controller_storage.h"
#include "zwave_controller_transport.h"
#include "zwave_tx.h"
#include "S2.h"
#include "zwave_s2_keystore.h"
#include "s2_keystore.h"
#include "aes.h"
#include "sl_log.h"
Include dependency graph for zwave_s0_transport.c:

Classes

struct  sec_tx_session
 
struct  _authdata_
 
struct  nonce_block_t
 
struct  nonce
 
struct  rx_session_t
 

Macros

#define LOG_TAG   "zwave_s0_transport"
 
#define NONCE_TABLE_SIZE   5 * 3
 
#define NUM_TX_SESSIONS   2
 
#define MAX_ENCRYPTED_MSG_SIZE   128
 
#define MAX_NONCES   10
 
#define MAX_RXSESSIONS   2
 
#define NONCE_TIMEOUT   10
 
#define NONCE_REQUEST_TIMER   10000
 
#define NONCE_REPORT_DISCARD_TIMEOUT   20000
 
#define NONCE_BLOCK_LIST_SIZE   10
 
#define RECEIVERS_NONCE_SIZE   8
 
#define S0_IV_SIZE   8
 
#define RECEIVER_NONCE_IDENTIFIER_OFFSET_FROM_END   9
 
#define S0_MAC_SIZE   8
 
#define S0_ENCAP_HEADER_LEN   20
 
#define UNUSED(x)   x = x;
 

Typedefs

typedef struct sec_tx_session sec_tx_session_t
 
typedef struct _authdata_ auth_data_t
 
typedef struct nonce nonce_t
 

Enumerations

enum  tx_state_t {
  NONCE_GET , NONCE_GET_SENT , ENC_MSG , ENC_MSG_SENT ,
  ENC_MSG2 , ENC_MSG2_SENT , TX_DONE
}
 
enum  rx_session_state_t { RX_INIT , RX_ENC1 , RX_ENC2 , RX_SESSION_DONE }
 

Functions

static void restart_s0_timer (void)
 
const char * s0_cmd_name (uint8_t cmd)
 
const char * s0_state_name (tx_state_t state)
 
static void aes_encrypt (uint8_t *in, uint8_t *out)
 
static void aes_set_key_tpt (const uint8_t *key, const uint8_t *iv)
 
static void aes_ofb (uint8_t *data, uint8_t len)
 
static void aes_cbc_mac (const uint8_t *data, uint8_t len, uint8_t *mac)
 
static unsigned int s0_is_nonce_blocked (const uint8_t src, const uint8_t dst, const uint8_t *nonce)
 
static void s0_block_nonce (const uint8_t src, const uint8_t dst, const uint8_t *nonce)
 
static u8_t register_nonce (u8_t src, u8_t dst, u8_t reply_nonce, const u8_t nonce[8])
 
static u8_t get_s0_nonce (u8_t src, u8_t dst, u8_t ri, u8_t nonce[RECEIVERS_NONCE_SIZE], u8_t any_nonce)
 
static void nonce_clear (u8_t src, u8_t dst)
 
static void nonce_timer_timeout (void *data)
 
static void tx_session_state_set (sec_tx_session_t *s, tx_state_t state)
 Move a S0 Tx Session state to a new state. More...
 
void s0_set_key (const uint8_t *network_key)
 Set the S0 network key. More...
 
static void s0_timeout (void *user)
 
static sec_tx_session_tget_tx_session_by_node (uint8_t snode, uint8_t dnode)
 
static uint8_t get_node_max_frame_size (zwave_node_id_t node_id)
 
static uint8_t s0_encrypt_message (sec_tx_session_t *s, uint8_t pass2)
 
static void reset_tx_session_data (sec_tx_session_t *s)
 Resets the data from the previous S0 Tx Session. More...
 
static void callback (uint8_t status, const zwapi_tx_report_t *tx_info, void *user)
 Z-Wave Tx Send data callback function. More...
 
static uint8_t get_seq ()
 
sl_status_t zwave_s0_send_data (const zwave_controller_connection_info_t *conn_info, uint16_t data_length_2_byte, const uint8_t *cmd_data, const zwave_tx_options_t *tx_options, const on_zwave_tx_send_data_complete_t on_send_complete, void *user, zwave_tx_session_id_t parent_session_id)
 Sending an S0 encapsulated frame. More...
 
static void s0_register_nonce (uint8_t src, uint8_t dst, const uint8_t *nonce)
 
uint8_t is_free (const rx_session_t *e)
 
rx_session_tnew_rx_session (uint8_t snode, uint8_t dnode)
 
static void free_rx_session (rx_session_t *s)
 
void s0_abort_all_tx_sessions ()
 Abort all S0 network TX sessions. More...
 
void free_all_rx_session ()
 Free all S0 RX sessions. More...
 
rx_session_tget_rx_session_by_nodes (uint8_t snode, uint8_t dnode)
 
static void s0_send_nonce (const zwave_controller_connection_info_t *conn_info)
 
static uint8_t s0_decrypt_message (const zwave_controller_connection_info_t *connection_info, const zwave_rx_receive_options_t *rx_options, const uint8_t *encrypted_frame, uint16_t encrypted_frame_len, uint8_t *decrypted_frame, uint16_t decrypted_frame_len)
 
sl_status_t s0_application_command_handler (const zwave_controller_connection_info_t *c, const zwave_rx_receive_options_t *rx_options, const uint8_t *frame_data, uint16_t frame_length)
 
sl_status_t zwave_s0_on_frame_received (const zwave_controller_connection_info_t *c, const zwave_rx_receive_options_t *rx_options, const uint8_t *encrypted_frame, uint16_t encrypted_frame_len)
 Entry point of S0 frames received from the PHY/radio stack. More...
 
void free_all_tx_sessions ()
 Free all S0 Tx sessions. More...
 
void free_nonce_block_list ()
 Free S0 nonce block list. More...
 
void reset_block_next_elem ()
 Reset (block_next_elem)s0 block next elem variable. More...
 
void reset_s0_timers ()
 Reset nonce timer. More...
 
sl_status_t zwave_s0_on_abort_send_data (zwave_tx_session_id_t session_id)
 Z-Wave controller transport callback function which will be triggered when S0 frame tranmission is aborted. More...
 
static void s0_on_new_network (zwave_home_id_t home_id, zwave_node_id_t node_id, zwave_keyset_t granted_keys, zwave_kex_fail_type_t kex_fail_type)
 
sl_status_t zwave_s0_transport_init ()
 Initialize the S0 Transport Also calls zwave_s0_network_init() which aborts all tx sessions and frees them and also frees rx sessions and reads S0 key from keystore and initializes the S0 key. More...
 

Variables

static sec_tx_session_t tx_sessions [NUM_TX_SESSIONS]
 
nonce_block_t nonce_block [NONCE_BLOCK_LIST_SIZE]
 
static unsigned int block_next_elem
 
static uint8_t aes_key [16]
 
static uint8_t aes_iv [16]
 
static nonce_t nonce_table [NONCE_TABLE_SIZE]
 
struct ctimer nonce_timer
 
static uint8_t enckey [16]
 
static uint8_t authkey [16]
 
static uint8_t enckeyz [16]
 
static uint8_t authkeyz [16]
 
rx_session_t rxsessions [MAX_RXSESSIONS]
 
static const zwave_controller_callbacks_t s0_callbacks = {.on_new_network_entered = &s0_on_new_network}
 

Macro Definition Documentation

◆ LOG_TAG

#define LOG_TAG   "zwave_s0_transport"

◆ MAX_ENCRYPTED_MSG_SIZE

#define MAX_ENCRYPTED_MSG_SIZE   128

◆ MAX_NONCES

#define MAX_NONCES   10

◆ MAX_RXSESSIONS

#define MAX_RXSESSIONS   2

◆ NONCE_BLOCK_LIST_SIZE

#define NONCE_BLOCK_LIST_SIZE   10

◆ NONCE_REPORT_DISCARD_TIMEOUT

#define NONCE_REPORT_DISCARD_TIMEOUT   20000

◆ NONCE_REQUEST_TIMER

#define NONCE_REQUEST_TIMER   10000

◆ NONCE_TABLE_SIZE

#define NONCE_TABLE_SIZE   5 * 3

◆ NONCE_TIMEOUT

#define NONCE_TIMEOUT   10

◆ NUM_TX_SESSIONS

#define NUM_TX_SESSIONS   2

◆ RECEIVER_NONCE_IDENTIFIER_OFFSET_FROM_END

#define RECEIVER_NONCE_IDENTIFIER_OFFSET_FROM_END   9

◆ RECEIVERS_NONCE_SIZE

#define RECEIVERS_NONCE_SIZE   8

◆ S0_ENCAP_HEADER_LEN

#define S0_ENCAP_HEADER_LEN   20

◆ S0_IV_SIZE

#define S0_IV_SIZE   8

◆ S0_MAC_SIZE

#define S0_MAC_SIZE   8

◆ UNUSED

#define UNUSED (   x)    x = x;

Typedef Documentation

◆ auth_data_t

typedef struct _authdata_ auth_data_t

◆ nonce_t

typedef struct nonce nonce_t

◆ sec_tx_session_t

Enumeration Type Documentation

◆ rx_session_state_t

Enumerator
RX_INIT 
RX_ENC1 
RX_ENC2 
RX_SESSION_DONE 

◆ tx_state_t

enum tx_state_t
Enumerator
NONCE_GET 
NONCE_GET_SENT 
ENC_MSG 
ENC_MSG_SENT 
ENC_MSG2 
ENC_MSG2_SENT 
TX_DONE 

Function Documentation

◆ aes_cbc_mac()

static void aes_cbc_mac ( const uint8_t *  data,
uint8_t  len,
uint8_t *  mac 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ aes_encrypt()

static void aes_encrypt ( uint8_t *  in,
uint8_t *  out 
)
static
Here is the caller graph for this function:

◆ aes_ofb()

static void aes_ofb ( uint8_t *  data,
uint8_t  len 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ aes_set_key_tpt()

static void aes_set_key_tpt ( const uint8_t *  key,
const uint8_t *  iv 
)
static
Here is the caller graph for this function:

◆ callback()

static void callback ( uint8_t  status,
const zwapi_tx_report_t tx_info,
void *  user 
)
static

Z-Wave Tx Send data callback function.

This function is invoked when a frame queue by the S0 transport has been transmitted.

Parameters
statusTx Status for the transmision
tx_infoZ-Wave Tx Report for our frame
userUser pointer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_rx_session()

static void free_rx_session ( rx_session_t s)
static
Here is the caller graph for this function:

◆ get_node_max_frame_size()

static uint8_t get_node_max_frame_size ( zwave_node_id_t  node_id)
static

Get the maximum frame size supported by a node.

Here is the caller graph for this function:

◆ get_rx_session_by_nodes()

rx_session_t * get_rx_session_by_nodes ( uint8_t  snode,
uint8_t  dnode 
)

Get a specific nonce from the nonce table. The session must not be expired

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_s0_nonce()

static u8_t get_s0_nonce ( u8_t  src,
u8_t  dst,
u8_t  ri,
u8_t  nonce[RECEIVERS_NONCE_SIZE],
u8_t  any_nonce 
)
static

Receive nonce sent from src to dst, if th ri. If a nonce is found, then remove all entries from that src->dst combination from the table.

If any_nonce is set then ri is ignored

Here is the caller graph for this function:

◆ get_seq()

static uint8_t get_seq ( )
static

Get the next sequence number no node may receive the same sequence number in two concurrent transmissions

Here is the caller graph for this function:

◆ get_tx_session_by_node()

static sec_tx_session_t * get_tx_session_by_node ( uint8_t  snode,
uint8_t  dnode 
)
static

Lookup a tx session by nodeid

Here is the caller graph for this function:

◆ is_free()

uint8_t is_free ( const rx_session_t e)
Here is the caller graph for this function:

◆ new_rx_session()

rx_session_t * new_rx_session ( uint8_t  snode,
uint8_t  dnode 
)

Get a new free RX session.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nonce_clear()

static void nonce_clear ( u8_t  src,
u8_t  dst 
)
static

Remove all nonces from nonce table sent from src to dst

Parameters
src
dst
Here is the caller graph for this function:

◆ nonce_timer_timeout()

static void nonce_timer_timeout ( void *  data)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_nonce()

static u8_t register_nonce ( u8_t  src,
u8_t  dst,
u8_t  reply_nonce,
const u8_t  nonce[8] 
)
static

Register a new nonce from sent from src to dst

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset_tx_session_data()

static void reset_tx_session_data ( sec_tx_session_t s)
static

Resets the data from the previous S0 Tx Session.

Parameters
sPointer to the S0 Tx Session
Here is the caller graph for this function:

◆ restart_s0_timer()

static void restart_s0_timer ( void  )
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_application_command_handler()

sl_status_t s0_application_command_handler ( const zwave_controller_connection_info_t c,
const zwave_rx_receive_options_t rx_options,
const uint8_t *  frame_data,
uint16_t  frame_length 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_block_nonce()

static void s0_block_nonce ( const uint8_t  src,
const uint8_t  dst,
const uint8_t *  nonce 
)
static

We block the last NONCE_BLOCK_LIST_SIZE external nonces we have used. This function adds nonce to the block.

Here is the caller graph for this function:

◆ s0_cmd_name()

const char * s0_cmd_name ( uint8_t  cmd)
Here is the caller graph for this function:

◆ s0_decrypt_message()

static uint8_t s0_decrypt_message ( const zwave_controller_connection_info_t connection_info,
const zwave_rx_receive_options_t rx_options,
const uint8_t *  encrypted_frame,
uint16_t  encrypted_frame_len,
uint8_t *  decrypted_frame,
uint16_t  decrypted_frame_len 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_encrypt_message()

static uint8_t s0_encrypt_message ( sec_tx_session_t s,
uint8_t  pass2 
)
static

Encrypt a message and write the encrypted data into s->crypted_msg

Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_is_nonce_blocked()

static unsigned int s0_is_nonce_blocked ( const uint8_t  src,
const uint8_t  dst,
const uint8_t *  nonce 
)
static

Test if an S0 nonce with particular source and destination is blocked.

Returns
1 if nonce is in block, 0 otherwise
Here is the caller graph for this function:

◆ s0_on_new_network()

static void s0_on_new_network ( zwave_home_id_t  home_id,
zwave_node_id_t  node_id,
zwave_keyset_t  granted_keys,
zwave_kex_fail_type_t  kex_fail_type 
)
static
Here is the call graph for this function:

◆ s0_register_nonce()

static void s0_register_nonce ( uint8_t  src,
uint8_t  dst,
const uint8_t *  nonce 
)
static

Register a nonce by source and destination

Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_send_nonce()

static void s0_send_nonce ( const zwave_controller_connection_info_t conn_info)
static

Send a nonce from given source to given destination. The nonce is registered internally

Here is the call graph for this function:
Here is the caller graph for this function:

◆ s0_state_name()

const char * s0_state_name ( tx_state_t  state)
Here is the caller graph for this function:

◆ s0_timeout()

static void s0_timeout ( void *  user)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tx_session_state_set()

static void tx_session_state_set ( sec_tx_session_t s,
tx_state_t  state 
)
static

Move a S0 Tx Session state to a new state.

Parameters
sPointer to the S0 Tx Session
stateNew state for the session.
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ aes_iv

uint8_t aes_iv[16]
static

◆ aes_key

uint8_t aes_key[16]
static

◆ authkey

uint8_t authkey[16]
static

◆ authkeyz

uint8_t authkeyz[16]
static

◆ block_next_elem

unsigned int block_next_elem
static

◆ enckey

uint8_t enckey[16]
static

◆ enckeyz

uint8_t enckeyz[16]
static

◆ nonce_block

◆ nonce_table

nonce_t nonce_table[NONCE_TABLE_SIZE]
static

◆ nonce_timer

struct ctimer nonce_timer

◆ rxsessions

◆ s0_callbacks

const zwave_controller_callbacks_t s0_callbacks = {.on_new_network_entered = &s0_on_new_network}
static

◆ tx_sessions

sec_tx_session_t tx_sessions[NUM_TX_SESSIONS]
static