· 6 years ago · Apr 12, 2019, 08:12 PM
1/**************************************************************************************************
2 Filename: ZGlobals.c
3 Revised: $Date: 2015-10-05 14:56:09 -0700 (Mon, 05 Oct 2015) $
4 Revision: $Revision: 44517 $
5
6 Description: User definable Z-Stack parameters.
7
8
9 Copyright 2007-2015 Texas Instruments Incorporated. All rights reserved.
10
11 IMPORTANT: Your use of this Software is limited to those specific rights
12 granted under the terms of a software license agreement between the user
13 who downloaded the software, his/her employer (which must be your employer)
14 and Texas Instruments Incorporated (the "License"). You may not use this
15 Software unless you agree to abide by the terms of the License. The License
16 limits your use, and you acknowledge, that the Software may not be modified,
17 copied or distributed unless embedded on a Texas Instruments microcontroller
18 or used solely and exclusively in conjunction with a Texas Instruments radio
19 frequency transceiver, which is integrated into your product. Other than for
20 the foregoing purpose, you may not use, reproduce, copy, prepare derivative
21 works of, modify, distribute, perform, display or sell this Software and/or
22 its documentation for any purpose.
23
24 YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
25 PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
26 INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
27 NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
28 TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
29 NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
30 LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
31 INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
32 OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
33 OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
34 (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
35
36 Should you have any questions regarding your right to use this Software,
37 contact Texas Instruments Incorporated at www.TI.com.
38**************************************************************************************************/
39
40/*********************************************************************
41 * INCLUDES
42 */
43
44#include "ZComDef.h"
45#include "OSAL_Nv.h"
46#include "ZDObject.h"
47#include "ZGlobals.h"
48#include "ZDNwkMgr.h"
49#include "OnBoard.h"
50#include "ZDSecMgr.h"
51#include "bdb.h"
52
53/*********************************************************************
54 * MACROS
55 */
56
57/*********************************************************************
58 * CONSTANTS
59 */
60
61/*********************************************************************
62 * TYPEDEFS
63 */
64
65typedef struct zgItem
66{
67 uint16 id;
68 uint16 len;
69 void *buf;
70} zgItem_t;
71
72/*********************************************************************
73 * NWK GLOBAL VARIABLES
74 */
75
76// Polling values
77uint32 zgPollRate = POLL_RATE;
78uint32 zgSavedPollRate = POLL_RATE;
79uint16 zgQueuedPollRate = QUEUED_POLL_RATE;
80uint16 zgResponsePollRate = RESPONSE_POLL_RATE;
81uint16 zgRejoinPollRate = REJOIN_POLL_RATE;
82
83// Rejoin backoff (silent period ) duration
84uint32 zgDefaultRejoinBackoff = REJOIN_BACKOFF;
85
86// Rejoin scan duration
87uint32 zgDefaultRejoinScan = REJOIN_SCAN ;
88
89// Transmission retries numbers
90uint8 zgMaxDataRetries = NWK_MAX_DATA_RETRIES;
91uint8 zgMaxPollFailureRetries = MAX_POLL_FAILURE_RETRIES;
92
93// Default channel list
94uint32 zgDefaultChannelList = 0;
95
96// Stack profile Id
97uint8 zgStackProfile = STACK_PROFILE_ID;
98
99// Default indirect message holding timeout
100uint8 zgIndirectMsgTimeout = NWK_INDIRECT_MSG_TIMEOUT;
101
102// Security mode
103uint8 zgSecurityMode = ZG_SECURITY_MODE;
104
105// Secure permit join
106uint8 zgSecurePermitJoin = TRUE;
107
108// trustcenter allows rejoins using well known or default keys
109uint8 zgAllowRejoins = FALSE; // FALSE by default
110
111//if zgAllowRejoins is set to FALSE, the rejoining device will receive a rejoin rsp success and also a leave command.
112//The leave command will have set the rejoin parameter = 'zgAllowRejoinsOptions' value.
113uint8 zgAllowRejoinsOptions = FALSE; //FALSE by default
114
115//allowInstallCodes
116uint8 zgAllowInstallCodes = ZG_IC_SUPPORTED_NOT_REQUIRED;
117//Allow other devices in the network to change the TC permit joining policy
118uint8 zgAllowRemoteTCPolicyChange = TRUE;
119
120//Change these policies to FALSE is not supported
121//uint8 zgAllowTrustCenterLinkKeyRequest = TRUE;
122//uint8 zgAllowApplicationKeyRequests = TRUE;
123
124
125// Trust center address
126uint8 zgApsTrustCenterAddr[Z_EXTADDR_LEN] = { 0 };
127
128
129// Route Discovery Time - amount of time that a route request lasts
130uint8 zgRouteDiscoveryTime = ROUTE_DISCOVERY_TIME;
131
132// Route expiry
133uint8 zgRouteExpiryTime = ROUTE_EXPIRY_TIME;
134
135// Extended PAN Id
136uint8 zgExtendedPANID[Z_EXTADDR_LEN];
137
138// Broadcast parameters
139uint8 zgMaxBcastRetires = MAX_BCAST_RETRIES;
140uint8 zgPassiveAckTimeout = PASSIVE_ACK_TIMEOUT;
141uint8 zgBcastDeliveryTime = BCAST_DELIVERY_TIME;
142
143// Network mode
144uint8 zgNwkMode = NWK_MODE;
145
146// Many-to-one values
147uint8 zgConcentratorEnable = CONCENTRATOR_ENABLE;
148uint8 zgConcentratorDiscoveryTime = CONCENTRATOR_DISCOVERY_TIME;
149uint8 zgConcentratorRadius = CONCENTRATOR_RADIUS;
150uint8 zgConcentratorRC = CONCENTRATOR_ROUTE_CACHE; // concentrator with route cache (no memory constraints)
151uint8 zgNwkSrcRtgExpiryTime = SRC_RTG_EXPIRY_TIME;
152
153// Cleanup Child Table according to routing traffic
154uint8 zgRouterOffAssocCleanup = FALSE;
155
156// Determines whether or not a remote NWK leave request command frame received
157// by the local device is accepted .
158uint8 zgNwkLeaveRequestAllowed = TRUE;
159
160
161
162// Enable or disable processing a leave request confirm generated by local
163// device when it sends a leave request to a remote device.
164// NOTE: This is only used for testing purposes, do not disable
165uint8 zgNwkProcessLocalLeaveCnf = TRUE;
166
167
168//======= Child Aging PARENT ROUTER (ZR/ZC) configuration ========
169// You can setup a router to support Child Table Aging in 1 of 2 modes of
170// operation. The first mode is NWK_PARENT_INFO_ORPHAN_NOTIFICATION and it
171// expects end devices to use orphan scan periodically as a means of a keep-alive
172// notification to the parent. The other mode is NWK_PARENT_INFO_MAC_DATA_POLL
173// which uses the end device's MAC POLL request as the keep-alive notification.
174// The first method is preferred for new devices, where the end devices provide
175// support for it (which will be manditory in future Zigbee Home Automation
176// Specifications).
177// The second method is compatible with older end devices without the need for
178// specific child aging support.
179//
180// The method supported by the router (or coordinator) is determined at build time
181// by setting zgNwkParentInformation to either NWK_PARENT_INFO_ORPHAN_NOTIFICATION
182// or NWK_PARENT_INFO_MAC_DATA_POLL.
183//
184// End device built with Child Table Aging support both methods, the method is
185// determined by the parent and communicated at run-time.
186#if ( ZG_BUILD_RTR_TYPE )
187uint8 zgNwkParentInformation = NWK_PARENT_INFO_MAC_DATA_POLL;
188#else
189uint8 zgNwkParentInformation = NWK_PARENT_INFO_UNDEFINED;
190#endif
191
192// This is an index into table Requested Timeout Enumerated Values.
193// It is used by the parent router, it indicates the default timeout value
194// for any end device that does not negotiate a different timeout value
195uint8 zgNwkEndDeviceTimeoutDefault = NWK_END_DEV_TIMEOUT_DEFAULT;
196
197// Index into table Requested Timeout Enumerated Values.
198// Used to keep the leave message into MAC queue for child devices that has expired
199uint8 zgNwkEndDeviceLeaveTimeoutDefault = NWK_END_DEVICE_LEAVE_TIMEOUT;
200//=====================================================================
201
202//========== Child Aging END DEVICE configuration ===============
203// Values used by End Device when sending End Device Timeout Request
204uint8 zgEndDeviceTimeoutValue = END_DEV_TIMEOUT_VALUE;
205uint8 zgEndDeviceConfiguration = END_DEV_CONFIGURATION;
206
207
208//=====================================================================
209
210// Determines if the Child Aging Table Management process is active or not.
211// This feature is optional and it is disabled by default.
212//
213// NOTICE: Before enabling Child Aging make sure to review all the related
214// definitions in this file, especially zgNwkParentInformation.
215uint8 zgChildAgingEnable = TRUE;
216
217//========== TouchLink NWK configuration ===============
218// Values used by Router when starts a network as initiator
219uint8 zTouchLinkNwkStartRtr = FALSE;
220
221/*********************************************************************
222 * APS GLOBAL VARIABLES
223 */
224
225// The maximum number of retries allowed after a transmission failure
226uint8 zgApscMaxFrameRetries = APSC_MAX_FRAME_RETRIES;
227
228// The maximum number of seconds (milliseconds) to wait for an
229// acknowledgement to a transmitted frame.
230
231// This number is used by polled devices.
232uint16 zgApscAckWaitDurationPolled = APSC_ACK_WAIT_DURATION_POLLED;
233
234// This number is used by non-polled devices in the following formula:
235// (100 mSec) * (_NIB.MaxDepth * zgApsAckWaitMultiplier)
236uint8 zgApsAckWaitMultiplier = 2;
237
238// The maximum number of milliseconds for the end device binding
239uint16 zgApsDefaultMaxBindingTime = APS_DEFAULT_MAXBINDING_TIME;
240
241// The 64-big identifier of the network to join or form.
242// Default set to all zeros
243uint8 zgApsUseExtendedPANID[Z_EXTADDR_LEN] = {00,00,00,00,00,00,00,00};
244
245// A boolean flag that indicates whether it is OK to use insecure join
246// on startup. Default set to TRUE
247uint8 zgApsUseInsecureJoin = TRUE;
248
249// The radius of broadcast multicast transmissions
250uint8 zgApsNonMemberRadius = APS_DEFAULT_NONMEMBER_RADIUS;
251
252// Commissioned Network Address
253uint16 zgNwkCommissionedNwkAddr = INVALID_NODE_ADDR;
254
255// APS Duplication Rejection table variables
256uint16 zgApscDupRejTimeoutInc = DEFAULT_APS_DUP_REJ_TIMEOUT_INCREMENT;
257uint8 zgApscDupRejTimeoutCount = DEFAULT_APS_DUP_REJ_TIMEOUT;
258uint16 zgApsMinDupRejTableSize = APS_DUP_REJ_ENTRIES;
259
260
261
262/*********************************************************************
263 * SECURITY GLOBAL VARIABLES
264 */
265
266// If TRUE, preConfigKey should be configured on all devices on the network
267// If false, it is configured only on the coordinator and sent to other
268// devices upon joining.
269uint8 zgPreConfigKeys = FALSE;
270
271// The type of link key in use. This will determine the security
272// policies associated with sending and receiving APS messages.
273// If ZG_GLOBAL_LINK_KEY APS TCLK security may be used for specific APS commands
274// If ZG_UNIQUE_LINK_KEY APS TCLK security is required for specific APS commands
275uint8 zgApsLinkKeyType = ZG_GLOBAL_LINK_KEY;
276
277// With changes introduced in R20 of the ZigBee specification,
278// boolean value of zgUseDefaultTCLK is set depending on zgApsLinkKeyType value.
279//
280// For zgApsLinkKeyType = ZG_GLOBAL_LINK_KEY, zgUseDefaultTCLK = TRUE
281// For zgApsLinkKeyType = ZG_UNIQUE_LINK_KEY, different devices have
282// different value:
283// ZC should have zgUseDefaultTCLK = FALSE
284// Other devices should have zgUseDefaultTCLK = TRUE
285// This is initialized in zgInitItems()
286// If ZG_UNIQUE_LINK_KEY, individual trust center link key between each device
287// and the trust center should be manually configured via MT_SYS_OSAL_NV_WRITE
288uint8 zgUseDefaultTCLK;
289
290#if defined ( APP_TP2_TEST_MODE )
291uint8 guTxApsSecON = TP_GU_BOTH;
292uint8 guEnforceRxApsSec = TP_GU_ALL;
293#endif
294
295uint8 zgApsAllowR19Sec = FALSE;
296uint8 zgSwitchCoordKey = FALSE;
297uint8 zgSwitchCoordKeyIndex = 0;
298
299/*********************************************************************
300 * ZDO GLOBAL VARIABLES
301 */
302
303// Configured PAN ID
304uint16 zgConfigPANID = ZDAPP_CONFIG_PAN_ID;
305
306// Device Logical Type
307uint8 zgDeviceLogicalType = DEVICE_LOGICAL_TYPE;
308
309// Startup Delay
310uint8 zgStartDelay = START_DELAY;
311
312#if !defined MT_TASK
313// Flag to use verbose (i.e. "cc2480-style") direct MT callbacks in ZDProfile.c, ZDP_IncomingData().
314uint8 zgZdoDirectCB = TRUE;
315#endif
316
317// Min number of attempted transmissions for Channel Interference detection
318uint8 zgNwkMgrMinTransmissions = ZDNWKMGR_MIN_TRANSMISSIONS;
319
320/*********************************************************************
321 * APPLICATION GLOBAL VARIABLES
322 */
323
324// Network Manager Mode
325uint8 zgNwkMgrMode = ZDNWKMGR_ENABLE;
326
327/*********************************************************************
328 * NON-STANDARD GLOBAL VARIABLES
329 */
330
331// Simple API Endpoint
332uint8 zgSapiEndpoint = SAPI_ENDPOINT;
333
334/*********************************************************************
335 * LOCAL VARIABLES
336 */
337
338/*********************************************************************
339 * ZGlobal Item Table
340 */
341static CONST zgItem_t zgItemTable[] =
342{
343#if defined ( NV_INIT )
344#if !defined MT_TASK
345 {
346 ZCD_NV_ZDO_DIRECT_CB, sizeof(zgZdoDirectCB), &zgZdoDirectCB
347 },
348#endif
349 {
350 ZCD_NV_LOGICAL_TYPE, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType
351 },
352 {
353 ZCD_NV_POLL_RATE, sizeof(zgPollRate), &zgPollRate
354 },
355 {
356 ZCD_NV_QUEUED_POLL_RATE, sizeof(zgQueuedPollRate), &zgQueuedPollRate
357 },
358 {
359 ZCD_NV_RESPONSE_POLL_RATE, sizeof(zgResponsePollRate), &zgResponsePollRate
360 },
361 {
362 ZCD_NV_REJOIN_POLL_RATE, sizeof(zgRejoinPollRate), &zgRejoinPollRate
363 },
364 {
365 ZCD_NV_DATA_RETRIES, sizeof(zgMaxDataRetries), &zgMaxDataRetries
366 },
367 {
368 ZCD_NV_POLL_FAILURE_RETRIES, sizeof(zgMaxPollFailureRetries), &zgMaxPollFailureRetries
369 },
370 {
371 ZCD_NV_CHANLIST, sizeof(zgDefaultChannelList), &zgDefaultChannelList
372 },
373 {
374 ZCD_NV_SCAN_DURATION, sizeof(zgDefaultStartingScanDuration), &zgDefaultStartingScanDuration
375 },
376 {
377 ZCD_NV_STACK_PROFILE, sizeof(zgStackProfile), &zgStackProfile
378 },
379 {
380 ZCD_NV_INDIRECT_MSG_TIMEOUT, sizeof(zgIndirectMsgTimeout), &zgIndirectMsgTimeout
381 },
382 {
383 ZCD_NV_ROUTE_EXPIRY_TIME, sizeof(zgRouteExpiryTime), &zgRouteExpiryTime
384 },
385 {
386 ZCD_NV_EXTENDED_PAN_ID, Z_EXTADDR_LEN, zgExtendedPANID
387 },
388 {
389 ZCD_NV_BCAST_RETRIES, sizeof(zgMaxBcastRetires), &zgMaxBcastRetires
390 },
391 {
392 ZCD_NV_PASSIVE_ACK_TIMEOUT, sizeof(zgPassiveAckTimeout), &zgPassiveAckTimeout
393 },
394 {
395 ZCD_NV_BCAST_DELIVERY_TIME, sizeof(zgBcastDeliveryTime), &zgBcastDeliveryTime
396 },
397 {
398 ZCD_NV_NWK_MODE, sizeof(zgNwkMode), &zgNwkMode
399 },
400 {
401 ZCD_NV_CONCENTRATOR_ENABLE, sizeof(zgConcentratorEnable), &zgConcentratorEnable
402 },
403 {
404 ZCD_NV_CONCENTRATOR_DISCOVERY, sizeof(zgConcentratorDiscoveryTime), &zgConcentratorDiscoveryTime
405 },
406 {
407 ZCD_NV_CONCENTRATOR_RADIUS, sizeof(zgConcentratorRadius), &zgConcentratorRadius
408 },
409 {
410 ZCD_NV_CONCENTRATOR_RC, sizeof(zgConcentratorRC), &zgConcentratorRC
411 },
412 {
413 ZCD_NV_SRC_RTG_EXPIRY_TIME, sizeof(zgNwkSrcRtgExpiryTime), &zgNwkSrcRtgExpiryTime
414 },
415 {
416 ZCD_NV_ROUTE_DISCOVERY_TIME, sizeof(zgRouteDiscoveryTime), &zgRouteDiscoveryTime
417 },
418#ifndef NONWK
419 {
420 ZCD_NV_PANID, sizeof(zgConfigPANID), &zgConfigPANID
421 },
422 {
423 ZCD_NV_PRECFGKEYS_ENABLE, sizeof(zgPreConfigKeys), &zgPreConfigKeys
424 },
425 {
426 ZCD_NV_SECURITY_MODE, sizeof(zgSecurityMode), &zgSecurityMode
427 },
428 {
429 ZCD_NV_SECURE_PERMIT_JOIN, sizeof(zgSecurePermitJoin), &zgSecurePermitJoin
430 },
431 {
432 ZCD_NV_USE_DEFAULT_TCLK, sizeof(zgUseDefaultTCLK), &zgUseDefaultTCLK
433 },
434 {
435 ZCD_NV_TRUSTCENTER_ADDR, Z_EXTADDR_LEN, zgApsTrustCenterAddr
436 },
437 {
438 ZCD_NV_APS_LINK_KEY_TYPE, sizeof(zgApsLinkKeyType), &zgApsLinkKeyType
439 },
440#endif // NONWK
441 {
442 ZCD_NV_APS_FRAME_RETRIES, sizeof(zgApscMaxFrameRetries), &zgApscMaxFrameRetries
443 },
444 {
445 ZCD_NV_APS_ACK_WAIT_DURATION, sizeof(zgApscAckWaitDurationPolled), &zgApscAckWaitDurationPolled
446 },
447 {
448 ZCD_NV_APS_ACK_WAIT_MULTIPLIER, sizeof(zgApsAckWaitMultiplier), &zgApsAckWaitMultiplier
449 },
450 {
451 ZCD_NV_BINDING_TIME, sizeof(zgApsDefaultMaxBindingTime), &zgApsDefaultMaxBindingTime
452 },
453 {
454 ZCD_NV_APS_USE_EXT_PANID, Z_EXTADDR_LEN, zgApsUseExtendedPANID
455 },
456 {
457 ZCD_NV_APS_USE_INSECURE_JOIN, sizeof(zgApsUseInsecureJoin), &zgApsUseInsecureJoin
458 },
459 {
460 ZCD_NV_APS_NONMEMBER_RADIUS, sizeof(zgApsNonMemberRadius), &zgApsNonMemberRadius
461 },
462 {
463 ZCD_NV_START_DELAY, sizeof(zgStartDelay), &zgStartDelay
464 },
465 {
466 ZCD_NV_SAPI_ENDPOINT, sizeof(zgSapiEndpoint), &zgSapiEndpoint
467 },
468 {
469 ZCD_NV_NWK_MGR_MODE, sizeof(zgNwkMgrMode), &zgNwkMgrMode
470 },
471 {
472 ZCD_NV_NWKMGR_MIN_TX, sizeof(zgNwkMgrMinTransmissions), &zgNwkMgrMinTransmissions
473 },
474 {
475 ZCD_NV_ROUTER_OFF_ASSOC_CLEANUP, sizeof(zgRouterOffAssocCleanup), &zgRouterOffAssocCleanup
476 },
477 {
478 ZCD_NV_NWK_LEAVE_REQ_ALLOWED, sizeof(zgNwkLeaveRequestAllowed), &zgNwkLeaveRequestAllowed
479 },
480 {
481 ZCD_NV_COMMISSIONED_NWK_ADDR, sizeof(zgNwkCommissionedNwkAddr), &zgNwkCommissionedNwkAddr
482 },
483 {
484 ZCD_NV_APS_ALLOW_R19_SECURITY, sizeof(zgApsAllowR19Sec), &zgApsAllowR19Sec
485 },
486 {
487 ZCD_NV_APS_DUPREJ_TIMEOUT_INC, sizeof(zgApscDupRejTimeoutInc), &zgApscDupRejTimeoutInc
488 },
489 {
490 ZCD_NV_APS_DUPREJ_TIMEOUT_COUNT, sizeof(zgApscDupRejTimeoutCount), &zgApscDupRejTimeoutCount
491 },
492 {
493 ZCD_NV_APS_DUPREJ_TABLE_SIZE, sizeof(zgApsMinDupRejTableSize), &zgApsMinDupRejTableSize
494 },
495 {
496 ZCD_NV_NWK_CHILD_AGE_ENABLE, sizeof(zgChildAgingEnable), &zgChildAgingEnable
497 },
498 {
499 ZCD_NV_NWK_PARENT_INFO, sizeof(zgNwkParentInformation), &zgNwkParentInformation
500 },
501 {
502 ZCD_NV_NWK_ENDDEV_TIMEOUT_DEF, sizeof(zgNwkEndDeviceTimeoutDefault), &zgNwkEndDeviceTimeoutDefault
503 },
504 {
505 ZCD_NV_END_DEV_TIMEOUT_VALUE, sizeof(zgEndDeviceTimeoutValue), &zgEndDeviceTimeoutValue
506 },
507 {
508 ZCD_NV_END_DEV_CONFIGURATION, sizeof(zgEndDeviceConfiguration), &zgEndDeviceConfiguration
509 },
510#endif // NV_INIT
511 // Last item -- DO NOT MOVE IT!
512 {
513 0x00, 0, NULL
514 }
515};
516
517/*********************************************************************
518 * LOCAL FUNCTIONS
519 */
520
521static uint8 zgItemInit( uint16 id, uint16 len, void *buf, uint8 setDefault );
522
523static void zgUpgradeNVItems( void );
524
525#ifndef NONWK
526static uint8 zgPreconfigKeyInit( uint8 setDefault );
527#endif
528
529#ifdef UPGRADE_SECURITY_NV_ITEMS
530static void zgUpgradeSecurityNVItems( void );
531#endif // UPGRADE_SECURITY_NV_ITEMS
532/*********************************************************************
533 * @fn zgItemInit()
534 *
535 * @brief
536 *
537 * Initialize a global item. If the item doesn't exist in NV memory,
538 * write the system default (value passed in) into NV memory. But if
539 * it exists, set the item to the value stored in NV memory.
540 *
541 * Also, if setDefault is TRUE and the item exists, we will write
542 * the default value to NV space.
543 *
544 * @param id - item id
545 * @param len - item len
546 * @param buf - pointer to the item
547 * @param setDefault - TRUE to set default, not read
548 *
549 * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not
550 * exist in NV, NV_OPER_FAILED if failure.
551 */
552static uint8 zgItemInit( uint16 id, uint16 len, void *buf, uint8 setDefault )
553{
554 uint8 status;
555
556 // If the item doesn't exist in NV memory, create and initialize
557 // it with the value passed in.
558 status = osal_nv_item_init( id, len, buf );
559 if ( status == ZSUCCESS )
560 {
561 if ( setDefault )
562 {
563 // Write the default value back to NV
564 status = osal_nv_write( id, 0, len, buf );
565 }
566 else
567 {
568 // The item exists in NV memory, read it from NV memory
569 status = osal_nv_read( id, 0, len, buf );
570 }
571 }
572
573 return (status);
574}
575
576/*********************************************************************
577 * API FUNCTIONS
578 */
579
580/*********************************************************************
581 * @fn zgInit
582 *
583 * @brief
584 *
585 * Initialize the Z-Stack Globals. If an item doesn't exist in
586 * NV memory, write the system default into NV memory. But if
587 * it exists, set the item to the value stored in NV memory.
588 *
589 * NOTE: The Startup Options (ZCD_NV_STARTUP_OPTION) indicate
590 * that the Config state items (zgItemTable) need to be
591 * set to defaults (ZCD_STARTOPT_DEFAULT_CONFIG_STATE). The
592 *
593 * @param none
594 *
595 * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not
596 * exist in NV, NV_OPER_FAILED if failure.
597 */
598uint8 zgInit( void )
599{
600 uint8 setDefault = FALSE;
601 uint8 status;
602
603#ifdef NV_RESTORE
604 // Do we want to default the Config state values
605 if ( zgReadStartupOptions() & ZCD_STARTOPT_DEFAULT_CONFIG_STATE )
606 {
607 setDefault = TRUE;
608 }
609#else
610 setDefault = TRUE;
611#endif
612
613 status = osal_nv_item_init(ZCD_NV_BDBNODEISONANETWORK,sizeof(bdbAttributes.bdbNodeIsOnANetwork),&bdbAttributes.bdbNodeIsOnANetwork);
614
615 //Force to reset state if device is forced to FN
616 if((status == SUCCESS) && setDefault)
617 {
618 bdb_setNodeIsOnANetwork(false);
619 }
620
621#if defined (FEATURE_SYSTEM_STATS)
622 {
623 // This sections tracks the number of resets
624 uint16 bootCnt = 0;
625
626 // Update the Boot Counter
627 if ( osal_nv_item_init( ZCD_NV_BOOTCOUNTER, sizeof(bootCnt), &bootCnt ) == ZSUCCESS )
628 {
629 // Get the old value from NV memory
630 osal_nv_read( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt );
631 }
632
633 // Increment the Boot Counter and store it into NV memory
634 if ( setDefault )
635 {
636 bootCnt = 0;
637 }
638 else
639 {
640 bootCnt++;
641 }
642
643 osal_nv_write( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt );
644 }
645#endif // FEATURE_SYSTEM_STATS
646
647 zgUpgradeNVItems();
648
649 // Initialize the Extended PAN ID as my own extended address
650 ZMacGetReq( ZMacExtAddr, zgExtendedPANID );
651
652 // Initialize the items table
653 zgInitItems( setDefault );
654
655#ifndef NONWK
656 if ( ZG_SECURE_ENABLED )
657 {
658 // Initialize the Pre-Configured Key to the default key
659 zgPreconfigKeyInit( setDefault );
660
661 // Initialize NV items for all Keys: NWK, APS, TCLK and Master
662 ZDSecMgrInitNVKeyTables( setDefault );
663 }
664#endif // NONWK
665
666#ifdef UPGRADE_SECURITY_NV_ITEMS
667 zgUpgradeSecurityNVItems();
668#endif // UPGRADE_SECURITY_NV_ITEMS
669
670 // Clear the Config State default
671 if ( setDefault )
672 {
673 zgWriteStartupOptions( ZG_STARTUP_CLEAR, ZCD_STARTOPT_DEFAULT_CONFIG_STATE );
674 }
675
676 return ( ZSUCCESS );
677}
678
679/*********************************************************************
680 * @fn zgInitItems
681 *
682 * @brief Initializes RAM variables from NV. If NV items don't
683 * exist, then the NV is initialize with what is in RAM
684 * variables.
685 *
686 * @param none
687 *
688 * @return none
689 */
690void zgInitItems( uint8 setDefault )
691{
692 uint8 i = 0;
693
694 if ( ZG_BUILD_COORDINATOR_TYPE && ( zgApsLinkKeyType == ZG_UNIQUE_LINK_KEY ) )
695 {
696 zgUseDefaultTCLK = FALSE;
697 }
698 else
699 {
700 // Most of the time default TCLK will be used
701 zgUseDefaultTCLK = TRUE;
702 }
703
704 while ( zgItemTable[i].id != 0x00 )
705 {
706 // Initialize the item
707 zgItemInit( zgItemTable[i].id, zgItemTable[i].len, zgItemTable[i].buf, setDefault );
708
709 // Move on to the next item
710 i++;
711 }
712}
713
714/*********************************************************************
715 * @fn zgReadStartupOptions
716 *
717 * @brief Reads the ZCD_NV_STARTUP_OPTION NV Item.
718 *
719 * @param none
720 *
721 * @return the ZCD_NV_STARTUP_OPTION NV item
722 */
723uint8 zgReadStartupOptions( void )
724{
725 // Default to Use Config State and Use Network State
726 uint8 startupOption = 0;
727
728 // This should have been done in ZMain.c, but just in case.
729 if ( osal_nv_item_init( ZCD_NV_STARTUP_OPTION,
730 sizeof(startupOption),
731 &startupOption ) == ZSUCCESS )
732 {
733 // Read saved startup control
734 osal_nv_read( ZCD_NV_STARTUP_OPTION,
735 0,
736 sizeof( startupOption ),
737 &startupOption);
738 }
739 return ( startupOption );
740}
741
742/*********************************************************************
743 * @fn zgWriteStartupOptions
744 *
745 * @brief Writes bits into the ZCD_NV_STARTUP_OPTION NV Item.
746 *
747 * @param action - ZG_STARTUP_SET set bit, ZG_STARTUP_CLEAR to
748 * clear bit. The set bit is an OR operation, and the
749 * clear bit is an AND ~(bitOptions) operation.
750 *
751 * @param bitOptions - which bits to perform action on:
752 * ZCD_STARTOPT_DEFAULT_CONFIG_STATE
753 * ZCD_STARTOPT_DEFAULT_NETWORK_STATE
754 *
755 * @return ZSUCCESS if successful
756 */
757uint8 zgWriteStartupOptions( uint8 action, uint8 bitOptions )
758{
759 uint8 status;
760 uint8 startupOptions = 0;
761
762 status = osal_nv_read( ZCD_NV_STARTUP_OPTION,
763 0,
764 sizeof( startupOptions ),
765 &startupOptions );
766
767 if ( status == ZSUCCESS )
768 {
769 if ( action == ZG_STARTUP_SET )
770 {
771 // Set bits
772 startupOptions |= bitOptions;
773 }
774 else
775 {
776 // Clear bits
777 startupOptions &= (bitOptions ^ 0xFF);
778 }
779
780 // Changed?
781 status = osal_nv_write( ZCD_NV_STARTUP_OPTION,
782 0,
783 sizeof( startupOptions ),
784 &startupOptions );
785 }
786
787 return ( status );
788}
789
790/*********************************************************************
791 * @fn zgSetItem
792 *
793 * @brief Set RAM variables from set-NV, if it exist in the zgItemTable
794 *
795 * @param id - NV ID
796 * len - NV item length
797 * buf - pointer to the input buffer
798 *
799 * @return none
800 */
801void zgSetItem( uint16 id, uint16 len, void *buf )
802{
803
804 uint8 i = 0;
805
806 // Look up the NV item table
807 while ( zgItemTable[i].id != 0x00 )
808 {
809 if( zgItemTable[i].id == id )
810 {
811 if ( zgItemTable[i].len == len )
812 {
813 osal_memcpy( zgItemTable[i].buf, buf, len );
814 }
815 break;
816 }
817 // Move on to the next item
818 i++;
819 }
820}
821
822#ifndef NONWK
823/*********************************************************************
824 * @fn zgPreconfigKeyInit()
825 *
826 * @brief
827 *
828 * Initialize ZCD_NV_PRECFGKEY NV item. If the item doesn't exist in NV memory,
829 * write the system default (value passed in) into NV memory. But if
830 * it exists do not overwrite it.
831 *
832 * Also, if setDefault is TRUE and the item exists, we will write
833 * the default value to NV space.
834 *
835 * @param setDefault - TRUE to set default
836 *
837 * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not
838 * exist in NV, NV_OPER_FAILED if failure.
839 */
840static uint8 zgPreconfigKeyInit( uint8 setDefault )
841{
842 uint8 zgPreConfigKey[SEC_KEY_LEN];
843 uint8 status;
844
845 //NWK KEY
846 //if nwk key is set to zeros, then generate a random key and use it
847 osal_memset(zgPreConfigKey,0,SEC_KEY_LEN);
848
849#if (ZG_BUILD_RTR_TYPE)
850 if(ZG_DEVICE_RTR_TYPE)
851 {
852 if(osal_memcmp(defaultKey, zgPreConfigKey,SEC_KEY_LEN))
853 {
854 ZDSecMgrGenerateRndKey(zgPreConfigKey);
855 }
856 else
857 {
858 // Initialize the Pre-Configured Key to the default key
859 osal_memcpy( zgPreConfigKey, defaultKey, SEC_KEY_LEN );
860 }
861 }
862#endif
863
864
865 // If the item doesn't exist in NV memory, create and initialize it
866 status = osal_nv_item_init( ZCD_NV_PRECFGKEY, SEC_KEY_LEN, zgPreConfigKey );
867 if ( status == ZSUCCESS )
868 {
869 if ( setDefault )
870 {
871 // Write the default value back to NV
872 status = osal_nv_write( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, zgPreConfigKey );
873 }
874 }
875
876 // clear local copy of default key
877 osal_memset(zgPreConfigKey, 0x00, SEC_KEY_LEN);
878
879 return (status);
880}
881#endif
882
883/*********************************************************************
884 * @fn zgUpgradeNVItems()
885 *
886 * @brief
887 *
888 * Function that upgrades NV Items that have changed.
889 *
890 * @param none
891 *
892 * @return none
893 */
894static void zgUpgradeNVItems( void )
895{
896#if defined ( ZCD_NV_POLL_RATE_OLD16 )
897 {
898 // This conversion will only happen if the old poll rate exists and
899 // the new poll rate doesn't exist. It will read the old poll rate,
900 // convert it to the new poll rate, create the new poll rate NV item,
901 // then delete the old poll rate NV item.
902 uint16 oldNvLen;
903 uint16 newNvLen;
904
905 // Use the length of the NV items to determine if they exist
906 oldNvLen = osal_nv_item_len( ZCD_NV_POLL_RATE_OLD16 );
907 newNvLen = osal_nv_item_len( ZCD_NV_POLL_RATE );
908 if ( (newNvLen == 0) && (oldNvLen == sizeof ( uint16 )) )
909 {
910 // The old poll rate exists, so read it and convert to the new 32 bit poll rate
911 uint16 oldPollRate;
912 osal_nv_read( ZCD_NV_POLL_RATE_OLD16, 0, sizeof(uint16), &oldPollRate );
913 zgPollRate = (uint32)oldPollRate;
914 osal_nv_item_init( ZCD_NV_POLL_RATE, sizeof(zgPollRate), &zgPollRate );
915 osal_nv_delete( ZCD_NV_POLL_RATE_OLD16, oldNvLen );
916 }
917 }
918#endif // ZCD_NV_POLL_RATE_OLD16
919}
920
921/*********************************************************************
922 * @fn zgUpgradeSecurityNVItems()
923 *
924 * @brief
925 *
926 * Function that upgrades NV Items that have changed.
927 *
928 * @param none
929 *
930 * @return none
931 */
932#ifdef UPGRADE_SECURITY_NV_ITEMS
933static void zgUpgradeSecurityNVItems( void )
934{
935 //Nv configuration to allow upgrade from HA1.2 to Z3.0
936
937 uint8 isOnANetwork = 1;
938 //Read bdb attribute
939 if(osal_nv_read(ZCD_NV_BDBNODEISONANETWORK, 0, sizeof(uint8), &isOnANetwork) == SUCCESS)
940 {
941 //After upgrade, this parameter will be 0, then update properly as it is in a network.
942 //If the device was not in a network and is upgraded, the BDB will handle the network
943 //configuration status and will performing FN reset.
944
945 nwkSecMaterialDesc_t nwkSecMaterialDesc;
946 nwkActiveKeyItems keyItems;
947 uint8 keyAttributes;
948 uint8 tempKey[SEC_KEY_LEN];
949
950 osal_memset(tempKey, 0x00, SEC_KEY_LEN);
951
952 //Get the network frame counter from old NV item, also check if old key exists.
953 //if it doesn't, we can assume that this is factory new Z3.0 device instead of
954 //upgraded ZHA 1.2 device
955 osal_nv_read( ZCD_NV_NWKKEY, 0, sizeof( nwkActiveKeyItems ),(void *)&keyItems );
956
957 if( osal_memcmp(tempKey, keyItems.active.key, SEC_KEY_LEN) )
958 {
959 // device is factory new, don't do anything
960 }
961 // else if node is not on a network currently and is not factory new Z3.0 device,
962 // it must be ZHA 1.2 -> Z3.0.1 upgraded device
963 else if(!isOnANetwork)
964 {
965 //If none of these parameters can be configured by Nv operations BDB will be able to initialize or handle.
966
967 //set bdbNodeIsOnANetwork attribute to 1 indicating that we need to resume our network state
968 isOnANetwork = 0x01;
969 osal_nv_write( ZCD_NV_BDBNODEISONANETWORK, 0, sizeof(uint8), &isOnANetwork );
970
971 //Set the network frame counter in new NV item, frame counter will be incremented by 1000+250 in ZDApp_RestoreNwkSecMaterial()
972 //to ensure that its outgoing packets can be used by devices in its previous network
973 nwkSecMaterialDesc.FrameCounter = keyItems.frameCounter;
974
975 //Retrieve Extended PANID from NIB in NV
976 osal_nv_read( ZCD_NV_NIB, osal_offsetof(nwkIB_t,extendedPANID), Z_EXTADDR_LEN, &nwkSecMaterialDesc.extendedPanID );
977
978 //Set the BDB network security material, BDB state machine will restore network state if this is a valid entry
979 osal_nv_write( ZCD_NV_NWK_SEC_MATERIAL_TABLE_START, 0, sizeof(nwkSecMaterialDesc_t), &nwkSecMaterialDesc );
980
981 //indicate to BDB that our previous nwk was non-R21, so don't expect TC Link Key exchange
982 keyAttributes = ZG_NON_R21_NWK_JOINED;
983 osal_nv_write(ZCD_NV_TCLK_TABLE_START, osal_offsetof(APSME_TCLKDevEntry_t,keyAttributes), sizeof(uint8), &keyAttributes);
984 }
985 }
986}
987#endif // UPGRADE_SECURITY_NV_ITEMS
988/*********************************************************************
989*********************************************************************/