00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00019 #include <stdint.h>
00020 #include <stdbool.h>
00021 #include <string.h>
00022
00023 #include "gzll.h"
00024 #include "gzp.h"
00025 #include "hal_aes.h"
00026 #include "hal_delay.h"
00027 #include "hal_flash.h"
00028 #include "memdefs.h"
00029
00030
00031
00032
00033 #define GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS 0
00034 #define GZP_PARAMS_DB_ELEMENT_HOST_ID (GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH)
00035 #define GZP_PARAMS_DB_ELEMENT_SIZE (GZP_SYSTEM_ADDRESS_WIDTH + GZP_HOST_ID_LENGTH)
00036 #define GZP_PARAMS_DB_MAX_ENTRIES 14 // [#elements]. Max 14.
00037
00038
00039
00040
00041
00042 #define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR
00043 #define GZP_PARAMS_DB_SIZE (GZP_PARAMS_DB_MAX_ENTRIES * GZP_PARAMS_DB_ELEMENT_SIZE)
00044
00045 #define GZP_INDEX_DB_ADR (GZP_PARAMS_STORAGE_ADR + GZP_PARAMS_DB_SIZE)
00046 #define GZP_INDEX_DB_SIZE (GZP_DEVICE_PARAMS_STORAGE_SIZE - GZP_PARAMS_DB_SIZE)
00047
00048 #if(GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE)
00049 #error GZP_DEVICE_PARAMS_STORAGE_SIZE must be greater or equal to GZP_PAIRING_PARAMS_DB_SIZE
00050 #elif(GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE )
00051 #warning GZP_DEVICE_PARAMS_STORAGE_SIZE to low to be able store any pairing parameters NV memory
00052 #endif
00053
00054
00055
00056
00057
00061 typedef enum
00062 {
00063 GZP_TX_RX_SUCCESS,
00064 GZP_TX_RX_FAILED_TO_SEND,
00065 GZP_TX_RX_NO_RESPONSE
00066 } gzp_tx_rx_trans_result_t;
00067
00068
00069
00070
00071
00072 static xdata uint8_t gzp_system_address[GZP_SYSTEM_ADDRESS_WIDTH];
00073 static xdata uint8_t gzp_host_id[GZP_HOST_ID_LENGTH];
00074
00075
00076
00077
00078
00082 static xdata bool gzp_id_req_pending;
00083
00084
00085
00086
00087
00101 static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe);
00102
00113 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);
00114
00126 static bool gzp_crypt_tx_transaction(const uint8_t *tx_packet, uint8_t length);
00127
00134 static bool gzp_key_update();
00135
00147 static void gzp_params_db_add(const uint8_t *src_element, uint8_t index);
00148
00157 static void gzp_params_db_read(uint8_t* dst_element, uint8_t index);
00158
00164 static void gzp_index_db_add(uint8_t index);
00165
00169 static uint8_t gzp_index_db_read();
00170
00174 static bool gzp_index_db_full();
00175
00179 static bool gzp_index_db_empty();
00180
00187 static bool gzp_array_is_set(const uint8_t* src, uint8_t length);
00188
00197 static bool gzp_params_store(bool store_all);
00198
00202 static bool gzp_params_restore(void);
00203
00207 void gzp_delay_rx_periods(uint16_t rx_periods);
00208
00209
00210
00211
00212 void gzp_init()
00213 {
00214 gzp_id_req_pending = false;
00215
00216 #ifndef GZP_NV_STORAGE_DISABLE
00217 gzp_params_restore();
00218 #endif
00219
00220
00221 gzp_update_radio_params(gzp_system_address);
00222 }
00223
00224 bool gzp_address_req_send()
00225 {
00226 uint8_t i;
00227 bool retval = false;
00228 uint8_t address_req[GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH];
00229 uint8_t rx_payload[GZLL_MAX_PAYLOAD_LENGTH];
00230 uint16_t temp_power, temp_tx_timeout, temp_device_mode;
00231
00232 if(gzll_get_state() == GZLL_IDLE)
00233 {
00234
00235 temp_tx_timeout = gzll_get_param(GZLL_PARAM_TX_TIMEOUT);
00236 temp_power = gzll_get_param(GZLL_PARAM_OUTPUT_POWER);
00237 temp_device_mode = gzll_get_param(GZLL_PARAM_DEVICE_MODE);
00238
00239
00240 gzll_set_param(GZLL_PARAM_TX_TIMEOUT, GZP_REQ_TX_TIMEOUT);
00241 gzll_set_param(GZLL_PARAM_OUTPUT_POWER, GZP_POWER);
00242 gzll_set_param(GZLL_PARAM_DEVICE_MODE, 0);
00243
00244
00245 gzll_rx_fifo_flush();
00246
00247
00248 address_req[0] = GZP_CMD_HOST_ADDRESS_REQ;
00249
00250
00251
00252 for(i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++)
00253 {
00254 if(!gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, 0))
00255 {
00256 break;
00257 }
00258 }
00259
00260 gzp_delay_rx_periods(GZP_TX_ACK_WAIT_TIMEOUT);
00261
00262
00263 address_req[0] = GZP_CMD_HOST_ADDRESS_FETCH;
00264
00265 if(gzp_tx_packet(&address_req[0], GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, 0))
00266 {
00267
00268 if(gzll_rx_fifo_read(rx_payload, NULL, NULL))
00269 {
00270 if(rx_payload[0] == GZP_CMD_HOST_ADDRESS_RESP)
00271 {
00272 memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH);
00273 gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]);
00274
00275 #ifndef GZP_NV_STORAGE_DISABLE
00276 gzp_params_store(false);
00277 #endif
00278 retval = true;
00279 }
00280 }
00281 }
00282 else
00283 {
00284 gzp_delay_rx_periods(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT - GZP_TX_ACK_WAIT_TIMEOUT);
00285 }
00286
00287 gzp_delay_rx_periods(GZP_STEP1_RX_TIMEOUT);
00288
00289
00290 gzll_rx_fifo_flush();
00291 gzll_tx_fifo_flush();
00292 gzll_set_param(GZLL_PARAM_TX_TIMEOUT, temp_tx_timeout);
00293 gzll_set_param(GZLL_PARAM_OUTPUT_POWER, temp_power);
00294 gzll_set_param(GZLL_PARAM_DEVICE_MODE, temp_device_mode);
00295 }
00296
00297 return retval;
00298 }
00299
00300 #ifndef GZP_CRYPT_DISABLE
00301
00302 gzp_id_req_res_t gzp_id_req_send()
00303 {
00304 uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH];
00305 uint8_t rx_packet[GZLL_MAX_ACK_PAYLOAD_LENGTH];
00306
00307
00308 if(!gzp_id_req_pending)
00309 {
00310
00311 tx_packet[0] = GZP_CMD_HOST_ID_REQ;
00312
00313
00314 gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH);
00315
00316
00317 if(gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE))
00318 {
00319
00320 gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]);
00321 gzp_id_req_pending = true;
00322
00323 return GZP_ID_RESP_PENDING;
00324 }
00325 }
00326 else
00327 {
00328
00329 tx_packet[0] = GZP_CMD_HOST_ID_FETCH;
00330 gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]);
00331
00332
00333 gzp_crypt_select_key(GZP_ID_EXCHANGE);
00334 gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1);
00335
00336
00337 if(gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS)
00338 {
00339
00340 if(rx_packet[0] == GZP_CMD_HOST_ID_FETCH_RESP)
00341 {
00342 gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1);
00343 if(gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]))
00344 {
00345 switch(rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS])
00346 {
00347 case GZP_ID_RESP_PENDING:
00348 break;
00349 case GZP_ID_RESP_REJECTED:
00350 gzp_id_req_pending = false;
00351 break;
00352 case GZP_ID_RESP_GRANTED:
00353 gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]);
00354 #ifndef GZP_NV_STORAGE_DISABLE
00355 gzp_params_store(true);
00356 #endif
00357 gzp_id_req_pending = false;
00358 break;
00359 default:
00360 break;
00361 }
00362
00363 return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS];
00364 }
00365 else
00366 {
00367 gzp_id_req_pending = false;
00368 return GZP_ID_RESP_REJECTED;
00369 }
00370 }
00371 }
00372 }
00373
00374 gzp_id_req_pending = false;
00375 return GZP_ID_RESP_FAILED;
00376 }
00377
00378 void gzp_id_req_cancel()
00379 {
00380 gzp_id_req_pending = false;
00381 }
00382
00383 bool gzp_crypt_data_send(const uint8_t *src, uint8_t length)
00384 {
00385 if(length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH)
00386 {
00387 if(gzp_crypt_tx_transaction(src, length))
00388 {
00389 return true;
00390 }
00391 else
00392 {
00393
00394
00395 if(!gzp_id_req_pending)
00396 {
00397 gzp_key_update();
00398 return gzp_crypt_tx_transaction(src, length);
00399 }
00400 return false;
00401 }
00402 }
00403 else
00404 {
00405 return false;
00406 }
00407 }
00408
00409 #endif
00410
00411
00412
00413
00414
00415 static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe)
00416 {
00417 if(gzll_tx_data(tx_packet, length, pipe))
00418 {
00419 while(gzll_get_state() != GZLL_IDLE)
00420 ;
00421 return gzll_tx_success();
00422 }
00423 return false;
00424 }
00425
00426 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)
00427 {
00428 gzp_tx_rx_trans_result_t retval;
00429 uint8_t fetch_packet[GZPAR_CMD_FETCH_RESP_PAYLOAD_LENGTH];
00430
00431 gzll_rx_fifo_flush();
00432
00433 retval = GZP_TX_RX_FAILED_TO_SEND;
00434
00435 if(gzp_tx_packet(tx_packet, tx_length, pipe))
00436 {
00437 retval = GZP_TX_RX_NO_RESPONSE;
00438
00439 gzll_rx_fifo_flush();
00440 fetch_packet[0] = GZP_CMD_FETCH_RESP;
00441
00442 gzp_delay_rx_periods(GZP_TX_RX_TRANS_DELAY);
00443 gzp_tx_packet(fetch_packet, GZPAR_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe);
00444
00445 if(gzll_rx_fifo_read(rx_dst, rx_length, NULL))
00446 {
00447 retval = GZP_TX_RX_SUCCESS;
00448 }
00449 }
00450 return retval;
00451 }
00452
00453 #ifndef GZP_CRYPT_DISABLE
00454
00455 static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length)
00456 {
00457 uint8_t tx_packet[GZLL_MAX_FW_PAYLOAD_LENGTH];
00458 uint8_t rx_packet[GZLL_MAX_ACK_PAYLOAD_LENGTH];
00459 uint8_t tx_packet_length;
00460
00461 tx_packet_length = length + GZP_USER_DATA_PACKET_OVERHEAD;
00462
00463
00464 tx_packet[0] = GZP_CMD_ENCRYPTED_USER_DATA;
00465 gzp_add_validation_id(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]);
00466 memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length);
00467
00468
00469 if(gzp_id_req_pending)
00470 {
00471 gzp_crypt_select_key(GZP_ID_EXCHANGE);
00472 }
00473 else
00474 {
00475 gzp_crypt_select_key(GZP_DATA_EXCHANGE);
00476 }
00477 gzp_crypt(&tx_packet[1], &tx_packet[1], tx_packet_length - 1);
00478
00479
00480 if(gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS)
00481 {
00482
00483 if(rx_packet[0] == GZP_CMD_ENCRYPTED_USER_DATA_RESP)
00484 {
00485 gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH);
00486
00487
00488 if(gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]))
00489 {
00490
00491 if(!gzp_id_req_pending)
00492 {
00493 gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
00494 }
00495 return true;
00496 }
00497 else
00498 {
00499 return false;
00500 }
00501 }
00502 }
00503
00504 return false;
00505 }
00506
00507 static bool gzp_key_update(void)
00508 {
00509 uint8_t tx_packet[GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH], rx_packet[GZLL_MAX_ACK_PAYLOAD_LENGTH];
00510
00511
00512 tx_packet[0] = GZP_CMD_KEY_UPDATE_PREPARE;
00513
00514
00515 if(gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS)
00516 {
00517 if(rx_packet[0] == GZP_CMD_KEY_UPDATE_PREPARE_RESP)
00518 {
00519 gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]);
00520
00521
00522 tx_packet[0] = GZP_CMD_KEY_UPDATE;
00523 gzp_add_validation_id(&tx_packet[GZP_CMD_KEY_UPDATE_VALIDATION_ID]);
00524 gzp_random_numbers_generate(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY], GZP_DYN_KEY_LENGTH);
00525 gzp_crypt_set_dyn_key(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY]);
00526
00527
00528 gzp_crypt_select_key(GZP_KEY_EXCHANGE);
00529 gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1);
00530
00531
00532 if(gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE))
00533 {
00534 return true;
00535 }
00536 }
00537 }
00538
00539 return false;
00540 }
00541
00542 #endif
00543
00544 bool gzp_set_host_id(const uint8_t * id)
00545 {
00546 memcpy(gzp_host_id, id, GZP_HOST_ID_LENGTH);
00547 return true;
00548 }
00549
00550 bool gzp_get_host_id(uint8_t * dst_id)
00551 {
00552 memcpy(dst_id, gzp_host_id, GZP_HOST_ID_LENGTH);
00553 return true;
00554 }
00555
00556 static void gzp_params_db_add(const uint8_t* src_element, uint8_t index)
00557 {
00558 hal_flash_bytes_write(GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE), src_element, GZP_PARAMS_DB_ELEMENT_SIZE);
00559 }
00560
00561 static void gzp_params_db_read(uint8_t* dst_element, uint8_t index)
00562 {
00563 hal_flash_bytes_read(GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE), dst_element, GZP_PARAMS_DB_ELEMENT_SIZE);
00564 }
00565
00566 static void gzp_index_db_add(uint8_t val)
00567 {
00568 int16_t i;
00569 uint8_t temp_val;
00570
00571
00572 for(i = 0; i < GZP_INDEX_DB_SIZE; i++)
00573 {
00574 temp_val = hal_flash_byte_read(GZP_INDEX_DB_ADR + i);
00575
00576
00577 if(i != (GZP_INDEX_DB_SIZE - 1))
00578 {
00579 if((temp_val & 0x0f) == 0x0f)
00580 {
00581 temp_val = (temp_val & 0xf0) | val;
00582 break;
00583 }
00584
00585 else if((temp_val & 0xf0) == 0xf0)
00586 {
00587 temp_val = (temp_val & 0x0f) | (val << 4);
00588 break;
00589 }
00590 }
00591 else
00592 {
00593 temp_val = (GZP_PARAMS_DB_MAX_ENTRIES << 4) | val;
00594 break;
00595 }
00596 }
00597
00598
00599 hal_flash_byte_write(GZP_INDEX_DB_ADR + i, temp_val);
00600 }
00601
00602 static uint8_t gzp_index_db_read()
00603 {
00604 uint8_t retval;
00605 int16_t i;
00606
00607
00608 for(i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--)
00609 {
00610 retval = hal_flash_byte_read(GZP_INDEX_DB_ADR + i);
00611
00612 if(retval != 0xff)
00613 {
00614 break;
00615 }
00616 }
00617
00618 if(retval == 0xff)
00619 {
00620 retval = GZP_PARAMS_DB_MAX_ENTRIES;
00621 }
00622 else if((retval & 0xf0) != 0xf0)
00623 {
00624 retval >>= 4;
00625 }
00626 else
00627 {
00628 retval &= 0x0f;
00629 }
00630
00631 return retval;
00632 }
00633
00634 static bool gzp_index_db_full()
00635 {
00636 return ((GZP_INDEX_DB_SIZE == 0) || ((hal_flash_byte_read(GZP_INDEX_DB_ADR + (GZP_INDEX_DB_SIZE - 1)) != 0xff)));
00637 }
00638
00639 static bool gzp_index_db_empty()
00640 {
00641 return ((GZP_INDEX_DB_SIZE == 0) || hal_flash_byte_read(GZP_INDEX_DB_ADR) == 0xff);
00642 }
00643
00644 static bool gzp_array_is_set(const uint8_t* src, uint8_t length)
00645 {
00646 uint8_t i;
00647
00648 for(i = 0; i < length; i++)
00649 {
00650 if(*(src++) != 0xff)
00651 {
00652 return false;
00653 }
00654 }
00655 return true;
00656 }
00657
00658 static bool gzp_params_store(bool store_all)
00659 {
00660 uint8_t i;
00661 bool write_index_db = false;
00662 bool write_param_db = false;
00663 uint8_t new_db_index;
00664 uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE];
00665
00666
00667 if(store_all)
00668 {
00669
00670 for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
00671 {
00672 gzp_params_db_read(temp_element, i);
00673
00674 if(((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0))
00675 {
00676 write_index_db = true;
00677 new_db_index = i;
00678 break;
00679 }
00680 }
00681
00682
00683 if(!write_index_db)
00684 {
00685 for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
00686 {
00687 gzp_params_db_read(temp_element, i);
00688
00689 if(((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \
00690 (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], GZP_HOST_ID_LENGTH)))
00691 {
00692 memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH);
00693 new_db_index = i;
00694 write_index_db = true;
00695 write_param_db = true;
00696 break;
00697 }
00698 }
00699 }
00700
00701
00702 if(!write_index_db)
00703 {
00704 for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
00705 {
00706 gzp_params_db_read(temp_element, i);
00707
00708 if(gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE))
00709 {
00710 memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH);
00711 memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH);
00712 new_db_index = i;
00713 write_index_db = true;
00714 write_param_db = true;
00715 break;
00716 }
00717 }
00718 }
00719 }
00720 else
00721 {
00722
00723 for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
00724 {
00725 gzp_params_db_read(temp_element, i);
00726
00727 if((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0)
00728 {
00729
00730 write_index_db = true;
00731 new_db_index = i;
00732 break;
00733 }
00734 }
00735
00736
00737 if(!write_index_db)
00738 {
00739 for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
00740 {
00741 gzp_params_db_read(temp_element, i);
00742
00743 if(gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH))
00744 {
00745 memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH);
00746 write_index_db = true;
00747 write_param_db = true;
00748 new_db_index = i;
00749 break;
00750 }
00751 }
00752 }
00753 }
00754
00755 if(write_param_db)
00756 {
00757 gzp_params_db_add(temp_element, new_db_index);
00758 }
00759
00760 if(write_index_db)
00761 {
00762 if(!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES))
00763 {
00764 gzp_index_db_add(new_db_index);
00765
00766 return true;
00767 }
00768 }
00769
00770 return false;
00771 }
00772
00773 static bool gzp_params_restore(void)
00774 {
00775 uint8_t i;
00776 uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE];
00777
00778 if(!gzp_index_db_full() && !gzp_index_db_empty())
00779 {
00780 i = gzp_index_db_read();
00781
00782 if(i < GZP_PARAMS_DB_MAX_ENTRIES)
00783 {
00784 gzp_params_db_read(temp_element, i);
00785 memcpy(gzp_system_address, &temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH);
00786 gzp_set_host_id(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID]);
00787 return true;
00788 }
00789 }
00790
00791 return false;
00792 }
00793
00794 void gzp_delay_rx_periods(uint16_t rx_periods)
00795 {
00796 uint16_t i;
00797
00798 for(i=0; i < rx_periods; i++)
00799 {
00800 delay_us(GZLL_DEFAULT_PARAM_RX_PERIOD);
00801 }
00802 }
00803