NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Component 4/ZigBee/802_15_4.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "802_15_4.h"
16#include "Animation.h"
17#include "NetSim_utility.h"
18#include "AdvancedPlots.h"
19#pragma comment(lib,"AdvancedPlots.lib")
20
21int fn_NetSim_Zigbee_FreePacket_F(NetSim_PACKET* pstruPacket);
22
23static double zigbee_get_link_quality(NETSIM_ID trx, NETSIM_ID tri,
24 NETSIM_ID rx, NETSIM_ID ri)
25{
26 double p = _propagation_get_received_power_dbm(find_propagation_info(
27 trx, tri,
28 rx, ri), ldEventTime);
29 assert(tri == 1);
30 double rs = MW_TO_DBM(WSN_PHY(trx)->dReceiverSensivity);
31 //make positive for easy calculation
32 rs *= -1;
33 p *= -1;
34 if (rs < p)
35 return 0.0;
36 else if (p < 0)
37 return 1.0;
38 else
39 return (1.0 - (1.0 / rs) * p);
40}
41
42/** This function is called by NetworkStack.dll, whenever the event gets triggered
43inside the NetworkStack.dll.
44It includes MAC_OUT,MAC_IN,PHY_OUT,PHY_IN and TIMER_EVENT. */
45_declspec(dllexport) int fn_NetSim_Zigbee_Run()
46{
47 int nSub_Event_Type;
48 NETSIM_ID nDeviceId, nInterfaceId;
49 nEventType = pstruEventDetails->nEventType; /* Get the EventType from Event details */
50 nSub_Event_Type = pstruEventDetails->nSubEventType; /* Get the sub EventType from Event details*/
51 nDeviceId = pstruEventDetails->nDeviceId;
52 nInterfaceId = pstruEventDetails->nInterfaceId;
53
54 /*Check event type*/
55 switch (nEventType)
56 {
57 case MAC_OUT_EVENT:
58 {
59 NetSim_PACKET* pstruPacket = NULL;
60 double dEventTime;
61 dEventTime = pstruEventDetails->dEventTime;
62
63 if (WSN_MAC(nDeviceId)->pstruBuffer)
64 {
65 pstruPacket = WSN_MAC(nDeviceId)->pstruBuffer;
66 }
67 else if (fn_NetSim_GetBufferStatus(DEVICE_MAC_NW_INTERFACE(nDeviceId, nInterfaceId)->pstruAccessBuffer))
68 {
69 pstruPacket = fn_NetSim_Packet_GetPacketFromBuffer(DEVICE_MAC_NW_INTERFACE(nDeviceId, nInterfaceId)->pstruAccessBuffer, 0);
70 }
71
72 /* Get the packet from Upper layer, */
73 if (pstruPacket)
74 {
75 pstruEventDetails->nPacketId = pstruPacket->nPacketId;
76 if (pstruPacket->pstruAppData)
77 pstruEventDetails->nApplicationId = pstruPacket->pstruAppData->nApplicationId;
78
79 if (pstruPacket->nControlDataType / 100 != MAC_PROTOCOL_IEEE802_15_4)
80 {
81 if (WSN_MAC(nDeviceId))
82 {
83 if (WSN_MAC(nGlobalPANCoordinatorId)->nBeaconMode == BEACON_ENABLE && WSN_MAC(nGlobalPANCoordinatorId)->nMacBeaconOrder <= 14)
84 {
85 if (pstruSuperFrame->nSuperFrameStatus == CAPMODE)
86 ZIGBEE_SLOTTED();
87 else
88 {
89 //wait for CAP
90 }
91 }
92 else
93 {
94 ZIGBEE_UNSLOTTED();
95 }
96 }
97 }
98 else
99 {
100 //Control packet of IEEE 802.15.4
101 }
102 }
103 break;
104 }
105 case MAC_IN_EVENT:
106 {
107 NetSim_PACKET* pstruPacket;
108
109 WSN_MAC(nDeviceId)->nNodeStatus = IDLE;
110 pstruPacket = pstruEventDetails->pPacket;
111 pstruPacket->pstruMacData->dArrivalTime = pstruEventDetails->dEventTime;
112 pstruPacket->pstruMacData->dStartTime = pstruEventDetails->dEventTime;
113 pstruPacket->pstruMacData->dEndTime = pstruEventDetails->dEventTime;
114
115 if (WSN_MAC_HEADER(pstruPacket)->nAckRequestFlag)
116 {
117 NetSim_PACKET* pstruAckPacket;
118 IEEE802_15_4_HEADER* pstruHeader;
119
120 if (!ZIGBEE_CHANGERADIOSTATE(nDeviceId, WSN_PHY(nDeviceId)->nRadioState, TRX_ON_BUSY))
121 {
122 return 0;
123 }
124
125 WSN_MAC(nDeviceId)->nNodeStatus = TX_MODE;
126
127 pstruAckPacket = fn_NetSim_Packet_CreatePacket(MAC_LAYER);
128 pstruAckPacket->dEventTime = pstruEventDetails->dEventTime;
129 pstruAckPacket->nControlDataType = ACK_FRAME;
130 pstruAckPacket->nPacketType = PacketType_Control;
131 pstruAckPacket->nTransmitterId = pstruPacket->nReceiverId;
132 pstruAckPacket->nReceiverId = pstruPacket->nTransmitterId;
133 pstruAckPacket->nSourceId = pstruAckPacket->nTransmitterId;
134 add_dest_to_packet(pstruAckPacket, pstruAckPacket->nReceiverId);
135 pstruAckPacket->pstruMacData->dArrivalTime = pstruAckPacket->dEventTime;
136 pstruAckPacket->pstruMacData->dStartTime = pstruAckPacket->dEventTime;
137 pstruAckPacket->pstruMacData->dEndTime = pstruAckPacket->dEventTime;
138 pstruAckPacket->pstruMacData->szSourceMac = (pstruPacket->pstruMacData->szDestMac);
139 pstruAckPacket->pstruMacData->szDestMac = (pstruPacket->pstruMacData->szSourceMac);
140 pstruAckPacket->pstruMacData->nMACProtocol = MAC_PROTOCOL_IEEE802_15_4;
141
142 pstruAckPacket->pstruMacData->dOverhead = 5;
143 pstruAckPacket->pstruMacData->dPacketSize = pstruAckPacket->pstruMacData->dPayload + pstruPacket->pstruMacData->dOverhead;
144 pstruEventDetails->dPacketSize = pstruAckPacket->pstruMacData->dPacketSize;
145
146 pstruHeader = fnpAllocateMemory(1, sizeof(IEEE802_15_4_HEADER));
147 pstruAckPacket->pstruMacData->Packet_MACProtocol = pstruHeader;
148
149 pstruEventDetails->pPacket = pstruAckPacket;
150
151 pstruEventDetails->nPacketId = 0;
152 pstruEventDetails->dEventTime = ldEventTime + 12 * dUnitSymbolTime;
153 pstruAckPacket->nPacketId = 0;
154
155 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
156 pstruEventDetails->nSubEventType = 0;
157 fnpAddEvent(pstruEventDetails);
158 pstruEventDetails->dEventTime = ldEventTime;
159 }
160 if (pstruPacket->nControlDataType != ACK_FRAME && pstruPacket->nControlDataType / 100 != MAC_PROTOCOL_IEEE802_15_4)
161 {
162 pstruMetrics[pstruEventDetails->nDeviceId - 1]->pstruIEEE802_15_4_Metrics->nPacketReceived++;
163 }
164 if (pstruPacket->nControlDataType / 100 != MAC_PROTOCOL_IEEE802_15_4)
165 {
166 //Prepare the Network in event details
167 pstruPacket->pstruMacData->dOverhead -= 5;
168 pstruPacket->pstruMacData->dPacketSize = pstruPacket->pstruMacData->dPayload + pstruPacket->pstruMacData->dOverhead;
169 pstruEventDetails->dPacketSize = pstruPacket->pstruMacData->dPacketSize;
170 pstruEventDetails->pPacket = pstruPacket;
171 pstruEventDetails->nEventType = NETWORK_IN_EVENT;
172 pstruEventDetails->nSubEventType = 0;
173 pstruEventDetails->nPacketId = pstruPacket->nPacketId;
174 if (pstruPacket->pstruAppData)
175 {
176 pstruEventDetails->nSegmentId = pstruPacket->pstruAppData->nSegmentId;
177 pstruEventDetails->nApplicationId = pstruPacket->pstruAppData->nApplicationId;
178 }
179 fn_NetSim_Zigbee_FreePacket(pstruPacket);
180 pstruEventDetails->nProtocolId = fn_NetSim_Stack_GetNWProtocol(pstruEventDetails->nDeviceId);
181 //Add Network in event
182 fnpAddEvent(pstruEventDetails);
183 }
184 else if (pstruPacket->nControlDataType == BEACON_FRAME)
185 {
186 BEACONFRAME* pstruBeaconFrame;
187 pstruMetrics[pstruEventDetails->nDeviceId - 1]->pstruIEEE802_15_4_Metrics->nBeaconReceived++;
188 pstruBeaconFrame = WSN_MAC_HEADER(pstruPacket)->pstruBeaconFrame;
189 if (WSN_MAC(pstruEventDetails->nDeviceId)->nBeaconReceivedFlag == 0 && WSN_MAC(pstruEventDetails->nDeviceId)->nLastBeaconId < pstruBeaconFrame->nBeaconId)
190 {
191 WSN_MAC(pstruEventDetails->nDeviceId)->nLastBeaconId = pstruBeaconFrame->nBeaconId;
192 pstruEventDetails->nEventType = PHYSICAL_OUT_EVENT;
193 pstruEventDetails->pPacket->nTransmitterId = pstruEventDetails->nDeviceId;
194 pstruEventDetails->pPacket->nReceiverId = 0;
195 //fnpAddEvent(pstruEventDetails);
196 pstruMetrics[pstruEventDetails->nDeviceId - 1]->pstruIEEE802_15_4_Metrics->nBeaconForwarded++;
197 }
198 else
199 {
200 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
201 }
202 }
203 else if (pstruPacket->nControlDataType == ACK_FRAME)
204 {
205 pstruMetrics[pstruEventDetails->nDeviceId - 1]->pstruIEEE802_15_4_Metrics->nAckReceived++;
206
207 WSN_MAC(pstruEventDetails->nDeviceId)->nRetryCount = 0;
208 if (WSN_MAC(pstruEventDetails->nDeviceId)->pstruBuffer)
209 {
210 if (WSN_MAC(pstruEventDetails->nDeviceId)->pstruBuffer->ReceiveAckNotification)
211 {
212 WSN_MAC(pstruEventDetails->nDeviceId)->pstruBuffer->ReceiveAckNotification(pstruPacket);
213 }
214 fn_NetSim_Packet_FreePacket(WSN_MAC(pstruEventDetails->nDeviceId)->pstruBuffer);
215 WSN_MAC(pstruEventDetails->nDeviceId)->pstruBuffer = NULL;
216 }
217
218 if (fn_NetSim_GetBufferStatus(NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->pstruAccessInterface->pstruAccessBuffer))
219 {
220 NetSim_PACKET* packet = fn_NetSim_Packet_GetPacketFromBuffer(NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->pstruAccessInterface->pstruAccessBuffer, 0);
221 WSN_MAC(pstruEventDetails->nDeviceId)->nNodeStatus = IDLE;
222 //Prepare the mac out event details
223 pstruEventDetails->dEventTime += 40 * dUnitSymbolTime;
224 pstruEventDetails->pPacket = NULL;
225 if (packet->pstruAppData)
226 {
227 pstruEventDetails->nApplicationId = packet->pstruAppData->nApplicationId;
228 pstruEventDetails->nSegmentId = packet->pstruAppData->nSegmentId;
229 }
230 else
231 {
232 pstruEventDetails->nApplicationId = 0;
233 pstruEventDetails->nSegmentId = 0;
234 }
235 pstruEventDetails->dPacketSize = fnGetPacketSize(packet);
236 pstruEventDetails->nPacketId = packet->nPacketId;
237
238 pstruEventDetails->nEventType = MAC_OUT_EVENT;
239 pstruEventDetails->nSubEventType = 0;
240 pstruEventDetails->nProtocolId = MAC_PROTOCOL_IEEE802_15_4;
241 //Add mac out event
242 fnpAddEvent(pstruEventDetails);
243 }
244
245 fn_NetSim_Packet_FreePacket(pstruPacket);
246 }
247 break;
248 }
249 case PHYSICAL_OUT_EVENT:
250 {
251 NetSim_EVENTDETAILS pevent;
252 NETSIM_ID nLoop;
253 NetSim_PACKET* pstruPacket;
254 NETSIM_ID nLink_Id; /*Link id b/w Current device and connected device Id*/
255 NETSIM_ID nDevice_Id; /*Device id From Event details*/
256 int nDevice_Type; /*Device Type From Event details*/
257 NETSIM_ID nDevice_PortId; /*Device port id From Event details*/
258 double dTxTime = 0.0f; /*Stores Transmission Time*/
259 double dDataRate;
260 bool txFlag = false;
261
262 memcpy(&pevent, pstruEventDetails, sizeof pevent);
263 /*Get the current device Type*/
264 nDevice_Type = pstruEventDetails->nDeviceType;
265 /*Get the current device Id*/
266 nDevice_Id = pstruEventDetails->nDeviceId;
267 /*Get the current device Port ID*/
268 nDevice_PortId = pstruEventDetails->nInterfaceId;
269
270 nLink_Id = DEVICE_PHYLAYER(nDevice_Id, nDevice_PortId)->nLinkId;
271
272 pstruPacket = pstruEventDetails->pPacket;
273 pstruPacket->pstruPhyData->dArrivalTime = pstruEventDetails->dEventTime;
274 pstruPacket->pstruPhyData->dPayload = pstruPacket->pstruMacData->dPacketSize;
275 //6 byte overhead
276 if (pstruPacket->nControlDataType == ACK_FRAME)
277 pstruPacket->pstruPhyData->dOverhead = 1;
278 else
279 pstruPacket->pstruPhyData->dOverhead = 6;
280 pstruPacket->pstruPhyData->dPacketSize = pstruPacket->pstruPhyData->dPayload + pstruPacket->pstruPhyData->dOverhead;
281 pstruEventDetails->dPacketSize = pstruPacket->pstruPhyData->dPacketSize;
282
283 if (NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniMedProp.pstruWirelessLink.dDataRateUp)
284 dDataRate = NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniMedProp.pstruWirelessLink.dDataRateUp;
285 else
286 dDataRate = 0.250;
287
288 dTxTime = pstruPacket->pstruPhyData->dPacketSize * 8 / dDataRate;
289
290 if (pstruPacket->pstruPhyData->dArrivalTime <= NETWORK->ppstruDeviceList[nDevice_Id - 1]->ppstruInterfaceList[nDevice_PortId - 1]->pstruPhysicalLayer->dLastPacketEndTime)
291 {
292 pstruPacket->pstruPhyData->dStartTime = NETWORK->ppstruDeviceList[nDevice_Id - 1]->ppstruInterfaceList[nDevice_PortId - 1]->pstruPhysicalLayer->dLastPacketEndTime;
293 }
294 else
295 pstruPacket->pstruPhyData->dStartTime = pstruPacket->pstruPhyData->dArrivalTime;
296
297 pstruPacket->pstruPhyData->dEndTime = pstruPacket->pstruPhyData->dStartTime + dTxTime;
298 NETWORK->ppstruDeviceList[nDevice_Id - 1]->ppstruInterfaceList[nDevice_PortId - 1]->pstruPhysicalLayer->dLastPacketEndTime = pstruPacket->pstruPhyData->dEndTime;
299
300 for (nLoop = 1; nLoop <= NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.nConnectedDeviceCount; nLoop++)
301 {
302 NETSIM_ID ncon = NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.anDevIds[nLoop - 1];
303 if (ncon == pstruPacket->nTransmitterId)
304 continue;
305
306 WSN_PHY(ncon)->dTotalReceivedPower += GET_RX_POWER_mw(pstruPacket->nTransmitterId, ncon, pstruEventDetails->dEventTime);
307
308 if (ncon == pstruPacket->nReceiverId || pstruPacket->nReceiverId == 0)
309 {
310 NetSim_PACKET* packet = pstruPacket;
311 if (pstruPacket->nReceiverId == 0)
312 {
313 packet = fn_NetSim_Packet_CopyPacket(pstruPacket);
314 }
315
316 if (WSN_PHY(ncon)->dTotalReceivedPower - GET_RX_POWER_mw(pstruPacket->nTransmitterId, ncon, pstruEventDetails->dEventTime) >= WSN_PHY(ncon)->dReceiverSensivity)
317 packet->nPacketStatus = PacketStatus_Collided;
318
319 if (GET_RX_POWER_dbm(pstruPacket->nTransmitterId, ncon, pstruEventDetails->dEventTime) > MW_TO_DBM(WSN_PHY(ncon)->dReceiverSensivity))
320 {
321 if (WSN_PHY(ncon)->nRadioState == RX_ON_IDLE)
322 {
323 if (!ZIGBEE_CHANGERADIOSTATE(ncon, WSN_PHY(ncon)->nRadioState, RX_ON_BUSY))
324 {
325 if (isBroadcastPacket(packet) ||
326 isMulticastPacket(packet))
327 continue; // Other node maybe alive.
328 else
329 return 0;
330 }
331 // Metrics
332 WSN_MAC(ncon)->nNodeStatus = RX_MODE;
333 txFlag = true;
334 pstruEventDetails->dEventTime = packet->pstruPhyData->dEndTime;
335 pstruEventDetails->dPacketSize = packet->pstruPhyData->dPacketSize;
336 pstruEventDetails->nDeviceId = ncon;
337 packet->nReceiverId = pstruEventDetails->nDeviceId;
338 pstruEventDetails->nDeviceType = NETWORK->ppstruDeviceList[ncon - 1]->nDeviceType;
339 pstruEventDetails->nInterfaceId = fn_NetSim_Stack_GetWirelessInterface(nLink_Id, ncon);
340 pstruEventDetails->pPacket = packet;
341 pstruEventDetails->nEventType = PHYSICAL_IN_EVENT;
342 fnpAddEvent(pstruEventDetails);
343 }
344 }
345 }
346 }
347 if (WSN_MAC_HEADER(pstruPacket)->nAckRequestFlag)
348 {
349 pevent.nEventType = TIMER_EVENT;
350 pevent.nSubEventType = ACK_TIMEOUT;
351 pevent.dEventTime = pstruPacket->pstruPhyData->dEndTime + WSN_PHY(nDevice_Id)->macAckWaitDuration * 4 / dDataRate;
352 pevent.pPacket = NULL;
353 fnpAddEvent(&pevent);
354 }
355
356 if (pstruPacket->nControlDataType != ACK_FRAME && pstruPacket->nControlDataType / 100 != MAC_PROTOCOL_IEEE802_15_4 && txFlag == true)
357 {
358 pstruMetrics[nDevice_Id - 1]->pstruIEEE802_15_4_Metrics->nPacketTransmitted++;
359 }
360 if (pstruPacket->nControlDataType == ACK_FRAME && txFlag == true)
361 {
362 pstruMetrics[nDevice_Id - 1]->pstruIEEE802_15_4_Metrics->nAckTransmitted++;
363 }
364
365 //store the end time
366 NETWORK->ppstruDeviceList[nDevice_Id - 1]->ppstruInterfaceList[nDevice_PortId - 1]->pstruPhysicalLayer->dLastPacketEndTime = pstruPacket->pstruPhyData->dEndTime;
367 if (!pstruPacket->nReceiverId || txFlag == false)
368 fn_NetSim_Packet_FreePacket(pstruPacket);
369 //Add timer event to update the medium
370 pstruEventDetails->dEventTime = NETWORK->ppstruDeviceList[nDevice_Id - 1]->ppstruInterfaceList[nDevice_PortId - 1]->pstruPhysicalLayer->dLastPacketEndTime + 1;
371 pstruEventDetails->nDeviceId = nDevice_Id;
372 pstruEventDetails->nEventType = TIMER_EVENT;
373 pstruEventDetails->nSubEventType = UPDATE_MEDIUM;
374 pstruEventDetails->pPacket = NULL;
375 //Add the physical in event
376 fnpAddEvent(pstruEventDetails);
377 break;
378 }
379 case PHYSICAL_IN_EVENT:
380 {
381 NetSim_PACKET* pstruPacket;
382 PACKET_STATUS nPacketStatus;
383 double dFadingPower = 0;
384 NETSIM_ID ifid;
385 double SNR;
386 double dBER;
387
388 pstruPacket = pstruEventDetails->pPacket;
389 if (pstruPacket->nReceiverId && pstruPacket->nReceiverId != pstruEventDetails->nDeviceId)
390 {
391 fnNetSimError("Different device packet received..");
392 assert(false);
393 return 0;
394 }
395
396 if (!ZIGBEE_CHANGERADIOSTATE(pstruEventDetails->nDeviceId, WSN_PHY(pstruEventDetails->nDeviceId)->nRadioState, RX_ON_IDLE))
397 return 0;
398
399 if (WSN_PHY(pstruEventDetails->nDeviceId)->dTotalReceivedPower - GET_RX_POWER_mw(pstruPacket->nTransmitterId, pstruPacket->nReceiverId, pstruEventDetails->dEventTime) >= WSN_PHY(pstruEventDetails->nDeviceId)->dReceiverSensivity)
400 pstruPacket->nPacketStatus = PacketStatus_Collided;
401
402 nPacketStatus = pstruPacket->nPacketStatus;
403
404 double pdbm = GET_RX_POWER_dbm(pstruPacket->nTransmitterId,
405 pstruPacket->nReceiverId,
406 pstruEventDetails->dEventTime);
407
408 //Getting interface id of transmitter
409 ifid = fn_NetSim_Stack_GetConnectedInterface(pstruEventDetails->nDeviceId,
410 pstruEventDetails->nInterfaceId,
411 pstruPacket->nTransmitterId);
412
413 //calculating fading loss
414 dFadingPower = _propagation_calculate_fadingloss(
415 find_propagation_info(pstruPacket->nTransmitterId, ifid,
416 pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId));
417
418 pdbm -= dFadingPower;
419 ZIGBEE_SINR(&SNR, WSN_PHY(pstruEventDetails->nDeviceId)->dTotalReceivedPower, DBM_TO_MW(pdbm));
420
421 dBER = fn_NetSim_Zigbee_CalculateBER(SNR);
422
423 RadioMeasurements_802_15_4_Log(pstruPacket, pstruPacket->nTransmitterId, ifid,
424 pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId);
425
426 if (fn_NetSim_Packet_DecideError(dBER, pstruEventDetails->dPacketSize))
427 {
428 pstruPacket->nPacketStatus = PacketStatus_Error;
429 nPacketStatus = PacketStatus_Error;
430 }
431
432 fn_NetSim_WritePacketTrace(pstruPacket);
433
434 if (pstruPacket->nControlDataType == ACK_FRAME)
435 pstruPacket->pstruPhyData->dOverhead -= 1;
436 else
437 pstruPacket->pstruPhyData->dOverhead -= 6;
438
439 pstruPacket->pstruPhyData->dPacketSize = pstruPacket->pstruPhyData->dPayload + pstruPacket->pstruPhyData->dOverhead;
440 pstruEventDetails->dPacketSize = pstruPacket->pstruPhyData->dPacketSize;
441 LinkPacketLog();
442 if ((nPacketStatus == PacketStatus_Error) || (nPacketStatus == PacketStatus_Collided))
443 {
444 fn_NetSim_Metrics_Add(pstruPacket);
445 fn_NetSim_Packet_FreePacket(pstruPacket);
446 WSN_MAC(pstruEventDetails->nDeviceId)->nNodeStatus = IDLE;
447 }
448 else
449 {
450 pstruPacket->pstruPhyData->dArrivalTime = pstruEventDetails->dEventTime;
451 pstruPacket->pstruPhyData->dStartTime = pstruEventDetails->dEventTime;
452 pstruPacket->pstruPhyData->dEndTime = pstruEventDetails->dEventTime;
453
454 fn_NetSim_Metrics_Add(pstruPacket);
455
456 //Prepare the mac in event details
457 pstruEventDetails->nEventType = MAC_IN_EVENT;
458 //Add mac in event
459 fnpAddEvent(pstruEventDetails);
460 }
461 break;
462 }
463 case TIMER_EVENT:
464 {
465 switch (nSub_Event_Type)
466 {
467 case CARRIERSENSE_START:
468 {
469 if (WSN_MAC(nGlobalPANCoordinatorId)->nBeaconMode == BEACON_ENABLE && WSN_MAC(nGlobalPANCoordinatorId)->nMacBeaconOrder <= 14)//&& pstruSuperFrame->nSuperFrameStatus == CAPMODE)
470 {
471 if (pstruSuperFrame->nSuperFrameStatus == CAPMODE)
472 {
473 ZIGBEE_SLOTTED();
474 }
475 else
476 {
477 //wait for CAP
478 }
479 }
480 else
481 {
482 ZIGBEE_UNSLOTTED();
483 }
484 break;
485 }
486 case CARRIERSENSE_END:
487 {
488 if (WSN_MAC(nGlobalPANCoordinatorId)->nBeaconMode == BEACON_ENABLE && WSN_MAC(nGlobalPANCoordinatorId)->nMacBeaconOrder <= 14)//&& pstruSuperFrame->nSuperFrameStatus == CAPMODE)
489 {
490 if (pstruSuperFrame->nSuperFrameStatus == CAPMODE)
491 {
492 ZIGBEE_SLOTTED();
493 }
494 else
495 {
496 //wait for CAP
497 }
498 }
499 else
500 {
501 ZIGBEE_UNSLOTTED();
502 }
503 break;
504 }
505 case UPDATE_MEDIUM:
506 {
507 double dtime = pstruEventDetails->dEventTime;
508 NETSIM_ID nLink_Id, nConnectionID, nConnectionPortID, nLoop;
509 NETSIM_ID nTransmitterID;
510
511 nTransmitterID = pstruEventDetails->nDeviceId;
512
513 ZIGBEE_CHANGERADIOSTATE(nTransmitterID, WSN_PHY(nTransmitterID)->nRadioState, RX_ON_IDLE);
514 if (WSN_PHY(nTransmitterID)->nRadioState != RX_OFF)
515 WSN_MAC(nTransmitterID)->nNodeStatus = IDLE;
516 nLink_Id = fn_NetSim_Stack_GetConnectedDevice(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId, &nConnectionID, &nConnectionPortID);
517
518 for (nLoop = 1; nLoop <= NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.nConnectedDeviceCount; nLoop++)
519 {
520 NETSIM_ID ncon = NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.anDevIds[nLoop - 1];
521 if (ncon != pstruEventDetails->nDeviceId)
522 {
523 WSN_PHY(ncon)->dTotalReceivedPower -= GET_RX_POWER_mw(nTransmitterID, ncon, pstruEventDetails->dEventTime);
524
525 if (WSN_PHY(ncon)->dTotalReceivedPower < WSN_PHY(ncon)->dReceiverSensivity)
526 WSN_PHY(ncon)->dTotalReceivedPower = 0;
527 }
528 }
529
530 for (nLoop = 1; nLoop <= NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.nConnectedDeviceCount; nLoop++)
531 {
532 nDeviceId = NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.anDevIds[nLoop - 1];
533 IEEE802_15_4_MAC_VAR* macVar = WSN_MAC(nDeviceId);
534 IEEE802_15_4_PHY_VAR* phyVar = WSN_PHY(nDeviceId);
535 if ((phyVar->dTotalReceivedPower < phyVar->dReceiverSensivity) &&
536 (macVar->nNodeStatus == IDLE) && (phyVar->nRadioState == RX_ON_IDLE) &&
537 fn_NetSim_GetBufferStatus(NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[0]->pstruAccessInterface->pstruAccessBuffer))
538 {
539 NetSim_PACKET* packet = fn_NetSim_Packet_GetPacketFromBuffer(NETWORK->ppstruDeviceList[nDeviceId - 1]->ppstruInterfaceList[0]->pstruAccessInterface->pstruAccessBuffer, 0);
540
541 //Add Mac out event
542 if (nDeviceId == nTransmitterID)
543 pstruEventDetails->dEventTime += 40 * dUnitSymbolTime;
544 else
545 pstruEventDetails->dEventTime = dtime;
546 pstruEventDetails->nDeviceId = nDeviceId;
547 pstruEventDetails->nEventType = MAC_OUT_EVENT;
548 pstruEventDetails->nSubEventType = 0;
549 pstruEventDetails->pPacket = NULL;
550 pstruEventDetails->dPacketSize = fnGetPacketSize(packet);
551 pstruEventDetails->nPacketId = packet->nPacketId;
552 if (packet->pstruAppData)
553 {
554 pstruEventDetails->nApplicationId = packet->pstruAppData->nApplicationId;
555 pstruEventDetails->nSegmentId = packet->pstruAppData->nSegmentId;
556 }
557 else
558 {
559 pstruEventDetails->nApplicationId = 0;
560 pstruEventDetails->nSegmentId = 0;
561 }
562 fnpAddEvent(pstruEventDetails);
563 }
564 }
565 break;
566 }
567 case ACK_TIMEOUT:
568 {
569 if (WSN_MAC(nDeviceId)->pstruBuffer)
570 {
571 WSN_MAC(nDeviceId)->nRetryCount++;
572 if (WSN_MAC(nDeviceId)->nRetryCount <= WSN_MAC(nDeviceId)->nMacMaxFrameRetries)
573 {
574 pstruEventDetails->nEventType = MAC_OUT_EVENT;
575 pstruEventDetails->nSubEventType = 0;
576 fnpAddEvent(pstruEventDetails);
577 }
578 else
579 {
580 WSN_MAC(nDeviceId)->nRetryCount = 0;
581 if (WSN_MAC(nDeviceId)->pstruBuffer->DropNotification)
582 WSN_MAC(nDeviceId)->pstruBuffer->DropNotification(WSN_MAC(nDeviceId)->pstruBuffer);
583 //Drop the packet
584 WSN_MAC(nDeviceId)->pstruBuffer->nPacketStatus = PacketStatus_Buffer_Dropped;
585 fn_NetSim_WritePacketTrace(WSN_MAC(nDeviceId)->pstruBuffer);
586 fn_NetSim_Packet_FreePacket(WSN_MAC(nDeviceId)->pstruBuffer);
587 WSN_MAC(nDeviceId)->pstruBuffer = NULL;
588 //try next packet
589 if (WSN_MAC(nDeviceId)->nNodeStatus == IDLE)
590 if (fn_NetSim_GetBufferStatus(NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->pstruAccessInterface->pstruAccessBuffer))
591 {
592 NetSim_PACKET* packet = fn_NetSim_Packet_GetPacketFromBuffer(NETWORK->ppstruDeviceList[pstruEventDetails->nDeviceId - 1]->ppstruInterfaceList[pstruEventDetails->nInterfaceId - 1]->pstruAccessInterface->pstruAccessBuffer, 0);
593 //Prepare the mac out event details
594 pstruEventDetails->dEventTime += (double)40 * dUnitSymbolTime;
595 pstruEventDetails->pPacket = NULL;
596 if (packet->pstruAppData)
597 {
598 pstruEventDetails->nApplicationId = packet->pstruAppData->nApplicationId;
599 pstruEventDetails->nSegmentId = packet->pstruAppData->nSegmentId;
600 }
601 else
602 {
603 pstruEventDetails->nApplicationId = 0;
604 pstruEventDetails->nSegmentId = 0;
605 }
606 pstruEventDetails->dPacketSize = fnGetPacketSize(packet);
607 pstruEventDetails->nPacketId = packet->nPacketId;
608
609 pstruEventDetails->nEventType = MAC_OUT_EVENT;
610 pstruEventDetails->nSubEventType = 0;
611 pstruEventDetails->nProtocolId = MAC_PROTOCOL_IEEE802_15_4;
612 //Add mac out event
613 fnpAddEvent(pstruEventDetails);
614 }
615 }
616 }
617 break;
618 }
619 case SUPERFRAME_EVENT:
620 {
621 ZIGBEE_SUPERFRAME();
622 }
623 break;
624 case BEACON_TRANSMISSION_END:
625 {
626 NETSIM_ID nLoop;
627 //For the data transmission
628 for (nLoop = 0; nLoop < NETWORK->nDeviceCount; nLoop++)
629 {
630 if (fn_NetSim_GetBufferStatus(DEVICE_INTERFACE(nLoop + 1, 1)->pstruAccessInterface->pstruAccessBuffer))
631 {
632 WSN_MAC(nLoop + 1)->nNodeStatus = IDLE;
633 WSN_MAC(nLoop + 1)->nRetryCount = 0;
634 WSN_MAC(nLoop + 1)->nNoOfBackOff = 0;
635
636 pstruEventDetails->nDeviceId = (NETSIM_ID)nLoop + 1;
637 pstruEventDetails->nInterfaceId = 1;
638 pstruEventDetails->pPacket = fn_NetSim_Packet_GetPacketFromBuffer(DEVICE_MAC_NW_INTERFACE(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId)->pstruAccessBuffer, 1);
639 pstruEventDetails->dPacketSize = pstruEventDetails->pPacket->pstruNetworkData->dPacketSize;
640 pstruEventDetails->nEventType = MAC_OUT_EVENT;
641 pstruEventDetails->nSubEventType = 0;
642 pstruEventDetails->nProtocolId = MAC_PROTOCOL_IEEE802_15_4;
643 fnpAddEvent(pstruEventDetails);
644 }
645 }
646 //Update the super frame status
647 pstruSuperFrame->nSuperFrameStatus = CAPMODE;
648 pstruEventDetails->dEventTime = pstruEventDetails->dEventTime + pstruSuperFrame->dCAPLength;
649 pstruEventDetails->nDeviceId = nGlobalPANCoordinatorId;
650 pstruEventDetails->nInterfaceId = 1;
651 pstruEventDetails->nEventType = TIMER_EVENT;
652 pstruEventDetails->nSubEventType = CAP_END;
653 pstruEventDetails->nProtocolId = MAC_PROTOCOL_IEEE802_15_4;
654 fnpAddEvent(pstruEventDetails);
655
656 break;
657 }
658 case CAP_END:
659 {
660 pstruSuperFrame->nSuperFrameStatus = CFPMODE;
661 pstruEventDetails->dEventTime = pstruEventDetails->dEventTime + pstruSuperFrame->dCFPLength;
662 pstruEventDetails->nDeviceId = nGlobalPANCoordinatorId;
663 pstruEventDetails->nInterfaceId = 1;
664 pstruEventDetails->nEventType = TIMER_EVENT;
665 pstruEventDetails->nSubEventType = CFP_END;
666 pstruEventDetails->nProtocolId = MAC_PROTOCOL_IEEE802_15_4;
667 fnpAddEvent(pstruEventDetails);
668 }
669 break;
670 case CFP_END:
671 {
672 NETSIM_ID nLink_Id, nConnectionID, nConnectionPortID, nLoop;
673 nLink_Id = fn_NetSim_Stack_GetConnectedDevice(pstruEventDetails->nDeviceId, pstruEventDetails->nInterfaceId, &nConnectionID, &nConnectionPortID);
674 for (nLoop = 1; nLoop <= NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.nConnectedDeviceCount; nLoop++)
675 {
676 nDeviceId = NETWORK->ppstruNetSimLinks[nLink_Id - 1]->puniDevList.pstruMP2MP.anDevIds[nLoop - 1];
677 WSN_MAC(nDeviceId)->nNodeStatus = OFF;
678 ZIGBEE_CHANGERADIOSTATE(nDeviceId, WSN_PHY(nDeviceId)->nRadioState, SLEEP);
679 }
680 //Set the super frame status as inactive
681 pstruSuperFrame->nSuperFrameStatus = INACTIVEMODE;
682 }
683 break;
684
685 case SUBEVENT_GETLINKQUALITY:
686 {
687 double* pass = pstruEventDetails->szOtherDetails;
688 NETSIM_ID trx = (NETSIM_ID)pass[0];
689 NETSIM_ID tri = (NETSIM_ID)pass[1];
690 NETSIM_ID rx = (NETSIM_ID)pass[2];
691 NETSIM_ID ri = (NETSIM_ID)pass[3];
692 pass[4] = zigbee_get_link_quality(trx, tri, rx, ri);
693 }
694 break;
695 default:
696 fnNetSimError("Invalid event %d for zigbee protocol\n", pstruEventDetails->nSubEventType);
697 break;
698 }
699 break;
700 }
701 default:
702 fnNetSimError("Invalid event 5d for zigbee protocol\n", pstruEventDetails->nEventType);
703 break;
704 }
705 return 0;
706}
707/** This function is called by NetworkStack.dll to configure the Zigbee Protocol related devices. */
708_declspec(dllexport) int fn_NetSim_Zigbee_Configure(void** var)
709{
710 return fn_NetSim_Zigbee_Configure_F(var);
711}
712/** This function Initializes the Zigbee protocol parameters.*/
713_declspec (dllexport) int fn_NetSim_Zigbee_Init()
714{
715 init_linkpacketlog();
716 RadioMeasurements_802_15_4_Init();
717 return fn_NetSim_Zigbee_Init_F();
718}
719/**
720This function is called by NetworkStack.dll, once the simulation end, this function free
721the allocated memory for the network.
722*/
723_declspec(dllexport) int fn_NetSim_Zigbee_Finish()
724{
725 fn_NetSim_IEEE802_15_4_FreePropagationInfo();
726 fn_NetSim_Zigbee_Finish_F();
727 RadioMeasurements_802_15_4_Finish();
728 LinkPacketLog_close();
729 return 0;
730}
731
732_declspec (dllexport) char* fn_NetSim_Zigbee_Trace(int nSubEvent)
733{
734 return (fn_NetSim_Zigbee_Trace_F(nSubEvent));
735}
736/** This function is called by NetworkStack.dll,to free the packet. */
737_declspec(dllexport) int fn_NetSim_Zigbee_FreePacket(NetSim_PACKET* pstruPacket)
738{
739 return fn_NetSim_Zigbee_FreePacket_F(pstruPacket);
740}
741/** This function is called by NetworkStack.dll, to copy the Zigbee destination packet to source packet. */
742_declspec(dllexport) int fn_NetSim_Zigbee_CopyPacket(NetSim_PACKET* pstruSrcPacket, NetSim_PACKET* pstruDestPacket)
743{
744 return fn_NetSim_Zigbee_CopyPacket_F(pstruSrcPacket, pstruDestPacket);
745}
746/** This function write the metrics in metrics.txt */
747_declspec(dllexport) int fn_NetSim_Zigbee_Metrics(PMETRICSWRITER metricsWriter)
748{
749 return fn_NetSim_Zigbee_Metrics_F(metricsWriter);
750}
751
752/**
753This function is to configure the Zigbee protocol packet trace parameter.
754This function return a string which has the parameters separated by comma.
755*/
756_declspec(dllexport) char* fn_NetSim_Zigbee_ConfigPacketTrace(const void* xmlNetSimNode)
757{
758 xmlNetSimNode;
759 return "";
760}
761
762/**
763This function is called while writing the Packet trace for Zigbee protocol.
764This function is called for every packet while writing the packet trace.
765*/
766_declspec(dllexport) int fn_NetSim_Zigbee_WritePacketTrace(NetSim_PACKET* pstruPacket, char** ppszTrace)
767{
768 ppszTrace;
769 pstruPacket;
770 return 1;
771}
772/** This function is used to form the channel as well as to allocate the frequency,channel number */
773int fn_NetSim_Zigbee_ChannelFormation(CHANNELS** pstruChannelList)
774{
775 *pstruChannelList = calloc(1, sizeof(CHANNELS));
776 (*pstruChannelList)->nChannelStatus = IDLE;
777 (*pstruChannelList)->dFrequency = WSN_PHY(nGlobalPANCoordinatorId)->dFrequencyBand_MHz;
778 (*pstruChannelList)->nChannelNumber = (int)((*pstruChannelList)->dFrequency - 2405) / 5 + 11;
779 return 1;
780}
781
782_declspec(dllexport) int fn_NetSim_ZigBee_SinkNodeApp()
783{
784 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
785 return 0;
786}
787
788bool get_protocol_log_status(char* logname)
789{
790 FILE* fp;
791 char str[BUFSIZ];
792 sprintf(str, "%s/%s", pszIOPath, "ProtocolLogsConfig.txt");
793 fp = fopen(str, "r");
794 if (!fp)
795 return false;
796
797 char data[BUFSIZ];
798 while (fgets(data, BUFSIZ, fp))
799 {
800 lskip(data);
801 sprintf(str, "%s=true", logname);
802 if (!_strnicmp(data, str, strlen(str)))
803 {
804 fclose(fp);
805 return true;
806 }
807 }
808 fclose(fp);
809
810 return false;
811}