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

📄 connectivitytest.c

📁 是zmac的协议的全部完整的解析.代码例子很全
💻 C
字号:
// *******************************************************************
//  connectivitytest.c
//
//  Connectivity testing application.
//
//  This example also provides some simple commands that can be sent to the
//  node via the serial port. A brief explanation of the commands is
//  provided below:
//  ('?') prints the help menu
//
//  Copyright 2006 by Ember Corporation. All rights reserved.              *80*
// *******************************************************************

#include "connectivitytest.h"

// buffer for organizing data before we send a datagram
int8u buttonZeroPress, buttonOnePress;
int8u operationMode = RX_MODE; // receive, transmit
int8u rxPacketReceived = FALSE; // when a packet is received
EmberNodeId receiverNodeId;

// *******************************************************************
// Begin main application loop

int main(void)

{
  EmberStatus status;
  EmberResetType reset;

  //Initialize the hal
  halInit();

  // allow interrupts
  INTERRUPTS_ON();

  reset = halGetResetInfo();

  //
  //---

  // inititialize the serial port
  // good to do this before emberInit, that way any errors that occur
  // can be printed to the serial port.
  if(emberSerialInit(APP_SERIAL, BAUD_115200, PARITY_NONE, 1) 
     != EMBER_SUCCESS) {
    emberSerialInit(APP_SERIAL, BAUD_19200, PARITY_NONE, 1);
  }

#ifdef DEBUG
  emberDebugInit(DEBUG_SERIAL);
#endif

  // emberInit must be called before other EmberNet stack functions
  status = emberInit(reset);
  if (status != EMBER_SUCCESS) {
    emberSerialGuaranteedPrintf(APP_SERIAL,
              "ERROR: emberInit 0x%x\r\n", status);
    // Not sure what to do here.
    assert(FALSE);
  } else {
    emberSerialPrintf(APP_SERIAL, "EVENT: emberInit passed\r\n");
  }

  // TODO save the channel, customize it
  forceNetworkJoin(APP_PANID, APP_CHANNEL);

  // print a startup message
  emberSerialWriteString(APP_SERIAL,
                         "\r\nINIT: connectivitytest\r\n");
  emberSerialPrintf(APP_SERIAL, "\r\n");
  emberSerialWaitSend(APP_SERIAL);
  emberSerialWaitSend(APP_SERIAL);

  // event loop
  while(TRUE) {

    halResetWatchdog();
    
    applicationTick();
    checkButtonEvents();


    emberTick();

    processSerialInput();

    // only blink LEDs if app is joined
    if (emberNetworkState() == EMBER_JOINED_NETWORK) {
    }

    #ifdef DEBUG
      emberSerialBufferTick();   // Needed for debug which uses buffered serial
    #endif
  }

}

// end main application loop
// *******************************************************************

// *******************************************************************
// Begin Ember callback handlers
// Populate as needed
//

// Called when a message has completed transmission --
// status indicates whether the message was successfully
// transmitted or not.
void emberMessageSent(int8u bindingTableIndex,
                      int8u clusterId,
                      EmberMessageBuffer message,
                      EmberStatus status)
{
}

void emberIncomingMessageHandler(EmberIncomingMessageType type,
                                 EmberApsFrame *apsFrame,
                                 EmberMessageBuffer message)
{
  // Called with an incoming message
  int8u length;
  length = emberMessageBufferLength(message);

  if (type == EMBER_INCOMING_MULTICAST_LOOPBACK) {
    // throw it out if it came from us
    return;
  }
  
  // ********************************************
  // handle the incoming message
  // ********************************************
  switch (apsFrame->clusterId) {
  case TEST_PACKET_CLUSTER_ID:
    // Received packet
    rxPacketReceived = TRUE;
    break;

  case RECEIVER_REQUEST_CLUSTER_ID:
    if (operationMode == RX_MODE) {
      appSendApsUnicastDirect(emberGetSender(), RECEIVER_RESPONSE_CLUSTER_ID,
			      (int8u *)NULL, 0);
    
    }
    break;
    
  case RECEIVER_RESPONSE_CLUSTER_ID:
    if (operationMode == TX_LOCATE_RECEIVER_MODE) {
      // Found our receiver
      receiverNodeId = emberGetSender();
      operationMode = TX_MODE;
    }
    break;

  }


}

