/**
*
* CPM (closest-pattern matching) is a wireless noise simulation model
- * based on statistical extraction from empirical noise data.
- * This model provides far more precise
- * software simulation environment by exploiting time-correlated noise
- * characteristic and shadowing effect as well as path-loss model. For
- * details, please refer to the paper
+ * based on statistical extraction from empirical noise data. This
+ * model provides far more precise software simulation environment by
+ * exploiting time-correlated noise characteristics. For details,
+ * please refer to the paper
*
* "Improving Wireless Simulation through Noise Modeling." HyungJune
* Lee and Philip Levis, IPSN 2007. You can find a copy at
message_t* outgoing; // If I'm sending, this is my outgoing packet
bool requestAck;
bool receiving = 0; // Whether or not I think I'm receiving a packet
+ bool transmitting = 0; // Whether or not I think I'm tranmitting a packet
+ sim_time_t transmissionEndTime; // to check pending transmission
struct receive_message;
typedef struct receive_message receive_message_t;
sim_time_t end;
double power;
double reversePower;
+ int8_t strength;
bool lost;
bool ack;
message_t* msg;
else {
noise_val = (double)sim_noise_generate(node_id, quotient);
}
- dbg("CpmModelC", "OUT: noise_hash_generation()\n");
+ dbg("CpmModelC,Tal", "%s: OUT: noise_hash_generation(): %lf\n", sim_time_string(), noise_val);
return noise_val;
}
}
double arr_estimate_from_snr(double SNR) {
- double beta1 = 1.3687;
- double beta2 = 0.9187;
- double SNR_lin = pow(10.0, SNR/10.0);
- double X = fabs(SNR_lin-beta2);
- double PSE = 0.5*erfc(beta1*sqrt(X/2));
+ double beta1 = 0.9794;
+ double beta2 = 2.3851;
+ double X = SNR-beta2;
+ double PSE = 0.5*erfc(beta1*X/sqrt(2));
double prr_hat = pow(1-PSE, 23*2);
dbg("CpmModelC,SNRLoss", "SNR is %lf, ARR is %lf\n", SNR, prr_hat);
if (prr_hat > 1)
- prr_hat = 1;
+ prr_hat = 1.1;
else if (prr_hat < 0)
- prr_hat = 0;
+ prr_hat = -0.1;
return prr_hat;
}
int shouldAckReceive(double snr) {
double prr = arr_estimate_from_snr(snr);
double coin = RandomUniform();
- if ( (prr != 0) && (prr != 1) ) {
+ if ( (prr >= 0) && (prr <= 1) ) {
if (coin < prr)
prr = 1.0;
else
}
command bool Model.clearChannel() {
- dbg("CpmModelC", "Checking clear channel @ %s: %f <= %f \n", sim_time_string(), (double)noise_hash_generation(), clearThreshold);
- return noise_hash_generation() < clearThreshold;
+ dbg("CpmModelC", "Checking clear channel @ %s: %f <= %f \n", sim_time_string(), (double)packetNoise(NULL), clearThreshold);
+ return packetNoise(NULL) < clearThreshold;
}
void sim_gain_schedule_ack(int source, sim_time_t t, receive_message_t* r) {
}
double prr_estimate_from_snr(double SNR) {
- double beta1 = 1.3687;
- double beta2 = 0.9187;
- double SNR_lin = pow(10.0, SNR/10.0);
- double X = fabs(SNR_lin-beta2);
- double PSE = 0.5*erfc(beta1*sqrt(X/2));
+ // Based on CC2420 measurement by Kannan.
+ // The updated function below fixes the problem of non-zero PRR
+ // at very low SNR. With this function PRR is 0 for SNR <= 3.
+ double beta1 = 0.9794;
+ double beta2 = 2.3851;
+ double X = SNR-beta2;
+ double PSE = 0.5*erfc(beta1*X/sqrt(2));
double prr_hat = pow(1-PSE, 23*2);
dbg("CpmModelC,SNR", "SNR is %lf, PRR is %lf\n", SNR, prr_hat);
if (prr_hat > 1)
- prr_hat = 1;
+ prr_hat = 1.1;
else if (prr_hat < 0)
- prr_hat = 0;
+ prr_hat = -0.1;
return prr_hat;
}
bool shouldReceive(double SNR) {
double prr = prr_estimate_from_snr(SNR);
double coin = RandomUniform();
- if ( (prr != 0) && (prr != 1) ) {
+ if ( (prr >= 0) && (prr <= 1) ) {
if (coin < prr)
prr = 1.0;
else
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) {
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
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;
}
}
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 && (other == dest), power + sim_gain_value(sim_node(), other), reversePower + sim_gain_value(other, sim_node()));
+ 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) {}