00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00044
00045 #define OQ_FHSS 50
00046 #define OQ_DSSS 20
00047 #define OQ_THRU 91
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
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
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
00269 msg.code = OQ_SKB_DROP;
00270
00271 return 0;
00272 }