Applicable VersionsNetSim StandardNetSim Pro


Applicable Releasesv12v13

NetSim allows users to interact with the simulation at runtime via a socket or through a file. The Real-Time Interaction option in NetSim, lets the NetSimCore.exe (server) wait for the client to connect using the socket port. The client can be a socket program written in any programming language. In this case, we will be considering a python socket program.


After the connection is established, various commands supported by NetSim's Interactive Simulation/SDN modules can be executed to view/modify certain device parameters during run-time.


This feature can be exploited to pass parameters from NetSim to an external socket program (say in Python). However, this will require modifications to the underlying source codes.


Modifying the source codes:


Open Visual Studio 2019 through Netsim->Open simulation->workspace options->open code)


CLI Interpreter Project:


1. Go to the CLIInterpretor Project in the solution explorer. 

2. The Socket Connection information variable is declared in the structure stru_clientInfo, which is part of the CLI.h file.
To access a pointer to this structure from a different source code project, the following code needs to be added(changes highlighted in red) to the CLI.h file:

typedef struct stru_clientInfo
{
CLIENTTYPE clientType;
union client
{
SOCKCLIENTINFO sockClient;
FILECLIENTINFO fileClient;
STRINGCLIENTINFO stringClient;
}CLIENT;

NETSIM_ID deviceId;
char* deviceName;

char* promptString;

bool isMultResp;
bool(*multResp)(void*, char*, int, bool);
void* multRespArg;
struct stru_clientInfo* next;
}CLIENTINFO, *ptrCLIENTINFO;

#ifndef SHARE_CLIENT_INFO
_declspec(dllexport) CLIENTINFO *socket_var;
#else
_declspec(dllimport) CLIENTINFO *socket_var;

#endif


3. The client info is defined inside the function command_recv_process() which is part of the Socket.c file. The socket_var shared parameter needs to be updated here for external access, as shown below (changes highlighted in red):

