#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include "api.h"
#include "network_ip.h"
#include "routing_qdsr.h"
#ifdef ADDON_DB
#include "dbapi.h"
#endif
#define DEBUG_TRACE 0
#define DEBUG_ROUTE_CACHE 0
#define DEBUG_ROUTING_TABLE 0
#define DEBUG_ERROR 0
#define DEBUG_MAINTENANCE_BUFFER 0
#define DEBUG_SEND_BUFFER 0
#define DEBUG_RREQ_BUFFER 0
#define DEBUG_DISCOVERY 0
//------------------------------------------
// QDsr Memory Manager
//------------------------------------------
//-------------------------------------------------------------------------
// FUNCTION: QDsrMemoryChunkAlloc
// PURPOSE: Function to allocate a chunk of memory
// ARGUMENTS: Pointer to QDsr main data structure
// RETURN: void
//-------------------------------------------------------------------------
static
void QDsrMemoryChunkAlloc(QDsrData* qdsr)
{
int i = 0;
QDsrMemPollEntry* freeList = NULL;
qdsr->freeList = (QDsrMemPollEntry *) MEM_malloc(
QDSR_MEM_UNIT * sizeof(QDsrMemPollEntry));
ERROR_Assert(qdsr->freeList != NULL, " No available Memory");
freeList = qdsr->freeList;
for (i = 0; i < QDSR_MEM_UNIT - 1; i++)
{
freeList[i].next = &freeList[i+1];
}
freeList[QDSR_MEM_UNIT - 1].next = NULL;
}
//-------------------------------------------------------------------------
// FUNCTION: QDsrMemoryMalloc
// PURPOSE: Function to allocate a single cell of memory from the memory
// chunk
// ARGUMENTS: Pointer to QDsr main data structure
// RETURN: Address of free memory cell
//-------------------------------------------------------------------------
static
QDsrRouteEntry* QDsrMemoryMalloc(QDsrData* qdsr)
{
QDsrRouteEntry* temp = NULL;
if (!qdsr->freeList)
{
QDsrMemoryChunkAlloc(qdsr);
}
temp = (QDsrRouteEntry*)qdsr->freeList;
qdsr->freeList = qdsr->freeList->next;
return temp;
}
//-------------------------------------------------------------------------
// FUNCTION: QDsrMemoryFree
// PURPOSE: Function to return a memory cell to the memory pool
// ARGUMENTS: Pointer to QDsr main data structure,
// pointer to route entry
// RETURN: void
//-------------------------------------------------------------------------
static
void QDsrMemoryFree(QDsrData* qdsr,QDsrRouteEntry* ptr)
{
QDsrMemPollEntry* temp = (QDsrMemPollEntry*)ptr;
temp->next = qdsr->freeList;
qdsr->freeList = temp;
}
//-------------------------------------------------------------------------
// QDsr Utility functions
//-------------------------------------------------------------------------
// FUNCTION: QDsrCheckIfAddressExists
// PURPOSE: Function to check whether a particular address exists in a path
// ARGUMENTS: Pointer to path, path length and the address to check
// RETURN: TRUE if the address exists in the path, FALSE otherwise
//-------------------------------------------------------------------------
static
BOOL QDsrCheckIfAddressExists(
unsigned char* path,
int hopCount,
NodeAddress addrToChk)
{
int i = 0;
for (i = 0; i < hopCount; i++)
{
NodeAddress addrInPath = 0;
memcpy(&addrInPath, path, sizeof(NodeAddress));
if (addrInPath == addrToChk)
{
// Found the desired address
return TRUE;
}
path += sizeof(NodeAddress);
}
// The address doesn't exist
return FALSE;
}
//-------------------------------------------------------------------------
// FUNCTION: SizeOfPathInRouteRequest
// PURPOSE: Returns path length in Route Request option
// ARGUMENTS: Pointer to the Route Request option in a packet
// RETURN: Size in integer
//-------------------------------------------------------------------------
static
unsigned int SizeOfPathInRouteRequest(unsigned char* rreq)
{
return *(rreq + sizeof(unsigned char))
- QDSR_SIZE_OF_ROUTE_REQUEST_WITHOUT_PATH_TYPE_LEN;
}
//-------------------------------------------------------------------------
// FUNCTION: SizeOfPathInRouteReply
// PURPOSE: Returns path length in Route Reply option
// ARGUMENTS: Pointer to the Route Reply option in a packet
// RETURN: Size in integer
//-------------------------------------------------------------------------
static
unsigned int SizeOfPathInRouteReply(unsigned char* rrep)
{
return *(rrep + sizeof(unsigned char)) -
QDSR_SIZE_OF_ROUTE_REPLY_WITHOUT_PATH_TYPE_LEN;
}
//-------------------------------------------------------------------------
// FUNCTION: SizeOfPathInSourceRoute
// PURPOSE: Returns path length in Source Route option
// ARGUMENTS: Pointer to the Source Route option in a packet
// RETURN: Size in integer
//-------------------------------------------------------------------------
static
unsigned int SizeOfPathInSourceRoute(unsigned char* srcRoute)
{
return *(srcRoute + sizeof(unsigned char))
- QDSR_SIZE_OF_SRC_ROUTE_WITHOUT_PATH_TYPE_LEN;
}
// Functions to print traces of QDsr packets
//-------------------------------------------------------------------------
// FUNCTION: QDsrTraceFileInit
// PURPOSE: Initialize the file to write QDsr packet traces
// ARGUMENTS: Handler of the file
// RETURN: None
//-------------------------------------------------------------------------
static
void QDsrTraceFileInit(FILE *fp)
{
fprintf(fp, "ROUTING_QDsr Trace\n"
"\n"
"Fields are space separated. The format of each line is:\n"
"1. Running serial number (for cross-reference)\n"
"2. Node ID at which trace is captured\n"
"3. Time in seconds (There is delay before PHY transmit)\n"
"4. IP Source & Destination address\n"
"5. A character indicating S)end R)eceive\n"
"6. Payload length\n"
"7. Type of option (Request, Reply, SrcRoute, ...)\n"
" --- (separator)\n"
" Fields as necessary (depending on option type)\n"
"\n");
}
//-------------------------------------------------------------------------
// FUNCTION: QDsrTraceWriteNodeAddrAsDotIP
// PURPOSE: Printing IP address in dotted decimal format in trace file
// ARGUMENTS: IP address to print and trance file handler
// RETURN: None
//-------------------------------------------------------------------------
static
void QDsrTraceWriteNodeAddrAsDotIP(
NodeAddress address,
FILE *fp)
{
char addrStr[MAX_ADDRESS_STRING_LENGTH];
IO_ConvertIpAddressToString(address, addrStr);
fprintf(fp, "%s ", addrStr);
}
//-------------------------------------------------------------------------
// FUNCTION: QDsrTraceWriteCommonHeader
// PURPOSE: Printing QDsr header in trace file
// ARGUMENTS: IP address to print and trance file handler
// RETURN: None
//-------------------------------------------------------------------------
static
void QDsrTraceWriteCommonHeader(
Node *node,
unsigned char* qdsrPkt,
const char *flag,
NodeAddress destAddr,
NodeAddress srcAddr,
FILE *fp)
{
char clockStr[MAX_CLOCK_STRING_LENGTH];
QDsrHeader *hdr = (QDsrHeader *) qdsrPkt;
fprintf(fp, "%4u ", node->nodeId);
TIME_PrintClockInSecond(node->getNodeTime(), clockStr);
fprintf(fp, "%s ", clockStr);
QDsrTraceWriteNodeAddrAsDotIP(srcAddr, fp);
QDsrTraceWriteNodeAddrAsDotIP(destAddr, fp);
fprintf(fp, "%c %4u ", *flag, hdr->payloadLength);
}
//-------------------------------------------------------------------------
// FUNCTION: QDsrTraceWriteRequest
// PURPOSE: Printing Route request option
// ARGUMENTS: Pointer to route request option
// RETURN: None
//-------------------------------------------------------------------------
static
void QDsrTraceWriteRequest(
char *rreqOpt,
unsigned char optLen,
FILE *fp)
{
unsigned short id;
NodeAddress targetAddr;
char *dataPtr;
unsigned char remainLen;
memcpy(&id, rreqOpt + QDSR_SIZE_O