NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Ethernet_Phy.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* This source code is licensed per the NetSim license agreement. *
12* *
13* No portion of this source code may be used as the basis for a derivative work, *
14* or used, for any purpose other than its intended use per the NetSim license *
15* agreement. *
16* *
17* This source code and the algorithms contained within it are confidential trade *
18* secrets of TETCOS and may not be used as the basis for any other software, *
19* hardware, product or service. *
20* *
21* Author: Shashi Kant Suman *
22* *
23* ----------------------------------------------------------------------------------*/
24#include "main.h"
25#include "Ethernet.h"
26#include "Ethernet_enum.h"
27#include "AdvancedPlots.h"
28#pragma comment(lib,"AdvancedPlots.lib")
29
30static void init_eth_phy_buffer(ptrETH_PHY phy)
31{
32 phy->packet = calloc(1, sizeof* phy->packet);
33 NETSIM_ID d = pstruEventDetails->nDeviceId;
34 NETSIM_ID in = phy->interfaceId;
35 NetSim_BUFFER* buff = DEVICE_ACCESSBUFFER(d, in);
36 memcpy(phy->packet, buff, sizeof* phy->packet);
37 phy->packet->nSchedulingType = SCHEDULING_FIFO;
38 phy->packet->queuingTechnique = QUEUING_DROPTAIL;
39 phy->packet->pstruPacketlist = NULL;
40}
41
42static void eth_phy_packet_add_to_list(ptrETH_PHY phy, NetSim_PACKET* packet)
43{
44 if (!packet)
45 return;
46
47 if (!phy->packet)
48 init_eth_phy_buffer(phy);
49
50 fn_NetSim_Packet_AddPacketToList(phy->packet, packet, 0);
51}
52
53static NetSim_PACKET* eth_phy_packet_get_from_list(ptrETH_PHY phy)
54{
55 if (!phy->packet)
56 return NULL;
57
58 return fn_NetSim_Packet_GetPacketFromBuffer(phy->packet, 1);
59}
60
61static bool isPhyHasPacket(ptrETH_PHY phy)
62{
63 if (phy->packet)
64 return fn_NetSim_GetBufferStatus(phy->packet);
65 else
66 return false;
67}
68
69double calculate_txtime(ptrETH_PHY phy, double size)
70{
71 double rate = phy->speed;
72 return (size * 8.0) / rate; //In Microsec
73}
74
75static void eth_phy_packet_set_param(NetSim_PACKET* packet,
76 double start,
77 double end,
78 double tx)
79{
80 packet->pstruPhyData->dArrivalTime = start;
81 packet->pstruPhyData->dEndTime = end;
82 packet->pstruPhyData->dOverhead = 0;
83 packet->pstruPhyData->dPacketSize = packet->pstruMacData->dPacketSize;
84 packet->pstruPhyData->dPayload = packet->pstruMacData->dPacketSize;
85 packet->pstruPhyData->dStartTime = start + tx;
86 packet->pstruPhyData->nPhyMedium = PHY_MEDIUM_WIRED;
87}
88
89static void eth_phy_add_phy_in(NetSim_PACKET* packet,
90 NETSIM_ID c,
91 NETSIM_ID ci)
92{
93 packet->nReceiverId = c;
94 packet->nTransmitterId = pstruEventDetails->nDeviceId;
95
96 NetSim_EVENTDETAILS pevent;
97 memset(&pevent, 0, sizeof pevent);
98 pevent.dEventTime = packet->pstruPhyData->dEndTime;
99 pevent.dPacketSize = packet->pstruPhyData->dPacketSize;
100 if (packet->pstruAppData)
101 {
102 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
103 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
104 }
105 pevent.nDeviceId = c;
106 pevent.nDeviceType = DEVICE_TYPE(c);
107 pevent.nEventType = PHYSICAL_IN_EVENT;
108 pevent.nInterfaceId = ci;
109 pevent.nPacketId = packet->nPacketId;
110 pevent.nProtocolId = MAC_PROTOCOL_IEEE802_3;
111 pevent.pPacket = packet;
112 fnpAddEvent(&pevent);
113}
114
115static void eth_phy_add_phy_out(double time, NetSim_PACKET* packet)
116{
117 NetSim_EVENTDETAILS pevent;
118 memcpy(&pevent, pstruEventDetails, sizeof pevent);
119 pevent.dEventTime = time;
120 pevent.dPacketSize = packet->pstruMacData->dPacketSize;
121 if (packet->pstruAppData)
122 {
123 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
124 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
125 }
126 else
127 {
128 pevent.nApplicationId = 0;
129 pevent.nSegmentId = 0;
130 }
131 pevent.nPacketId = packet->nPacketId;
132 pevent.nSubEventType = 0;
133 pevent.pPacket = NULL;
134 fnpAddEvent(&pevent);
135}
136int fn_NetSim_Ethernet_HandlePhyOut()
137{
138 NETSIM_ID d = pstruEventDetails->nDeviceId;
139 NETSIM_ID in = pstruEventDetails->nInterfaceId;
140 ptrETH_PHY phy = ETH_PHY_GET(d, in);
141 NetSim_PACKET* packet = pstruEventDetails->pPacket;
142 bool flag = true;
143
144 if (isPhyHasPacket(phy))
145 flag = false;
146
147 eth_phy_packet_add_to_list(phy, packet);
148
149 if (phy->lastPacketEndTime > pstruEventDetails->dEventTime)
150 {
151 // Wait for current transmission to finish
152 if (flag)
153 goto ADD_NEXT;
154 else
155 return 1;
156 }
157
158 packet = eth_phy_packet_get_from_list(phy);
159 if (!packet)
160 return 2; // No packet is there for transmission
161
162 double start;
163 if (phy->lastPacketEndTime + phy->IFG <= pstruEventDetails->dEventTime)
164 start = pstruEventDetails->dEventTime;
165 else
166 start = phy->lastPacketEndTime + phy->IFG;
167
168 double size = packet->pstruMacData->dPacketSize;
169
170 double txtime = calculate_txtime(phy, size);
171 double end = start + txtime + phy->propagationDelay;
172 eth_phy_packet_set_param(packet, start, end, txtime);
173
174 eth_phy_add_phy_in(packet, phy->connectedDevice, phy->connectedInterface);
175 phy->lastPacketEndTime = start + txtime;
176
177ADD_NEXT:
178 if (isPhyHasPacket(phy))
179 eth_phy_add_phy_out(phy->lastPacketEndTime,
180 fn_NetSim_Packet_GetPacketFromBuffer(phy->packet,0));
181 return 0;
182}
183
184int fn_NetSim_Ethernet_HandlePhyIn()
185{
186 NetSim_PACKET* packet = pstruEventDetails->pPacket;
187 NETSIM_ID d = pstruEventDetails->nDeviceId;
188 NETSIM_ID in = pstruEventDetails->nInterfaceId;
189 ptrETH_PHY phy = ETH_PHY_GET(d, in);
190
191 if (phy->isErrorChkReqd)
192 {
193 packet->nPacketStatus = fn_NetSim_Packet_DecideError(phy->BER, packet->pstruPhyData->dPacketSize);
194 LinkPacketLog();
195 if (packet->nPacketStatus)
196 {
197 fn_NetSim_WritePacketTrace(packet);
198 fn_NetSim_Metrics_Add(packet);
199 fn_NetSim_Packet_FreePacket(packet);
200 return -1; //Packet is error. Dropped
201 }
202 }
203
204 fn_NetSim_WritePacketTrace(packet);
205 fn_NetSim_Metrics_Add(packet);
206 pstruEventDetails->nEventType = MAC_IN_EVENT;
207 fnpAddEvent(pstruEventDetails);
208 return 0;
209}