// this is called when the stack status changes
void emberStackStatusHandler(EmberStatus status)
{
}

// Called when a unicast has completed transmission --
// status indicates whether the message was successfully
// transmitted or not.
void emberUnicastSent(EmberNodeId destination,
                      EmberApsFrame *apsFrame,
                      EmberMessageBuffer message,
                      EmberStatus status)
{
}

// called when a remote device sends a message to add a binding
EmberStatus emberRemoteSetBindingHandler(EmberBindingTableEntry *entry)
{
  // this application doesn't allow external provisioning
  return EMBER_INVALID_BINDING_INDEX;
}

// called when a remote device sends a message to delete a binding
EmberStatus emberRemoteDeleteBindingHandler(int8u index)
{
  // this application doesn't allow external provisioning
  return EMBER_INVALID_BINDING_INDEX;
}

// end Ember callback handlers
// *******************************************************************


// *******************************************************************
// Functions that use EmberZNet

// applicationTick - called to check application timeouts, button events,
// and periodically flash LEDs
static void applicationTick(void) {
  static int16u ledBlinkStart = 0;
  static int16u lastTransmitTime = 0;
  static int8u ledBlink = FALSE;
  int16u time;
  int8u led;

  time = halCommonGetInt16uMillisecondTick();

  if (operationMode == TX_MODE || operationMode == TX_LOCATE_RECEIVER_MODE) {

    if (time - lastTransmitTime > TRANSMIT_INTERVAL) {
      if (operationMode == TX_MODE) {
	appSendApsUnicastDirect(receiverNodeId, TEST_PACKET_CLUSTER_ID, 
				(int8u *)NULL, 0);
      } else {
	appSendApsBroadcast(RECEIVER_REQUEST_CLUSTER_ID, (int8u *)NULL, 0);
      }
      ledBlink = TRUE;
      ledBlinkStart = time;
      lastTransmitTime = time;
    }
    halClearLed(RX_LED);
    led = TX_LED;

  } else { // if (operationMode == RX_MODE)
    halClearLed(TX_LED);
    led = RX_LED;

    // Received a packet; blink
    if (rxPacketReceived == TRUE) {
      ledBlink = TRUE;
      ledBlinkStart = time;
      rxPacketReceived = FALSE;
    }
  }

  // Logic: if the ledBlink is TRUE then the LED is *off*; if the interval
  // has expired the LED should be turned back on.  Default is ON.
  if (ledBlink == TRUE && (time - ledBlinkStart < LED_BLINK_INTERVAL)) {
    halClearLed(led);
  } else {
    ledBlink = FALSE;
    halSetLed(led);
  }
}


void checkButtonEvents(void) {

    // **************************************
    // button 0 is pressed -- change channel
    // **************************************
    if (buttonZeroPress) {
      // TODO: Channel change
      buttonZeroPress = FALSE;
    }

    // ***********************************************
    // button 1 is pressed -- change to transmit mode
    // ***********************************************
    if (buttonOnePress) {
      operationMode = TX_LOCATE_RECEIVER_MODE;
      buttonOnePress = FALSE;
    }
}

//
// *******************************************************************

// *******************************************************************
// Callback from the HAL when a button state changes
// WARNING: this callback is an ISR so the best approach is to set a
// flag here when an action should be taken and then perform the action
// somewhere else. In this case the actions are serviced in the
// applicationTick function
void halButtonIsr(int8u button, int8u state)
{

  // button 0 (button 0 on the dev board) was pushed down
  if (button == BUTTON0 && state == BUTTON_PRESSED) {
    buttonZeroPress = TRUE;
  }

  // button 1 (button 1 on the dev board) was pushed down
  if (button == BUTTON1 && state == BUTTON_PRESSED) {
    buttonOnePress = TRUE;
  }
}

//
// *******************************************************************


// *******************************************************************
// Utility functions

// *****************************
// for processing serial cmds
// *****************************
void processSerialInput(void) {
  int8u cmd;

  if(emberSerialReadByte(APP_SERIAL, &cmd) == 0) {
    if (cmd != '\n') emberSerialPrintf(APP_SERIAL, "\r\n");

    switch(cmd) {

      // help
    case '?':
      printHelp();
      break;

      // bootloader
    case 'b':
      emberSerialPrintf(APP_SERIAL, "starting bootloader...\r\n");
      emberSerialWaitSend(APP_SERIAL);
      halLaunchStandaloneBootloader(STANDALONE_BOOTLOADER_NORMAL_MODE);
      break;

      // 0 and 1 mean button presses
    case '0':
      buttonZeroPress = TRUE;
      break;
    case '1':
      buttonOnePress = TRUE;
      break;

    case '\n':
    case '\r':
      break;

    default:
      emberSerialPrintf(APP_SERIAL, "unknown cmd\r\n");
      break;
     }

    if (cmd != '\n') emberSerialPrintf(APP_SERIAL, "\r\nconnectivitytest>");
  }

}

// *********************************
// print help
// *********************************
#define PRINT(x) emberSerialPrintf(APP_SERIAL, x); emberSerialWaitSend(APP_SERIAL)

void printHelp(void)
{
  PRINT("? = help\r\n");
  PRINT("0 = simulate button 0\r\n");
  PRINT("1 = simulate button 1\r\n");
}

void forceNetworkJoin(int16u panId, int8u channel)
{
  // Note that this is not standard behavior, but is useful for this very
  // small network test.
  // Write channel, PAN-ID to FLASH tokens
  {
    tokTypeStackNodeData tokNode;
    tokNode.panId = panId;
    tokNode.radioFreqChannel = channel;
    tokNode.stackProfile = 0;
    tokNode.nodeType = EMBER_ROUTER;
    tokNode.zigbeeNodeId = 0x0;      // TODO: should be random
    halCommonSetToken(TOKEN_STACK_NODE_DATA, &tokNode);
  }
  
  if (emberNetworkInit() != EMBER_SUCCESS)
  {
    // We have a large problem.  Eject.
    emberSerialGuaranteedPrintf(APP_SERIAL, "Failed to join pre-determined network.  Abort.");
  }
}

// End utility functions
// *******************************************************************

// *******************************************************************
//

EmberStatus appSendApsBroadcast(int8u clusterId, int8u *data, int8u length) {

  EmberMessageBuffer message; // Used to hold the message
  int8u afFrame[3];           // The Application Framework header (see ZB specification)
  EmberApsFrame frame;        // The APS frame structure
  EmberStatus status;         // EmberStatus for return values
  
  // AF Frame: defined by the ZB specification:
  //   Byte 0, bits 0-3: EMBER_AF_FRAME_TYPE_MSG or EMBER_AF_FRAME_TYPE_KVP
  //   Byte 0, bits 4-7: Number of transactions contained in this message (1-7)
  //   Byte 1: Sequence number for this frame - managed by application
  //   Byte 2: Transaction sequence number - this message contains only one transaction.
  afFrame[0] = EMBER_AF_FRAME_CONTROL(EMBER_AF_FRAME_TYPE_MSG, 1); // Assembly macro
  afFrame[1] = 0;          // Sequence Number: Managed by application
  afFrame[2] = 1;          // The sequence of the following transaction.

  message = emberFillLinkedBuffers(NULL, length + 3);  

  if (message == EMBER_NULL_MESSAGE_BUFFER) {
    return EMBER_NO_BUFFERS;
  }

  emberCopyToLinkedBuffers(afFrame, message, 0, 3);
  if (length != 0) {
    emberCopyToLinkedBuffers(data, message, 3, length);
  }

  frame.profileId = PROFILE_ID;          // The application profile ID
  frame.clusterId = clusterId;           // The cluster ID for this message
  frame.sourceEndpoint = ENDPOINT;       // Transmission endpoint
  frame.destinationEndpoint = ENDPOINT;  // Destination endpoint
  frame.options = 0;                     // Used only for unicast messages

  status = emberSendBroadcast(&frame,   
			      0,        // Broadcast radius (0 is EMBER_MAX_HOPS)
			      message); 

  emberReleaseMessageBuffer(message);

  if (status != EMBER_SUCCESS) {
    emberSerialPrintf(APP_SERIAL, "[appSendApsBroadcast] failed: 0x%x\r\n", status);
  }
  
  return status;
}


EmberStatus appSendApsUnicastDirect(int16u destNodeId, int8u clusterId, int8u *data, int8u length) {
  EmberMessageBuffer message; // Used to hold the message
  int8u afFrame[3];           // The Application Framework header (see ZB specification)
  EmberApsFrame frame;        // The APS frame structure
  EmberStatus status;         // EmberStatus for return values
  
  // AF Frame: defined by the ZB specification:
  //   Byte 0, bits 0-3: EMBER_AF_FRAME_TYPE_MSG or EMBER_AF_FRAME_TYPE_KVP
  //   Byte 0, bits 4-7: Number of transactions contained in this message (1-7)
  //   Byte 1: Sequence number for this frame - managed by application
  //   Byte 2: Transaction sequence number - this message contains only one transaction.
  afFrame[0] = EMBER_AF_FRAME_CONTROL(EMBER_AF_FRAME_TYPE_MSG, 1); // Assembly macro
  afFrame[1] = 0;          // Sequence Number: Managed by application
  afFrame[2] = 1;          // The sequence of the following transaction.

  message = emberFillLinkedBuffers(NULL, length + 3);  

  if (message == EMBER_NULL_MESSAGE_BUFFER) {
    return EMBER_NO_BUFFERS;
  }

  emberCopyToLinkedBuffers(afFrame, message, 0, 3);
  if (length != 0) {
    emberCopyToLinkedBuffers(data, message, 3, length);
  }

  frame.profileId = PROFILE_ID;          // The application profile ID
  frame.clusterId = clusterId;           // The cluster ID for this message
  frame.sourceEndpoint = ENDPOINT;       // Transmission endpoint
  frame.destinationEndpoint = ENDPOINT;  // Destination endpoint

  // APS Frame options summary (see API guide for details)
  //
  // EMBER_UNICAST_OPTION_NONE 	
  // EMBER_UNICAST_OPTION_APS_INDIRECT           - used to send indirect APS messages	
  // EMBER_UNICAST_OPTION_APS_RETRY              - resend if necessary using APS retry
  // EMBER_UNICAST_OPTION_ENABLE_ROUTE_DISCOVERY - initiate route discovery if required
  // EMBER_UNICAST_OPTION_FORCE_ROUTE_DISCOVERY  - force route discovery even if known
  // EMBER_UNICAST_OPTION_POLL_RESPONSE          - If sent to an end device, this message will 
  //                                               be sent immediately instead of being queued -
  //                                               Must be the only option if used.
  frame.options = EMBER_UNICAST_OPTION_NONE;

  status = emberSendUnicast(destNodeId, // 16-bit destination ID
			    &frame,   
			    message); 
  
  emberReleaseMessageBuffer(message);

  if (status != EMBER_SUCCESS) {
    emberSerialPrintf(APP_SERIAL, "[appSendApsUnicastDirect] failed: 0x%x\r\n", status);
  }
  
  return status;
}

//
// *******************************************************************

⌨️ 快捷键说明

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