static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint8_t *rx_length, uint8_t pipe) { gzp_tx_rx_trans_result_t retval; uint8_t fetch_packet[GZPAR_CMD_FETCH_RESP_PAYLOAD_LENGTH]; gzll_rx_fifo_flush(); retval = GZP_TX_RX_FAILED_TO_SEND; if(gzp_tx_packet(tx_packet, tx_length, pipe)) { retval = GZP_TX_RX_NO_RESPONSE; gzll_rx_fifo_flush(); fetch_packet[0] = GZP_CMD_FETCH_RESP; gzp_delay_rx_periods(GZP_TX_RX_TRANS_DELAY); gzp_tx_packet(fetch_packet, GZPAR_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe); if(gzll_rx_fifo_read(rx_dst, rx_length, NULL)) { retval = GZP_TX_RX_SUCCESS; } } return retval; }
static void gzp_process_address_req(uint8_t* gzp_req) { uint8_t temp_rx_pipes, temp_host_mode; uint8_t pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH]; gzp_address_exchanged_f = false; gzll_goto_idle(); temp_rx_pipes = gzll_get_param(GZLL_PARAM_RX_PIPES); temp_host_mode = gzll_get_param(GZLL_PARAM_HOST_MODE); // If requesting Device within close proximity if(gzll_rx_power_high()) { gzll_set_param(GZLL_PARAM_RX_PIPES, 0); gzll_set_param(GZLL_PARAM_HOST_MODE, 0); gzll_set_param(GZLL_PARAM_RX_TIMEOUT, GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT); gzll_rx_fifo_flush(); // Start "proximity" back off period gzll_rx_start(); while(gzll_get_state() != GZLL_IDLE) ; // Build pairing response packet pairing_resp[0] = GZP_CMD_HOST_ADDRESS_RESP; gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); gzll_ack_payload_write(&pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH, 0); gzll_set_param(GZLL_PARAM_RX_TIMEOUT, GZP_STEP1_RX_TIMEOUT); // Enable only pairing pipe when waiting for pairing request step 1 gzll_set_param(GZLL_PARAM_RX_PIPES, (1 << GZP_PAIRING_PIPE)); gzll_rx_start(); while(gzll_get_state() != GZLL_IDLE) { if(gzll_rx_fifo_read(&gzp_req[0], NULL, NULL)) { // Validate step 1 of pairing request if(gzp_req[0] == GZP_CMD_HOST_ADDRESS_FETCH) { gzp_address_exchanged_f = true; } } } gzll_tx_fifo_flush(); gzll_rx_fifo_flush(); gzll_set_param(GZLL_PARAM_RX_TIMEOUT, 0); gzll_set_param(GZLL_PARAM_RX_PIPES, temp_rx_pipes); gzll_set_param(GZLL_PARAM_HOST_MODE, temp_host_mode); // Return to normal operation gzll_rx_start(); } else { gzll_set_param(GZLL_PARAM_RX_PIPES, temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE)); gzll_set_param(GZLL_PARAM_RX_TIMEOUT, GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT); // Start "not proximity" backoff period gzll_rx_start(); } }
static void gzp_process_address_req(uint8_t* gzp_req) { uint8_t temp_rx_pipes; uint8_t pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH]; uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; gzp_address_exchanged_f = false; gzll_goto_idle(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); temp_rx_pipes = nrf_gzll_get_rx_pipes_enabled(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); // If requesting Device within close proximity if(prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD) { (void)nrf_gzll_set_rx_pipes_enabled(0); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); gzll_set_rx_timeout(GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); gzll_rx_fifo_flush(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); // Start "proximity" back off period gzll_rx_start(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); while(nrf_gzll_is_enabled()) {} // Build pairing response packet pairing_resp[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_RESP; gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); (void)nrf_gzll_add_packet_to_tx_fifo(0, &pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); gzll_set_rx_timeout(GZP_STEP1_RX_TIMEOUT); // Enable only pairing pipe when waiting for pairing request step 1 (void)nrf_gzll_set_rx_pipes_enabled((1 << GZP_PAIRING_PIPE)); gzll_rx_start(); while(nrf_gzll_is_enabled()) { if(nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE)) { (void)nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, &gzp_req[0], &rx_payload_length); // Validate step 1 of pairing request if(gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH) { gzp_address_exchanged_f = true; } } } gzll_tx_fifo_flush(); gzll_rx_fifo_flush(); gzll_set_rx_timeout(0); (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes); // Return to normal operation gzll_rx_start(); } else { (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE)); gzll_set_rx_timeout(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT); // Start "not proximity" backoff period gzll_rx_start(); } }
bool gzp_address_req_send(uint8_t idx) { 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]); pairing_list_addr_write(idx, gzp_system_address); 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; }