Applicable VersionsNetSim Standard NetSim Pro 


Applicable Releasesv13


RPL log file contains RPL protocol-specific information related to control message exchange, time stamps, ranks computed, parent selection, siblings list, etc. The child list can be additionally logged to this file by modifying the underlying source codes of the RPL protocol in NetSim.

 

Follow the steps given below to add RPL Child node information to the RPL Logfile:

 1. Open the source codes by going to Open Simulation-> Workspace Options and click on the Open Code button. This will load the source codes in Visual Studio.

2. Go to the RPL project in the solution explorer, expand, and double click on the RPL.h file.

3. Uncomment the line #define DEBUG_RPL and add the following lines of code(highlighted in red) to the stru_rpl_dodag structure as shown below:



typedef struct stru_rpl_dodag 

    {

        DODAGID dodag_id;

        UINT dodag_pref:3;

        bool grounded;

        bool dao_supported;

        bool dao_trigger;


        UINT8 dio_interval_doublings;

        UINT8 dio_interval_min;

        UINT8 dio_redundancy_constant;

.

.

.

        UINT16 sibling_count;

        PRPL_NEIGHBOR pref_parent;

        PRPL_NEIGHBOR* child_list;

        UINT16 child_count;

    

    } RPL_DODAG,*PRPL_DODAG;


4. In the RPL.h file add the functions prototypes(highlighted in red) as shown below:

//Siblings

    void rpl_node_add_sibling(NETSIM_ID d, PRPL_NEIGHBOR sibling);

    PRPL_NEIGHBOR rpl_node_find_sibling(NETSIM_ID d, NETSIM_ID sibling);

    void rpl_node_remove_all_siblings(NETSIM_ID d);

#define rpl_node_has_sibling(node, sibling)     (rpl_node_find_sibling(node, sibling) != NULL)


//Child

    void rpl_node_add_child(NETSIM_ID d, PRPL_NEIGHBOR child);

    void rpl_node_remove_child(NETSIM_ID p, NETSIM_ID c);

    void print_rpl_child_list(NETSIM_ID parent_id);


5. Click on the Neighbor.c file in the RPL project and add the following functions to add/remove child node entries in the child list, and print them to the RPL log file:

 

void rpl_node_add_child(NETSIM_ID d, PRPL_NEIGHBOR child)

{

            PRPL_NODE rpl = GET_RPL_NODE(d);

 

            if (!rpl->joined_dodag)

                        //fnNetSimError("joined_dodag is null for %d in %s\n", d, __FUNCTION__);

                        return;

 

            PRPL_DODAG dodag = rpl->joined_dodag;

 

            dodag->child_list = (PRPL_NEIGHBOR*)realloc(dodag->child_list, (dodag->child_count + 1) * sizeof(PRPL_NEIGHBOR));

            dodag->child_list[dodag->child_count++] = child;

}

 

void rpl_node_remove_child(NETSIM_ID p ,NETSIM_ID c)

{

            PRPL_NODE rpl = GET_RPL_NODE(p);

            if (!rpl->joined_dodag)

                        fnNetSimError("joined_dodag is null for %d device in %s\n", p, __FUNCTION__);

 

            PRPL_DODAG dodag = rpl->joined_dodag;

 

            int position = 0;

 

            for (int i = 0; i < dodag->child_count; i++)

            {

                        PRPL_NEIGHBOR neighbor = dodag->child_list[i];

                        if (neighbor->nodeId == c)

                                    position = i + 1;

            }

 

            if (position)

            {

                        for (int i = position - 1; i < dodag->child_count - 1; i++)

                        {

                                    dodag->child_list[i] = dodag->child_list[i + 1];

                        }

                        dodag->child_count-= 1;

            }

            

 

}

 

void print_rpl_child_list(NETSIM_ID parent_id)

