📄 cpmmodelc.nc
字号:
double prr = prr_estimate_from_snr(SNR);
double coin = RandomUniform();
if ( (prr >= 0) && (prr <= 1) ) {
if (coin < prr)
prr = 1.0;
else
prr = 0.0;
}
return prr;
}
bool checkReceive(receive_message_t* msg) {
double noise = noise_hash_generation();
receive_message_t* list = outstandingReceptionHead;
noise = pow(10.0, noise / 10.0);
while (list != NULL) {
if (list != msg) {
noise += pow(10.0, list->power / 10.0);
}
list = list->next;
}
noise = 10.0 * log(noise) / log(10.0);
return shouldReceive(msg->power - noise);
}
double packetNoise(receive_message_t* msg) {
double noise = noise_hash_generation();
receive_message_t* list = outstandingReceptionHead;
noise = pow(10.0, noise / 10.0);
while (list != NULL) {
if (list != msg) {
noise += pow(10.0, list->power / 10.0);
}
list = list->next;
}
noise = 10.0 * log(noise) / log(10.0);
return noise;
}
double checkPrr(receive_message_t* msg) {
return prr_estimate_from_snr(msg->power / packetNoise(msg));
}
/* Handle a packet reception. If the packet is being acked,
pass the corresponding receive_message_t* to the ack handler,
otherwise free it. */
void sim_gain_receive_handle(sim_event_t* evt) {
receive_message_t* mine = (receive_message_t*)evt->data;
receive_message_t* predecessor = NULL;
receive_message_t* list = outstandingReceptionHead;
dbg("CpmModelC", "Handling reception event @ %s.\n", sim_time_string());
while (list != NULL) {
if (list->next == mine) {
predecessor = list;
}
list = list->next;
}
if (predecessor) {
predecessor->next = mine->next;
}
else if (mine == outstandingReceptionHead) { // must be head
outstandingReceptionHead = mine->next;
}
else {
dbgerror("CpmModelC", "Incoming packet list structure is corrupted: entry is not the head and no entry points to it.\n");
}
dbg("CpmModelC,SNRLoss", "Packet from %i to %i\n", (int)mine->source, (int)sim_node());
if (!checkReceive(mine)) {
dbg("CpmModelC,SNRLoss", " - lost packet from %i as SNR was too low.\n", (int)mine->source);
mine->lost = 1;
}
if (!mine->lost) {
// Copy this receiver's packet signal strength to the metadata region
// of the packet. Note that this packet is actually shared across all
// receivers: a higher layer performs the copy.
tossim_metadata_t* meta = (tossim_metadata_t*)(&mine->msg->metadata);
meta->strength = mine->strength;
dbg_clear("CpmModelC,SNRLoss", " -signaling reception\n");
signal Model.receive(mine->msg);
if (mine->ack) {
dbg_clear("CpmModelC", " acknowledgment requested, ");
}
else {
dbg_clear("CpmModelC", " no acknowledgment requested.\n");
}
// If we scheduled an ack, receiving = 0 when it completes
if (mine->ack && signal Model.shouldAck(mine->msg)) {
dbg_clear("CpmModelC", " scheduling ack.\n");
sim_gain_schedule_ack(mine->source, sim_time() + 1, mine);
}
else { // Otherwise free the receive_message_t*
free_receive_message(mine);
}
// We're searching for new packets again
receiving = 0;
} // If the packet was lost, then we're searching for new packets again
else {
if (RandomUniform() < 0.001) {
dbg("CpmModelC,SNRLoss", "Packet was technically lost, but TOSSIM introduces an ack false positive rate.\n");
if (mine->ack && signal Model.shouldAck(mine->msg)) {
dbg_clear("CpmModelC", " scheduling ack.\n");
sim_gain_schedule_ack(mine->source, sim_time() + 1, mine);
}
else { // Otherwise free the receive_message_t*
free_receive_message(mine);
}
}
else {
free_receive_message(mine);
}
receiving = 0;
dbg_clear("CpmModelC,SNRLoss", " -packet was lost.\n");
}
}
// Create a record that a node is receiving a packet,
// enqueue a receive event to figure out what happens.
void enqueue_receive_event(int source, sim_time_t endTime, message_t* msg, bool receive, double power, double reversePower) {
sim_event_t* evt;
receive_message_t* list;
receive_message_t* rcv = allocate_receive_message();
double noiseStr = packetNoise(rcv);
rcv->source = source;
rcv->start = sim_time();
rcv->end = endTime;
rcv->power = power;
rcv->reversePower = reversePower;
// The strength of a packet is the sum of the signal and noise. In most cases, this means
// the signal. By sampling this here, it assumes that the packet RSSI is sampled at
// the beginning of the packet. This is true for the CC2420, but is not true for all
// radios. But generalizing seems like complexity for minimal gain at this point.
rcv->strength = (int8_t)(floor(10.0 * log(pow(10.0, power/10.0) + pow(10.0, noiseStr/10.0)) / log(10.0)));
rcv->msg = msg;
rcv->lost = 0;
rcv->ack = receive;
// If I'm off, I never receive the packet, but I need to keep track of
// it in case I turn on and someone else starts sending me a weaker
// packet. So I don't set receiving to 1, but I keep track of
// the signal strength.
if (!sim_mote_is_on(sim_node())) {
dbg("CpmModelC", "Lost packet from %i due to %i being off\n", source, sim_node());
rcv->lost = 1;
}
else if (!shouldReceive(power - noiseStr)) {
dbg("CpmModelC,SNRLoss", "Lost packet from %i to %i due to SNR being too low (%i)\n", source, sim_node(), (int)(power - noiseStr));
rcv->lost = 1;
}
else if (receiving) {
dbg("CpmModelC,SNRLoss", "Lost packet from %i due to %i being mid-reception\n", source, sim_node());
rcv->lost = 1;
}
else if (transmitting && (rcv->start < transmissionEndTime) && (transmissionEndTime <= rcv->end)) {
dbg("CpmModelC,SNRLoss", "Lost packet from %i due to %i being mid-transmission, transmissionEndTime %llu\n", source, sim_node(), transmissionEndTime);
rcv->lost = 1;
}
else {
receiving = 1;
}
list = outstandingReceptionHead;
while (list != NULL) {
if (!shouldReceive(list->power - rcv->power)) {
dbg("Gain,SNRLoss", "Going to lose packet from %i with signal %lf as am receiving a packet from %i with signal %lf\n", list->source, list->power, source, rcv->power);
list->lost = 1;
}
list = list->next;
}
rcv->next = outstandingReceptionHead;
outstandingReceptionHead = rcv;
evt = allocate_receive_event(endTime, rcv);
sim_queue_insert(evt);
}
void sim_gain_put(int dest, message_t* msg, sim_time_t endTime, bool receive, double power, double reversePower) {
int prevNode = sim_node();
dbg("CpmModelC", "Enqueing reception event for %i at %llu with power %lf.\n", dest, endTime, power);
sim_set_node(dest);
enqueue_receive_event(prevNode, endTime, msg, receive, power, reversePower);
sim_set_node(prevNode);
}
command void Model.putOnAirTo(int dest, message_t* msg, bool ack, sim_time_t endTime, double power, double reversePower) {
receive_message_t* list;
gain_entry_t* neighborEntry = sim_gain_first(sim_node());
requestAck = ack;
outgoing = msg;
transmissionEndTime = endTime;
dbg("CpmModelC", "Node %i transmitting to %i, finishes at %llu.\n", sim_node(), dest, endTime);
while (neighborEntry != NULL) {
int other = neighborEntry->mote;
sim_gain_put(other, msg, endTime, ack, power + sim_gain_value(sim_node(), other), reversePower + sim_gain_value(other, sim_node()));
neighborEntry = sim_gain_next(neighborEntry);
}
list = outstandingReceptionHead;
while (list != NULL) {
list->lost = 1;
dbg("CpmModelC,SNRLoss", "Lost packet from %i because %i has outstanding reception, startTime %llu endTime %llu\n", list->source, sim_node(), list->start, list->end);
list = list->next;
}
}
command void Model.setPendingTransmission() {
transmitting = TRUE;
dbg("CpmModelC", "setPendingTransmission: transmitting %i @ %s\n", transmitting, sim_time_string());
}
default event void Model.receive(message_t* msg) {}
sim_event_t* allocate_receive_event(sim_time_t endTime, receive_message_t* msg) {
sim_event_t* evt = (sim_event_t*)malloc(sizeof(sim_event_t));
evt->mote = sim_node();
evt->time = endTime;
evt->handle = sim_gain_receive_handle;
evt->cleanup = sim_queue_cleanup_event;
evt->cancelled = 0;
evt->force = 1; // Need to keep track of air even when node is off
evt->data = msg;
return evt;
}
receive_message_t* allocate_receive_message() {
return (receive_message_t*)malloc(sizeof(receive_message_t));
}
void free_receive_message(receive_message_t* msg) {
free(msg);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -