N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/OrbisQuartus/server/protocols/csmaca.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute
00027  * it and/or modify it under the terms of the GNU General Public
00028  * License as published by the Free Software Foundation; version 2 of
00029  * the License. Accordingly, this program is distributed in the hope
00030  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00031  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00032  * PURPOSE. See the GNU General Public License for more details.
00033  */
00034 
00035 
00036 #include <string.h>
00037 #include <math.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <sys/time.h>
00041 #include "mac_lib.h"
00042 
00043 #define OQ_OFDM    10   /* 802.11a (fake) */
00044 
00045 #define OQ_FHSS    50   
00046 #define OQ_DSSS    20   /* 802.11b/g */
00047 #define OQ_THRU    91   /* single char throughput in nanoseconds */
00048 
00049 
00050 static volatile int rx_pending = 0;
00051 static volatile int tx_pending = 0;
00052 static volatile int available_slot = 0;
00053 static long sequence = 0;
00054 
00055 static int csmaca_filter(struct oq_req_resp *rr, int oq_slot);
00056 long long csmaca_throughput(void);
00057 int csmaca_a_filter(struct oq_req_resp *rr);
00058 int csmaca_b_filter(struct oq_req_resp *rr);
00059 int csmaca_g_filter(struct oq_req_resp *rr);
00060 
00061 
00062 long long csmaca_throughput(void)
00063 {
00064         return (long long) OQ_THRU;
00065 }
00066 
00067 
00068 int csmaca_a_filter(struct oq_req_resp *rr)
00069 {
00070         return csmaca_filter(rr, OQ_OFDM);
00071 }
00072 
00073 
00074 int csmaca_b_filter(struct oq_req_resp *rr)
00075 {
00076         return csmaca_filter(rr, OQ_DSSS);
00077 }
00078 
00079 
00080 int csmaca_g_filter(struct oq_req_resp *rr)
00081 {
00082         return csmaca_filter(rr, OQ_DSSS);
00083 }
00084 
00085 
00086 static int csmaca_filter(struct oq_req_resp *rr, int oq_slot)
00087 {
00088         struct sock_buff msg;
00089         struct timeval seed;
00090 
00091         if (rr == NULL)
00092                 return -1;
00093 
00094         msg = rr->msgs[0];
00095         rr->num_msgs = 1;
00096 
00097         msg.slot_time = oq_slot;
00098         gettimeofday(&seed, NULL);
00099         srand(seed.tv_sec + seed.tv_usec);
00100 
00101         if (msg.tx_rx == OQ_RADIO_RX) {
00102                 if (strncasecmp(msg.mac, "RTS", 3) == 0) {
00103                         char *seqstr = strchr(msg.mac, ':') + 1;
00104                         char *seqend = strchr(seqstr, ':');
00105                         char *lenstr = seqend + 1;
00106                         char *lenend = strchr(lenstr, '|');
00107                         unsigned long long seq;
00108                         unsigned int len;
00109 
00110                         seqend[0] = lenend[0] = '\0';
00111                         seq = strtoull(seqstr, NULL, 10);
00112                         len = (int) strtoul(lenstr, NULL, 10);
00113                         seqend[0] = ':';
00114                         lenend[0] = '|';
00115 
00116                         if (!msg.to_me)
00117                                 available_slot = 2 + (int) 
00118                                         ceil((len * csmaca_throughput()) / 
00119                                              (double) msg.slot_time);
00120                         msg.code = OQ_SKB_DROP;
00121 
00122                         if (msg.to_me && !rx_pending && !tx_pending) {
00123                                 struct sock_buff cts = rr->msgs[1];
00124                                 rr->num_msgs = 2;
00125                                 cts.tx_rx = OQ_RADIO_TX;
00126                                 cts.to_me = 0;
00127                                 memset(cts.mac, '\0', sizeof(cts.mac));
00128                                 snprintf(cts.mac, OQ_MAC_LEN, "CTS:%lld:%d|", 
00129                                          seq, len);
00130                                 cts.length = (unsigned long) 
00131                                         ceil((double) (strlen(cts.mac) + 2) * 
00132                                              csmaca_throughput());
00133                                 cts.seq_num = seq;
00134                                 cts.slot_time = msg.slot_time;
00135                                 cts.next_slot = 0;
00136                                 cts.code = OQ_SKB_INJECT;
00137                                 rx_pending = 1;
00138                         }
00139                 } else if (strncasecmp(msg.mac, "CTS", 3) == 0) {
00140                         char *seqstr = strchr(msg.mac, ':') + 1;
00141                         char *seqend = strchr(seqstr, ':');
00142                         char *lenstr = seqend + 1;
00143                         char *lenend = strchr(lenstr, '|');
00144                         unsigned long long seq;
00145                         unsigned int len;
00146 
00147                         seqend[0] = lenend[0] = '\0';
00148                         seq = strtoull(seqstr, NULL, 10);
00149                         len = (int) strtoul(lenstr, NULL, 10);
00150                         seqend[0] = ':';
00151                         lenend[0] = '|';
00152 
00153                         if (!msg.to_me)
00154                                 available_slot = 1 + (int) 
00155                                         ceil((len * csmaca_throughput()) / 
00156                                              (double) msg.slot_time);
00157                         /* we _assume_ that actual throughput is faster */
00158                         msg.code = OQ_SKB_DROP;
00159 
00160                         if (msg.to_me && rx_pending) {
00161                                 struct sock_buff pkt = rr->msgs[1];
00162                                 rr->num_msgs = 2;
00163                                 pkt.tx_rx = OQ_RADIO_TX;
00164                                 pkt.to_me = 0;
00165                                 memset(pkt.mac, '\0', sizeof(pkt.mac));
00166                                 snprintf(pkt.mac, OQ_MAC_LEN, "PKT:%lld|", 
00167                                          seq);
00168                                 pkt.length = (unsigned long) 
00169                                         ceil((double) (strlen(pkt.mac) + 
00170                                                        2 + len) * 
00171                                              csmaca_throughput());
00172                                 pkt.seq_num = seq;
00173                                 pkt.slot_time = msg.slot_time;
00174                                 pkt.next_slot = 0;
00175                                 pkt.code = OQ_SKB_SEND;
00176                                 tx_pending = 1;
00177                         }
00178                 } else if (strncasecmp(msg.mac, "PKT", 3) == 0) {
00179                         char *seqstr = strchr(msg.mac, ':') + 1;
00180                         char *seqend = strchr(seqstr, '|');
00181                         unsigned long long seq;
00182 
00183                         seqend[0] = '\0';
00184                         seq = strtoull(seqstr, NULL, 10);
00185                         seqend[0] = '|';
00186 
00187                         available_slot = 1;
00188                         msg.code = OQ_SKB_RECV;
00189 
00190                         if (msg.to_me && rx_pending && tx_pending) {
00191                                 struct sock_buff ack = rr->msgs[1];
00192                                 rr->num_msgs = 2;
00193                                 ack.tx_rx = OQ_RADIO_TX;
00194                                 ack.to_me = 0;
00195                                 memset(ack.mac, '\0', sizeof(ack.mac));
00196                                 snprintf(ack.mac, OQ_MAC_LEN, "ACK:%lld|", 
00197                                          seq);
00198                                 ack.length = (unsigned long) 
00199                                         ceil((double) (strlen(ack.mac) + 2) * 
00200                                              csmaca_throughput());
00201                                 ack.seq_num = seq;
00202                                 ack.slot_time = msg.slot_time;
00203                                 ack.next_slot = 0;
00204                                 ack.code = OQ_SKB_INJECT;
00205                         }
00206                 } else if (strncasecmp(msg.mac, "ACK", 3) == 0) {
00207                         char *seqstr = strchr(msg.mac, ':') + 1;
00208                         char *seqend = strchr(seqstr, '|');
00209                         unsigned long seq;
00210 
00211                         seqend[0] = '\0';
00212                         seq = strtoul(seqstr, NULL, 10);
00213                         seqend[0] = '|';
00214 
00215                         available_slot = 0;
00216                         msg.code = OQ_SKB_DROP;
00217 
00218                         if (msg.to_me && rx_pending && tx_pending) {
00219                                 struct sock_buff zilch = rr->msgs[1];
00220                                 rr->num_msgs = 2;
00221                                 zilch.tx_rx = 0;
00222                                 zilch.to_me = 0;
00223                                 memset(zilch.mac, '\0', sizeof(zilch.mac));
00224                                 zilch.length = 0;
00225                                 zilch.seq_num = seq;
00226                                 zilch.slot_time = 0;
00227                                 zilch.next_slot = 0;
00228                                 zilch.code = OQ_SKB_RELEASE;
00229                                 rx_pending = 0;
00230                                 tx_pending = 0;
00231                         }
00232                 } else      /* abnormal packet, discard */
00233                         msg.code = OQ_SKB_DROP;
00234         } else if (msg.tx_rx == OQ_RADIO_TX) {
00235                 msg.to_me = 0;
00236                 memset(msg.mac, '\0', sizeof(msg.mac));
00237                 msg.length = 0;
00238                 msg.seq_num = sequence++;
00239                 msg.slot_time = oq_slot;
00240                 msg.next_slot = 3;
00241                 msg.code = OQ_SKB_WAIT;
00242                 
00243                 if (!rx_pending && !tx_pending) {
00244                         struct sock_buff rts = rr->msgs[1];
00245                         rr->num_msgs = 2;
00246                         rts.tx_rx = OQ_RADIO_TX;
00247                         rts.to_me = 0;
00248                         memset(rts.mac, '\0', sizeof(rts.mac));
00249                         snprintf(rts.mac, OQ_MAC_LEN, "RTS:%lld:%d|", 
00250                                  msg.seq_num, rr->size);
00251                         rts.length = (unsigned long) 
00252                                 ceil((double) (strlen(rts.mac) + 2) * 
00253                                      csmaca_throughput());
00254                         rts.seq_num = msg.seq_num;
00255                         rts.slot_time = msg.slot_time;
00256                         rts.next_slot = 0;
00257                         rts.code = OQ_SKB_INJECT;
00258 
00259                         msg.code = OQ_SKB_INJECT;
00260                 } else {
00261                         available_slot = 3 + (int)
00262                                 ceil(msg.length / (double) msg.slot_time);
00263                         msg.next_slot = (int)(pow(2, msg.slot_idx) * 
00264                                                (rand() / (double)RAND_MAX))
00265                                 + available_slot;
00266                         msg.slot_idx++;
00267                 }
00268         } else      /* impossible, discard */
00269                 msg.code = OQ_SKB_DROP;
00270 
00271         return 0;
00272 }


© 2007, Los Alamos National Security, LLC.