DWORD WINAPI command_recv_process(LPVOID lpParam)
{
ptrCLIENTINFO clientInfo = lpParam;
socket_var = clientInfo;
SOCKCLIENTINFO sockClient = clientInfo->CLIENT.sockClient;
int iResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;

// Receive until the peer shuts down the connection
do
    {

.

.

.


4. The function send_to_socket() can be used to send parameters from NetSim to an external socket program. For this function to be accessible from other projects, its definition needs to be exported. For this purpose, the function definition needs to be modified as shown below(changes highlighted in red):

_declspec(dllexport) void send_to_socket(ptrCLIENTINFO info,char* buf, int len)
{

.

.

.

5. The function prototype in the CLI.h file needs to be modified accordingly as shown below(changes highlighted in red):

void process_command(ptrCLIENTINFO clientInfo, char* command, int len);
_declspec(dllexport) void send_to_socket(ptrCLIENTINFO info, char* buf, int len);
void write_to_file(ptrCLIENTINFO info, char* msg, int len);


5. Save all the changes done and right-click on the CLIInterpretor project and select Rebuild. 

6. Upon successful build, output binaries will get created in <Current_Workspace_Directory\bin\bin(_x64/_x86)> path.

For Eg: C:\Users\Admin\Documents\NetSim_12.0.18_64_std_default\bin\bin_x64

7. Copy the CLIInterpretor.lib library file from the path and paste it in <Current_Workspace_Directory\src\Simulation\lib(_x64/_x86)> path. 

For Eg: C:\Users\Admin\Documents\NetSim_12.0.18_64_std_default\src\Simulation\lib_x64


Project from where parameters are to be passed outside (Eg: ZigBee):


1. In order to access the client info and to send parameters out to an external socket program, add the following lines of code in the ZigBee header file 802_15_4.h (changes highlighted in red):

#ifndef _NETSIM_802_15_4_H_
#define _NETSIM_802_15_4_H_
#ifdef __cplusplus
extern "C" {
#endif
#define SHARE_CLIENT_INFO
#pragma comment(lib,"CLIInterpretor.lib")

#pragma comment(lib,"PropagationModel.lib")
#pragma comment(lib,"BatteryModel.lib")


2. In this example, let's consider we send the device id and packet id whenever the ZigBee Physical In Event is triggred, i.e whenever a packet is received at any ZigBee device. Following lines of code are added to the PHYSICAL_IN_EVENT in the fn_NetSim_Zigbee_Run() function that is part of the 802_15_4.c file(changes highlighted in red) :

if(fn_NetSim_Packet_DecideError(dBER,pstruEventDetails->dPacketSize))
{
pstruPacket->nPacketStatus = PacketStatus_Error;
nPacketStatus = PacketStatus_Error;
}

char sendMSG[2 * BUFSIZ];
sprintf(sendMSG, "\nPacket Received at Node %d\nPacket ID %d\n", pstruEventDetails->nDeviceId, pstruPacket->nPacketId);
if(socket_var)
send_to_socket(socket_var, sendMSG, (int)strlen(sendMSG) + 1);

fn_NetSim_WritePacketTrace(pstruPacket);

if(pstruPacket->nControlDataType == ACK_FRAME)
pstruPacket->pstruPhyData->dOverhead -= 1;
else
                pstruPacket->pstruPhyData->dOverhead -= 6;


3. Include the CLI.h header file of the CLIInterpretor Project in the 802_15_4.c file to be able to use the shared variable socket_var as shown below:

#include "..\CLIInterpretor\CLI.h"


4. Save all the changes done and right-click on the ZigBee project and select Rebuild. 



External Socket Program(Python Code):


Following is a sample Python script, which does the following tasks:

1. Passes the Device Name of a node in the network scenario to be simulated. This allows initializing client info in NetSim.

2. Listens to the Socket continuously.


# An example script to send client request to NetSim server using socket programming in Python
import socket # for socket
import sys
import time


#----------------------Socket code-----------------------
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print ("Socket successfully created.")
except socket.error as err:
  print ("Socket creation failed with error %s" %(err))

# default port for socket
port = 8999

try:
  host_ip = socket.gethostbyname('127.0.0.1')
except socket.gaierror:
  # this means could not resolve the host
  print ("Error resolving host.")
  sys.exit()

# connecting to the server
s.connect((host_ip, port))
print ("Connection established to NetSim.")

#print ('each = ', each)

name = '6_LOWPAN_Gateway_6' #can be reset to a device name in the network scenario to be simulated.
name = name + '\0'
s.send(name.encode())

#command = 'route print'
#command = command + '\0'
#print ('static for ', route[each].decode('utf-8'), '=', command.decode('utf-8'))
#s.send(command.encode())

while True:
    resp = s.recv(1024).decode('utf-8')
    cont = '__continue__'
    resp = resp + s.recv(1024).decode('utf-8')
    print ("Received:", resp)


s.close()


Save the above code as a python file, say SocketInterface.py. A sample file is also attached herewith.


Simulation and client-server interactions:


Let us consider the following network scenario:


1. Create a network scenario in WSN/IoT network, where devices use ZigBee protocol. 

2. Click on Run Simulation option. For the python program to interact with NetSim during the simulation, Interactive Simulation parameters has to be set to 'True' under the Real-Time Interaction tab, before running the simulation.


This lets the NetSimCore.exe (server) to wait for the client (Python script) to connect using the socket port. 


3. Run simulation for 100 seconds. NetSim Simulation Console starts and waits for client application to connect as shown below:


4. Run the python socket client code socketInterface.py in a new command window as shown below:



6. Now during the simulation, whenever any ZigBee node receives a packet, the device name and the packet id will be passed to the Python Socket. The recieved information is printed to console as shown below:



Interactive Simulation commands can also be passed from the Python script to NetSim if required.


Refer the following articles for further details:

how-to-configure-acl-through-netsim-python-socket-interface-

how-to-add-custom-commands-to-netsim-sdn-interactive-simulation-module-

can-i-use-various-networking-commands-in-netsim-

does-netsim-have-a-python-interface-can-you-give-an-example-