Choco OS  V.0.16.9.0
Join to the chocolate world
oc_tcp_connection.c
Go to the documentation of this file.
1 
27 #include <oc_tcp.h>
28 #include <oc_thread.h>
29 #include <oc_ktime.h>
30 #include <oc_mutex.h>
31 #include <oc_math.h>
32 #include <oc_dynamic_config.h>
33 #include <oc_semaphore.h>
34 #include <oc_event.h>
35 #include <oc_intman.h>
36 #include <oc_netifman.h>
37 #include <oc_queue.h>
38 
44 #define _________________________________________MACROS_SECTION_____________________________________________________________________________
45 
46 #define IsConnected(C) ((C)->State == State_Established)
47 #define IsCorrect(C) (isram(C) && oC_CheckObjectControl(C,oC_ObjectId_TcpConnection,(C)->ObjectControl))
48 
49 #undef _________________________________________MACROS_SECTION_____________________________________________________________________________
50 
51 
52 
58 #define _________________________________________TYPES_SECTION______________________________________________________________________________
59 
60 typedef enum
61 {
62  State_NotConnected = 0 ,
63  State_WaitForSyn = 1 ,
64  State_NeedsToAccept = 3 ,
65  State_Connecting = 4 ,
66  State_Established = 5 ,
67  State_Disconnecting = 6 ,
68 } State_t;
69 
70 typedef enum
71 {
72  PredefinedPacket_SYN ,
73  PredefinedPacket_SYN_ACK ,
74  PredefinedPacket_SYN_RST ,
75  PredefinedPacket_ACK ,
76  PredefinedPacket_FIN_ACK ,
77  PredefinedPacket_FIN ,
78  PredefinedPacket_NumberOfElements ,
79 } PredefinedPacket_t;
80 
81 typedef struct
82 {
83  union
84  {
85  struct
86  {
87  #if defined(LITTLE_ENDIAN)
88  uint32_t DataOffset:4;
89  uint32_t Reserved:3;
90  uint32_t NS:1;
91  uint32_t CWR:1;
92  uint32_t ECE:1;
93  uint32_t URG:1;
94  uint32_t ACK:1;
95  uint32_t PSH:1;
96  uint32_t RST:1;
97  uint32_t SYN:1;
98  uint32_t FIN:1;
99  #elif defined(BIG_ENDIAN)
100  # error Structure is not defined for BIG_ENDIAN
101  #else
102  # error Endianess is not defined
103  #endif
104  };
105  struct
106  {
107  #if defined(LITTLE_ENDIAN)
108  uint8_t LowByte;
109  uint8_t HighByte;
110  #elif defined(BIG_ENDIAN)
111  # error Structure is not defined for BIG_ENDIAN
112  #else
113  # error Endianess is not defined
114  #endif
115  };
116 
117  };
118  uint32_t AddToSequence;
119  const char * Name;
120 } PacketFlags_t;
121 
122 typedef oC_Tcp_Packet_t * Packet_t;
123 
124 typedef struct
125 {
126  union
127  {
128  uint8_t * Buffer;
129  const uint8_t * ConstBuffer;
130  };
131  oC_MemorySize_t Size;
132  oC_MemorySize_t ConfirmedBytes;
133  union
134  {
135  oC_MemorySize_t ReceivedBytes;
136  oC_MemorySize_t SentBytes;
137  };
138 } Segment_t;
139 
140 typedef oC_Tcp_ConnectionFinishedFunction_t ConnectionFinishedHandler_t;
141 
142 //==========================================================================================================================================
146 //==========================================================================================================================================
148 {
149  oC_ObjectControl_t ObjectControl;
150  oC_DefaultString_t Name;
151  State_t State;
152  oC_Process_t Process;
153  oC_Thread_t ReceiveThread;
154  ConnectionFinishedHandler_t ConnectionFinishedFunction;
155  void * ConnectionFinishedParameter;
156 
157  // ///////////////////////////////////////////////////////////
158  // CONNECTION INFORMATION //
159  // ///////////////////////////////////////////////////////////
160  uint32_t InitialSequenceNumber;
161  uint32_t RemoteInitialSequenceNumber;
162  oC_Net_Address_t LocalAddress;
163  oC_Net_Address_t RemoteAddress;
164 
165  // ///////////////////////////////////////////////////////////
166  // TIMING PARAMETERS //
167  // ///////////////////////////////////////////////////////////
168  oC_Time_t ConfirmationTimeout;
169  oC_Time_t ExpirationTimeout;
170  oC_Time_t ReceiveTimeout;
171  oC_Time_t SendingAcknowledgeTimeout;
172  oC_Time_t ReadSegmentTimeout;
173  oC_Time_t SaveSegmentTimeout;
174  oC_Timestamp_t ExpirationTimestamp;
175 
176  // ///////////////////////////////////////////////////////////
177  // FIELDS REQUIRED FOR SENDING //
178  // ///////////////////////////////////////////////////////////
179  oC_Mutex_t ReadyForSendingMutex;
180  oC_Mutex_t SendingSegmentMutex;
181  oC_Event_t RemoteWindowSizeChangedEvent;
182  Packet_t PacketToSend;
183  uint16_t PacketSize;
184  oC_MemorySize_t RemoteWindowSize;
185  uint8_t RemoteWindowScale;
186  uint32_t NextSequenceNumberToSend;
187  uint32_t LastConfirmedSequenceNumber;
188 
189  // ///////////////////////////////////////////////////////////
190  // FIELDS REQUIRED FOR RECEIVING //
191  // ///////////////////////////////////////////////////////////
192  uint8_t LocalWindowScale;
193  Segment_t SegmentToReceive;
194  Packet_t LastReceivedPacket;
195  oC_Mutex_t ReadyForReceivingMutex;
196  oC_Semaphore_t NewPacketReceivedSemaphore;
197  oC_Event_t AcknowledgeReceivedEvent;
198  uint32_t NextSequenceNumberToReceive;
199  PacketFlags_t ReceivedPacketFlags;
200  bool AcknowledgePacketShouldBeSend;
201  bool FinishConnectionPacketShouldBeSend;
202  oC_Queue_t ReceiveQueue;
203 
204  // ///////////////////////////////////////////////////////////
205  // TRANSMISSION SPEED MEASUREMENT //
206  // ///////////////////////////////////////////////////////////
207  oC_Timestamp_t LastMeasureTimestamp;
208  oC_BaudRate_t BaudRate;
209  oC_MemorySize_t SentBytesFromLastMeasure;
210 };
211 
212 
213 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
214 
220 #define _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
221 
222 static oC_ErrorCode_t SendPredefinedPacket ( oC_Tcp_Connection_t Connection , PredefinedPacket_t PredefinedPacket , oC_Time_t Timeout );
223 static oC_ErrorCode_t WaitForPredefinedPacket ( oC_Tcp_Connection_t Connection , PredefinedPacket_t PredefinedPacket , oC_Time_t Timeout );
224 static oC_ErrorCode_t ReadConnectionDataFromPacket( oC_Tcp_Connection_t Connection , Packet_t Packet );
225 static oC_ErrorCode_t SendSegment ( oC_Tcp_Connection_t Connection , Segment_t * Segment , oC_Time_t Timeout );
226 static bool PacketFilterFunction ( oC_Net_Packet_t * ReceivedPacket, const void * Parameter , oC_Netif_t Netif );
227 static void ReceiveThread ( oC_Tcp_Connection_t Connection );
228 
229 #undef _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
230 
236 #define _________________________________________GLOBALS_SECTION____________________________________________________________________________
237 
238 static const PacketFlags_t PredefinedPacketFlags[PredefinedPacket_NumberOfElements] = {
239  [PredefinedPacket_SYN ] = { .Name = "SYN" , .AddToSequence = 1 , .DataOffset = 5, .SYN = 1 } ,
240  [PredefinedPacket_SYN_ACK] = { .Name = "SYN ACK" , .AddToSequence = 1 , .DataOffset = 5, .SYN = 1 , .ACK = 1 } ,
241  [PredefinedPacket_SYN_RST] = { .Name = "SYN RST" , .AddToSequence = 1 , .DataOffset = 5, .SYN = 1 , .RST = 1 } ,
242  [PredefinedPacket_ACK ] = { .Name = "ACK" , .AddToSequence = 0 , .DataOffset = 5, .ACK = 1 } ,
243  [PredefinedPacket_FIN_ACK] = { .Name = "FIN ACK" , .AddToSequence = 1 , .DataOffset = 5, .FIN = 1 , .ACK = 1 } ,
244  [PredefinedPacket_FIN ] = { .Name = "FIN" , .AddToSequence = 1 , .DataOffset = 5, .FIN = 1 , .ACK = 1 } ,
245 };
246 
247 #undef _________________________________________GLOBALS_SECTION____________________________________________________________________________
248 
249 
250 
256 #define _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
257 
258 //==========================================================================================================================================
269 //==========================================================================================================================================
271 {
272  oC_Tcp_Connection_t connection = NULL;
273 
274  if(
275  oC_SaveIfFalse( "Config" , isaddresscorrect(Config) , oC_ErrorCode_WrongConfigAddress )
276  && oC_SaveIfFalse( "Local " , oC_Net_IsAddressCorrect(&Config->LocalAddress) , oC_ErrorCode_IpAddressNotCorrect )
277  && oC_SaveIfFalse( "Remote " , oC_Net_IsAddressCorrect(&Config->RemoteAddress), oC_ErrorCode_IpAddressNotCorrect )
278  && oC_SaveIfFalse( "Local Port" , Config->LocalAddress.Port != oC_Tcp_Port_Empty , oC_ErrorCode_PortNotCorrect )
279  && oC_SaveIfFalse( "Confirmation", Config->ConfirmationTimeout >= 0 , oC_ErrorCode_TimeNotCorrect )
280  && oC_SaveIfFalse( "Expiration" , Config->ExpirationTimeout >= 0 , oC_ErrorCode_TimeNotCorrect )
281  && oC_SaveIfFalse( "ACK Time" , Config->SendingAcknowledgeTimeout >= 0 , oC_ErrorCode_TimeNotCorrect )
282  && oC_SaveIfFalse( "Read Segment", Config->ReadSegmentTimeout >= 0 , oC_ErrorCode_TimeNotCorrect )
283  && oC_SaveIfFalse( "Packet Size" , Config->PacketSize > 0 , oC_ErrorCode_SizeNotCorrect )
284  )
285  {
286  connection = malloc( sizeof(struct Tcp_Connection_t), AllocationFlags_ZeroFill );
287 
288  if( oC_SaveIfFalse( "Main Object", connection != NULL, oC_ErrorCode_AllocationError ) )
289  {
290  oC_MemorySize_t stackSize = oC_DynamicConfig_GetValue(Tcp,StackSize);
291  Allocator_t allocator = getcurallocator();
292 
293  sprintf(connection->Name, "TCP:%08x", Config->InitialSequenceNumber);
294 
295  connection->ObjectControl = oC_CountObjectControl(connection,oC_ObjectId_TcpConnection);
296  connection->State = State_NotConnected;
297  connection->Process = getcurprocess();
298  connection->ReceiveThread = oC_Thread_New( 0, stackSize , connection->Process, connection->Name, (oC_Thread_Function_t)ReceiveThread, connection);
299  connection->InitialSequenceNumber = Config->InitialSequenceNumber;
300  connection->RemoteInitialSequenceNumber = Config->InitialAcknowledgeNumber;
301  connection->ConnectionFinishedFunction = Config->ConnectionFinishedFunction;
302  connection->ConnectionFinishedParameter = Config->ConnectionFinishedParameter;
303 
304  // ///////////////////////////////////////////////////////////////////////////// //
305  // ADDRESS INITIALIZATION //
306  // ///////////////////////////////////////////////////////////////////////////// //
307  connection->LocalAddress.Protocol = oC_Net_Protocol_TCP;
308  connection->LocalAddress.Type = Config->LocalAddress.Type;
309  connection->LocalAddress.IPv4 = Config->LocalAddress.IPv4;
310  connection->LocalAddress.IPv6.LowPart = Config->LocalAddress.IPv6.LowPart;
311  connection->LocalAddress.IPv6.HighPart = Config->LocalAddress.IPv6.HighPart;
312  connection->LocalAddress.Port = Config->LocalAddress.Port;
313 
314  connection->RemoteAddress.Protocol = oC_Net_Protocol_TCP;
315  connection->RemoteAddress.Type = Config->RemoteAddress.Type;
316  connection->RemoteAddress.IPv4 = Config->RemoteAddress.IPv4;
317  connection->RemoteAddress.IPv6.LowPart = Config->RemoteAddress.IPv6.LowPart;
318  connection->RemoteAddress.IPv6.HighPart = Config->RemoteAddress.IPv6.HighPart;
319  connection->RemoteAddress.Port = Config->RemoteAddress.Port;
320 
321  // ///////////////////////////////////////////////////////////////////////////// //
322  // TIMING PARAMETERS //
323  // ///////////////////////////////////////////////////////////////////////////// //
324  connection->ConfirmationTimeout = Config->ConfirmationTimeout;
325  connection->ExpirationTimeout = Config->ExpirationTimeout;
326  connection->SendingAcknowledgeTimeout = Config->SendingAcknowledgeTimeout;
327  connection->ReadSegmentTimeout = Config->ReadSegmentTimeout;
328  connection->ReceiveTimeout = Config->ReceiveTimeout;
329  connection->ExpirationTimestamp = Config->ExpirationTimeout + gettimestamp();
330 
331  // ///////////////////////////////////////////////////////////////////////////// //
332  // FIELDS REQUIRED FOR SENDING //
333  // ///////////////////////////////////////////////////////////////////////////// //
334  connection->ReadyForSendingMutex = oC_Mutex_New(oC_Mutex_Type_Normal,allocator,0);
335  connection->SendingSegmentMutex = oC_Mutex_New(oC_Mutex_Type_Normal,allocator,0);
336  connection->RemoteWindowSizeChangedEvent = oC_Event_New(0,allocator,0);
337  connection->PacketToSend = oC_Tcp_Packet_New(&connection->LocalAddress,&connection->RemoteAddress,sizeof(oC_Tcp_Header_t) + sizeof(uint32_t),NULL,Config->PacketSize);
338  connection->PacketSize = Config->PacketSize;
339  connection->RemoteWindowSize = 0;
340  connection->RemoteWindowScale = 0;
341  connection->NextSequenceNumberToSend = Config->InitialSequenceNumber;
342 
343  // ///////////////////////////////////////////////////////////////////////////// //
344  // FIELDS REQUIRED FOR RECEIVING //
345  // ///////////////////////////////////////////////////////////////////////////// //
346  connection->LocalWindowScale = Config->LocalWindowScale;
347  connection->SegmentToReceive.Size = Config->LocalWindowSize << Config->LocalWindowScale;
348  connection->SegmentToReceive.Buffer = malloc( connection->SegmentToReceive.Size, 0 );
349  connection->SegmentToReceive.ReceivedBytes = 0;
350  connection->SegmentToReceive.ConfirmedBytes = 0;
351  connection->LastReceivedPacket = malloc( sizeof(oC_Tcp_Packet_t), AllocationFlags_ZeroFill );
352  connection->ReadyForReceivingMutex = oC_Mutex_New(oC_Mutex_Type_Normal, allocator, 0);
353  connection->NewPacketReceivedSemaphore = oC_Semaphore_New(oC_Semaphore_Type_Binary, 0, allocator, 0);
354  connection->AcknowledgeReceivedEvent = oC_Event_New(0,allocator,0);
355  connection->NextSequenceNumberToReceive = Config->InitialAcknowledgeNumber;
356  connection->ReceivedPacketFlags.LowByte = 0;
357  connection->ReceivedPacketFlags.HighByte = 0;
358  connection->AcknowledgePacketShouldBeSend = false;
359  connection->FinishConnectionPacketShouldBeSend = false;
360  connection->ReceiveQueue = oC_Queue_New(allocator,connection->SegmentToReceive.Size);
361 
362  // ///////////////////////////////////////////////////////////////////////////// //
363  // FIELDS REQUIRED FOR BAUD RATE //
364  // ///////////////////////////////////////////////////////////////////////////// //
365  connection->LastMeasureTimestamp = gettimestamp();
366  connection->BaudRate = 0;
367  connection->SentBytesFromLastMeasure = 0;
368 
369  if(
370  oC_SaveIfFalse( "Thread" , oC_Thread_IsCorrect (connection->ReceiveThread) , oC_ErrorCode_AllocationError )
371  && oC_SaveIfFalse( "Mutex" , oC_Mutex_IsCorrect (connection->ReadyForSendingMutex) , oC_ErrorCode_AllocationError )
372  && oC_SaveIfFalse( "Mutex" , oC_Mutex_IsCorrect (connection->SendingSegmentMutex) , oC_ErrorCode_AllocationError )
373  && oC_SaveIfFalse( "Event" , oC_Event_IsCorrect (connection->RemoteWindowSizeChangedEvent) , oC_ErrorCode_AllocationError )
374  && oC_SaveIfFalse( "Packet" , connection->PacketToSend != NULL , oC_ErrorCode_AllocationError )
375  && oC_SaveIfFalse( "Packet" , connection->LastReceivedPacket != NULL , oC_ErrorCode_AllocationError )
376  && oC_SaveIfFalse( "Buffer" , connection->SegmentToReceive.Buffer != NULL , oC_ErrorCode_AllocationError )
377  && oC_SaveIfFalse( "Mutex" , oC_Mutex_IsCorrect (connection->ReadyForReceivingMutex) , oC_ErrorCode_AllocationError )
378  && oC_SaveIfFalse( "Semaphore" , oC_Semaphore_IsCorrect (connection->NewPacketReceivedSemaphore) , oC_ErrorCode_AllocationError )
379  && oC_SaveIfFalse( "Event" , oC_Event_IsCorrect (connection->AcknowledgeReceivedEvent) , oC_ErrorCode_AllocationError )
380  && oC_SaveIfFalse( "Queue" , oC_Queue_IsCorrect (connection->ReceiveQueue) , oC_ErrorCode_AllocationError )
381  && oC_SaveIfFalse( "Run Thread" , oC_Thread_Run(connection->ReceiveThread) , oC_ErrorCode_CannotRunThread )
382  )
383  {
384  tcplog(oC_LogType_Track, "0x%08X: New connection allocated", Config->InitialSequenceNumber);
385  }
386  else
387  {
388  connection->ObjectControl = 0;
389  oC_Thread_Delete (&connection->ReceiveThread);
390  oC_Mutex_Delete (&connection->ReadyForSendingMutex , 0);
391  oC_Mutex_Delete (&connection->SendingSegmentMutex , 0);
392  oC_Event_Delete (&connection->RemoteWindowSizeChangedEvent,0);
393  oC_Tcp_Packet_Delete(&connection->PacketToSend);
394  free(connection->LastReceivedPacket,0);
395  free(connection->SegmentToReceive.Buffer,0);
396  oC_Mutex_Delete (&connection->ReadyForReceivingMutex,0);
397  oC_Semaphore_Delete (&connection->NewPacketReceivedSemaphore,0);
398  oC_Event_Delete (&connection->AcknowledgeReceivedEvent,0);
399  oC_Queue_Delete (&connection->ReceiveQueue);
400  free(connection,0);
401  connection = NULL;
402  }
403  }
404  }
405 
406  return connection;
407 }
408 
409 //==========================================================================================================================================
410 //==========================================================================================================================================
411 bool oC_Tcp_Connection_Delete( oC_Tcp_Connection_t * Connection , oC_Time_t Timeout )
412 {
413  bool deleted = false;
414 
415  if(
416  oC_SaveIfFalse( "Connection", isram(Connection) , oC_ErrorCode_AddressNotInRam )
417  && oC_SaveIfFalse( "Connection", IsCorrect(*Connection) , oC_ErrorCode_ObjectNotCorrect )
418  && oC_SaveIfFalse( "Timeout" , Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
419  )
420  {
421  oC_IntMan_EnterCriticalSection();
422  oC_Tcp_Connection_t connection = *Connection;
423 
424  connection->ObjectControl = 0;
425  bool deletedReceiveThread = oC_Thread_Delete (&connection->ReceiveThread );
426  bool deletedReadyForSendingMutex = oC_Mutex_Delete (&connection->ReadyForSendingMutex , 0);
427  bool deletedSendingSegmentMutex = oC_Mutex_Delete (&connection->SendingSegmentMutex , 0);
428  bool deletedRemoteWindowSizeChangedEvent = oC_Event_Delete (&connection->RemoteWindowSizeChangedEvent , 0);
429  bool deletedPacketToSend = oC_Tcp_Packet_Delete(&connection->PacketToSend );
430  bool deletedBuffer = free(connection->SegmentToReceive.Buffer , 0);
431  bool deletedReceiveBuffer = free(connection->LastReceivedPacket , 0);
432  bool deletedReadyForReceivingMutex = oC_Mutex_Delete (&connection->ReadyForReceivingMutex , 0);
433  bool deletedNewPacketReceivedSemaphore = oC_Semaphore_Delete (&connection->NewPacketReceivedSemaphore , 0);
434  bool deletedAcknowledgeReceivedEvent = oC_Event_Delete (&connection->AcknowledgeReceivedEvent , 0);
435  bool deletedReceiveQueue = oC_Queue_Delete (&connection->ReceiveQueue);
436  bool deletedObject = free(connection,0);
437 
438  if(
439  oC_SaveIfFalse( "ReceiveThread ", deletedReceiveThread , oC_ErrorCode_ReleaseError )
440  && oC_SaveIfFalse( "ReadyForSendingMutex ", deletedReadyForSendingMutex , oC_ErrorCode_ReleaseError )
441  && oC_SaveIfFalse( "SendingSegmentMutex ", deletedSendingSegmentMutex , oC_ErrorCode_ReleaseError )
442  && oC_SaveIfFalse( "RemoteWindowSizeChangedEvent ", deletedRemoteWindowSizeChangedEvent , oC_ErrorCode_ReleaseError )
443  && oC_SaveIfFalse( "PacketToSend ", deletedPacketToSend , oC_ErrorCode_ReleaseError )
444  && oC_SaveIfFalse( "PacketToReceive ", deletedReceiveBuffer , oC_ErrorCode_ReleaseError )
445  && oC_SaveIfFalse( "Buffer ", deletedBuffer , oC_ErrorCode_ReleaseError )
446  && oC_SaveIfFalse( "ReadyForReceivingMutex ", deletedReadyForReceivingMutex , oC_ErrorCode_ReleaseError )
447  && oC_SaveIfFalse( "NewPacketReceivedSemaphore ", deletedNewPacketReceivedSemaphore , oC_ErrorCode_ReleaseError )
448  && oC_SaveIfFalse( "AcknowledgeReceivedEvent ", deletedAcknowledgeReceivedEvent , oC_ErrorCode_ReleaseError )
449  && oC_SaveIfFalse( "ReceiveQueue" , deletedReceiveQueue , oC_ErrorCode_ReleaseError )
450  && oC_SaveIfFalse( "Object" , deletedObject , oC_ErrorCode_ReleaseError )
451  )
452  {
453  deleted = true;
454  }
455 
456  oC_IntMan_ExitCriticalSection();
457  }
458 
459  return deleted;
460 }
461 
462 //==========================================================================================================================================
463 //==========================================================================================================================================
464 bool oC_Tcp_Connection_AreTheSame( oC_Tcp_Connection_t ConnectionA, oC_Tcp_Connection_t ConnectionB )
465 {
466  bool theSame = false;
467 
468  if(
469  oC_SaveIfFalse( "Connection A", IsCorrect(ConnectionA) , oC_ErrorCode_ObjectNotCorrect )
470  && oC_SaveIfFalse( "Connection B", IsCorrect(ConnectionB) , oC_ErrorCode_ObjectNotCorrect )
471  )
472  {
473  theSame = ConnectionA->InitialSequenceNumber == ConnectionB->InitialSequenceNumber
474  && oC_Net_AreAddressesTheSame(&ConnectionA->RemoteAddress, &ConnectionB->RemoteAddress);
475  }
476 
477  return theSame;
478 }
479 
480 //==========================================================================================================================================
481 //==========================================================================================================================================
482 bool oC_Tcp_Connection_IsCorrect( oC_Tcp_Connection_t Connection )
483 {
484  return isram(Connection) && oC_CheckObjectControl(Connection,oC_ObjectId_TcpConnection,Connection->ObjectControl);
485 }
486 
487 //==========================================================================================================================================
488 //==========================================================================================================================================
489 bool oC_Tcp_Connection_IsConnected( oC_Tcp_Connection_t Connection )
490 {
491  return IsCorrect(Connection) && IsConnected(Connection);
492 }
493 
494 //==========================================================================================================================================
495 //==========================================================================================================================================
496 oC_Process_t oC_Tcp_Connection_GetProcess( oC_Tcp_Connection_t Connection )
497 {
498  oC_Process_t process = NULL;
499 
500  if(oC_SaveIfFalse("Connection", IsCorrect(Connection), oC_ErrorCode_ObjectNotCorrect))
501  {
502  process = Connection->Process;
503  }
504 
505  return process;
506 }
507 
508 //==========================================================================================================================================
509 //==========================================================================================================================================
510 const char * oC_Tcp_Connection_GetName( oC_Tcp_Connection_t Connection )
511 {
512  const char * name = "incorrect connection";
513 
514  if(oC_SaveIfFalse("connection", IsCorrect(Connection), oC_ErrorCode_ObjectNotCorrect))
515  {
516  name = Connection->Name;
517  }
518 
519  return name;
520 }
521 
522 //==========================================================================================================================================
523 //==========================================================================================================================================
524 oC_ErrorCode_t oC_Tcp_Connection_Connect( oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
525 {
526  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
527  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
528 
529  if(
530  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
531  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
532  && ErrorCondition( !IsConnected(Connection) , oC_ErrorCode_AlreadyConnected )
533  )
534  {
535  Connection->State = State_Connecting;
536 
537  while(ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_SYN, gettimeout(endTimestamp)) ))
538  {
539  if( ErrorCode( WaitForPredefinedPacket(Connection, PredefinedPacket_SYN_ACK, Connection->ConfirmationTimeout) ) )
540  {
541  if( ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_ACK , gettimeout(endTimestamp)) ) )
542  {
543  Connection->State = State_Established;
544  errorCode = oC_ErrorCode_None;
545  }
546  break;
547  }
548  else if(errorCode != oC_ErrorCode_Timeout)
549  {
550  break;
551  }
552  }
553  }
554 
555  return errorCode;
556 }
557 
558 //==========================================================================================================================================
559 //==========================================================================================================================================
560 oC_ErrorCode_t oC_Tcp_Connection_Disconnect( oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
561 {
562  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
563  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
564 
565  if(
566  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
567  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
568  && ErrorCondition( IsConnected(Connection) , oC_ErrorCode_NotConnected )
569  )
570  {
571  tcplog( oC_LogType_Track, "%s: Sending disconnect packets...", Connection->Name );
572 
573  Connection->State = State_Disconnecting;
574 
575  if(
576  ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_FIN_ACK, gettimeout(endTimestamp)) )
577  && ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_ACK , gettimeout(endTimestamp)) )
578  )
579  {
580  errorCode = oC_ErrorCode_None;
581  }
582  }
583 
584  return errorCode;
585 }
586 
587 //==========================================================================================================================================
588 //==========================================================================================================================================
589 oC_ErrorCode_t oC_Tcp_Connection_WaitForConnection ( oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
590 {
591  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
592 
593  if(
594  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
595  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
596  && ErrorCondition( !IsConnected(Connection) , oC_ErrorCode_AlreadyConnected )
597  )
598  {
599  Connection->State = State_WaitForSyn;
600 
601  if(
602  ErrorCode( WaitForPredefinedPacket( Connection, PredefinedPacket_SYN, Timeout ))
603  )
604  {
605  Connection->State = State_NeedsToAccept;
606  errorCode = oC_ErrorCode_None;
607  }
608  }
609 
610  return errorCode;
611 }
612 
613 //==========================================================================================================================================
614 //==========================================================================================================================================
615 oC_ErrorCode_t oC_Tcp_Connection_Accept( oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
616 {
617  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
618  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
619 
620  if(
621  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
622  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
623  && ErrorCondition( Connection->State == State_NeedsToAccept , oC_ErrorCode_ConnectionNotRequested )
624  )
625  {
626  while(ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_SYN_ACK, gettimeout(endTimestamp)) ))
627  {
628  if(ErrorCode( WaitForPredefinedPacket(Connection, PredefinedPacket_ACK, Connection->ConfirmationTimeout) ))
629  {
630  tcplog( oC_LogType_Info, "%s: Connection has been accepted", Connection->Name );
631  Connection->State = State_Established;
632  errorCode = oC_ErrorCode_None;
633  break;
634  }
635  else if(errorCode != oC_ErrorCode_Timeout)
636  {
637  Connection->NextSequenceNumberToReceive = Connection->RemoteInitialSequenceNumber + 1;
638  Connection->NextSequenceNumberToSend = Connection->InitialSequenceNumber;
639  break;
640  }
641  }
642  }
643 
644  return errorCode;
645 }
646 
647 //==========================================================================================================================================
648 //==========================================================================================================================================
649 oC_ErrorCode_t oC_Tcp_Connection_Reject( oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
650 {
651  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
652  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
653 
654  if(
655  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
656  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
657  && ErrorCondition( Connection->State == State_NeedsToAccept , oC_ErrorCode_ConnectionNotRequested )
658  )
659  {
660  if( ErrorCode( SendPredefinedPacket(Connection, PredefinedPacket_SYN_RST, gettimeout(endTimestamp)) ) )
661  {
662  Connection->State = State_NotConnected;
663  errorCode = oC_ErrorCode_None;
664  }
665  }
666 
667  return errorCode;
668 }
669 
670 //==========================================================================================================================================
671 //==========================================================================================================================================
672 oC_ErrorCode_t oC_Tcp_Connection_ReadRemote( oC_Tcp_Connection_t Connection , oC_Net_Address_t * outAddress )
673 {
674  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
675 
676  if(
677  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
678  && ErrorCondition( IsConnected(Connection) , oC_ErrorCode_NotConnected )
679  && ErrorCondition( isram(outAddress) , oC_ErrorCode_OutputAddressNotInRAM )
680  )
681  {
682  memcpy(outAddress, &Connection->RemoteAddress, sizeof(*outAddress));
683  errorCode = oC_ErrorCode_None;
684  }
685 
686  return errorCode;
687 }
688 
689 //==========================================================================================================================================
690 //==========================================================================================================================================
691 oC_ErrorCode_t oC_Tcp_Connection_ReadLocal( oC_Tcp_Connection_t Connection , oC_Net_Address_t * outAddress )
692 {
693  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
694 
695  if(
696  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
697  && ErrorCondition( IsConnected(Connection) , oC_ErrorCode_NotConnected )
698  && ErrorCondition( isram(outAddress) , oC_ErrorCode_OutputAddressNotInRAM )
699  )
700  {
701  memcpy(outAddress, &Connection->LocalAddress, sizeof(*outAddress));
702  errorCode = oC_ErrorCode_None;
703  }
704 
705  return errorCode;
706 }
707 
708 //==========================================================================================================================================
709 //==========================================================================================================================================
710 oC_ErrorCode_t oC_Tcp_Connection_Send( oC_Tcp_Connection_t Connection , const void * Buffer , oC_MemorySize_t Size, oC_Time_t Timeout )
711 {
712  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
713 
714  if(
715  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
716  && ErrorCondition( isaddresscorrect(Buffer) , oC_ErrorCode_WrongAddress )
717  && ErrorCondition( Size > 0 , oC_ErrorCode_SizeNotCorrect )
718  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
719  && ErrorCondition( IsConnected(Connection) , oC_ErrorCode_NotConnected )
720  )
721  {
722  Segment_t segment = {
723  .ConstBuffer = Buffer ,
724  .Size = Size
725  };
726  errorCode = SendSegment(Connection,&segment,Timeout);
727  }
728 
729  return errorCode;
730 }
731 
732 //==========================================================================================================================================
733 //==========================================================================================================================================
734 oC_ErrorCode_t oC_Tcp_Connection_Receive( oC_Tcp_Connection_t Connection, void * outBuffer, oC_MemorySize_t Size , oC_Time_t Timeout )
735 {
736  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
737  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
738 
739  if(
740  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
741  && ErrorCondition( isram(outBuffer) , oC_ErrorCode_OutputAddressNotInRAM )
742  && ErrorCondition( Size > 0 , oC_ErrorCode_SizeNotCorrect )
743  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
744  && ErrorCondition( IsConnected(Connection) , oC_ErrorCode_NotConnected )
745  )
746  {
747  if( ErrorCondition( oC_Mutex_Take( Connection->ReadyForReceivingMutex, gettimeout(endTimestamp) ), oC_ErrorCode_Timeout ) )
748  {
749  oC_MemorySize_t segmentSize = 0;
750 
751  if( ErrorCondition( oC_Queue_Get(Connection->ReceiveQueue,&segmentSize,sizeof(oC_MemorySize_t), gettimeout(endTimestamp)), oC_ErrorCode_Timeout ) )
752  {
753  oC_MemorySize_t sizeToCopy = oC_MIN(Size,segmentSize);
754  oC_MemorySize_t sizeToDrop = segmentSize - sizeToCopy;
755 
756  if(
757  ErrorCondition( oC_Queue_Get(Connection->ReceiveQueue,outBuffer,sizeToCopy,gettimeout(endTimestamp)) , oC_ErrorCode_Timeout )
758  && ErrorCondition( sizeToDrop == 0 || oC_Queue_Get(Connection->ReceiveQueue,NULL ,sizeToDrop,gettimeout(endTimestamp)) , oC_ErrorCode_Timeout )
759  )
760  {
761  if(sizeToDrop > 0)
762  {
763  tcplog(oC_LogType_Warning, "%s: Output buffer is too small. Dropping %d bytes", Connection->Name, sizeToDrop);
764  }
765 
766  tcplog(oC_LogType_Track, "%s: %d bytes received", Connection->Name, sizeToCopy);
767  errorCode = oC_ErrorCode_None;
768  }
769  }
770  oC_Mutex_Give( Connection->ReadyForReceivingMutex );
771  }
772  }
773 
774  return errorCode;
775 }
776 
777 #undef _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
778 
784 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
785 
786 //==========================================================================================================================================
790 //==========================================================================================================================================
791 static oC_ErrorCode_t PreparePacketToSend( oC_Tcp_Connection_t Connection, Packet_t Packet, const PacketFlags_t * Flags, const uint8_t * Data, oC_MemorySize_t * Size )
792 {
793  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
794 
795  if(
796  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
797  && ErrorCondition( isram(Packet) , oC_ErrorCode_AddressNotInRam )
798  )
799  {
801 
802  oC_Net_Packet_SetAddress( &Packet->Packet, &Connection->LocalAddress, &Connection->RemoteAddress );
803 
804  if( ErrorCondition( header != NULL, oC_ErrorCode_PacketNotCorrect ) )
805  {
806  oC_MemorySize_t localWindowSize = Connection->SegmentToReceive.Size - Connection->SegmentToReceive.ReceivedBytes;
807  header->SourcePort = Connection->LocalAddress.Port;
808  header->DestinationPort = Connection->RemoteAddress.Port;
809  header->SequenceNumber = Connection->NextSequenceNumberToSend;
810  header->AcknowledgmentNumber = Connection->NextSequenceNumberToReceive;
811  header->DataOffset = Flags->DataOffset;
812  header->Reserved = 0;
813  header->Flags = Flags->HighByte;
814  header->NS = Flags->NS;
815  header->WindowSize = localWindowSize >> Connection->LocalWindowScale;
816  header->UrgentPointer = 0;
817 
818  if(Data != NULL && Size != NULL && (*Size) > 0)
819  {
820  oC_IntMan_EnterCriticalSection();
821  uint16_t sizeToSend = oC_MIN(Connection->PacketSize,*Size);
822  oC_MemorySize_t leftBytesToSend = 0;
823 
824  sizeToSend = oC_MIN(sizeToSend,Connection->RemoteWindowSize);
825  leftBytesToSend = *Size - sizeToSend;
826 
827  oC_Tcp_Packet_SetData(Packet,Data,sizeToSend);
828 
829  *Size = sizeToSend;
830 
831  if(leftBytesToSend == 0)
832  {
833  header->PSH = 1;
834  }
835  else
836  {
837  header->PSH = 0;
838  }
839 
840  oC_IntMan_ExitCriticalSection();
841  }
842  else
843  {
844  oC_Tcp_Packet_SetSize(Packet,0);
845  }
846 
847  header->Checksum = oC_Tcp_Packet_CalculateChecksum(Packet);
848  errorCode = oC_ErrorCode_None;
849  }
850  }
851 
852  return errorCode;
853 }
854 
855 //==========================================================================================================================================
859 //==========================================================================================================================================
860 static oC_ErrorCode_t SendPacket( oC_Tcp_Connection_t Connection, Packet_t Packet, oC_Time_t Timeout )
861 {
862  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
863  uint16_t dataSize = oC_Tcp_Packet_GetDataSize(Packet);
864  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
865 
866  while( dataSize > Connection->RemoteWindowSize )
867  {
868  if(!oC_Event_WaitForState(Connection->RemoteWindowSizeChangedEvent,
869  Connection->RemoteWindowSize,
870  oC_Event_StateMask_DifferentThan,
871  gettimeout(endTimestamp)
872  )
873  )
874  {
875  break;
876  }
877  }
878  if(
879  ErrorCondition( dataSize <= Connection->RemoteWindowSize , oC_ErrorCode_NoSpaceOnRemoteServer )
880  && ErrorCondition( oC_Tcp_Packet_ConvertToNetworkEndianess(Packet) , oC_ErrorCode_CannotConvertHeaderEndianess )
881  && ErrorCode ( oC_NetifMan_SendPacket( &Connection->RemoteAddress, &Packet->Packet, gettimeout(endTimestamp), NULL) )
882  && ErrorCondition( oC_Tcp_Packet_ConvertFromNetworkEndianess(Packet) , oC_ErrorCode_CannotConvertHeaderEndianess )
883  )
884  {
885  oC_IntMan_EnterCriticalSection();
886 
887  Connection->NextSequenceNumberToSend += dataSize;
888  Connection->RemoteWindowSize -= dataSize;
889 
890  tcplog( oC_LogType_Track, "%s: Packet SEQ 0x%08X with %d bytes of data has been send", Connection->Name, Packet->IPv4.TcpHeader.SequenceNumber , dataSize);
891 
892  errorCode = oC_ErrorCode_None;
893 
894  oC_IntMan_ExitCriticalSection();
895  }
896 
897  return errorCode;
898 }
899 
900 //==========================================================================================================================================
904 //==========================================================================================================================================
905 static oC_ErrorCode_t PrepareAndSendPacket( oC_Tcp_Connection_t Connection, Packet_t Packet, const PacketFlags_t * Flags, const uint8_t * Data, oC_MemorySize_t * Size , uint32_t * outSequenceNumber , oC_Time_t Timeout )
906 {
907  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
908  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
909 
910  if(
911  ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
912  && ErrorCondition( oC_Mutex_Take(Connection->ReadyForSendingMutex,gettimeout(endTimestamp)) , oC_ErrorCode_Timeout )
913  )
914  {
915  if(
916  ErrorCode( PreparePacketToSend( Connection, Packet, Flags, Data, Size ) )
917  && ErrorCode( SendPacket( Connection, Packet, gettimeout(endTimestamp) ) )
918  )
919  {
920  Connection->NextSequenceNumberToSend += Flags->AddToSequence;
921  if(outSequenceNumber != NULL)
922  {
923  *outSequenceNumber = Connection->NextSequenceNumberToSend;
924  }
925  errorCode = oC_ErrorCode_None;
926  }
927  oC_Mutex_Give(Connection->ReadyForSendingMutex);
928  }
929 
930  return errorCode;
931 }
932 
933 //==========================================================================================================================================
937 //==========================================================================================================================================
938 static bool PacketFilterFunction( oC_Net_Packet_t * ReceivedPacket , const void * Parameter , oC_Netif_t Netif )
939 {
940  bool packetForUs = false;
942  oC_Tcp_Connection_t connection = (oC_Tcp_Connection_t)Parameter;
943 
944  if( header != NULL )
945  {
946  if(connection->State == State_WaitForSyn)
947  {
948  packetForUs = header->NetworkOrder.SYN == 1 && header->NetworkOrder.ACK == 0;
949  }
950  else if(header->NetworkOrder.ACK == 1 && header->NetworkOrder.SYN == 0)
951  {
952  uint32_t sequenceNumber = oC_Net_ConvertUint32FromNetworkEndianess(header->SequenceNumber);
953 
954  packetForUs = sequenceNumber == connection->NextSequenceNumberToReceive;
955  }
956  }
957 
958  return packetForUs;
959 }
960 
961 //==========================================================================================================================================
965 //==========================================================================================================================================
966 static oC_ErrorCode_t ReceivePacket( oC_Tcp_Connection_t Connection, Packet_t Packet, oC_Time_t Timeout )
967 {
968  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
969  oC_Net_Packet_t * localPacket = (oC_Net_Packet_t*)Packet;
970  if(
971  ErrorCode ( oC_NetifMan_ReceivePacket(&Connection->RemoteAddress, localPacket , Timeout, NULL, PacketFilterFunction, Connection) )
972  && ErrorCondition( oC_Tcp_Packet_ConvertFromNetworkEndianess((Packet_t)localPacket) , oC_ErrorCode_CannotConvertHeaderEndianess )
973  )
974  {
975  errorCode = oC_ErrorCode_None;
976  }
977 
978  return errorCode;
979 }
980 
981 //==========================================================================================================================================
985 //==========================================================================================================================================
986 static oC_ErrorCode_t SendPredefinedPacket( oC_Tcp_Connection_t Connection , PredefinedPacket_t PredefinedPacket , oC_Time_t Timeout )
987 {
988  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
989 
990  oC_STATIC_ASSERT( sizeof(PredefinedPacketFlags) <= (sizeof(PacketFlags_t) * 10),
991  "Size of 'PredefinedPacketFlags' array is too big! (Have you changed the PredefinedPacket_t definition? - you should not do it!)" );
992 
993  if(
994  ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
995  && ErrorCondition( PredefinedPacket < PredefinedPacket_NumberOfElements , oC_ErrorCode_InternalDataAreDamaged )
996  )
997  {
998  errorCode = PrepareAndSendPacket(Connection,Connection->PacketToSend, &PredefinedPacketFlags[PredefinedPacket], NULL, NULL, NULL, Timeout);
999  }
1000 
1001  return errorCode;
1002 }
1003 
1004 //==========================================================================================================================================
1008 //==========================================================================================================================================
1009 static oC_ErrorCode_t WaitForPredefinedPacket( oC_Tcp_Connection_t Connection , PredefinedPacket_t PredefinedPacket , oC_Time_t Timeout )
1010 {
1011  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1012  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
1013 
1014  if(
1015  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
1016  && ErrorCondition( PredefinedPacket < PredefinedPacket_NumberOfElements , oC_ErrorCode_InternalDataAreDamaged )
1017  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
1018  )
1019  {
1020  while( ErrorCondition(oC_Semaphore_Take(Connection->NewPacketReceivedSemaphore,gettimeout(endTimestamp)), oC_ErrorCode_Timeout) )
1021  {
1022  if(oC_Bits_AreBitsSetU8( Connection->ReceivedPacketFlags.HighByte ,PredefinedPacketFlags[PredefinedPacket].HighByte ))
1023  {
1024  Connection->NextSequenceNumberToReceive += PredefinedPacketFlags[PredefinedPacket].AddToSequence;
1025  errorCode = oC_ErrorCode_None;
1026  break;
1027  }
1028  }
1029  }
1030 
1031  return errorCode;
1032 }
1033 
1034 //==========================================================================================================================================
1038 //==========================================================================================================================================
1039 static oC_ErrorCode_t WaitForAcknowledge( oC_Tcp_Connection_t Connection, uint32_t AcknowledgeNumber, oC_Time_t Timeout )
1040 {
1041  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1042  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
1043  if(
1044  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
1045  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
1046  )
1047  {
1048  if( ErrorCondition(oC_Event_WaitForValue(Connection->AcknowledgeReceivedEvent, AcknowledgeNumber,oC_Event_CompareType_GreaterOrEqual,gettimeout(endTimestamp)), oC_ErrorCode_Timeout) )
1049  {
1050  errorCode = oC_ErrorCode_None;
1051  }
1052  }
1053 
1054  return errorCode;
1055 }
1056 
1057 //==========================================================================================================================================
1061 //==========================================================================================================================================
1062 static oC_ErrorCode_t ReadConnectionDataFromPacket( oC_Tcp_Connection_t Connection , Packet_t Packet )
1063 {
1064  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1065 
1066  if(
1067  ErrorCondition( IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
1068  && ErrorCondition( isram(Packet) , oC_ErrorCode_AddressNotInRam )
1069  )
1070  {
1071  uint8_t optionSize = sizeof(Connection->RemoteWindowScale);
1072  oC_DefaultString_t tempString = {0};
1073  oC_Tcp_Packet_ReadOption(Packet,oC_Tcp_OptionKind_WindowScale, &Connection->RemoteWindowScale, &optionSize);
1074 
1075  if(oC_Net_Packet_GetType(&Packet->Packet) == oC_Net_PacketType_IPv4)
1076  {
1077  /* IP Header */
1078  Connection->LocalAddress.Type = oC_Net_AddressType_IPv4;
1079  Connection->RemoteAddress.Type = oC_Net_AddressType_IPv4;
1080  Connection->LocalAddress.IPv4 = Packet->IPv4.IpHeader.DestinationIp;
1081  Connection->RemoteAddress.IPv4 = Packet->IPv4.IpHeader.SourceIp;
1082 
1083  /* TCP Header */
1084  Connection->RemoteAddress.Port = Packet->IPv4.TcpHeader.SourcePort;
1085  Connection->LocalAddress.Port = Packet->IPv4.TcpHeader.DestinationPort;
1086  Connection->NextSequenceNumberToReceive = Packet->IPv4.TcpHeader.SequenceNumber;
1087  Connection->RemoteWindowSize = Packet->IPv4.TcpHeader.WindowSize << Connection->RemoteWindowScale;
1088  Connection->RemoteInitialSequenceNumber = Packet->IPv4.TcpHeader.SequenceNumber;
1089 
1090  Connection->ReceivedPacketFlags.DataOffset = Packet->IPv4.TcpHeader.DataOffset;
1091  Connection->ReceivedPacketFlags.NS = Packet->IPv4.TcpHeader.NS;
1092  Connection->ReceivedPacketFlags.HighByte = Packet->IPv4.TcpHeader.Flags;
1093 
1094  oC_Net_AddressToString(&Connection->RemoteAddress,tempString,sizeof(tempString));
1095  sprintf(Connection->Name, "%s:%x", tempString, Connection->InitialSequenceNumber);
1096 
1097  errorCode = oC_ErrorCode_None;
1098  }
1099  else if(oC_Net_Packet_GetType(&Packet->Packet) == oC_Net_PacketType_IPv6)
1100  {
1101  Connection->LocalAddress.Type = oC_Net_AddressType_IPv6;
1102  Connection->RemoteAddress.Type = oC_Net_AddressType_IPv6;
1103 
1104  errorCode = oC_ErrorCode_NotImplemented;
1105  }
1106  else
1107  {
1108  errorCode = oC_ErrorCode_PacketNotCorrect;
1109  }
1110  }
1111 
1112  return errorCode;
1113 }
1114 
1115 //==========================================================================================================================================
1119 //==========================================================================================================================================
1120 static oC_ErrorCode_t SendSegment( oC_Tcp_Connection_t Connection, Segment_t * Segment, oC_Time_t Timeout )
1121 {
1122  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1123  oC_Timestamp_t endTimestamp = gettimestamp() + Timeout;
1124  uint8_t * dataToSend = NULL;
1125  oC_MemorySize_t dataToSendSize = 0;
1126  uint32_t sequenceNumberToConfirm = 0;
1127 
1128  if( ErrorCondition( oC_Mutex_Take(Connection->SendingSegmentMutex, gettimeout(endTimestamp)), oC_ErrorCode_Timeout ) )
1129  {
1130  Segment->ConfirmedBytes = 0;
1131  Segment->SentBytes = 0;
1132 
1133  tcplog( oC_LogType_Track, "%s: The thread %s has entered to the function", Connection->Name, oC_Thread_GetName(getcurthread()) );
1134 
1135  while(gettimestamp() <= endTimestamp)
1136  {
1137  dataToSend = &Segment->Buffer[Segment->SentBytes];
1138  dataToSendSize = Segment->Size - Segment->SentBytes;
1139  errorCode = PrepareAndSendPacket(Connection,Connection->PacketToSend,&PredefinedPacketFlags[PredefinedPacket_ACK],dataToSend,&dataToSendSize,&sequenceNumberToConfirm,gettimeout(endTimestamp));
1140 
1141  if(oC_ErrorOccur(errorCode))
1142  {
1143  tcplog( oC_LogType_Error, "%s: Cannot send packet - %s", Connection->Name, oC_GetErrorString(errorCode) );
1144  break;
1145  }
1146 
1147  tcplog( oC_LogType_Track, "%s: Waiting for acknowledge of SEQ 0x%08X", Connection->Name , sequenceNumberToConfirm);
1148 
1149  if( ErrorCode( WaitForAcknowledge(Connection, sequenceNumberToConfirm, Connection->ConfirmationTimeout) ) )
1150  {
1151  tcplog( oC_LogType_GoodNews, "%s: SEQ 0x%08X has beeen confirmed", Connection->Name, sequenceNumberToConfirm );
1152  Segment->SentBytes += dataToSendSize;
1153  Connection->SentBytesFromLastMeasure += dataToSendSize;
1154 
1155  if(Segment->SentBytes >= Segment->Size)
1156  {
1157  errorCode = oC_ErrorCode_None;
1158  break;
1159  }
1160  }
1161  else
1162  {
1163  tcplog( oC_LogType_Error, "%s: Packet SEQ 0x%08X not confirmed, sending once again", Connection->Name, Connection->NextSequenceNumberToSend );
1164  Connection->NextSequenceNumberToSend = Connection->LastConfirmedSequenceNumber;
1165  if(errorCode != oC_ErrorCode_Timeout)
1166  {
1167  break;
1168  }
1169  }
1170  }
1171 
1172  tcplog( oC_LogType_Track, "%s: The thread %s has exit from the function", Connection->Name, oC_Thread_GetName(getcurthread()) );
1173 
1174  oC_Mutex_Give(Connection->SendingSegmentMutex);
1175  }
1176 
1177  return errorCode;
1178 }
1179 
1180 //==========================================================================================================================================
1184 //==========================================================================================================================================
1186 {
1187  oC_Timestamp_t endTimestamp = gettimestamp() + Connection->SaveSegmentTimeout;
1188  void * buffer = Connection->SegmentToReceive.Buffer;
1189  oC_MemorySize_t size = Connection->SegmentToReceive.ReceivedBytes;
1190  oC_Queue_t queue = Connection->ReceiveQueue;
1191 
1192 
1193  if(
1194  oC_SaveIfFalse("Size of segment", oC_Queue_Put(queue, &size , sizeof(size), gettimeout(endTimestamp)), oC_ErrorCode_Timeout )
1195  && oC_SaveIfFalse("Data of segment", oC_Queue_Put(queue, buffer, size , gettimeout(endTimestamp)), oC_ErrorCode_Timeout )
1196  )
1197  {
1198  tcplog( oC_LogType_GoodNews, "%s: %d bytes of data have been put to the queue", Connection->Name, size );
1199  }
1200  else
1201  {
1202  tcplog( oC_LogType_Error, "%s: Cannot put %d bytes of data into the queue", Connection->Name, size );
1203  }
1204  Connection->SegmentToReceive.ReceivedBytes = 0;
1205  Connection->SegmentToReceive.ConfirmedBytes = 0;
1206 }
1207 
1208 //==========================================================================================================================================
1212 //==========================================================================================================================================
1213 static void AnalyzeReceivedPacket( oC_Tcp_Connection_t Connection , Packet_t Packet )
1214 {
1215  oC_IntMan_EnterCriticalSection();
1216 
1218 
1219  if(oC_SaveIfFalse("Header", header != NULL, oC_ErrorCode_PacketNotCorrect))
1220  {
1221  uint16_t receivedDataSize = oC_Tcp_Packet_GetDataSize(Packet);
1222  uint8_t * data = receivedDataSize > 0 ? oC_Tcp_Packet_GetDataReference(Packet) : NULL;
1223 
1224  if(receivedDataSize > 0 && data != NULL)
1225  {
1226  tcplog( oC_LogType_Track, "%s: %d bytes of data has been received '%s'", Connection->Name, receivedDataSize, (char*)data );
1227  if(oC_SaveIfFalse("Receive buffer is full", Connection->SegmentToReceive.ReceivedBytes < Connection->SegmentToReceive.Size, oC_ErrorCode_NoSpaceAvailable))
1228  {
1229  uint8_t * buffer = &Connection->SegmentToReceive.Buffer[ Connection->SegmentToReceive.ReceivedBytes ];
1230  oC_MemorySize_t leftSize = Connection->SegmentToReceive.Size - Connection->SegmentToReceive.ReceivedBytes;
1231  oC_MemorySize_t copySize = oC_MIN(leftSize,receivedDataSize);
1232 
1233  memcpy(buffer, data, copySize);
1234 
1235  Connection->SegmentToReceive.ConfirmedBytes += copySize;
1236  Connection->SegmentToReceive.ReceivedBytes += receivedDataSize;
1237  Connection->AcknowledgePacketShouldBeSend = true;
1238  }
1239 
1240  if(header->PSH == 1)
1241  {
1242  SaveReceivedSegmentInQueue(Connection);
1243  }
1244  }
1245  else
1246  {
1247  tcplog( oC_LogType_Track, "%s: ACK has been received 0x%08X (without DATA)", Connection->Name, header->AcknowledgmentNumber );
1248  }
1249 
1250  Connection->LastConfirmedSequenceNumber = header->AcknowledgmentNumber;
1251  Connection->NextSequenceNumberToReceive = header->SequenceNumber + receivedDataSize;
1252  Connection->RemoteWindowSize = header->WindowSize << Connection->RemoteWindowScale;
1253  Connection->ReceivedPacketFlags.DataOffset = header->DataOffset;
1254  Connection->ReceivedPacketFlags.NS = header->NS;
1255  Connection->ReceivedPacketFlags.HighByte = header->Flags;
1256 
1257  if(header->SYN == 1 && header->ACK == 0)
1258  {
1259  ReadConnectionDataFromPacket(Connection,Packet);
1260  }
1261  if((header->FIN == 1 || header->RST == 1) && Connection->State != State_Disconnecting)
1262  {
1263  Connection->FinishConnectionPacketShouldBeSend = true;
1264  Connection->State = State_Disconnecting;
1265  }
1266 
1267  oC_Event_SetState(Connection->RemoteWindowSizeChangedEvent, Connection->RemoteWindowSize);
1268  oC_Event_SetState(Connection->AcknowledgeReceivedEvent , Connection->LastConfirmedSequenceNumber);
1269  oC_Semaphore_Give(Connection->NewPacketReceivedSemaphore);
1270  }
1271  oC_IntMan_ExitCriticalSection();
1272 }
1273 
1274 //==========================================================================================================================================
1278 //==========================================================================================================================================
1279 static void CalculateBaudRate( oC_Tcp_Connection_t Connection )
1280 {
1281  oC_Timestamp_t currentTimestamp = gettimestamp();
1282  oC_Time_t measureTime = currentTimestamp - Connection->LastMeasureTimestamp;
1283 
1284  if(measureTime >= s(1))
1285  {
1286  Connection->BaudRate = (oC_BaudRate_t)(((oC_Time_t)Connection->SentBytesFromLastMeasure) / measureTime);
1287  Connection->LastMeasureTimestamp = currentTimestamp;
1288  Connection->SentBytesFromLastMeasure = 0;
1289 
1290  tcplog(oC_LogType_Track, "%s: Connection baud rate = %u B", Connection->Name, Connection->BaudRate);
1291 
1292  }
1293 }
1294 
1295 //==========================================================================================================================================
1299 //==========================================================================================================================================
1300 static void ReceiveThread( oC_Tcp_Connection_t Connection )
1301 {
1302  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
1303 
1304  while( oC_Tcp_Connection_IsCorrect(Connection) )
1305  {
1306  if( ErrorCode( ReceivePacket( Connection, Connection->LastReceivedPacket, Connection->ReceiveTimeout)) )
1307  {
1308  Connection->ExpirationTimestamp = gettimestamp() + Connection->ExpirationTimeout;
1309 
1310  AnalyzeReceivedPacket(Connection,Connection->LastReceivedPacket);
1311  CalculateBaudRate(Connection);
1312 
1313  if(Connection->FinishConnectionPacketShouldBeSend)
1314  {
1315  break;
1316  }
1317  if(Connection->AcknowledgePacketShouldBeSend)
1318  {
1319  oC_SaveIfErrorOccur("Cannot send ACK", SendPredefinedPacket(Connection, PredefinedPacket_ACK, Connection->SendingAcknowledgeTimeout));
1320  Connection->AcknowledgePacketShouldBeSend = false;
1321  }
1322  }
1323  else if(errorCode != oC_ErrorCode_Timeout)
1324  {
1325  oC_SaveError("Cannot receive packet", errorCode);
1326  tcplog( oC_LogType_Error, "%s: Cannot receive packet - %s", Connection->Name, oC_GetErrorString(errorCode) );
1327  break;
1328  }
1329  else if(Connection->State != State_WaitForSyn)
1330  {
1331  if(gettimestamp() >= Connection->ExpirationTimestamp)
1332  {
1333  tcplog( oC_LogType_Warning, "Connection '%s' has expired, closing...", Connection->Name );
1334  break;
1335  }
1336  else if(Connection->State == State_Disconnecting)
1337  {
1338  tcplog( oC_LogType_Track, "%s: Detect disconnect request - disconnecting...", Connection->Name );
1339  break;
1340  }
1341  }
1342  }
1343 
1344  oC_SaveIfErrorOccur( "Sending FIN ACK" , SendPredefinedPacket(Connection, PredefinedPacket_FIN_ACK, Connection->SendingAcknowledgeTimeout));
1345  oC_SaveIfErrorOccur( "Sending ACK" , SendPredefinedPacket(Connection, PredefinedPacket_ACK , Connection->SendingAcknowledgeTimeout));
1346 
1347  Connection->State = State_NotConnected;
1348 
1349  if(isaddresscorrect(Connection->ConnectionFinishedFunction))
1350  {
1351  Connection->ConnectionFinishedFunction( Connection, Connection->ConnectionFinishedParameter );
1352  }
1353 }
1354 
1355 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
1356 
1357 
Packet in type IPv4.
Definition: oc_net.h:177
static bool oC_Net_AreAddressesTheSame(const oC_Net_Address_t *Address1, const oC_Net_Address_t *Address2)
returns true if both pointers stores the same address
Definition: oc_net.h:1033
static oC_ErrorCode_t WaitForAcknowledge(oC_Tcp_Connection_t Connection, uint32_t AcknowledgeNumber, oC_Time_t Timeout)
waits for the acknowledge of the given packet
bool oC_Event_WaitForState(oC_Event_t Event, oC_Event_State_t State, oC_Event_StateMask_t StateMask, oC_Time_t Timeout)
Definition: oc_event.c:245
Basic math operations.
#define s(time)
Number of s.
Definition: oc_cfg.h:133
uint64_t HighPart
High 8 bytes of the IPv6 address.
Definition: oc_net.h:145
oC_Net_Protocol_t Protocol
IP Protocol.
Definition: oc_net.h:449
bool oC_Tcp_Packet_ConvertToNetworkEndianess(oC_Tcp_Packet_t *Packet)
converts packet to network endianess
stores TCP connection data
The file with interface for thread managing.
static oC_ErrorCode_t ReceivePacket(oC_Tcp_Connection_t Connection, Packet_t Packet, oC_Time_t Timeout)
receives packet via TCP connection
static oC_ErrorCode_t SendPredefinedPacket(oC_Tcp_Connection_t Connection, PredefinedPacket_t PredefinedPacket, oC_Time_t Timeout)
simply sends one of standard (predefined) packets
identifier for allocations
Definition: oc_stdlib.h:159
bool oC_Tcp_Packet_ConvertFromNetworkEndianess(oC_Tcp_Packet_t *Packet)
converts packet from network endianess
oC_ErrorCode_t oC_NetifMan_ReceivePacket(const oC_Net_Address_t *Address, oC_Net_Packet_t *outPacket, oC_Time_t Timeout, oC_Netif_t *outNetif, oC_NetifMan_PacketFilterFunction_t FilterFunction, const void *Parameter)
receives packet from the network
Definition: oc_netifman.c:763
oC_Tcp_Connection_t oC_Tcp_Connection_New(const oC_Tcp_Connection_Config_t *Config)
allocates memory for a new TCP connection object
static void oC_Net_Packet_SetAddress(oC_Net_Packet_t *Packet, const oC_Net_Address_t *Source, const oC_Net_Address_t *Destination)
sets addresses in the packet
Definition: oc_net.h:1446
Packet in type IPv6.
Definition: oc_net.h:178
uint16_t oC_Tcp_Packet_CalculateChecksum(oC_Tcp_Packet_t *Packet)
calculates checksum for TCP packet
oC_Tcp_Packet_t * oC_Tcp_Packet_New(const oC_Net_Address_t *Source, const oC_Net_Address_t *Destination, uint16_t HeaderSize, const void *Data, uint16_t Size)
Allocates memory for a TCP packet.
Definition: oc_tcp_packet.c:98
Stores interface of netif manager module.
stores network address
Definition: oc_net.h:441
static bool oC_Bits_AreBitsSetU8(uint8_t BitMask, uint8_t BitsToCheck)
checks if all bits in field are set
Definition: oc_bits.h:850
static oC_ErrorCode_t PrepareAndSendPacket(oC_Tcp_Connection_t Connection, Packet_t Packet, const PacketFlags_t *Flags, const uint8_t *Data, oC_MemorySize_t *Size, uint32_t *outSequenceNumber, oC_Time_t Timeout)
prepares and sends TCP packet
static oC_Net_PacketType_t oC_Net_Packet_GetType(const oC_Net_Packet_t *Packet)
returns type of the packet
Definition: oc_net.h:1370
Transmission Control Protocol.
Definition: oc_net.h:159
struct Tcp_Connection_t * oC_Tcp_Connection_t
stores TCP connection data
Definition: oc_tcp.h:339
static void CalculateBaudRate(oC_Tcp_Connection_t Connection)
calculates current Baud Rate of TCP connection
static oC_ErrorCode_t WaitForPredefinedPacket(oC_Tcp_Connection_t Connection, PredefinedPacket_t PredefinedPacket, oC_Time_t Timeout)
waits for one of predefined packets
static oC_ErrorCode_t SendPacket(oC_Tcp_Connection_t Connection, Packet_t Packet, oC_Time_t Timeout)
sends packet via TCP connection
static void SaveReceivedSegmentInQueue(oC_Tcp_Connection_t Connection)
saves data from the queue
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
The file with interface for event module.
oC_Queue_t oC_Queue_New(Allocator_t Allocator, oC_MemorySize_t BufferSize)
allocates memory for a queue
Definition: oc_queue.c:89
stores network packet
Definition: oc_net.h:302
oC_Net_Ipv4_t IPv4
Address in IPv4 version.
Definition: oc_net.h:446
void oC_Tcp_Packet_SetSize(oC_Tcp_Packet_t *Packet, uint16_t Size)
sets size of the TCP packet
static oC_ErrorCode_t oC_Net_AddressToString(const oC_Net_Address_t *Address, char *outString, oC_MemorySize_t Size)
prints IP to the string
Definition: oc_net.h:807
static uint32_t oC_Net_ConvertUint32FromNetworkEndianess(uint32_t v)
converts uint32_t from network byte order
Definition: oc_net.h:590
The file with interface for interrupt manager.
stores TCP header
Definition: oc_tcp.h:348
Handles configuration of the Dynamic.
Special value for marks port as not filled.
Definition: oc_tcp.h:77
static oC_ErrorCode_t ReadConnectionDataFromPacket(oC_Tcp_Connection_t Connection, Packet_t Packet)
reads connection data from the given packet
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
oC_Net_Ipv6_t IPv6
Address in IPv6 version.
Definition: oc_net.h:447
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
Definition: oc_object.h:203
The file with interface for Queue module.
static bool oC_Net_IsAddressCorrect(const oC_Net_Address_t *Address)
returns true if the given address is correct
Definition: oc_net.h:918
The file with interface for mutex managing.
uint64_t LowPart
Low 8 bytes of the IPv6 address.
Definition: oc_net.h:144
IP address in version 4.
Definition: oc_net.h:429
oC_ErrorCode_t oC_Tcp_Packet_SetData(oC_Tcp_Packet_t *Packet, const void *Data, uint16_t Size)
sets data in the TCP packet
oC_Tcp_Header_t * oC_Tcp_Packet_GetHeaderReference(oC_Tcp_Packet_t *Packet)
returns TCP header reference
const char * oC_GetErrorString(oC_ErrorCode_t ErrorCode)
Definition: oc_errors.c:115
oC_ErrorCode_t oC_Tcp_Packet_ReadOption(oC_Tcp_Packet_t *Packet, oC_Tcp_OptionKind_t OptionKind, void *outData, uint8_t *Size)
reads option from the TCP packet
The file with interface for semaphores.
oC_ErrorCode_t oC_NetifMan_SendPacket(const oC_Net_Address_t *Address, oC_Net_Packet_t *Packet, oC_Time_t Timeout, oC_Netif_t *outNetif)
sends packet via active network interface
Definition: oc_netifman.c:689
void * oC_Tcp_Packet_GetDataReference(oC_Tcp_Packet_t *Packet)
returns pointer to the data inside the packet
uint16_t oC_Tcp_Packet_GetDataSize(oC_Tcp_Packet_t *Packet)
returns size of data section inside TCP packet
bool oC_Tcp_Packet_Delete(oC_Tcp_Packet_t **outPacket)
releases memory allocated for a packet
static void AnalyzeReceivedPacket(oC_Tcp_Connection_t Connection, Packet_t Packet)
analyzes received data
static oC_ErrorCode_t PreparePacketToSend(oC_Tcp_Connection_t Connection, Packet_t Packet, const PacketFlags_t *Flags, const uint8_t *Data, oC_MemorySize_t *Size)
initializes Packet to send via TCP connection
oC_Net_AddressType_t Type
Type of the address stored inside.
Definition: oc_net.h:443
IP address in version 6.
Definition: oc_net.h:430
static oC_ErrorCode_t SendSegment(oC_Tcp_Connection_t Connection, Segment_t *Segment, oC_Time_t Timeout)
sends data segment by using TCP connection
oC_Net_Port_t Port
Port of the address.
Definition: oc_net.h:450
static bool PacketFilterFunction(oC_Net_Packet_t *ReceivedPacket, const void *Parameter, oC_Netif_t Netif)
the function for filtering packets
The file with interface of kernel time module.
#define NULL
pointer to a zero
Definition: oc_null.h:37