Common Device and Host functions | |
void | gzp_init (void) |
void | gzp_id_req_cancel (void) |
Device functions | |
_Bool | gzp_address_req_send (void) |
gzp_id_req_res_t | gzp_id_req_send (void) |
_Bool | gzp_crypt_data_send (const uint8_t *src, uint8_t length) |
Host functions | |
void | gzp_pairing_enable (_Bool enable) |
void | gzp_host_execute (void) |
_Bool | gzp_address_exchanged (void) |
_Bool | gzp_id_req_received (void) |
void | gzp_id_req_reject (void) |
void | gzp_id_req_grant (void) |
_Bool | gzp_crypt_user_data_received (void) |
_Bool | gzp_crypt_user_data_read (uint8_t *dst, uint8_t *length) |
void gzp_init | ( | void | ) |
Initialization function. This function initializes the Gazell Pairing Library.
This function must be called before any of the other Gazell Pairing Library functions are used and must be called after gzll_init() is called.
Definition at line 212 of file gzp_device.c.
{ gzp_id_req_pending = false; #ifndef GZP_NV_STORAGE_DISABLE gzp_params_restore(); #endif // Update radio parameters from gzp_system_address gzp_update_radio_params(gzp_system_address); }
void gzp_id_req_cancel | ( | void | ) |
Function for cancelling an ongoing (pending) "Host ID request".
After calling this function the "Host ID request" status will go to "ID request Idle".
Definition at line 378 of file gzp_device.c.
{
gzp_id_req_pending = false;
}
_Bool gzp_address_req_send | ( | void | ) |
Function for sending a "system address" request to a Host.
When calling this function the Device will attempt acquiring the "system address" from any Host within close proximity.
If a host is located within close proximity and pairing is enabled in the Host, a "system address" will be sent in return to the Device.
The new "system address" will apply immediately in the Device, and the new "system address" will be stored in non volatile (NV) memory.
Note. Using OTP devices limits the number of times a new "system address" can be stored in NV memory.
true | if new "system address" was received from a Host. |
false | if no "system address" was received from a Host. |
Definition at line 224 of file gzp_device.c.
{ uint8_t i; bool retval = false; uint8_t address_req[GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH]; uint8_t rx_payload[GZLL_MAX_PAYLOAD_LENGTH]; uint16_t temp_power, temp_tx_timeout, temp_device_mode; if(gzll_get_state() == GZLL_IDLE) { // Store parameters that are temporarily changed temp_tx_timeout = gzll_get_param(GZLL_PARAM_TX_TIMEOUT); temp_power = gzll_get_param(GZLL_PARAM_OUTPUT_POWER); temp_device_mode = gzll_get_param(GZLL_PARAM_DEVICE_MODE); // Modify parameters gzll_set_param(GZLL_PARAM_TX_TIMEOUT, GZP_REQ_TX_TIMEOUT); gzll_set_param(GZLL_PARAM_OUTPUT_POWER, GZP_POWER); gzll_set_param(GZLL_PARAM_DEVICE_MODE, 0); // Flush RX FIFO gzll_rx_fifo_flush(); // Build "request" packet address_req[0] = GZP_CMD_HOST_ADDRESS_REQ; // Send a number of packets in order to broadcast that devices not within // close proximity must back off. for(i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++) { if(!gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, 0)) { break; } } gzp_delay_rx_periods(GZP_TX_ACK_WAIT_TIMEOUT); // Send message for fetching pairing response from host. address_req[0] = GZP_CMD_HOST_ADDRESS_FETCH; if(gzp_tx_packet(&address_req[0], GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, 0)) { // If pairing response received if(gzll_rx_fifo_read(rx_payload, NULL, NULL)) { if(rx_payload[0] == GZP_CMD_HOST_ADDRESS_RESP) { memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]); #ifndef GZP_NV_STORAGE_DISABLE gzp_params_store(false); // "False" indicates that only "system address" part of DB element will be stored #endif retval = true; } } } else { gzp_delay_rx_periods(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT - GZP_TX_ACK_WAIT_TIMEOUT); } gzp_delay_rx_periods(GZP_STEP1_RX_TIMEOUT); // Clean-up and restore parameters temporarily modified gzll_rx_fifo_flush(); gzll_tx_fifo_flush(); gzll_set_param(GZLL_PARAM_TX_TIMEOUT, temp_tx_timeout); gzll_set_param(GZLL_PARAM_OUTPUT_POWER, temp_power); gzll_set_param(GZLL_PARAM_DEVICE_MODE, temp_device_mode); } return retval; }
gzp_id_req_res_t gzp_id_req_send | ( | void | ) |
Function for sending a "Host ID request" to a Host.
The "Host ID" is needed to be able to send encrypted data using gzp_crypt_data_send().
The request will be sent using the "system address" previously received using gzp_address_req_send().
It is not required that the Host is within close proximity in order to acquire the "Host ID".
The new "Host ID" will apply immediately for the Device, and the new "Host ID" will be stored in non volatile (NV) memory.
Note. Using OTP devices limits the number of times a new "Host ID" can be stored in NV memory.
GZP_ID_RESP_PENDING | if a "Host ID request" has been sent to the Host, but the Host application has not yet decided whether to Grant or Reject the "ID request". |
GZP_ID_RESP_GRANTED | if the "Host ID" has been received from the Host. The received "Host ID" will be stored in non volatile memory. |
GZP_ID_RESP_REJECTED | if the Host application has rejected the "Host ID request". |
GZP_ID_RESP_FAILED | if failing to send a request or receive a response from the Host. |
Definition at line 302 of file gzp_device.c.
{ uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH]; uint8_t rx_packet[GZLL_MAX_ACK_PAYLOAD_LENGTH]; // If no ID request is pendning, send new "ID request" if(!gzp_id_req_pending) { // Build "Host ID request packet" tx_packet[0] = GZP_CMD_HOST_ID_REQ; // Generate new session token gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); // Send "Host ID request" if(gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE)) { // Update session token if "Host ID request" was successfully transmitted gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); gzp_id_req_pending = true; return GZP_ID_RESP_PENDING; } } else // If "ID request is pending" send "fetch ID" packet { // Build "host ID fetch" packet tx_packet[0] = GZP_CMD_HOST_ID_FETCH; gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]); // Encrypt "host ID fetch" packet gzp_crypt_select_key(GZP_ID_EXCHANGE); gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); // If packet was successfully sent AND a response packet was received if(gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS) { // Validate response packet if(rx_packet[0] == GZP_CMD_HOST_ID_FETCH_RESP) { gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); if(gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID])) { switch(rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]) { case GZP_ID_RESP_PENDING: break; case GZP_ID_RESP_REJECTED: gzp_id_req_pending = false; break; case GZP_ID_RESP_GRANTED: gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]); #ifndef GZP_NV_STORAGE_DISABLE gzp_params_store(true); #endif gzp_id_req_pending = false; break; default: break; } return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]; } else { gzp_id_req_pending = false; return GZP_ID_RESP_REJECTED; } } } } gzp_id_req_pending = false; return GZP_ID_RESP_FAILED; }
_Bool gzp_crypt_data_send | ( | const uint8_t * | src, |
uint8_t | length | ||
) |
Function for sending encrypted user data to the Host.
Before any data can be sent the Device must acquire both the Host's "system address" by using gzp_address_req_send() and the "Host ID" by using gzp_id_req_send().
*src | is a pointer to the data packet to be sent. |
length | is the length of the data packet to be sent. |
true | if the data was successfully transmitted and decrypted by the Host. |
false | if data transmission failed or Host failed to decryption data correctly. |
Definition at line 383 of file gzp_device.c.
{ if(length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH) { if(gzp_crypt_tx_transaction(src, length)) { return true; } else { // Attempt key update if user data transmission failed // during normal operation (!gzp_id_req_pending) if(!gzp_id_req_pending) { gzp_key_update(); return gzp_crypt_tx_transaction(src, length); } return false; } } else { return false; } }
void gzp_pairing_enable | ( | _Bool | enable ) |
Function for enabling/disabling pairing in a host. When pairing is enabled the host will be monitoring for "system address" and "Host ID" requests from Devices.
A "system address request" received from a Device will always be granted. When a "host ID request" has been received, the Host application have to grant, reject or cancel this by using one of the following functions:
enable |
|
Definition at line 130 of file gzp_host.c.
{ gzll_states_t temp_gzll_state; temp_gzll_state = gzll_get_state(); if(gzp_pairing_enabled_f != enable) { gzll_goto_idle(); if(enable) { gzll_set_param(GZLL_PARAM_RX_PIPES, gzll_get_param(GZLL_PARAM_RX_PIPES) | (1 << GZP_PAIRING_PIPE)); } else { gzll_set_param(GZLL_PARAM_RX_PIPES, gzll_get_param(GZLL_PARAM_RX_PIPES) & ~(1 << GZP_PAIRING_PIPE)); gzp_id_req_stat = GZP_ID_REQ_IDLE; } gzp_pairing_enabled_f = enable; if(temp_gzll_state == GZLL_HOST_ACTIVE) { gzll_rx_start(); } } }
void gzp_host_execute | ( | void | ) |
Function for executing Gazell Pairing Library host operation.
This function must be called regularly by the Host application.
Definition at line 159 of file gzp_host.c.
{ uint8_t rx_pipe; uint8_t payload_length; uint8_t rx_payload[GZLL_MAX_FW_PAYLOAD_LENGTH]; gzp_address_exchanged_f = false; rx_pipe = gzll_get_rx_data_ready_pipe_number(); if((rx_pipe == GZP_PAIRING_PIPE) || ((rx_pipe == GZP_DATA_PIPE) && (gzp_encrypted_user_data_length == 0))) { gzll_rx_fifo_read(rx_payload, &payload_length, NULL); switch(rx_payload[0]) { case GZP_CMD_HOST_ADDRESS_REQ: gzp_process_address_req(rx_payload); break; #ifndef GZP_CRYPT_DISABLE case GZP_CMD_HOST_ID_REQ: gzp_process_id_req(rx_payload); break; case GZP_CMD_HOST_ID_FETCH: gzp_process_id_fetch(rx_payload); break; case GZP_CMD_KEY_UPDATE_PREPARE: gzp_process_key_update_prepare(); break; case GZP_CMD_KEY_UPDATE: gzp_process_key_update(rx_payload); break; case GZP_CMD_ENCRYPTED_USER_DATA: gzp_process_encrypted_user_data(rx_payload, payload_length); break; #endif case GZP_CMD_FETCH_RESP: default: break; } } // Restart reception if "not proximity backoff" period has elapsed if(gzll_get_state() == GZLL_IDLE) { gzll_set_param(GZLL_PARAM_RX_TIMEOUT, 0); if(gzp_pairing_enabled_f) { gzll_set_param(GZLL_PARAM_RX_PIPES, gzll_get_param(GZLL_PARAM_RX_PIPES) | (1 << GZP_PAIRING_PIPE)); } gzll_rx_start(); } #ifndef GZP_CRYPT_DISABLE gzp_session_counter_inc(); #endif }
_Bool gzp_address_exchanged | ( | void | ) |
Function returning true if a "system address" was delivered to a requesting Device during the previous call to gzp_host_execute();
Definition at line 294 of file gzp_host.c.
{
return gzp_address_exchanged_f;
}
_Bool gzp_id_req_received | ( | void | ) |
Function for checking if a "Host ID request" has been received from a Device.
If a request has been received, the Pairing library will enter "ID request pending" state.
The application is responsible for responding to this request by calling one of the following functions:
true | if a "Host ID request" has been received (internal state is "ID request pending") |
false | if no "Host ID request" has been received (internal state is "ID request idle") |
Definition at line 326 of file gzp_host.c.
{ return (gzp_id_req_stat != GZP_ID_REQ_IDLE); }
void gzp_id_req_reject | ( | void | ) |
Function for rejecting the previously received "Host ID request". This function should be called only when a "Host ID request" has been received (internal state is "ID request pending").
The internal state of the Pairing library will remain "ID request pending" until the a "reject" message has been successfully transmitted to the requesting Device. After this the internal state will change to "ID request idle".
Definition at line 331 of file gzp_host.c.
{ if(gzp_id_req_received()) { gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_REJECTED; } }
void gzp_id_req_grant | ( | void | ) |
Function for granting the previously received "Host ID request". This function should be called only when a "Host ID request" has been received (internal state is "ID request pending").
The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has been successfully transmitted to the requesting Device. After this the internal state will change to "ID request idle".
Definition at line 339 of file gzp_host.c.
{ if(gzp_id_req_received()) { gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_GRANTED; } }
_Bool gzp_crypt_user_data_received | ( | void | ) |
Function returning true if encrypted user data has been received.
Definition at line 301 of file gzp_host.c.
{
return (gzp_encrypted_user_data_length > 0);
}
_Bool gzp_crypt_user_data_read | ( | uint8_t * | dst, |
uint8_t * | length | ||
) |
Function for reading encrypted user data.
Note that the read user data will be automatically decrypted. Only data that was decrypted correctly will be presented.
dst* | is a pointer to where the received data will be written. |
length* | is a pointer for returning the number of bytes received. Only 1 byte will be writtem to length*. |
true | if data has been received and is written to dst* |
false | if no data has been received. |
Definition at line 306 of file gzp_host.c.
{ if(gzp_encrypted_user_data_length > 0) { memcpy(dst, (void*)gzp_encrypted_user_data, gzp_encrypted_user_data_length); if(length != NULL) { *length = gzp_encrypted_user_data_length; } gzp_encrypted_user_data_length = 0; return true; } else { return false; } }