/**************************************************************************** * * NAME: MibNwkProfile_vApply * * DESCRIPTION: * Timing function * ****************************************************************************/ PUBLIC void MibNwkProfile_vApply(void) { tsNwkProfile sNwkProfile; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_PROFILE, "\nMibNwkProfile_vApply()"); /* Read network profile */ vJnc_GetNwkProfile(&sNwkProfile); /* Update min beacon LQI */ sNwkProfile.u8MinBeaconLQI = psMibNwkProfile->sPerm.u8MinBeaconLqi; /* In standalone mode ? */ if (u16Api_GetStackMode() & MIB_COMMON_STACK_MODE_STANDALONE) { /* Zero profile values */ sNwkProfile.u8MaxFailedPkts = 0; sNwkProfile.u16RouterPingPeriod = 0; } /* In gateway mode ? */ else { /* Apply profile values */ sNwkProfile.u8MaxFailedPkts = psMibNwkProfile->sPerm.u8MaxFailedPackets; sNwkProfile.u16RouterPingPeriod = psMibNwkProfile->sPerm.u16RouterPingPeriod; } /* Apply as user profiles */ (void) bJnc_SetJoinProfile(PROFILE_USER, &sNwkProfile); (void) bJnc_SetRunProfile(PROFILE_USER, &sNwkProfile); }
/**************************************************************************** * * NAMES: DriverBulb_vTick * * DESCRIPTION: 10 ms Ticks from higher layer for timing * ****************************************************************************/ PUBLIC void DriverBulb_vTick(void) { #ifdef MK_JIP_DEVICE_ID /* Indicating gateway mode on LED ? */ #if (LAMP_GW_PIN < 21) { /* Gateway mode ? */ if (u16Api_GetStackMode() == 0) { /* Set output low, turning on LED */ vAHI_DioSetOutput(0, (1 << LAMP_GW_PIN)); } /* Non-gateway mode ? */ else { /* Set output high, turning off LED */ vAHI_DioSetOutput((1 << LAMP_GW_PIN), 0); } } #endif #endif }
/**************************************************************************** * * NAME: MibNwkSecurity_vStackEvent * * DESCRIPTION: * Called when stack events take place * ****************************************************************************/ PUBLIC bool_t MibNwkSecurity_bStackEvent(te6LP_StackEvent eEvent, uint8 *pu8Data, uint8 u8DataLen) { bool_t bReturn = FALSE; /* Which event ? */ switch (eEvent) { /* Joined network ? */ /* Started network ? */ case E_STACK_JOINED: case E_STACK_STARTED: { tsNwkInfo *psNwkInfo; /* Cast data pointer to correct type */ psNwkInfo = (tsNwkInfo *) pu8Data; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\nMibNwkSecurity_vStackEvent(JOINED) {%x}", u16Api_GetStackMode()); /* Note the channel and PAN ID */ psMibNwkSecurity->sPerm.u8Channel = psNwkInfo->u8Channel; psMibNwkSecurity->sPerm.u16PanId = psNwkInfo->u16PanID; /* Security enabled ? */ if (psMibNwkSecurity->bSecurity) { /* Not a coordinator ? */ if (psMibNwkSecurity->u8DeviceType != E_6LP_COORDINATOR) { /* Take a copy of the network key */ memcpy(&psMibNwkSecurity->sPerm.asSecurityKey[MIB_NWK_SECURITY_SECURITY_KEY_NETWORK], psApi_GetNwkKey(), sizeof(tsSecurityKey)); /* Invalidate commissioning key */ vSecurityInvalidateKey(1); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvSecurityInvalidateKey(1)"); /* Have we joined in standalone mode ? */ if (u16Api_GetStackMode() & STACK_MODE_STANDALONE) { /* Make sure we are not in commissioning mode */ vApi_SetStackMode(STACK_MODE_STANDALONE); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvApi_SetStackMode(%x)", STACK_MODE_STANDALONE); /* Add parent as secure address */ MibNwkSecurity_bAddSecureAddr(&psNwkInfo->sParentAddr); } } } /* Note network is up */ psMibNwkSecurity->bUp = TRUE; /* Save data to flash */ psMibNwkSecurity->bSaveRecord = TRUE; } break; /* Stack reset ? */ case E_STACK_RESET: { /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\nMibNwkSecurity_vStackEvent(RESET, %d) {%x}", psMibNwkSecurity->bUp, u16Api_GetStackMode()); /* Security enabled ? */ if (psMibNwkSecurity->bSecurity) { /* Not a coordinator ? */ if (psMibNwkSecurity->u8DeviceType != E_6LP_COORDINATOR) { /* Not joined ? */ if (psMibNwkSecurity->bUp == FALSE) { /* Trying to rejoin a gateway network ? */ if (psMibNwkSecurity->u8GatewayRejoin > 0) { /* Decrement rejoin counter */ psMibNwkSecurity->u8GatewayRejoin--; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tpsMibNwkSecurity->u8Rejoin=%d", psMibNwkSecurity->u8GatewayRejoin); } /* Not trying to rejoin a gateway network ? */ if (psMibNwkSecurity->u8GatewayRejoin == 0) { /* Were we trying to join in standalone mode ? */ if (u16Api_GetStackMode() & STACK_MODE_STANDALONE) { /* Set profile for gateway system */ MibNwkSecurity_vSetProfile(FALSE); /* Use gateway commissioning key */ MibNwkSecurity_vSetSecurityKey(MIB_NWK_SECURITY_SECURITY_KEY_GATEWAY_COMMISSIONING); /* Swap to gateway mode */ vApi_SetStackMode(0); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvApi_SetStackMode(%x)", 0); } /* Trying to join in gateway mode ? */ else { /* Set profile for standalone system */ MibNwkSecurity_vSetProfile(TRUE); /* Use standalone commissioning key */ MibNwkSecurity_vSetSecurityKey(MIB_NWK_SECURITY_SECURITY_KEY_STANDALONE_COMMISSIONING); /* Swap to standalone commissioning mode */ vApi_SetStackMode(STACK_MODE_STANDALONE | STACK_MODE_COMMISSION); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvApi_SetStackMode(%x)", (STACK_MODE_STANDALONE | STACK_MODE_COMMISSION)); } } } /* Network was up so we've lost it ? */ else { /* Lost standalone system (shouldn't happen!!!) ? */ if (u16Api_GetStackMode() & STACK_MODE_STANDALONE) { /* Return unexpected event - which should force a reset */ bReturn = TRUE; } /* Lost gateway system ? */ else { /* Make three attempts to rejoin gateway with current network key */ psMibNwkSecurity->u8GatewayRejoin = 3; } } } /* Coordinator (shouldn't happen!!!) ? */ else { /* Return unexpected event - which should force a reset */ bReturn = TRUE; } } /* Note network is down */ psMibNwkSecurity->bUp = FALSE; } break; /* Others ? */ default: { /* Do nothing */ ; } break; } return bReturn; }
/**************************************************************************** * * NAME: vKeyPressTracker * * DESCRIPTION: * * track user key press sequences on remote for various operating conditions * training and erasing behaviour * * PARAMETERS: Name RW Usage * eTouckKeys R The key pressed on the remote * * RETURNS: None * ****************************************************************************/ PUBLIC teKeyStatusCode eKeyPressTracker(teTouchKeys eTouchKeys, bool_t bNormal) { uint8 u8Index; teKeyStatusCode eKeyStatusCode = E_MODE_NORMAL; if (eTouchKeys != E_KEY_NONE) { for (u8Index = 0;u8Index<5;u8Index++) { sKeyInfo.au8History[u8Index] = sKeyInfo.au8History[u8Index+1]; } sKeyInfo.au8History[5] = eTouchKeys; /* S-R latch to track when user is entering a mode change */ if (sKeyInfo.au8History[5] == E_KEY_PROG) { sKeyInfo.bModeChange = TRUE; sKeyInfo.u16ModeChangeTimer = MODE_CHANGE_KEY_PRESS_TIMEOUT; } } else { /* No key pressed (=last key released so we check if we were dimming up or */ /* down. If so then we need to tell the lamp to stop changing the light level */ if (((sKeyInfo.au8History[5] == E_KEY_UP) || (sKeyInfo.au8History[5] == E_KEY_DOWN)) && !sKeyInfo.bModeChange) { if (bNormal) vSetModeMibVar(eTouchKeys); } } while (eTouchKeys != E_KEY_NONE) /* Only process key presses */ { if (memcmp(au8Decommission,&sKeyInfo.au8History[1],4)==0) { if ((eGetKeyType(eTouchKeys) == E_KEY_TYPE_GROUP) && (u16Api_GetStackMode() & NONE_GATEWAY_MODE) && bNormal) { DBG_vPrintf(TRACE_KEYS,"\nDecommission GRP"); eKeyStatusCode = E_MODE_DCMSNG_START; break; } } if (memcmp(au8Commission,&sKeyInfo.au8History[1],4)==0) { /* Are we in standalone mode ? */ if ((u16Api_GetStackMode() & NONE_GATEWAY_MODE) && bNormal) { /* Ended with a group ? */ if (eGetKeyType(eTouchKeys) == E_KEY_TYPE_GROUP) { /* Commission bulb */ eKeyStatusCode = E_MODE_CMSNG_BULB_START; break; } /* Ended with down ? */ else if (eTouchKeys == E_KEY_DOWN) { /* Commission remote */ eKeyStatusCode = E_MODE_CMSNG_REMOTE_START; break; } /* Ended with up ? */ else if (eTouchKeys == E_KEY_UP) { /* Clone remote */ eKeyStatusCode = E_MODE_CLONE_REMOTE_START; break; } /* Ended with off ? */ else if (eTouchKeys == E_KEY_OFF) { /* Clone border router */ eKeyStatusCode = E_MODE_CMSNG_BR_START; break; } } } if (memcmp(au8StartNwk,&sKeyInfo.au8History[2],4)==0) { DBG_vPrintf(TRACE_KEYS,"\nStandalone combo"); DBG_vPrintf(TRACE_KEYS,"\nStandalone mode"); /* Reset into standalone mode */ eKeyStatusCode = E_MODE_RESET_TO_STANDALONE; break; } if (memcmp(au8JoinNwk,&sKeyInfo.au8History[2],4)==0) { DBG_vPrintf(TRACE_KEYS,"\nGateway combo"); DBG_vPrintf(TRACE_KEYS,"\nGateway mode"); /* Reset into gateway mode */ eKeyStatusCode = E_MODE_RESET_TO_GATEWAY; break; } if (memcmp(au8Reset,&sKeyInfo.au8History[2],4)==0) { DBG_vPrintf(TRACE_KEYS,"\nReset combo"); /* Reset into gateway mode */ eKeyStatusCode = E_MODE_RESET; break; } if (memcmp(au8FactoryReset,&sKeyInfo.au8History[2],4)==0) { DBG_vPrintf(TRACE_KEYS,"\nFactory reset combo"); /* Reset into gateway mode */ eKeyStatusCode = E_MODE_FACTORY_RESET; break; } if (memcmp(au8AddGroup,&sKeyInfo.au8History[2],3)==0) { /* Ended with a group ? */ if (eGetKeyType(eTouchKeys) == E_KEY_TYPE_GROUP && bNormal) { /* Add group */ eKeyStatusCode = E_MODE_ADD_GROUP_START; break; } } if (memcmp(au8DelGroup,&sKeyInfo.au8History[2],3)==0) { /* Ended with a group ? */ if (eGetKeyType(eTouchKeys) == E_KEY_TYPE_GROUP && bNormal) { /* Del group */ eKeyStatusCode = E_MODE_DEL_GROUP_START; break; } } break; } /* while (eTouchKeys != E_KEY_NONE) */ if (!sKeyInfo.bModeChange) { if (bNormal) { if (eGetKeyType(eTouchKeys) == E_KEY_TYPE_COMMAND) { vSetModeMibVar(eTouchKeys); } } } else /* Successfully changed mode within timeout allowed so cancel timer */ { if ((sKeyInfo.u16ModeChangeTimer >0) && (eKeyStatusCode != E_MODE_NORMAL)) { sKeyInfo.u16ModeChangeTimer = 0; sKeyInfo.bModeChange = FALSE; } } return (eKeyStatusCode); }
/**************************************************************************** * * NAME: MibNwkProfile_bCbScanSort * * DESCRIPTION: * Sorts incoming beacon repsonses into preferred order * ****************************************************************************/ PUBLIC bool_t MibNwkProfile_bScanSortCallback(tsScanElement *pasScanResult, uint8 u8ScanListSize, uint8 *pau8ScanListOrder) { bool_t bReturn = FALSE; uint8 i,n,tmp; bool_t bSwapped; DBG_vPrintf(TRUE, "\nMibNwkProfile_bCbScanSortCallback(%d)", u8ScanListSize); if (u8ScanListSize > 0) { n = u8ScanListSize; /* simple bubblesort for the time being, since it's only a small list */ do { bSwapped = FALSE; n = n - 1; for (i=0;i<n;i++) { /* sort order is depth, loading and link quality in that order */ if (MibNwkProfile_bScanSortCheckSwap(pasScanResult, i, pau8ScanListOrder)) { /* to make sort quicker we'll find the final order first, then copy all the data later */ tmp = pau8ScanListOrder[i]; pau8ScanListOrder[i] = pau8ScanListOrder[i+1]; pau8ScanListOrder[i+1] = tmp; bSwapped = TRUE; } } } while (bSwapped); /* Loop through entries */ for (i = 0; i < u8ScanListSize; i++) { DBG_vPrintf(CONFIG_DBG_MIB_NWK_PROFILE, "\nBcnSrt {%x:%x %x %d %d %d %d %x %x %x%x%x%x%x%x %d} [%x]", pasScanResult[pau8ScanListOrder[i]].sExtAddr.u32H, pasScanResult[pau8ScanListOrder[i]].sExtAddr.u32L, pasScanResult[pau8ScanListOrder[i]].u16PanId, pasScanResult[pau8ScanListOrder[i]].u16Depth, pasScanResult[pau8ScanListOrder[i]].u8Channel, pasScanResult[pau8ScanListOrder[i]].u8LinkQuality, pasScanResult[pau8ScanListOrder[i]].u8NumChildren, pasScanResult[pau8ScanListOrder[i]].u16StackMode, pasScanResult[pau8ScanListOrder[i]].u32DevType, pasScanResult[pau8ScanListOrder[i]].au8UserDefined[0], pasScanResult[pau8ScanListOrder[i]].au8UserDefined[1], pasScanResult[pau8ScanListOrder[i]].au8UserDefined[2], pasScanResult[pau8ScanListOrder[i]].au8UserDefined[3], pasScanResult[pau8ScanListOrder[i]].au8UserDefined[4], pasScanResult[pau8ScanListOrder[i]].au8UserDefined[5], pasScanResult[pau8ScanListOrder[i]].u8JoinProfile, u16Api_GetStackMode()); } } return bReturn; }
/**************************************************************************** * * NAME: MibNwkConfigPatch_bBeaconNotifyCallback * * DESCRIPTION: * Callback when processing beacon responses * Ignores responses from nodes using a different network ID * ****************************************************************************/ PUBLIC bool_t MibNwkConfigPatch_bBeaconNotifyCallback(tsScanElement *psBeaconInfo, uint16 u16ProtocolVersion) { bool_t bReturn; /* Call unpatched function */ bReturn = MibNwkConfig_bBeaconNotifyCallback(psBeaconInfo, u16ProtocolVersion); /* Going to accept this response ? */ if (bReturn) { /* Got a valid nwk status data pointer ? */ if (psMibNwkStatus != NULL) { /* Joining for first time ? */ if (psMibNwkStatus->sPerm.u8UpMode == MIB_NWK_STATUS_UP_MODE_NONE) { /* LQI below preferred level ? */ if (psBeaconInfo->u8LinkQuality < CONFIG_PRF_BEACON_LQI) { /* Reject beacon */ bReturn = FALSE; } } /* Re-joining ? */ else { /* LQI below minimum level ? */ if (psBeaconInfo->u8LinkQuality < CONFIG_MIN_BEACON_LQI) { /* Reject beacon */ bReturn = FALSE; } } } } /* Still going to accept this repsonse ? */ if (bReturn) { /* Is this a response from a device in standalone commissioning mode ? */ if ((psBeaconInfo->u16StackMode & (STACK_MODE_STANDALONE | STACK_MODE_COMMISSION)) == (STACK_MODE_STANDALONE | STACK_MODE_COMMISSION)) { /* Are we currently in gateway mode ? */ if ((u16Api_GetStackMode() & STACK_MODE_STANDALONE) == 0) { /* Flag that we need to complete swapping to standalone mode */ bStandaloneBeacon = TRUE; /* Swap to standalone commissioning mode */ vApi_SetStackMode(STACK_MODE_STANDALONE | STACK_MODE_COMMISSION); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_CONFIG, "\n\tvApi_SetStackMode(%x)", (STACK_MODE_STANDALONE | STACK_MODE_COMMISSION)); } } } DBG_vPrintf(CONFIG_DBG_MIB_NWK_CONFIG, "\nBeacon {%x:%x %x %d %d %d %d %x %x %02x%02x%02x%02x %02x%02x %d} [%x] = %d", psBeaconInfo->sExtAddr.u32H, psBeaconInfo->sExtAddr.u32L, psBeaconInfo->u16PanId, psBeaconInfo->u16Depth, psBeaconInfo->u8Channel, psBeaconInfo->u8LinkQuality, psBeaconInfo->u8NumChildren, psBeaconInfo->u16StackMode, psBeaconInfo->u32DevType, psBeaconInfo->au8UserDefined[0], psBeaconInfo->au8UserDefined[1], psBeaconInfo->au8UserDefined[2], psBeaconInfo->au8UserDefined[3], psBeaconInfo->au8UserDefined[4], psBeaconInfo->au8UserDefined[5], psBeaconInfo->u8JoinProfile, u16Api_GetStackMode(), bReturn); return bReturn; }