Choco OS  V.0.16.9.0
Join to the chocolate world
oc_tcp_server.c
Go to the documentation of this file.
1 
27 #include <oc_tcp.h>
28 #include <oc_object.h>
29 #include <oc_stdio.h>
30 #include <oc_thread.h>
31 #include <oc_dynamic_config.h>
32 #include <oc_semaphore.h>
33 #include <oc_intman.h>
34 
40 #define _________________________________________TYPES_SECTION______________________________________________________________________________
41 
42 //==========================================================================================================================================
48 //==========================================================================================================================================
49 typedef struct
50 {
52  bool Handled;
54 
55 //==========================================================================================================================================
59 //==========================================================================================================================================
60 typedef oC_Tcp_ConnectionFinishedFunction_t ConnFinishedFunction_t;
61 
62 //==========================================================================================================================================
66 //==========================================================================================================================================
67 struct Server_t
68 {
75  char Name[30];
78  bool Running;
79  uint32_t MaxConnections;
81 };
82 
83 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
84 
90 #define _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
91 
92 static void ConnectionFinished ( oC_Tcp_Connection_t Connection , oC_Tcp_Server_t Server );
93 static void ServerThread ( oC_Tcp_Server_t Server );
94 
95 #undef _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
96 
102 #define _________________________________________INTERFACE_SECTION__________________________________________________________________________
103 
104 //==========================================================================================================================================
121 //==========================================================================================================================================
123 {
124  oC_Tcp_Server_t server = NULL;
125 
126  if(
127  oC_SaveIfFalse("TCP::Server::New " , isaddresscorrect(ListenAddress) , oC_ErrorCode_WrongAddress )
128  && oC_SaveIfFalse("TCP::Server::New " , oC_Net_IsAddressCorrect(ListenAddress) , oC_ErrorCode_IpAddressNotCorrect )
129  && oC_SaveIfFalse("TCP::Server::New " , ListenAddress->Port > 0 , oC_ErrorCode_PortNotCorrect )
130  && oC_SaveIfFalse("TCP::Server::New " , oC_Tcp_IsPortReserved(ListenAddress->Port) , oC_ErrorCode_PortNotReserved )
131  && oC_SaveIfFalse("TCP::Server::New " , oC_Tcp_IsPortReservedBy(ListenAddress->Port,getcurprocess()) , oC_ErrorCode_PortReservedByDifferentProcess )
132  && oC_SaveIfFalse("TCP::Server::New " , MaxConnections > 0 , oC_ErrorCode_MaximumValueNotCorrect )
133  )
134  {
135  server = malloc( sizeof(struct Server_t) + (sizeof(ConnectionSlot_t) * MaxConnections) , AllocationFlags_ZeroFill );
136 
137  if( oC_SaveIfFalse("TCP::Server::New ", server != NULL , oC_ErrorCode_AllocationError) )
138  {
139 
140  sprintf(server->Name, "TCP Server:%d/%d", ListenAddress->Port, MaxConnections);
141 
142  server->Thread = oC_Thread_New( 0, oC_DynamicConfig_GetValue(Tcp,StackSize), NULL, server->Name, (oC_Thread_Function_t)ServerThread, server );
143  server->NewConnectionSemaphore = oC_Semaphore_New( MaxConnections, 0 , getcurallocator(), AllocationFlags_ZeroFill );
144  server->FreeSlotsSemaphore = oC_Semaphore_New( MaxConnections, MaxConnections, getcurallocator(), AllocationFlags_ZeroFill );
145 
146  if(
147  oC_SaveIfFalse("TCP::Server::New ", server->Thread != NULL , oC_ErrorCode_CannotCreateThread )
148  && oC_SaveIfFalse("TCP::Server::New ", server->NewConnectionSemaphore!= NULL , oC_ErrorCode_AllocationError )
149  && oC_SaveIfFalse("TCP::Server::New ", server->FreeSlotsSemaphore!= NULL , oC_ErrorCode_AllocationError )
150  )
151  {
152  server->ObjectControl = oC_CountObjectControl( server, oC_ObjectId_TcpServer );
153  server->MaxConnections = MaxConnections;
154  server->Process = getcurprocess();
155  server->ConnectionConfig.RemoteAddress.Type = ListenAddress->Type;
156 
157  memcpy(&server->ConnectionConfig.LocalAddress, ListenAddress, sizeof(oC_Net_Address_t));
158 
159  server->ConnectionConfig.LocalWindowSize = oC_DynamicConfig_GetValue(Tcp,WindowSize);
160  server->ConnectionConfig.LocalWindowScale = oC_DynamicConfig_GetValue(Tcp,WindowScale);
161  server->ConnectionConfig.ConfirmationTimeout = oC_DynamicConfig_GetValue(Tcp,ConfirmationTimeout);
162  server->ConnectionConfig.ExpirationTimeout = oC_DynamicConfig_GetValue(Tcp,ExpirationTimeout);
163  server->ConnectionConfig.SendingAcknowledgeTimeout = oC_DynamicConfig_GetValue(Tcp,SendingAcknowledgeTimeout);
164  server->ConnectionConfig.ReadSegmentTimeout = oC_DynamicConfig_GetValue(Tcp,ReadSegmentTimeout);
165  server->ConnectionConfig.ReceiveTimeout = oC_DynamicConfig_GetValue(Tcp,ReceiveTimeout);
166  server->ConnectionConfig.PacketSize = oC_DynamicConfig_GetValue(Tcp,PacketSize);
167  server->ConnectionConfig.InitialAcknowledgeNumber = 0;
168  server->ConnectionConfig.InitialSequenceNumber = 0;
169  server->ConnectionConfig.ConnectionFinishedFunction = (oC_Tcp_ConnectionFinishedFunction_t)ConnectionFinished;
170  server->ConnectionConfig.ConnectionFinishedParameter= server;
171  }
172  else
173  {
174  oC_SaveIfFalse("TCP::Server::New Thread " , server->Thread == NULL || oC_Thread_Delete ( &server->Thread ) , oC_ErrorCode_ReleaseError );
175  oC_SaveIfFalse("TCP::Server::New Semaphore ", server->NewConnectionSemaphore == NULL || oC_Semaphore_Delete( &server->NewConnectionSemaphore,0) , oC_ErrorCode_ReleaseError );
176  free(server, AllocationFlags_Default);
177  server = NULL;
178  }
179  }
180  }
181 
182  return server;
183 }
184 
185 //==========================================================================================================================================
196 //==========================================================================================================================================
197 bool oC_Tcp_Server_Delete( oC_Tcp_Server_t * Server , oC_Time_t Timeout )
198 {
199  bool deleted = false;
200  oC_Timestamp_t endTimestamp = oC_KTime_GetTimestamp() + Timeout;
201 
202  if(
203  oC_SaveIfFalse("Server reference" , isram(Server) , oC_ErrorCode_AddressNotInRam )
204  && oC_SaveIfFalse("Server object" , oC_Tcp_Server_IsCorrect(*Server) , oC_ErrorCode_ObjectNotCorrect )
205  && oC_SaveIfFalse("Timeout" , Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
206  )
207  {
208  (*Server)->ObjectControl = 0;
209 
210  bool allConnectionsDeleted = true;
211  bool threadDeleted = false;
212  bool eventDeleted = false;
213  bool event2Deleted = false;
214 
215  for(uint32_t i = 0; i < (*Server)->MaxConnections; i++)
216  {
217  if((*Server)->Connections[i].Connection != NULL)
218  {
219  allConnectionsDeleted = oC_Tcp_Connection_Delete(&((*Server)->Connections[i].Connection), oC_KTime_CalculateTimeout(endTimestamp)) && allConnectionsDeleted;
220  }
221  }
222 
223  threadDeleted = oC_Thread_Delete(&(*Server)->Thread);
224  eventDeleted = oC_Semaphore_Delete(&(*Server)->NewConnectionSemaphore , AllocationFlags_Default);
225  event2Deleted = oC_Semaphore_Delete(&(*Server)->FreeSlotsSemaphore , AllocationFlags_Default);
226 
227  if(
228  oC_SaveIfFalse("Main object" , free( *Server, AllocationFlags_Default ) , oC_ErrorCode_ReleaseError )
229  && oC_SaveIfFalse("One of connections" , allConnectionsDeleted , oC_ErrorCode_CannotDeleteObject )
230  && oC_SaveIfFalse("Server Thread" , threadDeleted , oC_ErrorCode_CannotDeleteThread )
231  && oC_SaveIfFalse("New Connection Semaphore", eventDeleted , oC_ErrorCode_ReleaseError )
232  && oC_SaveIfFalse("Free Slot Semaphore" , event2Deleted , oC_ErrorCode_ReleaseError )
233  )
234  {
235  *Server = NULL;
236  deleted = true;
237  }
238  }
239 
240  return deleted;
241 }
242 
243 //==========================================================================================================================================
254 //==========================================================================================================================================
256 {
257  return isram(Server) && oC_CheckObjectControl( Server, oC_ObjectId_TcpServer, Server->ObjectControl);
258 }
259 
260 //==========================================================================================================================================
270 //==========================================================================================================================================
272 {
273  return oC_Tcp_Server_IsCorrect(Server) && Server->Running;
274 }
275 
276 //==========================================================================================================================================
299 //==========================================================================================================================================
301 {
302  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
303 
304  if(
305  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
306  && ErrorCondition( isaddresscorrect(Config) , oC_ErrorCode_WrongAddress )
307  && ErrorCondition( Config->ConfirmationTimeout > 0 , oC_ErrorCode_TimeNotCorrect )
308  && ErrorCondition( Config->LocalAddress.Port > 0 , oC_ErrorCode_PortNotCorrect )
309  && ErrorCondition( Config->LocalWindowSize > 0 , oC_ErrorCode_SizeNotCorrect )
310  && ErrorCondition( oC_Tcp_IsPortReserved( Config->LocalAddress.Port ) , oC_ErrorCode_PortNotReserved )
311  && ErrorCondition( oC_Tcp_IsPortReservedBy( Config->LocalAddress.Port, getcurprocess() ) , oC_ErrorCode_PortReservedByDifferentProcess )
312  )
313  {
314  memcpy(&Server->ConnectionConfig, Config, sizeof(oC_Tcp_Connection_Config_t));
315  errorCode = oC_ErrorCode_None;
316  }
317 
318  return errorCode;
319 }
320 
321 //==========================================================================================================================================
339 //==========================================================================================================================================
340 oC_ErrorCode_t oC_Tcp_Server_Run( oC_Tcp_Server_t Server )
341 {
342  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
343 
344  if(
345  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
346  && ErrorCondition( Server->Running == false , oC_ErrorCode_AlreadyRunning )
347  && ErrorCondition( oC_Thread_Run(Server->Thread) == true , oC_ErrorCode_CannotRunThread )
348  )
349  {
350  Server->Running = true;
351  errorCode = oC_ErrorCode_None;
352  }
353 
354  return errorCode;
355 }
356 
357 //==========================================================================================================================================
378 //==========================================================================================================================================
379 oC_ErrorCode_t oC_Tcp_Server_Stop( oC_Tcp_Server_t Server )
380 {
381  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
382 
383  if(
384  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
385  && ErrorCondition( Server->Running == true , oC_ErrorCode_NotRunning )
386  )
387  {
388  oC_Thread_t thread = oC_Thread_CloneWithNewStack(Server->Thread, oC_Thread_GetStackSize(Server->Thread));
389 
390  if( ErrorCondition( thread != NULL , oC_ErrorCode_AllocationError ) )
391  {
392  if(
393  ErrorCondition( oC_Thread_Cancel(&Server->Thread) , oC_ErrorCode_CannotDeleteThread )
394  )
395  {
396  Server->Running = false;
397  Server->Thread = thread;
398  errorCode = oC_ErrorCode_None;
399  }
400  else
401  {
402  oC_SaveIfFalse( "TCP::Server::Stop ", oC_Thread_Delete(&thread), oC_ErrorCode_ReleaseError );
403  }
404  }
405  }
406 
407  return errorCode;
408 }
409 
410 //==========================================================================================================================================
437 //==========================================================================================================================================
438 oC_ErrorCode_t oC_Tcp_Server_WaitForConnection( oC_Tcp_Server_t Server , oC_Tcp_Connection_t * outConnection , oC_Time_t Timeout )
439 {
440  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
441 
442  if(
443  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
444  && ErrorCondition( Server->Running == true , oC_ErrorCode_NotRunning )
445  && ErrorCondition( isram(outConnection) , oC_ErrorCode_OutputAddressNotInRAM )
446  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
447  && ErrorCondition( oC_Semaphore_TakeCounting( Server->NewConnectionSemaphore, 1, Timeout ) , oC_ErrorCode_Timeout )
448  )
449  {
450  oC_IntMan_EnterCriticalSection();
451 
452  errorCode = oC_ErrorCode_InternalDataAreDamaged;
453 
454  for(uint32_t i = 0; i < Server->MaxConnections ; i++)
455  {
456  if(Server->Connections[i].Connection != NULL && Server->Connections[i].Handled == false)
457  {
458  *outConnection = Server->Connections[i].Connection;
459  Server->Connections[i].Handled = true;
460  errorCode = oC_ErrorCode_None;
461  break;
462  }
463  }
464  oC_IntMan_ExitCriticalSection();
465  }
466 
467  return errorCode;
468 }
469 
470 //==========================================================================================================================================
481 //==========================================================================================================================================
483 {
484  bool contains = false;
485 
486  if(
487  oC_SaveIfFalse("TCP::Server::ContainsConnection - Server " , oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
488  && oC_SaveIfFalse("TCP::Server::ContainsConnection - Connection " , oC_Tcp_Connection_IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
489  )
490  {
491  for(uint32_t i = 0; i < Server->MaxConnections; i++)
492  {
493  if(Server->Connections[i].Connection != NULL)
494  {
495  if(Server->Connections[i].Connection == Connection || oC_Tcp_Connection_AreTheSame(Connection,Server->Connections[i].Connection))
496  {
497  contains = true;
498  break;
499  }
500  }
501  }
502  }
503 
504  return contains;
505 }
506 
507 //==========================================================================================================================================
538 //==========================================================================================================================================
539 oC_ErrorCode_t oC_Tcp_Server_AcceptConnection( oC_Tcp_Server_t Server , oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
540 {
541  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
542  oC_Timestamp_t endTimestamp = oC_KTime_GetTimestamp() + Timeout;
543 
544  if(
545  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
546  && ErrorCondition( oC_Tcp_Connection_IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
547  && ErrorCondition( Server->Running == true , oC_ErrorCode_NotRunning )
548  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
549  && ErrorCondition( oC_Tcp_Server_ContainsConnection(Server,Connection) , oC_ErrorCode_ConnectionFromDifferentServer )
550  )
551  {
552  if( ErrorCode( oC_Tcp_Connection_Accept( Connection, oC_KTime_CalculateTimeout(endTimestamp) ) ) )
553  {
554  errorCode = oC_ErrorCode_None;
555  }
556  else
557  {
558  oC_SaveIfErrorOccur ( "TCP::Server::Accept ", oC_Tcp_Server_RemoveConnection( Server, Connection ) );
559  oC_SaveIfFalse ( "TCP::Server::Accept ", oC_Tcp_Connection_Delete(&Connection, Timeout), oC_ErrorCode_ReleaseError );
560  }
561  }
562 
563  return errorCode;
564 }
565 
566 //==========================================================================================================================================
594 //==========================================================================================================================================
595 oC_ErrorCode_t oC_Tcp_Server_RejectConnection( oC_Tcp_Server_t Server , oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
596 {
597  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
598  oC_Timestamp_t endTimestamp = oC_KTime_GetTimestamp() + Timeout;
599 
600  if(
601  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
602  && ErrorCondition( oC_Tcp_Connection_IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
603  && ErrorCondition( Server->Running == true , oC_ErrorCode_NotRunning )
604  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
605  && ErrorCondition( oC_Tcp_Server_ContainsConnection(Server,Connection) , oC_ErrorCode_ConnectionFromDifferentServer )
606  )
607  {
608  if(
609  ErrorCode( oC_Tcp_Server_RemoveConnection( Server, Connection ) )
610  && ErrorCode( oC_Tcp_Connection_Reject( Connection, oC_KTime_CalculateTimeout(endTimestamp) ) )
611  && ErrorCondition( oC_Tcp_Connection_Delete( &Connection, oC_KTime_CalculateTimeout(endTimestamp) ) , oC_ErrorCode_ReleaseError )
612  )
613  {
614  errorCode = oC_ErrorCode_None;
615  }
616  else if(oC_Tcp_Connection_IsCorrect(Connection))
617  {
618  oC_SaveIfFalse("TCP::Server::Reject ", oC_Tcp_Connection_Delete(&Connection, Timeout), oC_ErrorCode_ReleaseError );
619  }
620  }
621 
622  return errorCode;
623 }
624 
625 //==========================================================================================================================================
645 //==========================================================================================================================================
646 oC_ErrorCode_t oC_Tcp_Server_AddConnection( oC_Tcp_Server_t Server , oC_Tcp_Connection_t Connection , oC_Time_t Timeout )
647 {
648  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
649 
650  if(
651  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
652  && ErrorCondition( oC_Tcp_Connection_IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
653  && ErrorCondition( oC_Tcp_Server_ContainsConnection(Server,Connection) == false , oC_ErrorCode_FoundOnList )
654  && ErrorCondition( oC_Semaphore_TakeCounting(Server->FreeSlotsSemaphore,1,Timeout) , oC_ErrorCode_NoFreeSlots )
655  )
656  {
657  uint32_t freeIndex = Server->MaxConnections;
658 
659  oC_IntMan_EnterCriticalSection();
660  for(uint32_t i = 0; i < Server->MaxConnections; i++)
661  {
662  if(Server->Connections[i].Connection == NULL)
663  {
664  freeIndex = i;
665  break;
666  }
667  }
668  oC_IntMan_ExitCriticalSection();
669 
670  if( ErrorCondition( freeIndex < Server->MaxConnections , oC_ErrorCode_NoFreeSlots ) )
671  {
672  oC_Semaphore_GiveCounting(Server->NewConnectionSemaphore, 1);
673  Server->Connections[freeIndex].Connection = Connection;
674  Server->Connections[freeIndex].Handled = false;
675  errorCode = oC_ErrorCode_None;
676  }
677  else
678  {
679  oC_Semaphore_GiveCounting(Server->FreeSlotsSemaphore,1);
680  }
681  }
682 
683  return errorCode;
684 }
685 
686 //==========================================================================================================================================
704 //==========================================================================================================================================
706 {
707  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
708 
709  if(
710  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
711  && ErrorCondition( oC_Tcp_Connection_IsCorrect(Connection) , oC_ErrorCode_ObjectNotCorrect )
712  )
713  {
714  errorCode = oC_ErrorCode_ObjectNotFoundOnList;
715 
716  oC_IntMan_EnterCriticalSection();
717  for(uint32_t i = 0; i < Server->MaxConnections; i++)
718  {
719  if(Server->Connections[i].Connection == Connection)
720  {
721  if(Server->Connections[i].Handled == false)
722  {
723  oC_Semaphore_TakeCounting(Server->NewConnectionSemaphore,1,0);
724  }
725  oC_Semaphore_GiveCounting(Server->FreeSlotsSemaphore,1);
726  Server->Connections[i].Connection = NULL;
727  Server->Connections[i].Handled = false;
728  errorCode = oC_ErrorCode_None;
729  break;
730  }
731  }
732  oC_IntMan_ExitCriticalSection();
733  }
734 
735  return errorCode;
736 }
737 
738 //==========================================================================================================================================
748 //==========================================================================================================================================
750 {
751  oC_Process_t process = NULL;
752 
753  if(oC_SaveIfFalse("Server object", oC_Tcp_Server_IsCorrect(Server), oC_ErrorCode_ObjectNotCorrect))
754  {
755  process = Server->Process;
756  }
757 
758  return process;
759 }
760 
761 //==========================================================================================================================================
771 //==========================================================================================================================================
773 {
774  oC_Tcp_Port_t port = 0;
775 
776  if(oC_SaveIfFalse("TCP::Server::GetPort ", oC_Tcp_Server_IsCorrect(Server), oC_ErrorCode_ObjectNotCorrect))
777  {
778  port = Server->ConnectionConfig.LocalAddress.Port;
779  }
780 
781  return port;
782 }
783 
784 //==========================================================================================================================================
788 //==========================================================================================================================================
789 oC_ErrorCode_t oC_Tcp_Server_SetConnectionFinished( oC_Tcp_Server_t Server , oC_Tcp_ConnectionFinishedFunction_t Function , void * Parameter )
790 {
791  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
792 
793  if(
794  ErrorCondition( oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
795  && ErrorCondition( isaddresscorrect(Function) , oC_ErrorCode_WrongAddress )
796  )
797  {
798  Server->ConnectionFinishedFunction = Function;
799  Server->ConnectionFinishedParameter = Parameter;
800  errorCode = oC_ErrorCode_None;
801  }
802 
803  return errorCode;
804 }
805 
806 #undef _________________________________________INTERFACE_SECTION__________________________________________________________________________
807 
813 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
814 
815 //==========================================================================================================================================
819 //==========================================================================================================================================
820 static void ConnectionFinished( oC_Tcp_Connection_t Connection , oC_Tcp_Server_t Server )
821 {
822  if(
823  oC_SaveIfFalse("TCP::Server::ConnectionFinished (Connection)", oC_Tcp_Connection_IsCorrect(Connection), oC_ErrorCode_ObjectNotCorrect )
824  && oC_SaveIfFalse("TCP::Server::ConnectionFinished (Server)" , oC_Tcp_Server_IsCorrect(Server) , oC_ErrorCode_ObjectNotCorrect )
825  )
826  {
827  if(isaddresscorrect(Server->ConnectionFinishedFunction))
828  {
829  Server->ConnectionFinishedFunction(Connection,Server->ConnectionFinishedParameter);
830  }
831  oC_SaveIfErrorOccur("TCP::Server::ConnectionFinished ", oC_Tcp_Server_RemoveConnection(Server,Connection) );
832  oC_SaveIfFalse ("TCP::Server::ConnectionFinished ", oC_Tcp_Connection_Delete(&Connection, s(1)), oC_ErrorCode_ReleaseError );
833  }
834 }
835 
836 //==========================================================================================================================================
840 //==========================================================================================================================================
841 static void ServerThread( oC_Tcp_Server_t Server )
842 {
843  oC_Tcp_Connection_t connection = NULL;
844  uint32_t connectionId = 0;
845 
846  while(oC_Tcp_Server_IsCorrect(Server))
847  {
848  Server->ConnectionConfig.InitialSequenceNumber = connectionId += 0xFFFF;
849  connectionId = connectionId << 1;
850 
851  if(connection == NULL)
852  {
853  connection = oC_Tcp_Connection_New(&Server->ConnectionConfig);
854  }
855 
856  if(oC_SaveIfFalse("TCP::Server::ServerThread ", connection != NULL, oC_ErrorCode_AllocationError))
857  {
858  if(
859  oC_SaveIfErrorOccur("TCP::Server::ServerThread Wait for connection - ", oC_Tcp_Connection_WaitForConnection(connection, oC_DynamicConfig_GetValue( Tcp, WaitForConnectionTimeout )))
860  && oC_SaveIfErrorOccur("TCP::Server::ServerThread " , oC_Tcp_Server_AddConnection(Server, connection, oC_DynamicConfig_GetValue( Tcp, ExpirationTimeout )))
861  )
862  {
863  oC_Net_Address_t address;
864  char addressString[30] = {0};
865 
866  oC_Tcp_Connection_ReadRemote(connection,&address);
867  oC_Net_AddressToString(&address,addressString,sizeof(addressString));
868 
869  kdebuglog(oC_LogType_Track, "TCP::Server:%d - received new connection from %s\n", Server->ConnectionConfig.LocalAddress.Port, addressString);
870  connection = NULL;
871  }
872  else
873  {
874  if(oC_Tcp_Connection_IsCorrect(connection))
875  {
876  if(oC_Tcp_Server_ContainsConnection(Server,connection) == false)
877  {
878  oC_SaveIfErrorOccur("TCP::Server::ServerThread - rejecting -", oC_Tcp_Connection_Reject(connection, oC_DynamicConfig_GetValue( Tcp, RejectConnectionTimeout )));
879  }
880  oC_Tcp_Connection_Delete(&connection, oC_DynamicConfig_GetValue(Tcp,DeleteConnectionTimeout));
881  }
882  connection = NULL;
883  }
884  }
885  else
886  {
887  break;
888  }
889  }
890 }
891 
892 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
893 
oC_Tcp_Connection_Config_t ConnectionConfig
Configuration of connections of the server.
Definition: oc_tcp_server.c:70
oC_Tcp_Server_t oC_Tcp_Server_New(const oC_Net_Address_t *ListenAddress, uint32_t MaxConnections)
creates TCP server
#define s(time)
Number of s.
Definition: oc_cfg.h:133
oC_Tcp_ConnectionFinishedFunction_t ConnFinishedFunction_t
redefinition of type for storing pointer to the connection finished function
Definition: oc_tcp_server.c:60
oC_Process_t oC_Tcp_Server_GetProcess(oC_Tcp_Server_t Server)
returns process associated with the server
oC_ErrorCode_t oC_Tcp_Server_Run(oC_Tcp_Server_t Server)
starts the TCP server
static void ConnectionFinished(oC_Tcp_Connection_t Connection, oC_Tcp_Server_t Server)
function called, when the connection has been finished
stores TCP connection data
bool oC_Tcp_Server_ContainsConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t Connection)
checks if the server contains the connection
oC_Semaphore_t NewConnectionSemaphore
Semaphore that counts new connections - connections that are currently not handled.
Definition: oc_tcp_server.c:73
The file with interface for thread managing.
oC_Thread_t Thread
Thread for handling the server.
Definition: oc_tcp_server.c:72
oC_ErrorCode_t oC_Tcp_Server_RemoveConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t Connection)
removes connection from server&#39;s connections list
oC_ErrorCode_t oC_Tcp_Server_AcceptConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t Connection, oC_Time_t Timeout)
accepts TCP connection
oC_Tcp_Connection_t Connection
Connection object or NULL if it is not used.
Definition: oc_tcp_server.c:51
bool Handled
true if the slot is already handled by an application
Definition: oc_tcp_server.c:52
bool oC_Tcp_Server_IsRunning(oC_Tcp_Server_t Server)
checks if the TCP server is already running
oC_Tcp_Connection_t oC_Tcp_Connection_New(const oC_Tcp_Connection_Config_t *Config)
allocates memory for a new TCP connection object
stores network address
Definition: oc_net.h:441
oC_Tcp_Port_t
stores TCP port
Definition: oc_tcp.h:75
oC_Process_t Process
Process assiociated with the server.
Definition: oc_tcp_server.c:71
stores data for handling connections array
Definition: oc_tcp_server.c:49
bool oC_Tcp_IsPortReservedBy(oC_Tcp_Port_t Port, oC_Process_t Process)
checks if the port is reserved by the given process
Definition: oc_tcp.c:406
The file with helper macros for managing objects.
bool oC_Tcp_IsPortReserved(oC_Tcp_Port_t Port)
checks if the port is reserved
Definition: oc_tcp.c:396
oC_ErrorCode_t oC_Tcp_Server_AddConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t Connection, oC_Time_t Timeout)
adds connection to server&#39;s connections list
uint32_t MaxConnections
Maximum number of connections that server can handle.
Definition: oc_tcp_server.c:79
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
oC_ErrorCode_t oC_Tcp_Server_WaitForConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t *outConnection, oC_Time_t Timeout)
Waits for new TCP connection.
void * ConnectionFinishedParameter
Parameter to give to the connection finished function.
Definition: oc_tcp_server.c:77
oC_Semaphore_t FreeSlotsSemaphore
Semaphore that counts free slots for connections.
Definition: oc_tcp_server.c:74
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 void ServerThread(oC_Tcp_Server_t Server)
main thread of TCP servers
The file with interface for interrupt manager.
ConnectionSlot_t Connections[1]
Array with TCP connections slots.
Definition: oc_tcp_server.c:80
Handles configuration of the Dynamic.
oC_ObjectControl_t ObjectControl
Special field for storing magic cookie that helps to recognize correct TCP server object...
Definition: oc_tcp_server.c:69
oC_Tcp_Port_t oC_Tcp_Server_GetPort(oC_Tcp_Server_t Server)
returns local port of the server
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
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
static bool oC_Net_IsAddressCorrect(const oC_Net_Address_t *Address)
returns true if the given address is correct
Definition: oc_net.h:918
oC_ErrorCode_t oC_Tcp_Server_SetConnectionConfig(oC_Tcp_Server_t Server, const oC_Tcp_Connection_Config_t *Config)
sets connection configuration
bool oC_Tcp_Server_IsCorrect(oC_Tcp_Server_t Server)
checks if the TCP server object is correct
oC_ErrorCode_t oC_Tcp_Server_Stop(oC_Tcp_Server_t Server)
stops the TCP server
stores TCP server data
Definition: oc_tcp_server.c:67
The file with interface for semaphores.
oC_ErrorCode_t oC_Tcp_Server_SetConnectionFinished(oC_Tcp_Server_t Server, oC_Tcp_ConnectionFinishedFunction_t Function, void *Parameter)
sets a pointer for &#39;connection finished function&#39;
char Name[30]
Name of the TCP server.
Definition: oc_tcp_server.c:75
bool Running
The flag is set to true if the server is already running.
Definition: oc_tcp_server.c:78
oC_Net_AddressType_t Type
Type of the address stored inside.
Definition: oc_net.h:443
oC_ErrorCode_t oC_Tcp_Server_RejectConnection(oC_Tcp_Server_t Server, oC_Tcp_Connection_t Connection, oC_Time_t Timeout)
rejects TCP connection
oC_Net_Port_t Port
Port of the address.
Definition: oc_net.h:450
ConnFinishedFunction_t ConnectionFinishedFunction
Pointer to the function to call when the connection has finished.
Definition: oc_tcp_server.c:76
bool oC_Tcp_Server_Delete(oC_Tcp_Server_t *Server, oC_Time_t Timeout)
deletes TCP server
The file with standard input/output operations.
#define NULL
pointer to a zero
Definition: oc_null.h:37