{

            char child_list_str[BUFSIZ];

            child_list_str[0] = '\0';

            PRPL_NODE rpl_parent = GET_RPL_NODE(parent_id);

 

            if (rpl_parent->joined_dodag)

            {

                        PRPL_DODAG dodag_parent = rpl_parent->joined_dodag;

 

                        for (int i = 0; i < dodag_parent->child_count; i++)

                        {

                                    PRPL_NEIGHBOR neighbor1 = dodag_parent->child_list[i];

 

                                    char sz[10];

                                    sprintf(sz, "%d", neighbor1->nodeId);

                                    strcat(child_list_str, sz);

 

                                    if (i < dodag_parent->child_count - 1)

                                    {

                                                strcat(child_list_str, ", ");

                                    }

 

                        }

                        print_rpl_log("node '%d': chosen children in dodag_id = '%s': new rank = %d, child_list = [%s]",

                                    parent_id, RPL_IP_TO_STR(dodag_parent->dodag_id), dodag_parent->rank, child_list_str);

            }

}


6. In the Neighbor.c file in the RPL project add the following lines of code (highlighted in red) to the choose_parents_and_siblings() function as shown below:


void choose_parents_and_siblings(NETSIM_ID d)

{

    PRPL_NODE rpl = GET_RPL_NODE(d);


    if (!rpl->joined_dodag)

        fnNetSimError("joined_dodag is null for %d device in %s\n", d, __FUNCTION__);


    PRPL_DODAG dodag = rpl->joined_dodag;


    /* forget about previous DIO routes */

    rpl_delete_all_route(d);


    rpl_node_remove_all_parents(d);

    rpl_node_remove_all_siblings(d);

.

.

.

.
 

      NETSIM_ID old_pref_parent = ((dodag->pref_parent== NULL) ? (0)(dodag>pref_parent->nodeId));

      dodag->pref_parent = rpl->neighbor_list[best_rank_index]; 

 

      PRPL_NEIGHBOR neighbor1 = (PRPL_NEIGHBOR)calloc(1, sizeof * neighbor1);

      neighbor1->nodeId = d;

       

      if (dodag->pref_parent->nodeId != old_pref_parent)

      {

                  if (old_pref_parent)

                  {

                              rpl_node_remove_child(old_pref_parent, d);

                              print_rpl_child_list(old_pref_parent);

                  } 

                  

                    NetSim_EVENTDETAILS pevent;

                  memset(&pevent, 0, sizeof pevent);

                  pevent.dEventTime = pstruEventDetails->dEventTime;

                  pevent.nDeviceId = d;

                  pevent.nDeviceType = DEVICE_TYPE(d);

                  pevent.nEventType = TIMER_EVENT;

                  pevent.nProtocolId = NW_PROTOCOL_RPL;

                  pevent.nSubEventType = RPL_NEW_PREF_PARENT;

                  fnpAddEvent(&pevent);

 

//Printing Child list to log

 

                  NETSIM_ID parent_id = dodag->pref_parent->nodeId;

 

                  if (neighbor1)

                  {

                              rpl_node_add_child(parent_id, neighbor1);

                              print_rpl_child_list(parent_id);

                  }

}

 

7. In DODAG.c file add the following lines of code (highlighted in red) to the rpl_dodag_create() and rpl_dodag_destroy() functions as shown below:

 

PRPL_DODAG rpl_dodag_create(PRPL_CTRL_MSG dio_pdu)

{

      PRPL_DIO_BASE diobase = dio_pdu->Base;

      PRPL_DODAG_CONFIG_OPTION dodag_config_suboption = get_option_from_msg(dio_pdu, RPLOPTION_DODAGConfiguration);

 

.

.

.

.

      dodag->parent_list = NULL;

      dodag->parent_count = 0;

      dodag->sibling_list = NULL;

      dodag->sibling_count = 0;

      dodag->pref_parent = NULL;

      dodag->child_list = NULL;

      dodag->child_count = 0;

 

      return dodag;

}

 

void rpl_dodag_destroy(PRPL_DODAG dodag)

{

      if (dodag->dodag_id != NULL)

      {

                  IP_FREE(dodag->dodag_id);

      }

.

.

.

 

      if (dodag->child_list != NULL)

      {

                  free(dodag->child_list);

      }

 

      free(dodag); 

}

 

8. After modifying the source codes as explained above, right-click on the project and select rebuild. 


Simulation Results and Analysis:

 

Now upon running any RPL based simulations, an RPL log file will be generated which can be accessed from the results dashboard as shown below:

 

 

 The log file contains the child list information updated each time a node selects a new parent as shown below: