⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 是zmac的协议的全部完整的解析.代码例子很全
💻 C
📖 第 1 页 / 共 2 页
字号:
    // and then bitwise AND to clear from the jitMask    jitMaskSinkAdvertise = jitMaskSinkAdvertise & (BIT(childIndex) ^ 0xFFFF);  }  // This application only sends 1 message per poll. If the sleepy child gets  // data from a poll it will nap and poll again (not hibernate) until it  // doesn't get any data from a poll. In order to send more than one message  // in response to a single poll, the parent needs to be sure to clear the  // message flag (emberClearMessageFlag) after the first message has been  // put into the message queue. If the flag is cleared before that, then  // the first message will have framePending=false and the child will not  // be awake to hear the second message. The best way to handle this is  // to keep track of the number of messages sent to each child, decrement  // this for each emberUnicastSent callback, and then clear the message  // flag (in emberUnicastSent) when the number of outstanding messages go  // to zero. This application doesn't do this and instead sends one  // JIT message at a time. If there is a second JIT message on the parent  // it will be picked up on the next nap cycle, set for 1 second.  if (!sentSinkAdv) {    // check if this child has already polled for the message    if (BIT(childIndex) & jitMaskMulticastHello) {      jitMessageApsFrame.clusterId = MSG_MULTICAST_HELLO;      /*mcastHelloStatus = */ emberSendUnicast(childId,                                &jitMessageApsFrame,                                jitMessageMulticastHello);      // sentMcastHello = TRUE;      // clear the bit - invert the number that has the child index'th bit set (xor)      // and then bitwise AND to clear from the jitMask      jitMaskMulticastHello = jitMaskMulticastHello & (BIT(childIndex) ^ 0xFFFF);    }  }  // The next section of code is used for debugging and is commented out.  // Serial characters are dropped when there are a bunch of these messages  // going out at the same time so it's not very useful with more than one  // or two children, but can be helpful when initially testing modifications  // to this code (for instance, adding another JIT type)  //   //  if (sentSinkAdv) {  //    emberSerialPrintf(APP_SERIAL, "TX JIT [adv]:%2x(%x)\r\n",   //                      childId, sinkAdvStatus);  //  }  //  if (sentMcastHello) {  //    emberSerialPrintf(APP_SERIAL, "TX JIT [hello]:%2x(%x)\r\n",   //                      childId, mcastHelloStatus);  //  }  // clear the message flag if there are no msgs waiting for this node  if ((!(BIT(childIndex) & jitMaskSinkAdvertise )) &&      (!(BIT(childIndex) & jitMaskMulticastHello)))  {    status = emberClearMessageFlag(childId);    if (status != EMBER_SUCCESS) {      emberSerialPrintf(APP_SERIAL, "ERROR: %x, clear flag %2x\r\n",                         status, childId);    }    // The next three lines are commented out but may be useful when    // modifying and then debugging this code.    //else {    //  emberSerialPrintf(APP_SERIAL, "JIT: clear flag %2x\r\n", childId);    //}  }}// This is called by the stack when a device polls. When// transmitExpected is true, this means the message flag is set for// this child.//void emberPollHandler(EmberNodeId childId, boolean transmitExpected){  // functions called from within this should not contain actions that  // could take a long time. The messages sent in response to the poll  // have to be within 15ms. Doing a emberSerialWaitSend in here, for  // example would cause the sleepy end device to go back to sleep  // before the parent was able to send any messages at all.  if (transmitExpected)  {	  // Check if we need to send the initial bootload launch message.    // In addition don't call appSendJitToChild if we have bootload process    // pending since it could confuse the bootload by sending other JIT message     // and also could clear the message flag    #ifdef USE_BOOTLOADER_LIB      // Check if the child that polls is the node to be bootloaded.      if(bootloadInProgressChildId == childId) {        if (parentLaunchBootload) {          sendBootloaderLaunchMessage(bootloadInProgressEui);          parentLaunchBootload = FALSE;          // Do not try to send any other JIT message when starting           // bootload process.          return;        } else if (blState == BOOTLOAD_STATE_DELAY_BEFORE_START) {          // We have received the authentication challenge.          bootloadUtilSendAuthResponse(bootloadInProgressEui);          emberClearMessageFlag(childId);          // Do not try to send any other JIT message when starting           // bootload process.          return;        }      }      if(!IS_BOOTLOADING) {        // take care of all the sending of JIT messages to the child        appSendJitToChild(childId);	      }    #else      appSendJitToChild(childId);	    #endif  }}// this function is called from jitMessageStatus to print the contents // of a JIT buffer. Useful in making sure the correct data is being// copied into the JIT buffer.void jitMessageStatusPrintMessageData(EmberMessageBuffer bufferToPrint){  int8u i;  if (bufferToPrint != EMBER_NULL_MESSAGE_BUFFER) {    emberSerialPrintf(APP_SERIAL, "   data: ");    for (i=0; i< emberMessageBufferLength(bufferToPrint); i++) {      emberSerialPrintf(APP_SERIAL, "%x ",                        emberGetLinkedBuffersByte(bufferToPrint, i));    }    emberSerialPrintf(APP_SERIAL, "\r\n");    emberSerialWaitSend(APP_SERIAL);  }}// This is called to print the status of the JIT storage on a parent node// (sink or line powered sensor)void jitMessageStatus(void){  halResetWatchdog();  // bitmasks  emberSerialPrintf(APP_SERIAL, "bitmask for Sink_Advertise message.: %2x\r\n",                    jitMaskSinkAdvertise);  emberSerialPrintf(APP_SERIAL, "bitmask for Multicast_Hello message: %2x\r\n",                    jitMaskMulticastHello);  emberSerialWaitSend(APP_SERIAL);  // sink adv packet buffer   emberSerialPrintf(APP_SERIAL, "packet buffer for Sink_Advertise: %x\r\n",                    jitMessageSinkAdvertise);  emberSerialWaitSend(APP_SERIAL);  jitMessageStatusPrintMessageData(jitMessageSinkAdvertise);  // mcast hello packet buffer  emberSerialPrintf(APP_SERIAL, "packet buffer for Multicast_Hello: %x\r\n",                    jitMessageMulticastHello);  emberSerialWaitSend(APP_SERIAL);  jitMessageStatusPrintMessageData(jitMessageMulticastHello);}// this is called to print the child tablevoid printChildTable(void){  int8u i;  EmberStatus status;  EmberEUI64 eui;  EmberNodeType type;  for (i=0; i<emberMaxChildCount(); i++)  {    status = emberGetChildData(i, eui, &type);    emberSerialPrintf(APP_SERIAL, "%x:", i);    if (status == EMBER_SUCCESS)    {      printEUI64(APP_SERIAL, (EmberEUI64*)eui);      switch (type){      case EMBER_SLEEPY_END_DEVICE:        emberSerialPrintf(APP_SERIAL, " sleepy");        break;      case EMBER_MOBILE_END_DEVICE:        emberSerialPrintf(APP_SERIAL, " mobile");        break;      default:        emberSerialPrintf(APP_SERIAL, " ??????");        break;      }    }    emberSerialPrintf(APP_SERIAL, "\r\n");  }}void emberChildJoinHandler(int8u index, boolean joining){  EmberStatus status;  EmberEUI64 eui;  EmberNodeType type;  // if the node is joining...  if (joining == TRUE)  {    status = emberGetChildData(index, eui, &type);    // ...and the type is mobile...    if ((status == EMBER_SUCCESS) &&        (type == EMBER_MOBILE_END_DEVICE))    {      // ...set the message flag so it gets any messages right      // away, since the node will not be in the child table      // (and not have it's message flag set) whenever it      // hibernates      status = emberSetMessageFlag(emberChildId(index));    }  }}#endif // defined(SENSOR_APP) || defined(SINK_APP)// **************************************************// utility calls to support the EM250 Bootloader//// **************************************************#ifdef USE_BOOTLOADER_LIB// this is called by the sensor or sink -- applications that act// as parents. This is called with the EUI of the child that the// parents wants to bootload. Since the sleepy device may not be// awake (likely not), this function sets the message flag of the// child and remembers which child needs to be bootloaded. When the// child wakes up and polls, the initial bootloader launch message // is sent -- see emberPollHandlervoid bootloadMySleepyChild(EmberEUI64 targetEui){  int8u index;    // message for the user  emberSerialPrintf(APP_SERIAL, "INFO: attempt child bootload, eui ");  printEUI64(APP_SERIAL, (EmberEUI64*)targetEui);  emberSerialPrintf(APP_SERIAL, "\r\n");  emberSerialWaitSend(APP_SERIAL);   // make sure the EUI is a child of this parent  if (!(isMyChild(targetEui, &index))) {	return;  }    // set the message flag for the child  emberSetMessageFlag(emberChildId(index));  // remember the EUI and shortId for the child we are bootloading  bootloadInProgressChildId = emberChildId(index);  MEMCOPY(bootloadInProgressEui, targetEui, EUI64_SIZE);    // the bootload util library tells us if a bootload is in progres  // with the IS_BOOTLOADING macro. We need to set a flag to send the  // bootload launch message. Only want to do this once.  parentLaunchBootload = TRUE;  // print a message explaining that passthru is initiating   // and there is a few seconds before the xmodem ('C' characters  // printing) starts.  emberSerialPrintf(APP_SERIAL,                    "If a bootload response is seen, xmodem ");  emberSerialPrintf(APP_SERIAL, "will start in 30 seconds\r\n");  emberSerialPrintf(APP_SERIAL,                     "If xmodem does not start, the bootload failed\r\n");}// called by a sensor or sink when bootloading a neighbor device is// desired. This function just prints a bunch of information for the// user's benefit and calls a function that sends the initial bootload// launch message.void bootloadMyNeighborRouter(EmberEUI64 targetEui){   // message for the user  emberSerialPrintf(APP_SERIAL, "INFO: attempt neighbor bootload, eui ");	  printEUI64(APP_SERIAL, (EmberEUI64*)targetEui);  emberSerialPrintf(APP_SERIAL, "\r\n");  emberSerialWaitSend(APP_SERIAL);  // print a message explaining that passthru is initiating   // and there is a few seconds before the xmodem ('C' characters  // printing) starts.  emberSerialPrintf(APP_SERIAL,                    "If a bootload response is seen, xmodem ");  emberSerialPrintf(APP_SERIAL, "will start in 10 seconds\r\n");  emberSerialPrintf(APP_SERIAL,                     "If xmodem does not start, the bootload failed\r\n");    sendBootloaderLaunchMessage(targetEui);}// does the sending of the bootloader launch message. This is really// just setting up the parameters and making a call to bootloadUtilSendRequestvoid sendBootloaderLaunchMessage(EmberEUI64 targetEui){  // encryptKey has to match the token TOKEN_MFG_BOOTLOADER_AES_KEY   // on the target device or the bootload will not start  int8u encryptKey[16] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,                          0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};  // mfgId and hardwareTag have to match what the target device is  // checking for in bootloadUtilRequestHandler. These values are meant  // to be stored in the manufacturing tokens TOKEN_MFG_MANUF_ID (mfgId)  // and TOKEN_MFG_BOARD_NAME (hardwareTag).  int16u mfgId = 0xE250;  int8u hardwareTag[8] = {'D', 'E', 'V', ' ', '0', '4', '5', '5'};    bootloadUtilSendRequest(targetEui,                          mfgId,                          hardwareTag,                          encryptKey,                          BOOTLOAD_MODE_PASSTHRU); 	}// determines if the EUI passed in is in this device's child table// return of true means the EUI is in the child table// return of false means the EUI is not in the child table// if the EUI is in the child table, then childIndex is set to the// index in the child table of the EUI.boolean isMyChild(EmberEUI64 candidateEui, int8u* childIndex){  int8u i;  EmberEUI64 childEui;  EmberNodeType type;  EmberStatus status;    // go through whole child table    for (i=0; i<emberMaxChildCount(); i++) {    status = emberGetChildData(i, childEui, &type);	if ((status == EMBER_SUCCESS) && 		(MEMCOMPARE(candidateEui, childEui, EUI64_SIZE)==0)) {      // we found a match      (*childIndex) = i;      return TRUE;    }  }  // didn't match any entry in my child table  return FALSE;	}// no check for now. If an attempt is made to bootload a device // that is not a neighbor the initial launch will fail.boolean isMyNeighbor(EmberEUI64 eui){  return TRUE;		}// get the eui from a unicast binding. The return value is FALSE // if the binding couldn't be read or the binding is not unicast.// This is used by sensor or sink to pick an EUI from the binding// table to then bootload.boolean getEuiFromUnicastBinding(int8u bindingIndex, EmberEUI64* eui){  EmberBindingTableEntry result;  EmberStatus status = emberGetBinding(bindingIndex, &result);  // binding must be in use.and be unicast  if ((status == EMBER_SUCCESS) && (result.type == EMBER_UNICAST_BINDING)) {	MEMCOPY(eui, result.identifier, EUI64_SIZE);    return TRUE;  }  return FALSE;	}#endif //USE_BOOTLOADER_LIB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -