Writing Custom Code in NetSim

Writing your own code#

NetSim allows the user to write the custom code for all the protocols by creating a DLL (Dynamic Link Library) for their custom code.

There are various important steps in this process, and each of these steps has various options as explained in the subsequent pages.

Microsoft Visual Studio 2019 Installation Settings#

NetSim requires only a few components of Visual Studio Community 2019 edition to be installed. Upon starting the installer:

  1. Under the Workloads tab users can select Desktop Development with C++ as shown below Figure 9‑1.

https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/14046428729/original/VypntDyzn_mIRjfGCHtw_kwb3-GJPl8pvw.png?1555474651

Figure 9‑1: In Workloads tab select Desktop Development with C++

  1. Under the Individual components tab select VC++2015.3 V140 toolset for desktop (x86, x64).

https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/14046428753/original/2Gsf6VBLwrg9je5gLPpSQP_VD3KdtrDrjQ.png?1555474698

Figure 9‑2: In Individual components tab select VC++2015.3 V140 toolset for desktop (x86, x64).

Modifying code#

DLL is the shared library concept, implemented by Microsoft. All DLL files have a .dll file extension. DLLs provide a mechanism for sharing code and data to upgrade functionality without requiring applications to be re-linked or re-compiled. It is not possible to directly execute a DLL, since it requires an EXE for the operating system to load it through an entry point. NetSim requires Visual Studio Compiler for building DLL's.

Note: Make sure that Visual Studio 2015 or above is installed in your system.

Refer section 4.13 section "How does a user open and modify source codes" to open NetSim Source Codes

  1. After this you may modify the source codes of any project. You can also add new files to the project if required. As an example, let us make a simple source code modification to TCP. Inside Solution Explorer pane in Visual Studio, double click on TCP project. Then open TCP.c file by double clicking on it. Using the drop down list of functions that are part of the current file, choose fn_Netsim_TCP_Init().

Figure 9‑3: Select fn_Netsim_TCP_Init() in TCP.C in Visual Studio

  1. Add the line fprintf(stderr, \"\nSource is Modified\n\"); statement inside the fn_Netsim_TCP_Init() function as shown below to print "Source is modified". _getch(); is added in the next line for the simulation to wait until it gets a user input.

Figure 9‑4: Source Code modified in fn_Netsim_TCP_Init() function in TCP project

Building Dlls#

  1. Identify the build of NetSim that is installed in your system from NetSim Home Screen as shown below.

    A picture containing application Description automatically
generated

Figure 9‑5: In NetSim Home Screen Identify the build of NetSim

  1. By default, x64 is choose for 64-bit version of NetSim. These changes will be automatically applied to all projects that are displayed in the Solution Figure 9‑6.

Graphical user interface, application, Word Description automatically
generated

Figure 9‑6: Based on the build of NetSim select x64 in Visual studio

  1. Now rebuild the network by right clicking on the project header and selecting Rebuild creates a Dll file in the bin folder of NetSim's current workspace path.

\< C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64> for 64-bit which contains your modifications. If build is successful a message similar to the following will be displayed in the output window as shown below.

Graphical user interface, text, application Description automatically
generated

Figure 9‑7: Build is successful a message similar to the following will be displayed in the output window

Running Simulation#

  1. After rebuilding the code, user can run the simulation via GUI (Please refer section 3). In this case, user can create a scenario in any network which involves TCP protocol. Running the simulation with the custom DLL will initially display a warning message as shown below.

Text Description automatically
generated

Figure 9‑8: Modified Project display a DLL warning message to NetSim Console

  1. The warning message lists the Dll files which have been modified in the bin folder (bin\bin_x64 for 64-bit) of NetSim's current workspace path. After pressing any key, the statement "Source is modified" will be printed to console as shown below.

Text Description automatically
generated

Figure 9‑9: Printf Statement written to console

  1. Press any key to proceed with the simulation. 

  2. The warning message will not be displayed if no Dll's are modified in the bin folder of current workspace path (bin\bin_x64 for 64-bit).

Source Code Dependencies#

The following are the list of projects that are part of NetSim source codes present in \<NetSim_Install_Directory>/src/Simulation directory and their dependencies:

PROJECT DEPENDENCY
Application IP
Cellular Application
CLIInterpertor Firewall, IP
Cognitive Radio Application
Ethernet Firewall
IEEE802_11 Battery Model
OSPF IP
Routing IP
RPL IP
ZigBee Battery Model
ZRP IP
Aloha -
AODV -
ARP` -
Battery Model -
CSMACD -
DSR -
Firewall -
IEEE1609 -
IP -
LTE NR
Mobility -
P2P -
SDN -
Support Function -
TCP -
Token_BR -
UDP -
UWAN
DTDMA -
TDMA -
Satellite Comm. Networks -

Table 9‑1: Source Code Dependencies

For E.g.: To perform modifications to Application Project, IP folder will also be required in addition to lib folder, Include folder and NetSim.sln file.

Enabling Additional Security Checks#

SDL -- Security Development Lifecycle checks adds recommended Security Development Lifecycle. These checks include extra security-relevant warnings as errors, and additional secure code-generation features.

/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks.

Figure 9‑10: Enabling Additional Security Checks application properties window

If SDL checks is enabled (/sdl), following warnings will be treated as errors:

Warning enabled by /sdl Equivalent command-line switch Description
C4146 /we4146 A unary minus operator was applied to an unsigned type, resulting in an unsigned result.
C4308 /we4308 A negative integral constant converted to unsigned type, resulting in a possibly meaningless result.
C4532 /we4532 Use of continue, break or goto keywords in a __finally/finally block has undefined behavior during abnormal termination.
C4533 /we4533 Code initializing a variable will not be executed.
C4700 /we4700 Use of an uninitialized local variable.
C4703 /we4703 Use of a potentially uninitialized local pointer variable.
C4789 /we4789 Buffer overrun when specific C run-time (CRT) functions are used.
C4995 /we4995 Use of a function marked with pragma deprecated.
C4996 /we4996 Use of a function marked as deprecated.

Table 9‑2: SDL Warnings Messages

Reference: https://docs.microsoft.com/en-us/cpp/build/reference/sdl-enable-additional-security-checks?view=vs-2019

Implementing your code - Examples#

Hello World Program#

Objective: Print Hello World from TCP protocol.

Implementation: Add fprintf (stderr, "\<MESSAGE>") statement inside the source code of TCP as shown below to print "Hello World" when custom built dll is executing.

fprintf(stderr, \"\nHello World\n\");

_getch();

A screenshot of a computer Description automatically
generated

Figure 9‑11: Hello World Printf Statement added in TCP Project

Build DLL as explained in Section 9.1.3 and run the simulation, you can see the following output on the console.

Text Description automatically
generated

Figure 9‑12: Hello World Statement written to console

Press enter then simulation will continue.

Introducing Node Failure in MANET#

Objective: Node failure using MANET-DSR using Device Id.

Implementation: Identify the Device ID of the particular node to be failed.

Step 1: Create a file with the name NodeFailure.txt inside the bin folder of NetSim's current workspace path

\<C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64> for 64-bit.

The file will contain two columns: one being the Node ID of the device to be failed and other being the failure time (in microseconds).

For example, to fail Node Id 2 from10^th^ sec onwards and fail Node Id 1 from 90^th^ sec onwards, the NodeFailure.txt file will be as follows Figure 9‑14.

Figure 9‑13: NodeFailure.txt file

Step 2: Go to DSR.c in DSR protocol.

Step 3: The function fn_NetSim_DSR_Init() will execute before the protocol execution starts. So, in this function, we will read the NodeFailure.txt and save information regarding which nodes will fail at which time. Add the following code inside the specified function.

int i;

FILE\* fp1;

char\* pszFilepath;

char pszConfigInput\[1000\];

pszFilepath = fnpAllocateMemory(36, sizeof(char) \* 50);

strcpy(pszFilepath, pszAppPath);

strcat(pszFilepath, \"/NodeFailure.txt\");

fp1 = fopen(pszFilepath, \"r\");

i = 0;

if (fp1)

{

while (fgets(pszConfigInput, 500, fp1) != NULL)

{

sscanf(pszConfigInput, \"%d %d\", &NodeArray\[i\], &TimeArray\[i\]);

i += 1;

}

fclose(fp1);

}

Step 4: The fn_NetSim_DSR_Run() is the main function to handle all the protocol functionalities. So, add the following code to the function at the start.

int i, nFlag = 1;

if (nFlag)

{

for (i = 0; i \< 100; i++)

if ((pstruEventDetails-\>nDeviceId == NodeArray\[i\]) &&

(pstruEventDetails-\>dEventTime \>= TimeArray\[i\]))

{

pstruEventDetails-\>nInterfaceId = 0;

pstruEventDetails-\>pPacket = NULL;

return 0;

}

}

Step 5: Add the following code inside DSR.h header file.

//Node failure model

int NodeArray\[200\];

int TimeArray\[200\];

Step 6: Build DLL as explained in Section 9.1.3.

Step 7: Create a scenario in MANET with DSR Protocol. where data packets should be travelling from source to destination through the mentioned node in NodeFailure.txt file. For that user can increase the pathloss exponent value and the distance among the nodes. User can utilize Packet Animation to check the node failure (i.e. no packets are forwarded by failed nodes) after the mentioned time.

Debugging your code#

This section is helpful to debug the code which user has written. To write your own code please refer Section 9.1.2.

Via GUI#

Debugging your code via GUI there are two methods available.

  • Using _getch()

  • Using Environment Variables (NETSIM_BREAK)

Using _getch()#

Step 1: Perform the required modification of the protocol source code and add _getch() (used to hold the program execution until the user enters a character) statement inside init function of the modified protocol. For example, take TCP protocol and add the following lines of code in the init function as shown in the below screenshot Figure 914.

fprintf(stderr, \"\nAttach to Process now\n\");

_getch();

Figure 9‑14: Added Two line of Code in TCP protocol

Step 2: Build the TCP protocol as explained in Section 9.1.3. Do not close Visual Studio.

Step 3: In NetSim, create a network scenario where the protocol is being used and start the simulation. In the console window user would get a warning message shown in the below screenshot Figure 9‑16 and the simulation will pause for user input (because of _getch() added in the init function)

Figure 9‑15: Attach to Process Statement written to console

Step 4: In Visual Studio, put break point inside the source code where you want to debug.

Step 5: Go to "DebugàAttach to Process" in Visual studio as shown and attach to NetSimCore.exe.

Figure 9‑16: Debug > Attach to Process in Visual studio

Graphical user interface, text, application, email Description
automatically generated

Figure 9‑17: Select NetSimCore.exe in Attach to Process Window

Click on Attach. Press enter in the command window. Then control goes to the project and stops at the break point in the source code as shown below Figure 9‑19. All debugging options like step over (F10), step into (F11), step out (Shift + F11), continue (F5) are available.

Graphical user interface, text, application, Word Description
automatically generated

Figure 9‑18: Control goes to the project and stops at the break point in the source code

After execution of the function, the control goes back to NetSim and then comes back to the custom code the next time the function is called in the simulation.

To stop debugging and continue execution, press Shift+F5 (key). This then gives the control back to NetSim, for normal execution to continue.

Using Environment Variable#

This section is helpful to Debug Using Environment Variable (NETSIM_BREAK). To set Environment variable follow the steps as shown.

Note: Setting NETSIM_BREAK Environment Variable will cause the simulation to slow down and it is recommended to remove this Environment Variables after debugging the simulation

Step 1: Right click on My Computer\ This PC and select Properties.

Step 2: Go to Advanced System setting à Advanced Tab à Environment Variables option

Step 3: Click New in System variables. Type "NETSIM_BREAK" as Variable name and any positive integer as variable value (e.g., 2). Click OK. The value of the variable is the event ID at which you want NetSim Simulation to break. In this example we have set the value to 2, which means that the simulation will break at the previous event.

Note: After adding NETSIM_BREAK in environment variable, user should restart the computer otherwise it won't affect the simulation.

Figure 9‑19: Environment Variable Window

Figure 9‑20: Add Variable name and Variable Value in New in System Variable

Step 4: Open NetSim and then open the source codes. Please refer Section 4.13 "How does a user open and modify source codes" for more information.

Step 5: Create a network scenario in NetSim (Internetworks or any other networks)

Figure 9‑21: Network Topology

Step 6: In this example we are placing a break point in TCP source code and thus TCP should be select in Application properties window.

Step 7: Enable Event trace option and run the simulation.

Simulation will break at event ID 1 as we have set the environment variable to 2 as shown below.

Figure 9‑22: Simulation will break at event ID 1

Here NetSim breakpoint has been triggered.

Step 8: Inside Solution Explorer pane in Visual Studio, double click on TCP project. Then open TCP.c file by double clicking on it. Using the drop down list of functions that are part of the current file, choose fn_NetSim_TCP_Run().

Step 9: In Visual Studio, Set the breakpoint in the code by clicking on the grey area on the left of the line or by right clicking on the line and selecting Breakpoint->Insert Breakpoint.

Figure 9‑23: Added Break point in line number 50

Step 10: Go to "DebugàAttach to Process" in Visual studio as shown Figure 9‑24 and select NetSimCore.exe from the list of processes displayed.

Figure 9‑24: Debug > Attach to Process in Visual studio

Figure 9‑25: Select NetSimCore.exe in Attach to Process Window

Click on Attach. Press any key in the command window to continue the process.

Step 11: Now we need to enter next event ID to break.

Figure 9‑26: Enter next event ID to break

Then control goes to the project and stops at the break point in the source code (NetSim will break wherever user has set the breakpoint) as shown below Figure 9‑27. All debugging options like step over (F10), step into (F11), step out (Shift + F11), continue (F5) are available.

Figure 9‑27: Control goes to the project and stops at the break point in the source code.

After execution of the function, the control goes back to NetSim and then comes back to the custom code the next time the function is called in the simulation. To stop debugging and continue execution, press Shift+F5 (key). This then gives the control back to NetSim, for normal execution to continue.

If NETSIM_BREAK environment variable is set, NetSim event trace file additionally logs the file name and line number of the source code where the event was added as shown below:

Figure 9‑28: NetSim event trace file additionally added two columns the file name and line number of the source code.

Via CLI#

Modify the TCP protocol and build the code. Create a scenario in Internetworks then follow the below steps.

Step 1: Open the Command prompt. Press "windows+R" and type "cmd".

Step 2: To run the NetSim via CLI copy the path where "NetSimCore.exe" is present.

>cd \<apppath>

>NetSimCore.exe\<space>-apppath\<space>\<apppath>\<space>-iopath\<space>\<iopath>\<space>-license\<space>5053@\<ServerIP Address>\<space> -d

Step 3: Type the following command.

A screenshot of a computer Description automatically generated with
medium confidence

Figure 9‑29: Run the NetSim via CLI Mode use the following Command.

Press enter, now you can see the following screen.

Text Description automatically
generated

Figure 9‑30: Enter the Event ID

Step 4: Open the Project in Visual Studio and put break point inside the source code.

Step 5: Go to "DebugàAttach to Process".

Graphical user interface, application Description automatically
generated

Figure 9‑31: Debug > Attach to Process

Attach to NetSimCore.exe.

Figure 9‑32: Select NetSimCore.exe in Attach to Process Window

Click on Attach.

Step 6: Go to command prompt which is already opened in Step 3. Enter the Event Id.

Note: If you do not want to stop at any event you can specify 0 as event id.

Text Description automatically
generated

Figure 9‑33: Enter the Event Id

Execution will stop at the specified event.

Text Description automatically
generated

Figure 9‑34: Execution stops at the specified event

Press enter then control goes to the project and stops at the break point in the source code as shown below.

Figure 9‑35: Control goes to the project and stops at the break point in the source code

All debugging options like step over (F10), step into (F11), step out (Shift + F11), continue (F5) are available.

After execution of the function, the control goes back to NetSim and then comes back to the custom code the next time the function is called in the simulation.

To stop debugging press Shift+F5. This then gives the control back to NetSim, for normal execution to continue.

Co-relating with Event Trace#

To debug your own (custom) code, it is often helpful to know which section of the code (file name & line number) generated the event under study. There are 2 ways to enable this feature.

Procedure 1

Step 1: Open configuration.netsim file and provide the file name, path and set status as Enable.

Text Description automatically
generated

Figure 9‑36: Enable Event Trace by editing Configuration.netsim and provide the file name, path and set status as Enable

Step 2: Run the NetSim via CLI in debug mode (Refer NetSim Help in Section 7àRunning Simulation via CLI) with --d as the fourth parameters.

Press enter.

Figure 9‑37: Run the NetSim via CLI

Step 3: Enter -1 as the event ID.

Text Description automatically
generated

Figure 9‑38: Enter -1 as the event ID

Upon running, NetSim will write the file name and line number of the source code that generated each event.

Figure 9‑39: NetSim writes the file name and line number of the source code in Event Trace

In the above trace file Event Id 46 is triggered inside the IEEE802_11_Phy.c file which is present in IEEE802_11 project. Since all the lib files are opaque to the end user, you cannot see the source code of the lib file. However, Event Id 56 is triggered at line number 420 of IEEE802_11_Phy.c file and you can find the location of the event by opening the IEEE802_11_Phy.c file as shown below.

Figure 9‑40: IEEE802_11_Phy.c file Code in Visual Studio

Procedure 2:

Step 1: Right click on my computer and select Properties.

Step 2: Go to Advanced System setting à Advanced Tab à Environment Variables.

Step 3: Click New. Type "NETSIM_BREAK" as Variable name and any negative integer as Variable value. Click OK.

Figure 9‑41: Environment Variables Window

Figure 9‑42: Enter Variable name and Value in New System Variable

Step 4: Restart the system.

Step 5: Now perform simulation in NetSim (Enable event trace in GUI). Upon running, NetSim will write the file name and line number of the source code that generated each event.

Figure 9‑43: NetSim writes the file name and line number of the source code in Event Trace

Viewing & Accessing variables#

Viewing variables while debugging code

To see the value of a variable, when debugging the mouse over the variable name in the code. A text box with variable contents appears. If the variable is a structure and contains other variables, then click on the plus sign which is there to the left of the text box. Users can pin the variable to watch by clicking on the pin icon to the right of that variable in the text box.

Figure 9‑44: Viewing variables while debugging code

Adding the variable to watch

Figure 9‑45: Adding the variable to watch

Watch the change in the variable as the code progress by right clicking on the variable & clicking on \"add watch\" tab. This is useful if to continuously monitor the change in the variable as the code progresses.

Viewing external variables

During the process of debug users would come across variables that are defined outside the source file being built as a .dll. Such variables cannot be viewed directly when added in the watch tab, as this would throw the error.

Error: Identifier "pstruEventDetails" is undefined

Figure 9‑46: Viewing external variables

In the watch window, the variable which the user has to watch should be edited by double clicking on it and prefixing {,,NetworkStack.dll} to the variable name and pressing enter. (The name of the respective file in which the variable is defined should be mentioned - in this case NetworkStack.dll).

Figure 9‑47: Variable In the watch window

Accessing External Variables

Each protocol in NetSim has a separate Dll file which contains the variables and functions which can be shared. In case of cross layer protocol implementations variables of one protocol may have to be accessed from another Dll.

An example is given below showing how Physical layer parameters of devices running IEEE802.11 can be accessed in the Network Layer with DSR protocol configured.

The variable battery is defined in a structure stru_802_11_Phy_Var which is part of IEEE802_11_Phy.h file. So the user will have to access a pointer of type stru_802_11_Phy_Var. In the header file where the structure definition is given, the following line of code must be written --

#ifndef SHARE_VARIABLE

\_declspec(dllexport) IEEE802_PHY_VAR\* var1;

#else

\_declspec(dllimport) IEEE802_PHY_VAR\* var1;

#endif

In the example, the code line must be written in IEEE802_11_Phy.h file present inside IEEE802_11 folder.

A computer screen capture Description automatically generated with
medium confidence

Figure 9‑48: Code Modification done in IEEE802_11_Phy.h file present inside IEEE802_11 folder

In the main function where a user wishes to find the dReceivedPower_mw, the variable must be assigned the respective value. In the above case, the following line of code must be written inside fn_NetSim_IEEE802_11_PhyIn() function in IEEE802_11_Phy.c file present inside IEEE802_11 folder.

var1 = DEVICE_PHYVAR(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId);

Note that the parameters given in the macro or any function which assigns a value to the variable must be defined beforehand in the code. Here nDeviceId and nInterfaceId are defined beforehand.

Graphical user interface, text, application Description automatically
generated

Figure 9‑49: Code Modification done in IEEE802_11_Phy.c file present inside IEEE802_11 folder

The IEEE802_11 project must be built and the resulting libIEEE802.11.dll file which gets created in the bin_x64 folder of NetSim's current workspace.

C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64 for 64-bit

The Object file IEEE802_11.lib which is also got created in the bin_x64 folder located in the current workspace path

\<C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64 >

Place the created IEEE802_11.lib inside simulation lib x64 or lib folder as shown in below path.

\<C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace\src\Simulation\

lib_x64>for 64-bit

Now expand the DSR project in solution explorer. For accessing the IEEE802_11 variable, the following lines must be added in DSR.h file.

#define SHARE_VARIABLE

#pragma comment(lib,\"IEEE802_11.lib\")

A computer screen capture Description automatically generated with
medium confidence

Figure 9‑50: Accessing the IEEE802_11 variable, Modification done in DSR.h file

Add the following lines of code to the DSR.c file as shown below.

#include \"../IEEE802_11/IEEE802_11_Phy.h\"

#include \"../BatteryModel/BatteryModel.h\"

Figure 9‑51: Add the following lines of code to the DSR.c file in DSR Project

In the fn_NetSim_DSR_Run() function add the following lines of code to print the value of dReceivedPower_mw variable from DSR project.

if (var1)

fprintf(stderr, \"\\n Remaining Energy(mJ): %lf\\n\",
battery_get_remaining_energy((ptrBATTERY)var1-\>battery));

A screenshot of a computer Description automatically
generated

Figure 9‑52: Code Related to Remaining Energy for nodes

The DSR project must be built and the resulting libDSR.dll file gets created in the bin_x64 folder of NetSim's current workspace path

\< C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64> for 64-bit. When a scenario is run, the remaining energy of the node will be printed to the simulation console as shown below.

Figure 9‑53: Remaining energy of the node printed in NetSim console

Users can try printing the Device ID, Application ID, Duplicate Ack Count etc.

To print to console: Print node positions in MANET

Open Mobility Project, and in Mobility.c file go to fn_NetSim_Mobility_Run() function. Inside the default case add following codes

fprintf(stderr, \"\\n The position of %s at time %.2lfms is X=%.2lf and
Y = %.2lf \\n\", DEVICE_NAME(pstruEventDetails-\>nDeviceId),

pstruEventDetails-\>dEventTime,

DEVICE_POSITION(pstruEventDetails-\>nDeviceId)-\>X,

DEVICE_POSITION(pstruEventDetails-\>nDeviceId)-\>Y);

\_getch();

Figure 9‑54: Code for Print node positions in MANET

Building Mobility project creates libMobility.dll inside the binary folder(bin_x64) of NetSim's current workspace path

\<C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64 > for 64-bit.

Create a scenario in MANET and configure the mobility model of the nodes. During simulation users can notice that the positions of the nodes are displayed in the console w.r.t. the simulation time.

Creating a new packet and adding a new event in NetSim#

In this example we show how users can create their own packet & event in 802.15.4 Zigbee. The same methodology can be applied to any network / protocol.

  1. Open the Source codes in Visual studio using the NetSim.sln file.

  2. Go to ZigBee project and Open 802_15_4.h file and add a subevent called "MY_EVENT" inside enum_IEEE802_15_4_Subevent_Type as shown below.

Figure 9‑55: Add "MY_EVENT" inside enum_IEEE802_15_4_Subevent_Type

  1. To add a new packet in NetSim first user has to initialize their new packet name inside 802_15_4.h file. Let us assume the new packet be "MY_PACKET" and it is a control packet. So, user has to define it inside the following enum as shown below Figure 9‑56

Figure 9‑56: Add "MY PACKET" inside enum_IEEE802_15_4_ControlPacket_Type

  1. We assume that MY_PACKET has the same fields as a Zigbee Ack and hence we are adding the following ack frame to 802_15_4.h file (Add this code just above the enum enum_IEEE_802_15_4_ControlPacket_Type {} defenition):
> struct stru_My_Frame
>
> {
>
> int nBeaconId;
>
> int nSuperFrameId;
>
> int nBeaconTime;
>
> double dPayload;
>
> double dOverhead;
>
> double dFrameSize;
>
> };
>
> typedef struct stru_My_Frame MY_FRAME;
>
> enum enum_IEEE_802_15_4\_ControlPacket_Type
>
> {

  1. Open 802_15_4.c file, go to the case TIMER_EVENT and add the following code to the subevent type.
case SUBEVENT_GETLINKQUALITY:

{

\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--

}

break;

case MY_EVENT:

{

//my event//

fprintf(stderr, \"My_event\");

pstruEventDetails-\>dEventTime = pstruEventDetails-\>dEventTime + 1 \*
SECOND;

pstruEventDetails-\>nDeviceId = nGlobalPANCoordinatorId;

pstruEventDetails-\>nInterfaceId = 1;

pstruEventDetails-\>nEventType = TIMER_EVENT;

pstruEventDetails-\>nSubEventType = MY_EVENT;

pstruEventDetails-\>nProtocolId = MAC_PROTOCOL_IEEE802_15_4;

fnpAddEvent(pstruEventDetails);

fn_NetSim_WSN_MY_PACKET();

//my event//

}

break;

Here we are adding a new event inside the timer event, and this event will occur every 1 second in the GlobalPANCoordinator. i.e., sink node. In this event, fn_NetSim_WSN_MY_PACKET() is called as explained in step 5.

  1. Inside 802_15_4.c file, add the following code at the end of the file for sending ack (broadcast):
int fn_NetSim_WSN_MY_PACKET()

{

double dTime;

NETSIM_ID nDeviceId = pstruEventDetails-\>nDeviceId;

NETSIM_ID nInterfaceId = pstruEventDetails-\>nInterfaceId;

IEEE802_15_4\_MAC_VAR\* pstruMacVar = DEVICE_MACVAR(nDeviceId,
nInterfaceId);

IEEE802_15_4\_PHY_VAR\* pstruPhyVar = DEVICE_PHYVAR(nDeviceId,
nInterfaceId);

NetSim_PACKET\* pstruPacket = pstruEventDetails-\>pPacket;

NetSim_PACKET\* pstruAckPkt;

MY_FRAME\* pstruAck;

dTime = pstruEventDetails-\>dEventTime;

// Create MY_Frame

pstruAckPkt = fn_NetSim_Packet_CreatePacket(MAC_LAYER);

pstruAckPkt-\>nPacketType = PacketType_Control;

pstruAckPkt-\>nPacketPriority = Priority_High;

pstruAckPkt-\>nControlDataType = MY_PACKET;

pstruAck = fnpAllocateMemory(1, sizeof(MY_FRAME));

// Update packet fields

pstruAckPkt-\>nSourceId = nDeviceId;

pstruAckPkt-\>nTransmitterId = nDeviceId;

pstruAckPkt-\>nReceiverId = 0;

add_dest_to_packet(pstruAckPkt, pstruAckPkt-\>nReceiverId);

pstruAckPkt-\>pstruMacData-\>Packet_MACProtocol = pstruAck;

pstruAckPkt-\>pstruMacData-\>dArrivalTime = dTime;

pstruAckPkt-\>pstruMacData-\>dStartTime = dTime;

pstruAckPkt-\>pstruMacData-\>dEndTime = dTime;

pstruAckPkt-\>pstruMacData-\>dPacketSize =

pstruAckPkt-\>pstruMacData-\>dOverhead;

pstruAckPkt-\>pstruMacData-\>nMACProtocol = MAC_PROTOCOL_IEEE802_15_4;

pstruAckPkt-\>nPacketId = 0;

strcpy(pstruAckPkt-\>szPacketType, \"MY_PACKET\");

//to see the packet in animation

// Add SEND ACK subevent

pstruEventDetails-\>dEventTime = dTime;

pstruEventDetails-\>dPacketSize =

pstruAckPkt-\>pstruMacData-\>dPacketSize;

pstruEventDetails-\>nSubEventType = 0;

pstruEventDetails-\>nEventType = PHYSICAL_OUT_EVENT;

pstruEventDetails-\>pPacket = pstruAckPkt;

fnpAddEvent(pstruEventDetails);

//Free the packet

fn_NetSim_Packet_FreePacket(pstruPacket);

pstruPacket = NULL;

return 0;

}


  1. Inside the above function NetSim API

fn_NetSim_Packet_CreatePacket(MAC_LAYER); is used. This is the API which creates a new packet in NetSim. Since in this example, new packet is created in MAC layer, it is passed as an argument. Users can give the respective Layer name for creating packets in any other layers. In the above code users can see the following line:

strcpy(pstruAckPkt->szPacketType, \"MY_PACKET\");

This is used visualize the packet transmission in the packet animation.

  1. In 802_15_4.c file, goto fn_NetSim_Zigbee_Init() function and add the following code in red color to call the timer_event. i.e. MY_EVENT
\_declspec(dllexport) int fn_NetSim_Zigbee_Init()

{

//MY_EVENT

pstruEventDetails-\>nDeviceId = nGlobalPANCoordinatorId;

pstruEventDetails-\>nInterfaceId = 1;

pstruEventDetails-\>dEventTime = pstruEventDetails-\>dEventTime;

pstruEventDetails-\>nEventType = TIMER_EVENT;

pstruEventDetails-\>nSubEventType = MY_EVENT;

pstruEventDetails-\>nProtocolId = MAC_PROTOCOL_IEEE802_15_4;

fnpAddEvent(pstruEventDetails);

//MY_EVENT

return fn_NetSim_Zigbee_Init_F();

}

In the above function, subevent type, "MY_EVENT" is called. So this function calls the MY_EVENT, timer event to execute.

  1. fn_NetSim_Zigbee_Trace() is an API to print the trace details to the event trace. So inside 802_15_4.c file add the following lines of code in red color inside fn_NetSim_Zigbee_Trace(int nSubEvent) as shown below:-
\_declspec (dllexport) char\* fn_NetSim_Zigbee_Trace(int nSubEvent)

{

if (nSubEvent == MY_EVENT)

return \"MY_EVENT\";

return (fn_NetSim_Zigbee_Trace_F(nSubEvent));

}

  1. Save the code and build Zigbee project, libZigBee.dll will get created in the bin folder of NetSim's current workspace path.

\< C:\Users\PC\Documents\NetSim\Workspaces\\<Your default workspace>\bin_x64 > for 64-bit.

  1. Create a basic scenario in WSN with 2 sensors and 1 sink node.

  2. While creating the application between two sensors, set

Application Type - Sensor App

Interarrival Time - 5000

  1. Run simulation for 10 seconds.

  2. Play packet animation. Here users can see that Sink node broadcasts "MY_PACKET" to the sensor.

Figure 9‑57: In animation window Sink node broadcasts "MY_PACKET" to the sensor

  1. Also, open packet trace and users can filter the control packet and see all the packet details of "MY_PACKET" written in the packet trace.

Figure 9‑58: Filter the Packet Type to control packet and See "MY_PACKET" in Packet Trace

  1. To analyze the "MY_EVENT" users can open event trace and filter the subevent type as "MY_EVENT". Here users can analyze that the event occurs for every 1 seconds.

Figure 9‑59: Filter Subevent type to "MY_EVENT"

NetSim API's#

NetSim provides a wide variety of APIs for protocol developers. These are available in

  1. packet.h -- Packet related APIs

  2. Create a new packet.

  3. fn_NetSim_Packet_CreatePacket_dbg(int nLayer,int line,const char* file);

  4. Copy a packet into a new packet.

  5. fn_NetSim_Packet_CopyPacket_dbg(const NetSim_PACKET* pstruPacket,int line,const char* file);

  6. Create error in packet.

  7. fn_NetSim_Packet_DecideError(double dBER, long double dPacketSize);

  8. Free a packet

  9. fn_NetSim_Packet_FreePacket_dbg(NetSim_PACKET**pstruPacket,int > line,char* file);

  10. stack.h -- Network / device / link and event related APIs

  11. Calculate distance between nodes.

  12. fn_NetSim_Utilities_CalculateDistance(NetSim_COORDINATES* > coordinate1,NetSim_COORDINATES* coordinates2);

  13. Stores the event details. Only one-time memory is allocated. Most > used variable

  14. struct stru_NetSim_EventDetails* pstruEventDetails;

  15. Retrieve values from xml file.

  16. GetXmlVal(void* var,char* name,void* xmlNode,int flag, > XMLDATATYPE type);

  17. list.h -- Optimized list operation calls since NetSim uses lists extensively.

- Add elments in list.#

  • list_add(void** list,void* mem,size_t offset,int (*check)(void* > current,void* mem));

  • Sorting the list

  • list_sort(void** list,size_t offset,int (*check)(void* current, > void* mem));

  • IP_Addressing.h -- For setting & getting IP address per the appropriate format.

  • Set Ip address of any node.

  • NETSIM_IPAddress

  • Checking ip address is broadcast or multicast.

  • isBroadcastIP(NETSIM_IPAddress ip);

  • isMulticastIP(NETSIM_IPAddress ip);

    For detailed help please refer the appropriateheader (.h) files inside:/NetSim_Standard/src/simulation/include or read through the doxygen source code documentation available inside Home Page under Documentation > source code Help

  • Include all the header (.h) files from the include folder.

  • NetworkStack.lib is a "import library" file and has the definitions for the functions present in the NetworkStack.dll

  • When developing new protocols users should create their own protocol.h and declare all the protocol specific variables here. Stack & packet related variables should be used from stack.h and packet.h

[NetSim Network Stack calling individual Protocol.]{.underline}

Every protocol should provide the following APIs as hooks to the network stack:

  • int (*fn_NetSim_protocol_init)(conststruct stru_NetSim_Network*,conststruct stru_NetSim_EventDetails*,constchar*,constchar*,int,constvoid**);

  • Using this API the stack passes all the relevant pointers to variables, paths etc needed for the protocol. Inside this function a) local variables should be initialized, b) Initial events if any should be written, eg: Hello packet in RIP, STP in Ethernet c) File pointers for reading & writing protocol_specific_IO files.

  • int (*fn_NetSim_protocol_Configure)(conststruct stru_NetSim_Network*,int nDeviceId, int nINterfaceID, int nlayertype, fnpAllocateMemory, fnpFreeMemory, fpConfigLog );

  • The stack calls this API when reading the config file. Upon reaching the appropriate protocol definition in the XML file, the stack calls this and passes all these pointers to the protocol.

  • int (*fn_NetSim_protocol_run)(): This is called by the stack to run the protocol

  • char* (*fn_NetSim_protocol_trace)(int): This called by the stack to write the event trace

  • int(*fn_NetSim_protocol_CopyPacket)(constNetSim_PACKET* pstruDestPacket,const NetSim_PACKET* pstruSrcPacket):

  • This is for copying protocol specific parameters / data into the packed

  • int (*fn_NetSim_protocol_FreePacket)(const NetSim_PACKET* pstruPacket): The this to free the protocol specific parameters / data in the packet

  • (*fn_NetSim_protocol_Metrics)(const FILE* fpMetrics): This is to write the metrics file upon completion of the simulation

  • int (*fn_NetSim_protocol_Finish)(): To release all memory after completion

  • char* (*fn_NetSim_protocol_ConfigPacketTrace)(constvoid* xmlNetSimNode); To configure the packet packet trace in terms of the parameters to be logged

  • char* (*fn_NetSim_protocol_WritePacketTrace)(const NetSim_PACKET*); To configure the event trace in terms of the parameters to be logged.