Hi everyone!
I'm a new user of ns2 and I'm trying to write a simple wireless routing
protocol, where nodes can listen packet broadcasting from one to another.
But, until now,
when I compile and run tcl file, just node that send broadcast can listen
it self. I don't see where're the errors.
May someone help me, please ?
This is my code:
/*************************PACKET TYPES**************/
/*
* wtr-packet.h
*
* Created on: Jul 30, 2012
* Author: adroaldo
*/
#ifndef WTR_PACKET_H_
#define WTR_PACKET_H_
#include <packet.h>
#include"constants.h"
#define FC_LEN 1
/*Defining packets format*/
#define DELETED_PCKT 0x00 /*binary
representation 00000000*/
#define NORMAL_TOKEN 0x01 /*binary
representation 00000001*/
#define ELECTION_TOKEN 0x02 /*binary representation
00000010*/
#define ELECTED_TOKEN 0x03 /*binary
representation 00000011*/
#define SOLICIT_SUCCESSOR 0x04 /*binary
representation 00000100*/
#define SET_PREDECESSOR 0x05 /*binary
representation 00000101*/
#define SET_SUCCESSOR 0x06 /*binary
representation 00000110*/
#define DATA_PCKT 0x07 /*binary representation
00000111*/
#define ACK_DATA_PCKT 0x08 /*binary
representation 00001000*/
#define VARAL_TOKEN 0x09 /*binary representation
00001001*/
#define VARAL_ELECTION_TOKEN 0x0A /*binary representation
00001010*/
#define VARAL_ELECTED_TOKEN 0x0B /*binary representation
00001011*/
#define VARAL_SOLICIT_SUCCESSOR 0x0C /*binary representation
00001100*/
#define VARAL_SET_PREDECESSOR 0x0D /*binary representation
00001101*/
#define VARAL_SET_SUCCESSOR 0x0E /*binary representation
00001110*/
#define VARAL_DATA_TOKEN 0x0F /*binary representation
00001111*/
#define VARAL_ACK_DATA 0x010 /*binary
representation 00010000*/
#define SELF_ADVERTISING 0x011 /*binary
representation 00010001*/
/*Acesso direto aos headers de pacotes*/
#define HDR_WTRP_PACKET(p) ((hdr_wtrp_packet *)hdr_wtrp_packet::access(p))
#define HDR_DEL(p) ((hdr_del *)hdr_wtrp_packet::access(p))
#define HDR_TOKEN(p) ((hdr_token *)hdr_wtrp_packet::access(p))
#define HDR_ELECTION(p) ((hdr_election *)hdr_wtrp_packet::access(p))
#define HDR_ELECTED(p) ((hdr_elected *)hdr_wtrp_packet::access(p))
#define HDR_SSUCC(p) ((hdr_ssucc *)hdr_wtrp_packet::access(p))
#define HDR_SPRED(p) ((hdr_spred *)hdr_wtrp_packet::access(p))
#define HDR_SESUC(p) ((hdr_sesuc *)hdr_wtrp_packet::access(p))
#define HDR_VTOKEN(p) ((hdr_vtoken *)hdr_wtrp_packet::access(p))
#define HDR_VELECTION(p) ((hdr_velection *)hdr_wtrp_packet::access(p))
#define HDR_VELECTED(p) ((hdr_velected *)hdr_wtrp_packet::access(p))
#define HDR_VSSUCC(p) ((hdr_vssucc *)hdr_wtrp_packet::access(p))
#define HDR_VSPRED(p) ((hdr_vspred *)hdr_wtrp_packet::access(p))
#define HDR_VSESUC(p) ((hdr_vsesuc *)hdr_wtrp_packet::access(p))
#define HDR_ADVERTISING(p) ((hdr_advertising *)hdr_wtrp_packet::access(p))
/* Pacote default*/
struct hdr_wtrp_packet {
u_int8_t FC;
inline int size() {
int size_var =3D 0;
size_var =3D sizeof (struct hdr_wtrp_packet);
assert(size_var >=3D 0);
return size_var;
}
// acesso ao header
static int offset_;
inline static int& offset() {
return offset_;
}
inline static hdr_wtrp_packet* access(const Packet *p) {
return (hdr_wtrp_packet*) p->access(offset_);
}
};
/*Self advertisement*/
struct hdr_advertising {
u_int8_t FC;
nsaddr_t RA;
nsaddr_t DA; /*Broadcast address*/
nsaddr_t SA;
static int offset_;
/*Teste*/
double send_time;
inline int size() {
int size_var =3D 0;
size_var =3D sizeof (struct hdr_advertising);
assert(size_var >=3D 0);
/*Declarac=E3o de tipos e prot=F3tipos */
/************************************/
class wtrp;
typedef void(wtrp::*firefunction)(void);
/*******************************************************/
/* Tipo gen=E9rico de Timer. */
/* Todos os cr=E9ditos devem ser atribuidos ao Ke Liu em */
/* cs.binghamton.edu/~kliu/research/ns2code/index.html */
/*******************************************************/
class WTRP_Timer: public TimerHandler {
public:
WTRP_Timer(wtrp *agent, firefunction function);
private:
virtual void expire(Event *e);
wtrp *agent_;
firefunction firing_;
};
/************************/
/* Agent */
/************************/
class wtrp: public Agent {
/*friend classes*/
friend class WTRP_Timer;
/*node inclui identificador do n=F3*/
node *i_node;
/*posic=E3o do n=F3*/
uint32_t pos_x;
uint32_t pos_y;
/*energia restante*/
double node_energy;
/*Func=F5es para lidar com pacotes*/
void forward_data(Packet *p);
void recv_packet(Packet *p);
void send_packet();
/*TEMP:DUAS FUNC=D5ES PARA TESTAR TIMER*/
void send_wtrp_packet_timer();
void reset_wtrp_packet_timer();
public:
/*Para pegar logs*/
Trace *logtarget_;
/*Um ponteiro =E0 fila de interface de rede que fica entre "classifier" e
"link layer"*/
PriQueue *ifqueue_;
/*Port classifier para passar pacotes ao agente*/
PortClassifier *dmux_;
/*N=F3*/
MobileNode *iNode;
/*Timers*/
/*TEMP:S=D3 TESTANDO TIMER*/
WTRP_Timer send_packet_timer;
WTRP_Timer reset_packet_timer;
wtrp(nsaddr_t id);
void recv(Packet *p, Handler *h);
int command(int argc, const char * const *argv);
/*Atualizac=E3o de posic=E3o*/
void update_position();
/*Atualizac=E3o de energia*/
void update_energy();
};
#endif /* WTRP_H_ */
/*******WTRP.CC******/
/*
* wtrp.cpp
*
* Created on: Aug 10, 2012
* Author: adroaldo
*/
#include <my-wtr-proto/wtrp.h>
/* Debug definition*/
#define DEBUG
/*******************************/
/** Conectando TCL =E0s classes **/
/*******************************/
int hdr_wtrp_packet::offset_;
static class WTRPHeaderClass: public PacketHeaderClass {
public:
WTRPHeaderClass() :
PacketHeaderClass("PacketHeader/WTRP", sizeof(hdr_all_packets)) {
bind_offset(&hdr_wtrp_packet::offset_);
}
} class_rtProtoWTRP_hdr;
/*************************************/
/* Bind Agent class to tcl interface */
/*************************************/
static class WtrpClass: public TclClass {
public:
WtrpClass() :
TclClass("Agent/WTRP") {
}
TclObject *create(int argc, const char* const * argv) {
assert(argc =3D=3D 5);
return (new wtrp((nsaddr_t) Address::instance().str2addr(argv[4])));
}
} class_rtWtrp;
wtrp::wtrp(nsaddr_t id) :
Agent(PT_WTRP), send_packet_timer(this, &wtrp::send_wtrp_packet_timer),
reset_packet_timer(this, &wtrp::reset_wtrp_packet_timer) {
#ifdef DEBUG
printf("N (%.6f): Agente de roteamento inicializado para node %d\n",
CURRENT_TIME, id);
#endif
i_node =3D new node(id);
pos_x =3D 0;
pos_y =3D 0;
node_energy =3D 0.0;
logtarget_ =3D 0;
ifqueue_ =3D 0;
iNode =3D (MobileNode *) (Node::get_node_by_address(id));
}
WTRP_Timer::WTRP_Timer(wtrp *agent, firefunction f) :
TimerHandler() {
agent_ =3D agent;
firing_ =3D f;
}
void WTRP_Timer::expire(Event *e) {
(agent_->*firing_)();
}
void wtrp::recv_packet(Packet *p) {
struct hdr_ip* ih =3D HDR_IP(p);
struct hdr_wtrp_packet *wtrph =3D HDR_WTRP_PACKET(p);
struct hdr_advertising *hdrA =3D 0;
/*All routing messages are sent from and to port RT_PORT,*/
/*so we check it*/
assert(ih->sport =3D=3D RT_PORT);
assert(ih->dport =3D=3D RT_PORT);
/*switch (wtrph->FC) {
case SELF_ADVERTISING:
hdrA =3D HDR_ADVERTISING(p);
printf(" Recv_packet: =C9 um pacote SELF_ADVERTISING source is %d ou %d\n",
hdrA->SA, ih->saddr());
break;
default:
break;
}*/
if ((u_int32_t)(ih->daddr()) =3D=3D IP_BROADCAST) {
printf("Recv_packet: =C9 um pacote SELF_ADVERTISING source is %d\n",
ih->saddr());
}
/*Release resources*/
Packet::free(p);
}
void wtrp::send_packet() {
Packet* p =3D allocpkt();
struct hdr_cmn* ch =3D HDR_CMN(p);
struct hdr_ip* ih =3D HDR_IP(p);
struct hdr_advertising* ph =3D HDR_ADVERTISING(p);
//ph->SA =3D i_node->getNode_address();
ph->FC =3D SELF_ADVERTISING;
ph->send_time =3D CURRENT_TIME;
ch->ptype() =3D PT_WTRP;
ch->direction() =3D hdr_cmn::DOWN;
ch->size() =3D IP_HDR_LEN + ph->size();
ch->error() =3D 0;
ch->next_hop() =3D IP_BROADCAST;
ch->addr_type() =3D NS_AF_INET;
/*Escrevendo cabecalho IP*/
//ih->saddr() =3D i_node->getNode_address();
ih->saddr() =3D Agent::addr();
ih->daddr() =3D IP_BROADCAST;
ih->sport() =3D RT_PORT;
ih->dport() =3D RT_PORT;
ih->ttl_ =3D 1;
printf("antes de scheduler\n");
Scheduler::instance().schedule(target_, p, 0.0);
printf("depois de scheduler\n");
}
void wtrp::send_wtrp_packet_timer() {
printf("wtrp::send_wtrp_packet_timer Node (%.6d)\n",
i_node->getNode_address());
}
void wtrp::reset_wtrp_packet_timer() {
reset_packet_timer.resched((double) 5.0);
}
void wtrp::recv(Packet *p, Handler *h) {
struct hdr_cmn *ch =3D HDR_CMN(p);
struct hdr_ip *ih =3D HDR_IP(p);
recv_packet(p);
}
int wtrp::command(int argc, const char * const *argv) {
if (argc =3D=3D 2) {
if (strcasecmp(argv[1], "start") =3D=3D 0) {
return TCL_OK;
}
else if (strcasecmp(argv[1], "send") =3D=3D 0) {
send_packet();
return TCL_OK;
}
else if (strcasecmp(argv[1], "start-WL-bcast") =3D=3D 0) {
send_packet();
return TCL_OK;
}
}// Pass the command to the base class
else if (argc =3D=3D 3) {
/*if(strcmp(argv[1], "index") =3D=3D 0) {
index =3D atoi(argv[2]);
return TCL_OK;
}*/
if (strcmp(argv[1], "log-target") =3D=3D 0
|| strcmp(argv[1], "tracetarget") =3D=3D 0) {
logtarget_ =3D (Trace*) TclObject::lookup(argv[2]);
if (logtarget_ =3D=3D 0)
return TCL_ERROR;
return TCL_OK;
}
else if (strcmp(argv[1], "drop-target") =3D=3D 0) {
return TCL_OK;
}
else if (strcmp(argv[1], "if-queue") =3D=3D 0) {
ifqueue_ =3D (PriQueue*) TclObject::lookup(argv[2]);
if (ifqueue_ =3D=3D 0)
return TCL_ERROR;
return TCL_OK;
}
else if (strcmp(argv[1], "port-dmux") =3D=3D 0) {
dmux_ =3D (PortClassifier *) TclObject::lookup(argv[2]);
if (dmux_ =3D=3D 0) {
fprintf(stderr, "%s: %s lookup of %s failed\n", __FILE__,
argv[1], argv[2]);
return TCL_ERROR;
}
return TCL_OK;
}
}
return Agent::command(argc, argv);
}
void wtrp::update_position() {
iNode->update_position();
pos_x =3D iNode->X();
pos_y =3D iNode->Y();
printf("U (%.6f): UPDATE POSITION, for Node %d, X: %.6u and Y: %.6u\n",
CURRENT_TIME, i_node->getNode_address(), pos_x, pos_y);
}
void wtrp::update_energy() {
node_energy =3D iNode->energy_model()->energy();
printf("U (%.6f): UPDATE ENERGY, for Node %d, Energy: %.4u\n",
CURRENT_TIME, i_node->getNode_address(), node_energy);
}
/********************************TCL FILE*********************************/
if {$argc !=3D 1} {
#criando objetos n=F3s
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns node]
$node_($i) random-motion 0
}
#Atribuindo cor verde
for {set i 0} {$i < $val(nn)} {incr i} {
$node_($i) color green
$ns at 0.0 "$node_($i) color green"
}
#positionamento aleat=F3rio
for {set i 0} {$i < $val(nn) } { incr i } {
$node_($i) set X_ [ expr {$val(x) * rand()} ]
$node_($i) set Y_ [ expr {$val(y) * rand()} ]
$node_($i) set Z_ 0
}
#criando agente wtrp e associando ao n=F3
for {set i 0} {$i < $val(nn)-1 } { incr i } {
set wtrpAgente_($i) [new Agent/WTRP [$node_($i) node-addr] ]
$ns attach-agent $node_($i) $wtrpAgente_($i)
}
set null2 [new Agent/Null]
$ns attach-agent $node_(2) $null2
#Setup a CBR over wtrp connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $wtrpAgente_(0)
$cbr set type_ CBR
$cbr set packet_size_ 50
$cbr set rate_ 0.1Mb
$cbr set interval_ 2
$ns duplex-link $node_(0) $node_(1) 10Mb 20ms DropTail
$ns duplex-link $node_(0) $node_(2) 10Mb 20ms DropTail
$ns connect $wtrpAgente_(1) $wtrpAgente_(0)
$ns connect $null2 $wtrpAgente_(0)
#define uma func=E3o 'recv' para a classe 'Agent/WTRP'
Agent/WTRP instproc recv_packet {from rtt} {
$self instvar node_
puts "node [$node_ id] received wtrp answer from \
$from with round-trip-time $rtt ms."
}
#posicao inicial de n=F3 em nam
for {set i 0} {$i < $val(nn)} {incr i} {
# o tamanho de cada n=F3 ser=E1 30
$ns initial_node_pos $node_($i) 30
}
#Programando eventos
$ns at 0.5 "$wtrpAgente_(0) start-WL-bcast"
$ns at 0.7 "$wtrpAgente_(1) start-WL-bcast"
$ns at 3.7 "$wtrpAgente_(1) start-WL-bcast"
$ns at 5.7 "$wtrpAgente_(0) start-WL-bcast"
$ns at $val(stop) "stop"
#Avisando aos n=F3s o final da simulacao
#for {set i 0} {$i < $val(nn)} {incr i} {
# $ns at $val(stop) "$node_($i) reset";
#}
#finalizando nam e a simulacao
#$ns at $val(stop) "$ns nam-end-wireless $val(stop)"
#$ns at $val(stop) "stop"
#$ns at 10.01 "puts \"end simulation\"; $ns halt"
proc stop {} {
global ns tracefd namtrace
$ns flush-trace
close $tracefd
close $namtrace
exec nam advertising_sim.nam &
}
$ns run
I'm using ns-2.35 + ubuntu 10.04 lts.
Thks in advance.
Adroaldo Borges