]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/tossim/CpmModelC.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / lib / tossim / CpmModelC.nc
index 167b6a8574a44df354025c3875cfe355bb7eefd2..4a84a278eed37e3a33d0358c9fda62a3131777db 100644 (file)
@@ -50,6 +50,8 @@ implementation {
   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;
 
@@ -139,17 +141,16 @@ implementation {
   }
   
   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;
   }
@@ -157,7 +158,7 @@ implementation {
   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
@@ -219,17 +220,19 @@ implementation {
   }
 
   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;
   }
@@ -237,7 +240,7 @@ implementation {
   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
@@ -390,6 +393,10 @@ implementation {
       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;
     }
@@ -419,20 +426,33 @@ implementation {
   }
 
   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) {}