24#define _NETSIM_MDEIUM_CODE_
27#include "ErrorModel.h"
28#include "PropagationModel.h"
29#pragma comment(lib,"NetworkStack.lib")
30#pragma comment(lib,"Metrics.lib")
31#pragma comment(lib,"PropagationModel.lib")
36 NetSim_PACKET* packet;
43 PHY_MODULATION modulation;
45 double dDataRate_mbps;
46 double dFrequency_MHz;
47 double dBandwidth_MHz;
49 double dMaxInterference_dbm;
52}PACKETINFO, *ptrPACKETINFO;
57 NETSIM_ID interfaceId;
60 double dRxSensitivity_dBm;
61 double dEDThreshold_dBm;
62 PHY_MODULATION modulation;
64 double dDataRate_mbps;
71 double dCummulativeReceivedPower_mw;
72 double dCummulativeReceivedPower_dbm;
74 void(*medium_change_callback)(NETSIM_ID, NETSIM_ID, bool, NetSim_PACKET*);
75 bool(*isRadioIdle)(NETSIM_ID, NETSIM_ID);
76 void* (*propagationinfo_find)(NETSIM_ID, NETSIM_ID, NETSIM_ID, NETSIM_ID);
77 bool(*isTranmitterBusy)(NETSIM_ID, NETSIM_ID);
78 void(*packetSentNotify)(NETSIM_ID, NETSIM_ID, NetSim_PACKET*);
79}DEVICE_IN_MEDIUM, *ptrDEVICE_IN_MEDIUM;
83 ptrDEVICE_IN_MEDIUM** devices;
84 ptrPACKETINFO transmissionPacket;
87static ptrDEVICE_IN_MEDIUM medium_find_device(NETSIM_ID devId,
91 fnNetSimError(
"Device id = %d, device interface = %d is not a valid input for %s,",
96 medium.devices[devId - 1])
97 return medium.devices[devId - 1][devIf - 1];
102static FILE* fplog = NULL;
103static void write_log(
char* format,...)
109 sprintf(str,
"%s\\%s", pszIOLogPath,
"medium.log");
110 fplog = fopen(str,
"w");
113 va_start(ls, format);
114 vfprintf(fplog, format, ls);
121static double GetRXPowerdBm(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri,
double time)
123 ptrDEVICE_IN_MEDIUM dm = medium_find_device(t, ti);
126 fnNetSimError(
"Device %d, interface %d is not added to medium before transmission.",
131 PPROPAGATION_INFO info = dm->propagationinfo_find(t, ti, r, ri);
134 fnNetSimErrorandStop(
"Propagation info is NULL between %d:%d-%d:%d\n", t, ti, r, ri);
137 return _propagation_get_received_power_dbm(info, time);
140_declspec(dllexport)
void medium_add_device(NETSIM_ID d,
142 double dFrequency_MHz,
143 double dBandwidth_MHz,
144 double dRxSensitivity_dBm,
145 double dEdThreshold_dBm,
146 void(*medium_change_callback)(NETSIM_ID, NETSIM_ID,
bool,NetSim_PACKET*),
147 bool(*isRadioIdle)(NETSIM_ID, NETSIM_ID),
148 bool(*isTransmitterBusy)(NETSIM_ID, NETSIM_ID),
149 void*(*propagationinfo_find)(NETSIM_ID, NETSIM_ID, NETSIM_ID, NETSIM_ID),
150 void(*packetsentnotify)(NETSIM_ID,NETSIM_ID,NetSim_PACKET*))
152 ptrDEVICE_IN_MEDIUM dm = calloc(1,
sizeof * dm);
154 dm->interfaceId = ifid;
155 dm->dEDThreshold_dBm = dEdThreshold_dBm;
156 dm->dRxSensitivity_dBm = dRxSensitivity_dBm;
157 dm->frequency_MHz = dFrequency_MHz;
158 dm->bandwidth_MHz = dBandwidth_MHz;
159 dm->dCummulativeReceivedPower_dbm = NEGATIVE_INFINITY;
160 dm->medium_change_callback = medium_change_callback;
161 dm->isRadioIdle = isRadioIdle;
162 dm->isTranmitterBusy = isTransmitterBusy;
163 dm->propagationinfo_find = propagationinfo_find;
164 dm->packetSentNotify = packetsentnotify;
167 medium.devices = calloc(NETWORK->nDeviceCount,
sizeof * medium.devices);
168 if (!medium.devices[d - 1])
169 medium.devices[d - 1] = calloc(DEVICE(d)->nNumOfInterface,
sizeof * medium.devices[d - 1]);
170 medium.devices[d - 1][ifid - 1] = dm;
173_declspec(dllexport)
void medium_update_frequency(NETSIM_ID d, NETSIM_ID in,
double f_MHz)
175 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
178 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
179 __FUNCTION__, d, in);
182 dm->frequency_MHz = f_MHz;
185_declspec(dllexport)
void medium_update_bandwidth(NETSIM_ID d, NETSIM_ID in,
double bw_MHz)
187 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
190 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
191 __FUNCTION__, d, in);
194 dm->bandwidth_MHz = bw_MHz;
197_declspec(dllexport)
void medium_update_rxsensitivity(NETSIM_ID d, NETSIM_ID in,
double p_dbm)
199 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
202 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
203 __FUNCTION__, d, in);
206 dm->dRxSensitivity_dBm = p_dbm;
209_declspec(dllexport)
void medium_update_edthershold(NETSIM_ID d, NETSIM_ID in,
double p_dbm)
211 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
214 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
215 __FUNCTION__, d, in);
218 dm->dEDThreshold_dBm = p_dbm;
221_declspec(dllexport)
void medium_update_modulation(NETSIM_ID d, NETSIM_ID in, PHY_MODULATION m,
double coderate)
223 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
226 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
227 __FUNCTION__, d, in);
231 dm->dCodeRate = coderate;
234_declspec(dllexport)
void medium_update_datarate(NETSIM_ID d, NETSIM_ID in,
double r_mbps)
236 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
239 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
240 __FUNCTION__, d, in);
243 dm->dDataRate_mbps = r_mbps;
246_declspec(dllexport)
void medium_update_MCS(NETSIM_ID d, NETSIM_ID in,
int MCS,
string Standard,
string BER_Model)
248 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
251 fnNetSimError(
"%s is called without adding device %d:%d to medium. use medium_add_device to add the device.\n",
252 __FUNCTION__, d, in);
256 dm->StandardType = Standard;
257 dm->Ber_Model = BER_Model;
260static void medium_remove_device(NETSIM_ID d,
263 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, ifId);
267 medium.devices[d - 1][ifId - 1] = NULL;
271static ptrPACKETINFO packetInfo_add(NetSim_PACKET* packet,
277 ptrDEVICE_IN_MEDIUM dm = medium_find_device(txId, txIf);
279 ptrPACKETINFO p = calloc(1,
sizeof* p);
283 p->startTime_us = packet->pstruPhyData->dArrivalTime;
284 p->endTime_us = packet->pstruPhyData->dEndTime;
288 p->codeRate = dm->dCodeRate;
289 p->dBandwidth_MHz = dm->bandwidth_MHz;
290 p->dDataRate_mbps = dm->dDataRate_mbps;
291 p->dFrequency_MHz = dm->frequency_MHz;
292 p->modulation = dm->modulation;
293 p->dRXPower_dbm = GetRXPowerdBm(txId, txIf, rxId, rxIf, p->startTime_us);
294 p->dMaxInterference_dbm = NEGATIVE_DBM;
296 if (medium.transmissionPacket)
298 ptrPACKETINFO t = medium.transmissionPacket;
305 medium.transmissionPacket = p;
307 write_log(
"New Packet %d,TX=%d-%d,RX=%d-%d,RxPower=%lf,\n",
308 p->packet->nPacketId == 0 ? p->packet->nControlDataType * -1 : p->packet->nPacketId,
309 txId, txIf, rxId, rxIf,
314static ptrPACKETINFO packetInfo_find(NetSim_PACKET* packet,
321 ptrPACKETINFO i = medium.transmissionPacket;
324 if (txId == i->txId && txIf == i->txIf && rxId == i->rxId && rxIf == i->rxIf && packet == i->packet)
332static ptrPACKETINFO packetInfo_remove(NetSim_PACKET* packet)
334 ptrPACKETINFO p = medium.transmissionPacket;
335 ptrPACKETINFO pr = NULL;
338 if (p->packet == packet)
347 medium.transmissionPacket = p->next;
355 write_log(
"remove Packet %d,TX=%d-%d,RX=%d-%d,RxPower=%lf,\n",
356 p->packet->nPacketId == 0 ? p->packet->nControlDataType * -1 : p->packet->nPacketId,
357 p->txId, p->txIf, p->rxId, p->rxIf,
362static void packetInfo_free(ptrPACKETINFO info)
367#define BOLTZMANN 1.38064852e-23
368#define TEMPERATURE 300
369static double compute_sinr(
double p,
double i,
double bw)
371 double noise = BOLTZMANN * TEMPERATURE * bw * 1000000;
372 double Pmw = DBM_TO_MW(p);
373 double imw = DBM_TO_MW(i);
375 return MW_TO_DBM(Pmw / (noise + imw));
378static double GetRXPowerMW(NETSIM_ID t, NETSIM_ID ti, NETSIM_ID r, NETSIM_ID ri,
double time)
380 return DBM_TO_MW(GetRXPowerdBm(t, ti, r, ri, time));
383static void medium_update_interference(ptrPACKETINFO info)
386 ptrPACKETINFO i = medium.transmissionPacket;
396 ptrDEVICE_IN_MEDIUM dm = medium_find_device(i->rxId, i->rxIf);
398 double pdbm = GetRXPowerdBm(i->txId, i->txIf,
401 double p = DBM_TO_MW(pdbm);
403 double interference = dm->dCummulativeReceivedPower_mw - p;
404 double interferencedbm = MW_TO_DBM(interference);
406 i->dMaxInterference_dbm = max(i->dMaxInterference_dbm, interferencedbm);
420static bool isAnypacketIsThereForThisTransmitter(ptrPACKETINFO info)
422 ptrPACKETINFO i = medium.transmissionPacket;
427 if (i->txId == info->txId &&
428 i->txIf == info->txIf)
436static bool CheckFrequencyInterfrence(
double dFrequency1,
double dFrequency2,
double bandwidth)
438 if (dFrequency1 > dFrequency2)
440 if ((dFrequency1 - dFrequency2) >= bandwidth)
447 if ((dFrequency2 - dFrequency1) >= bandwidth)
454static void update_power_due_to_transmission(ptrPACKETINFO info)
456 ptrDEVICE_IN_MEDIUM txdm = medium_find_device(info->txId, info->txIf);
459 fnNetSimError(
"Device %d, interface %d is not added to medium before transmission.",
460 info->txId, info->txIf);
464 NETSIM_ID nLoop, nLoopInterface;
465 for (nLoop = 1; nLoop <= NETWORK->nDeviceCount; nLoop++)
467 for (nLoopInterface = 1; nLoopInterface <= DEVICE(nLoop)->nNumOfInterface; nLoopInterface++)
469 ptrDEVICE_IN_MEDIUM dm = medium_find_device(nLoop, nLoopInterface);
473 if (!CheckFrequencyInterfrence(txdm->frequency_MHz, dm->frequency_MHz, txdm->bandwidth_MHz))
477 double p = GetRXPowerMW(txdm->deviceId, txdm->interfaceId,
478 dm->deviceId, dm->interfaceId,
481 dm->dCummulativeReceivedPower_mw += p;
483 dm->dCummulativeReceivedPower_dbm = MW_TO_DBM(dm->dCummulativeReceivedPower_mw);
485 write_log(
"\tTotal recv power of %d-%d = %lf\n", dm->deviceId, dm->interfaceId,
486 dm->dCummulativeReceivedPower_dbm);
488 if (nLoop == info->rxId &&
489 nLoopInterface == info->rxIf)
continue;
490 if (nLoop == info->txId &&
491 nLoopInterface == info->txIf)
continue;
493 if (dm->dCummulativeReceivedPower_dbm > dm->dEDThreshold_dBm &&
494 dm->medium_change_callback)
495 dm->medium_change_callback(dm->deviceId, dm->interfaceId,
true, info->packet);
496 double pdbm = GetRXPowerdBm(info->txId, info->txIf, dm->deviceId, dm->interfaceId, info->startTime_us);
497 if (pdbm > dm->dEDThreshold_dBm && dm->packetSentNotify)
498 dm->packetSentNotify(dm->deviceId, dm->interfaceId, info->packet);
503static void update_power_due_to_transmission_stop(ptrPACKETINFO info)
505 ptrDEVICE_IN_MEDIUM txdm = medium_find_device(info->txId, info->txIf);
508 fnNetSimError(
"Device %d, interface %d is not added to medium before transmission.",
509 info->txId, info->txIf);
513 NETSIM_ID nLoop, nLoopInterface;
514 for (nLoop = 1; nLoop <= NETWORK->nDeviceCount; nLoop++)
516 for (nLoopInterface = 1; nLoopInterface <= DEVICE(nLoop)->nNumOfInterface; nLoopInterface++)
518 if (nLoop == info->txId &&
519 nLoopInterface == info->txIf)
521 if(txdm->isRadioIdle(txdm->deviceId, txdm->interfaceId) &&
522 txdm->medium_change_callback)
523 txdm->medium_change_callback(txdm->deviceId, txdm->interfaceId,
false, NULL);
527 ptrDEVICE_IN_MEDIUM dm = medium_find_device(nLoop, nLoopInterface);
531 if (!CheckFrequencyInterfrence(txdm->frequency_MHz, dm->frequency_MHz, txdm->bandwidth_MHz))
535 dm->dCummulativeReceivedPower_mw -= GetRXPowerMW(txdm->deviceId, txdm->interfaceId,
536 dm->deviceId, dm->interfaceId,
539 dm->dCummulativeReceivedPower_dbm = MW_TO_DBM(dm->dCummulativeReceivedPower_mw);
541 if (nLoop == info->rxId &&
542 nLoopInterface == info->rxIf)
continue;
543 if (nLoop == info->txId &&
544 nLoopInterface == info->txIf)
continue;
546 if (dm->dCummulativeReceivedPower_dbm < dm->dEDThreshold_dBm &&
547 dm->medium_change_callback)
548 dm->medium_change_callback(dm->deviceId, dm->interfaceId,
false, NULL);
553static void medium_mark_packet_error(ptrPACKETINFO info)
555 ptrDEVICE_IN_MEDIUM dm = medium_find_device(info->txId, info->txIf);
556 double i = info->dMaxInterference_dbm;
557 double p = info->dRXPower_dbm;
558 double w = info->dBandwidth_MHz;
560 double f = _propagation_calculate_fadingloss(dm->propagationinfo_find(
561 info->txId, info->txIf,
562 info->rxId, info->rxIf));
566 if (strcmp(dm->Ber_Model,
"SINR_BER_PER_TABLE") == 0)
567 ber = calculate_BER_Using_Table(info->modulation, p, i, w, dm->MCS, dm->StandardType);
569 ber = calculate_FEC_BER(info->modulation, info->codeRate, p, i, w, info->dDataRate_mbps);
571 PACKET_STATUS status = fn_NetSim_Packet_DecideError(ber, info->packet->pstruPhyData->dPacketSize);
572 if (status == PacketStatus_Error && info->packet->nPacketStatus == PacketStatus_NoError)
574 if (i >= dm->dRxSensitivity_dBm) info->packet->nPacketStatus = PacketStatus_Collided;
575 else info->packet->nPacketStatus = PacketStatus_Error;
576 write_log(
"Packet %d errored, BER=%lf, Interference=%lf, RXPower=%lf,\n",
577 info->packet->nPacketId == 0 ? info->packet->nControlDataType * -1 : info->packet->nPacketId,
582_declspec(dllexport)
void medium_notify_packet_send(NetSim_PACKET* packet,
588 ptrPACKETINFO info = packetInfo_add(packet, txId, txIf, rxId, rxIf);
589 if (isAnypacketIsThereForThisTransmitter(info))
591 update_power_due_to_transmission(info);
592 medium_update_interference(info);
595_declspec(dllexport)
void medium_notify_packet_received(NetSim_PACKET* packet)
597 ptrPACKETINFO info = packetInfo_remove(packet);
598 medium_mark_packet_error(info);
599 if (!isAnypacketIsThereForThisTransmitter(info))
600 update_power_due_to_transmission_stop(info);
601 packetInfo_free(info);
604_declspec(dllexport)
bool medium_isIdle(NETSIM_ID d,
607 ptrDEVICE_IN_MEDIUM dm = medium_find_device(d, in);
608 return (dm->dCummulativeReceivedPower_dbm < dm->dEDThreshold_dBm);
611_declspec(dllexport)
double medium_get_interference(NetSim_PACKET* packet,
617 ptrPACKETINFO info = packetInfo_find(packet, txId, txIf, rxId, rxIf);
619 return (info->dMaxInterference_dbm);