AodvT_Route_Entry* aodv_route_table_entry_create (AodvT_Route_Table* route_table_ptr, InetT_Address dest_addr, InetT_Subnet_Mask subnet_mask, InetT_Address next_hop_addr, IpT_Port_Info out_port_info, int num_hops, int dest_seq_num, double expiry_time) { AodvT_Route_Entry* route_entry_ptr; AodvT_Global_Stathandles* global_stathandle_ptr; void* old_contents_ptr; /** Adds a new route table entry **/ /** in the route table **/ FIN (aodv_route_table_entry_create (<args>)); /* Allocate memory for the route entry */ route_entry_ptr = aodv_route_table_entry_mem_alloc (); route_entry_ptr->dest_prefix = ip_cmn_rte_table_dest_prefix_create (dest_addr, subnet_mask); route_entry_ptr->dest_seq_num = dest_seq_num; if (dest_seq_num != AODVC_DEST_SEQ_NUM_INVALID) route_entry_ptr->valid_dest_sequence_number_flag = OPC_TRUE; else route_entry_ptr->valid_dest_sequence_number_flag = OPC_FALSE; route_entry_ptr->route_entry_state = AodvC_Valid_Route; route_entry_ptr->next_hop_addr = inet_address_copy (next_hop_addr); route_entry_ptr->next_hop_port_info = out_port_info; route_entry_ptr->hop_count = num_hops; route_entry_ptr->route_expiry_time = op_sim_time () + expiry_time; /* This event will be processed by aodv_rte_entry_expiry_handle */ /* function when the timer expires. */ route_entry_ptr->route_expiry_evhandle = op_intrpt_schedule_call (route_entry_ptr->route_expiry_time, AODVC_ROUTE_ENTRY_INVALID, aodv_rte_entry_expiry_handle, route_entry_ptr); /* Set the route entry for this destination */ /* in the route table */ inet_addr_hash_table_item_insert (route_table_ptr->route_table, &dest_addr, route_entry_ptr, &old_contents_ptr); /* Insert the route in the IP common route table */ Inet_Cmn_Rte_Table_Entry_Add_Options (route_table_ptr->ip_cmn_rte_table_ptr, OPC_NIL, route_entry_ptr->dest_prefix, route_entry_ptr->next_hop_addr, route_entry_ptr->next_hop_port_info, route_entry_ptr->hop_count, route_table_ptr->aodv_protocol_id, 1, OPC_NIL, IPC_CMN_RTE_TABLE_ENTRY_ADD_INDIRECT_NEXTHOP_OPTION); /* Update the size of the route table */ route_table_ptr->active_route_count++; /* Update the route table size statistic */ op_stat_write (route_table_ptr->stat_handles_ptr->route_table_size_shandle, route_table_ptr->active_route_count); /* Update the statistic for the number of hops */ op_stat_write (route_table_ptr->stat_handles_ptr->num_hops_shandle, route_entry_ptr->hop_count); /* Get a handle to the global statistics */ global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); /* Update the global statistic for the number of hops */ op_stat_write (global_stathandle_ptr->num_hops_global_shandle, route_entry_ptr->hop_count); FRET (route_entry_ptr); }
static void aodv_packet_queue_route_discovery_time_stat_update (AodvT_Packet_Queue* pkt_queue_ptr, List* pkt_queue_lptr) { int num_pkts, count; AodvT_Packet_Entry* pkt_entry_ptr = OPC_NIL; AodvT_Global_Stathandles* global_stathandle_ptr = OPC_NIL; double first_enqueue_time = OPC_DBL_INFINITY; double route_discovery_time; /** Updates the statistic for the route discovery time **/ FIN (aodv_packet_queue_route_discovery_time_stat_update (<args>)); /* Get the number of packets for the */ /* destination whose route has just */ /* been discovered */ num_pkts = op_prg_list_size (pkt_queue_lptr); for (count = 0; count < num_pkts; count++) { /* Access each packet information */ /* and determine the first packet */ /* that was enqueued. */ pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_access (pkt_queue_lptr, count); if (pkt_entry_ptr->insert_time < first_enqueue_time) { /* This entry is earlier than */ /* any other so far */ first_enqueue_time = pkt_entry_ptr->insert_time; } } /* The route discovery time is the time */ /* difference between the first packet */ /* enqueued to this destination and the */ /* current simulation time when the */ /* route was discovered */ route_discovery_time = op_sim_time () - first_enqueue_time; /* Get a handle to the global statistics */ global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); /* Update the route discovery time for */ /* a specific destination */ op_stat_write (pkt_queue_ptr->stat_handle_ptr->route_discovery_time_shandle, route_discovery_time); /* Update the global route discovery time statistic */ op_stat_write (global_stathandle_ptr->route_discovery_time_global_shandle, route_discovery_time); FOUT; }
void aodv_support_routing_traffic_sent_stats_update (AodvT_Local_Stathandles* stat_handle_ptr, AodvT_Global_Stathandles* global_stathandle_ptr, Packet* pkptr) { OpT_Packet_Size pkt_size; /** Updates the routing traffic sent statistics **/ /** in both bits/sec and pkts/sec **/ FIN (aodv_support_routing_traffic_sent_stats_update (<args>)); /* Get the size of the packet */ pkt_size = op_pk_total_size_get (pkptr); /* Update the local routing traffic sent stat in bps */ op_stat_write (stat_handle_ptr->rte_traf_sent_bps_shandle, pkt_size); op_stat_write (stat_handle_ptr->rte_traf_sent_bps_shandle, 0.0); /* Update the local routing traffic sent stat in pps */ op_stat_write (stat_handle_ptr->rte_traf_sent_pps_shandle, 1.0); op_stat_write (stat_handle_ptr->rte_traf_sent_pps_shandle, 0.0); /* Update the global routing traffic sent stat in bps */ op_stat_write (global_stathandle_ptr->rte_traf_sent_bps_global_shandle, pkt_size); op_stat_write (global_stathandle_ptr->rte_traf_sent_bps_global_shandle, 0.0); /* Update the global routing traffic sent stat in pps */ op_stat_write (global_stathandle_ptr->rte_traf_sent_pps_global_shandle, 1.0); op_stat_write (global_stathandle_ptr->rte_traf_sent_pps_global_shandle, 0.0); FOUT; }
void aodv_packet_queue_all_pkts_to_dest_delete (AodvT_Packet_Queue* pkt_queue_ptr, InetT_Address dest_addr) { AodvT_Packet_Entry* pkt_entry_ptr; AodvT_Global_Stathandles* global_stathandle_ptr = OPC_NIL; List* pkt_lptr; int num_pkts; /** Deletes all packets to a specific destination **/ FIN (aodv_packet_queue_all_pkts_to_dest_delete (<args>)); /* Remove the packets form the queue */ pkt_lptr = (List *) inet_addr_hash_table_item_remove (pkt_queue_ptr->pkt_queue_table, &dest_addr); if (pkt_lptr == OPC_NIL) FOUT; /* Decrement the size of the queue */ num_pkts = op_prg_list_size (pkt_lptr); pkt_queue_ptr->current_queue_size -= num_pkts; /* Update the packet queue size statistic */ aodv_packet_queue_size_stat_update (pkt_queue_ptr); /* Update the number of packets dropped statistic */ op_stat_write (pkt_queue_ptr->stat_handle_ptr->num_pkts_discard_shandle, (double) num_pkts); /* Get a handle to the global statistics */ global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); /* Update the global statistic for the number of pkts dropped */ op_stat_write (global_stathandle_ptr->num_pkts_discard_global_shandle, (double) num_pkts); /* Free each entry in the list */ while (num_pkts > 0) { pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_remove (pkt_lptr, OPC_LISTPOS_HEAD); aodv_packet_queue_entry_mem_free (pkt_entry_ptr); num_pkts--; } /* Free the list */ op_prg_mem_free (pkt_lptr); FOUT; }
/*-------------------------------------------------------------------------------- * Function: wban_up5_traffic_generate * * Description: creates a MSDU requiring acknowledge based on the MSDU generation * specifications of the source model and sends it to the lower layer. * * No parameters *--------------------------------------------------------------------------------*/ static void wban_up5_traffic_generate() { Packet* msdu_ptr; Packet* app_traffic_ptr; int msdu_size; /* size in bits */ double next_intarr_time; /* interarrival time of next MSDU */ double abs_next_intarr_time; /* absolute interarrival time of next MSDU */ /* Stack tracing enrty point */ FIN (wban_up5_traffic_generate); /* Generate a MSDU size outcome. */ msdu_size = (int) ceil (oms_dist_outcome (up5_msdu_size_dist_ptr)); /* 0 <= MAC frame body <= pMaxFrameBodyLength_Bits */ if (msdu_size > pMaxFrameBodyLength_Bits) msdu_size = pMaxFrameBodyLength_Bits; /* The size of generated MSDU is bigger than the maximum - the size is set to the maximum. */ if (msdu_size < 0) msdu_size = 0; /* We produce unformatted packets. Create one. */ msdu_ptr = op_pk_create (msdu_size); /* create a App traffic frame that encapsulates the msdu packet */ app_traffic_ptr = op_pk_create_fmt ("wban_app_traffic_format"); /* increment the data sequence number by 1 at a time */ dataSN = (dataSN + 1) % 32768; op_pk_nfd_set (app_traffic_ptr, "App Sequence Number", dataSN); op_pk_nfd_set (app_traffic_ptr, "User Priority", 5); op_pk_nfd_set_pkt (app_traffic_ptr, "MSDU Payload", msdu_ptr); // wrap msdu in app traffic /* schedule next MSDU generation */ next_intarr_time = oms_dist_outcome (up5_msdu_interarrival_dist_ptr); /* Make sure that interarrival time is not negative. In that case it will be set to 0. */ if (next_intarr_time <0) next_intarr_time = 0.0; abs_next_intarr_time = op_sim_time () + next_intarr_time; /* Update the packet generation statistics. */ op_stat_write (up5_msdus_sent_hndl, 1.0); op_stat_write (up5_msdus_sent_hndl, 0.0); op_stat_write (up5_bits_sent_hndl, (double) msdu_size); op_stat_write (up5_bits_sent_hndl, 0.0); op_stat_write (up5_bits_sent_hndlG, (double) msdu_size); op_stat_write (up5_bits_sent_hndlG, 0.0); op_stat_write (up5_msdu_size_hndl, (double) msdu_size); op_stat_write (up5_msdu_interarrival_time_hndl, next_intarr_time); op_stat_write (up5_msdus_hndl, 1.0); op_stat_write (up5_msdus_hndlG, 1.0); // app_sent_msdu_bits = app_sent_msdu_bits + (msdu_size/1000.0); // app_sent_msdu_nbr = app_sent_msdu_nbr + 1; // printf(" [Node %s] t = %f, msdu_create_time = %f, app_pkt_create_time = %f\n", \ // node_name, op_sim_time(), op_pk_creation_time_get(msdu_ptr), op_pk_creation_time_get(app_traffic_ptr)); /* send the App traffic via the stream to the lower layer. */ op_pk_send (app_traffic_ptr, STRM_FROM_UP_TO_MAC); // printf (" [Node %s] t= %f -> UP5 MSDU (size = %d bits) \ // was generated and sent to MAC layer.\n", node_name, op_sim_time(), msdu_size); if ((abs_next_intarr_time <= up5_stop_time) || (up5_stop_time == SC_INFINITE_TIME)) { up5_next_msdu_evh = op_intrpt_schedule_self (abs_next_intarr_time, SC_GENERATE_UP5); // printf ("\t Next UP5 MSDU will be generated at %f\n\n", abs_next_intarr_time); } /* Stack tracing exit point */ FOUT; }
void ra_aloha_ss_intrpt_strm_handler(void) { Packet* sduptr; Packet* pduptr; int istrm; int ss_id; char pk_fmt_str[64]; static Boolean wait_ack_flag = OPC_FALSE; static Evhandle tr_ack; FIN(ra_aloha_ss_intrpt_strm_handler()); istrm = op_intrpt_strm(); if (istrm == svptr->istrm_hl) { sduptr = op_pk_get(istrm); if (wait_ack_flag) { //What will happen if the subq overflows? op_subq_pk_insert(0, sduptr, OPC_QPOS_TAIL); if (op_prg_odb_ltrace_active("aloha")) { op_prg_odb_print_major("Queueing a data packet.", OPC_NIL); } FOUT ; } buf_pkptr = op_pk_copy(sduptr); pduptr = op_pk_create_fmt(Ra_Aloha_Data_Pk_Name ); op_stat_write(svptr->sh_load_bits, op_pk_total_size_get(sduptr)); op_stat_write(svptr->sh_load_bits, 0.0); op_stat_write(svptr->gsh_load_bits, op_pk_total_size_get(sduptr)); op_stat_write(svptr->gsh_load_bits, 0.0); op_pk_nfd_set_pkt(pduptr, "Data", sduptr); op_pk_send(pduptr, svptr->ostrm_ll); tr_ack = op_intrpt_schedule_self(Cur_Time + tr_len_ack, TR_ACK_TO); wait_ack_flag = OPC_TRUE; if (op_prg_odb_ltrace_active("aloha")) { op_prg_odb_print_major("Sending a data packet.", OPC_NIL); } } else if (istrm == svptr->istrm_ll) { pduptr = op_pk_get(istrm); op_pk_format(pduptr, pk_fmt_str); if (strcmp(pk_fmt_str, Ra_Aloha_Ack_Pk_Name)==0) { op_pk_nfd_get_int32(pduptr, "SS ID", & ss_id); if (ss_id != svptr->ss_id) { op_pk_destroy(pduptr); FOUT; } wait_ack_flag = OPC_FALSE; //TODO: check whether the timer event is valid op_ev_cancel(tr_ack); //op_ev_cancel(svptr->tr_ack); op_stat_write(svptr->sh_goodput_bits, op_pk_total_size_get(buf_pkptr)); op_stat_write(svptr->sh_goodput_bits, 0.0); op_pk_destroy(buf_pkptr); //the waiting queue is not empty, scheduing next tx if (!op_subq_empty(0)) { sduptr = ra_aloha_ss_dequeue(); buf_pkptr = op_pk_copy(sduptr); pduptr = op_pk_create_fmt(Ra_Aloha_Data_Pk_Name ); op_pk_nfd_set(pduptr, "Data", sduptr); op_pk_send(pduptr, svptr->ostrm_ll); op_pk_send(pduptr, svptr->ostrm_ll); tr_ack = op_intrpt_schedule_self(Cur_Time + tr_len_ack, TR_ACK_TO); } } //op_pk_send(pduptr, svptr->ostrm_hl); } //istrm_ll FOUT; }
void aodv_packet_queue_insert (AodvT_Packet_Queue* pkt_queue_ptr, Packet* data_pkptr, InetT_Address dest_addr) { List* pkt_lptr; AodvT_Packet_Entry* pkt_entry_ptr; void* old_contents_ptr; AodvT_Global_Stathandles* global_stathandle_ptr = OPC_NIL; /** Inserts a new data packet into the packet queue. If the queue is full **/ /** the oldest packet in the queue that has the same destination with the **/ /** new packet is dropped and the new packet inserted; or the new packet is **/ /** dropped if there is no packet to the same destination in the full queue.**/ FIN (aodv_packet_queue_insert (<args>)); /* Check if there are already other packets */ /* waiting for this destination. */ pkt_lptr = (List *) inet_addr_hash_table_item_get (pkt_queue_ptr->pkt_queue_table, &dest_addr); /* Is the queue already full? */ if ((pkt_queue_ptr->max_queue_size != AODVC_INFINITE_PACKET_QUEUE) && (pkt_queue_ptr->max_queue_size == pkt_queue_ptr->current_queue_size)) { /* There is no more space in the queue to insert */ /* any other packet. Delete the oldest packet in */ /* packet queue to the same destination to make */ /* space for the new packet. */ if (pkt_lptr == OPC_NIL) { /* There is no packet in the queue for the same */ /* destination. Hence drop the new packet. */ manet_rte_ip_pkt_destroy (data_pkptr); /* Update the local and global number of */ /* packets dropped statistics. */ op_stat_write (pkt_queue_ptr->stat_handle_ptr->num_pkts_discard_shandle, 1.0); global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); op_stat_write (global_stathandle_ptr->num_pkts_discard_global_shandle, 1.0); FOUT; } else { /* Drop the oldest packet to the same */ /* destination, which is at the head of the */ /* queue. */ pkt_entry_ptr = (AodvT_Packet_Entry*) op_prg_list_remove (pkt_lptr, OPC_LISTPOS_HEAD); aodv_packet_queue_entry_mem_free (pkt_entry_ptr); /* Update the local and global number of */ /* packets dropped statistics. */ op_stat_write (pkt_queue_ptr->stat_handle_ptr->num_pkts_discard_shandle, 1.0); global_stathandle_ptr = aodv_support_global_stat_handles_obtain (); op_stat_write (global_stathandle_ptr->num_pkts_discard_global_shandle, 1.0); /* Decrement the size of the packet queue. */ pkt_queue_ptr->current_queue_size--; /* Update the packet queue size statistic. */ aodv_packet_queue_size_stat_update (pkt_queue_ptr); } } if (pkt_lptr == OPC_NIL) { /* No entry exists for this destination */ /* Create a queue for the destination. */ pkt_lptr = op_prg_list_create (); inet_addr_hash_table_item_insert (pkt_queue_ptr->pkt_queue_table, &dest_addr, pkt_lptr, &old_contents_ptr); } /* Allocate memory to store the new packet */ pkt_entry_ptr = aodv_packet_queue_entry_mem_alloc (); pkt_entry_ptr->pkptr = data_pkptr; pkt_entry_ptr->insert_time = op_sim_time (); /* Always insert at the tail of the list so */ /* that the oldest packets are at the head */ /* of the list automatically */ op_prg_list_insert (pkt_lptr, pkt_entry_ptr, OPC_LISTPOS_TAIL); pkt_queue_ptr->current_queue_size++; /* Update the packet queue size statistic */ aodv_packet_queue_size_stat_update (pkt_queue_ptr); FOUT; }