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

📄 halstack.c

📁 zigbee stack ---msstatePAN
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * "Copyright (c) 2006 Robert B. Reese ("AUTHOR")"
 * All rights reserved.
 * (R. Reese, reese@ece.msstate.edu, Mississippi State University)
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE "AUTHOR" BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHOR"
 * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE "AUTHOR" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE "AUTHOR" HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Please maintain this header in its entirety when copying/modifying
 * these files.
 *
 * Files in this software distribution may have different usage
 * permissions, see the header in each file. Some files have NO permission
 * headers since parts of the original sources in these files
 * came from vendor  sources with no usage restrictions.
 *
 */

/*
  V0.1 Initial Release   10/July/2006  RBR

*/


#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <string.h>
#include <process.h>


#include "lrwpan_config.h"
#include "hal.h"
#include "halstack.h"
#include "console.h"
#include "debug.h"
#include "ieee_lrwpan_defs.h"
#include "memalloc.h"


BOOL block_radio_rx;   //set by EVB to block radio TX

static RADIO_FLAGS local_radio_flags;


static void InitSharedMemory(void);

static LARGE_INTEGER lpFrequency;

static UINT32 tics_per_second;
static UINT16 radio_panid;
static SADDR radio_saddr;
static BYTE current_channel;  //channels 11 to 16

static TCHAR szName[]=TEXT("RadioSharedMemoryObject"); // name for shared memory
static TCHAR mutexName[]=TEXT("RADIOMUTEX123");  //name for mutex that controls shared memory

#define PKTBUF_SIZE (sizeof(UINT32)+1+128)
#define NUMBER_OF_CHANNELS  16
#define SHARED_MEM_HDR  (3*sizeof(UINT32))
#define SHARED_MEM_SIZE ((NUMBER_OF_CHANNELS*PKTBUF_SIZE)+SHARED_MEM_HDR )

//The shared memory header contains the following:
//UINT32  one-bit flag to indicate TX in progress
//UINT32  the global message ID
//UINT32  start tick of the TX, used for collision detection
//shared memory contains space for 16 channels
//Each channel is PKTBUF_SIZE, format of each pktbuf is:
//UINT32 pid: BYTE msgid: BYTE pktlen: PKT
static BYTE pktbuf[PKTBUF_SIZE];

static HANDLE hMapFile = NULL; //shared memory file handle
static BYTE *pSharedMem; //pointer to shared memory
static HANDLE hMutex = NULL;  //pointer to the mutex used to coordinate access to shared memory

//variables used by message passing in shared memory
static BYTE tx_msgid = 1;  //msg id of last message written to shared memory
static int last_rx_pid;
static BYTE last_rx_msgid;
static UINT32 mypid;

#define MIN_MSG_DURATION 1 //minimum amount of time a msg will be free of collision, in MILLISECONDS!!!
#define RANDOM_BACKOFF_INTERVAL   4    //will backoff 0 to RANDOM_BACKOFF_INTERVAL msecs on collision
#define MAX_BACKOFFS              3

static UINT32 global_msg_id; //incremented each time ANY node sends a message
static UINT32 last_global_msg_id;
//console handles
HANDLE hStdout, hStdin; 


typedef enum _RADIO_STATE_ENUM {
  RADIO_STATE_OFF,
  RADIO_STATE_ON
}RADIO_STATE_ENUM;

RADIO_STATE_ENUM radio_state;

//shared memory used to emulate radio channel
//the coordinator node creates this memory
void InitSharedMemory(void){

	mypid = (UINT32) _getpid();  //used in shared memory 
	last_global_msg_id = 0;
	//Create shared memory if not created yet
	if (hMapFile == NULL) { 
#ifdef LRWPAN_COORDINATOR
		//create the shared memory segment
		DEBUG_STRING(DBG_INFO,"In InitSharedMemory(), Coordinator creating shared memory\n");
		hMapFile = CreateFileMapping(
			INVALID_HANDLE_VALUE,    // use paging file
			NULL,                    // default security 
			PAGE_READWRITE,          // read/write access
			0,                       // max. object size 
			SHARED_MEM_SIZE,                // buffer size  
			szName);                 // name of mapping object
		if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE) 
		{ 
			printf("Could not create file mapping object (%d).\n", 
				GetLastError());
			return;
		}
		DEBUG_STRING(DBG_INFO,"Created shared memory segment\n");

#else
		//other nodes try to connect to this
		DEBUG_STRING(DBG_INFO,"In InitSharedMemory(), Router/RFD connecting to shared memory\n");
		hMapFile = OpenFileMapping(
			FILE_MAP_ALL_ACCESS,   // read/write access
			FALSE,                 // do not inherit the name
			szName);               // name of mapping object 

		if (hMapFile == NULL) 
		{ 
			printf("Could not open file mapping object (%d).\n", 
				GetLastError());
			return;
		} 
#endif
	}

	pSharedMem = (BYTE *) MapViewOfFile(hMapFile,   // handle to map object
		FILE_MAP_ALL_ACCESS, // read/write permission
		0,                   
		0,                   
		SHARED_MEM_SIZE);         

	if (pSharedMem == NULL) 
	{ 
		printf("Could not map view of file (%d).\n", 
			GetLastError()); 
		return;
	}
	//now initialize the shared memory
#ifdef LRWPAN_COORDINATOR

	//initialize to zero
	memset(pSharedMem,0,SHARED_MEM_SIZE);

#endif
	if (hMutex == NULL) {
		//create the mutex

		hMutex = CreateMutex(NULL, FALSE,mutexName);
		if(!hMutex) {
			printf("Mutex creation failed, exiting.\n");
			GetLastError(); 
		}
		DEBUG_STRING(DBG_INFO,"Mutex created\n");
	}


}

//parse the header, and see if we should reject this packet in the
//same way as the CC2430 does.
static BOOL util_accept_packet(BYTE *ptr) {

    BYTE i,fcflsb, fcfmsb,plen;
	BYTE srcmode, dstmode;
	BYTE addr[8];
	BYTE len;

	UINT16 destPANID, srcPANID;
	SADDR srcSADDR,dstSADDR;
	BYTE srcLADDR[8],dstLADDR[8];

	if (block_radio_rx) return FALSE;  //reject all packets.

	srcSADDR = 0xFFFE;
	dstSADDR = 0xFFFE;
	destPANID = 0x0000;
	srcPANID = 0x0000;
	memset(&srcLADDR[0],0,8);
    memset(&dstLADDR[0],0,8);
	
	plen = *ptr;ptr++;
	fcflsb = *ptr;ptr++;
	fcfmsb = *ptr;ptr++;
	//skip dsn
	ptr++;
	if (LRWPAN_IS_ACK(fcflsb)) return TRUE;
	dstmode = LRWPAN_GET_DST_ADDR(fcfmsb);
	srcmode = LRWPAN_GET_SRC_ADDR(fcfmsb);

    //do address checking

	if (dstmode != LRWPAN_ADDRMODE_NOADDR){
		addr[0] = *ptr; ptr++;
		addr[1] = *ptr; ptr++;
		destPANID = ((UINT16)addr[1]) << 8;
		destPANID = destPANID + addr[0];
		//see if we should reject
		if ((destPANID != radio_panid) && (destPANID != 0xFFFF)) {
			//reject this packet as it does not match our PANID and is not the broadcast PAN
			return (FALSE);
		}
	}
    if (dstmode == LRWPAN_ADDRMODE_SADDR || dstmode == LRWPAN_ADDRMODE_LADDR) {
		if (dstmode == LRWPAN_ADDRMODE_SADDR) {
			addr[0] = *ptr; ptr++;
			addr[1] = *ptr; ptr++;
			dstSADDR = ((UINT16)addr[1]) << 8;
			dstSADDR = dstSADDR + addr[0];
            if ((dstSADDR != radio_saddr) && (dstSADDR != 0xFFFF)) {
				//reject this packet as it does not match our SADDR and is not the broadcast PAN
				return(FALSE);
			}
		} else {
			memcpy(dstLADDR,ptr,8);
			halGetProcessorIEEEAddress(&addr[0]);
			//compare dst address to our address
			for(i=0;i<8;i++) {
				if (dstLADDR[i] != addr[i]) {
					//reject, does not match
					return(FALSE);
				}
			}
			ptr = ptr + 8;
		}
	}
    if ( !LRWPAN_GET_INTRAPAN(fcflsb) &&
		srcmode != LRWPAN_ADDRMODE_NOADDR
		) {
			//get SRC PANID
            addr[0] = *ptr; ptr++;
			addr[1] = *ptr; ptr++;
			srcPANID = ((UINT16)addr[1]) << 8;
			srcPANID = srcPANID + addr[0];
			//unusual to have SRC PANID
			if (LRWPAN_IS_BCN(fcflsb)) {
				if ((srcPANID != radio_panid) && (srcPANID != 0xFFFF)){
					//reject
					return(FALSE);
				}

			} else {
			 //data or MAC frame with srcPANID
			 if (dstmode == LRWPAN_ADDRMODE_NOADDR) {
				 //only src addressing mode present
				 if (!((srcPANID == radio_panid) && local_radio_flags.bits.pan_coordinator))
					 return FALSE;
				}

			}
			



		}


    return(TRUE);

}

//utility function
//format shmem_hdr
static void write_shmem_hdr(BYTE *ptr, UINT32 pid, BYTE msgid, BYTE len) {
        *(ptr+0) = (BYTE) (pid);
		*(ptr+1) = (BYTE) (pid>>8);
		*(ptr+2) = (BYTE) (pid>>16);
		*(ptr+3) = (BYTE) (pid>>24);
		*(ptr+4) = msgid;
		*(ptr+5) = len;
}

//when doing RF TX, these supply rssi, crc 
static BYTE util_get_rssi(void){
#ifdef LRWPAN_RSSI 
	return(LRWPAN_RSSI); //use this to simulate distance
#else
	return( 0x7F);      //about midrange
#endif
}

static BYTE util_get_CRC(void){
return( 0x80);
}


//transmit the packet

/*
Simulating RF transmission with 
Writing a RF packet to shared memory

To receive:
a. Look at first UINT32 in shared memory header. If this is
a '1', then a transmission is in progress, suspend, keep trying
until it becomes a '0'.
b. Look at the 2nd UINT32 in the shared memory header. This is
the global MSG id. If this is not different from last time, exit.
c. Since the global_msg_id is different, then grab the mutex.
d. Read the data
e. Release 

To Transmit:
a. Check for collision before grabbing mutex by reading 3rd UINT32 and seeing
if collision interval has expired. If not, then do random backoff, and
then try again. Once backoff succeeds, grab the mutex.
a. Grab mutex
b. Set the first UINT32 word to '1' indicating a transmit in progress.
c. increment msgid, copy sender_pid, msgid
to header, copy packet
d. read the global MSG id, increment, write it back.
e. Clear the transmit in progress.
c. Release mutex

*/

//rx flag is true if we want to check for reception
//if rx_flag is false, then we do transmit and do not do reception

void DoSharedMemTxRx(BOOL rx_flag, BYTE *pload,BYTE plen){
	DWORD rc;
	UINT32 sender_pid;
	BYTE sender_msgid;
	BYTE pktlen;
	BYTE len;
	BYTE *pBuf;
	BYTE *newpkt;
	BYTE fcflsb,fcfmsb,dsn;
	UINT32 *hdr;
	UINT32 my_timer;
	UINT8  backoffs;
	

	if (radio_state != RADIO_STATE_ON) {
		return;
	}
	hdr = (UINT32 *) &pSharedMem[0];
	if (rx_flag) {
		
		while ((volatile UINT32) *hdr) { Sleep(0);} //wait until the TX in progress flag is cleared.
        //read the new id
		if ((volatile UINT32) *(hdr+1) == last_global_msg_id) return; //nothing to do
	}else {
		//check for collision before TX
		backoffs = 0;
		do {
		 while ((volatile UINT32)*hdr) { Sleep(0);} //wait until the TX in progress flag is cleared.
		 if (halMACTimerNowDelta((volatile UINT32)*(hdr+2)) > MSECS_TO_MACTICKS(MIN_MSG_DURATION)) break;  //can transmit
		 //have a collision, need to wait.
		 backoffs++;
		 halSleep(MIN_MSG_DURATION + (halGetRandomByte()%RANDOM_BACKOFF_INTERVAL));
		}while(backoffs < MAX_BACKOFFS);
	}
	//if reach here, either there is a new message for RX or we are TXing.
	rc = WaitForSingleObject(hMutex,INFINITE);
	switch(rc) {
		case WAIT_OBJECT_0:
			break;
		case WAIT_FAILED:
		case WAIT_ABANDONED:
		case WAIT_TIMEOUT:
			printf("Radio shared mem Wait failed!\n");
			return;
	}
	

⌨️ 快捷键说明

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