discoLight
Loading...
Searching...
No Matches
SWE4211RPi::NetworkManager Class Reference
Inheritance diagram for SWE4211RPi::NetworkManager:
Collaboration diagram for SWE4211RPi::NetworkManager:

Public Member Functions

 NetworkManager (unsigned short port, CommandQueue *queues[], std::string threadName)
 
virtual ~NetworkManager ()
 
void run ()
 
void stopThreadExecution ()
 
int getSocketID ()
 
- Public Member Functions inherited from SWE4211RPi::RunnableClass
 RunnableClass (std::string threadName, int priority=0)
 
virtual ~RunnableClass ()
 
virtual void resetThreadDiagnostics ()
 
virtual void printInformation ()
 
virtual double getCPUUsageInfo ()
 
virtual pid_t getThreadID ()
 
virtual void start () final
 
virtual void setPriority (int priority) final
 
virtual int getPriority () final
 
virtual bool isShutdown () final
 
virtual bool isStarted () final
 
virtual void waitForShutdown ()
 

Protected Member Functions

bool receiveNetworkMessage (networkMessageStruct &message)
 
int processReceivedMessage (networkMessageStruct &receivedMessage)
 
void reportNewClientConnection (const struct sockaddr_in &clientAddress)
 
- Protected Member Functions inherited from SWE4211RPi::RunnableClass
virtual void startChildRunnables ()
 
virtual void stopChildRunnables ()
 

Private Attributes

unsigned short portNumber
 
CommandQueue ** referencequeues
 
int server_fd = -1
 
int connectedSocket = -1
 

Additional Inherited Members

- Static Public Member Functions inherited from SWE4211RPi::RunnableClass
static void printThreads ()
 
static void resetAllThreadInformation ()
 
- Protected Attributes inherited from SWE4211RPi::RunnableClass
std::thread * myThread = NULL
 
pthread_t executingThread = 0
 
pid_t myOSThreadID = 0
 
std::string myName
 
bool keepGoing = true
 
bool runCompleted = false
 
bool runStarted = false
 
int priority = -1
 
- Static Protected Attributes inherited from SWE4211RPi::RunnableClass
static std::list< RunnableClass * > runningThreads
 

Constructor & Destructor Documentation

◆ NetworkManager()

NetworkManager::NetworkManager ( unsigned short  port,
CommandQueue *  queues[],
std::string  threadName 
)

This is the constructor for the Network Manager. It will instantiate a new instance of the class.

Parameters
portThis is the port that the network manager is to listen on for incoming connections.
queuesThis is the array of pointers to queues that is to be used for enqueueing received requests.
threadNameThis is the name given to the executing thread. It is a simple, string that is human readable.

This is the constructor for the Network Manager. It will instantiate a new instance of the class.

Parameters
portThis is the port that the network manager is to listen on for incoming connections.
queueThis is the queue that is to be used for enqueueing received requests.
threadNameThis is the name given to the executing thread. It is a simple, string that is human readable.

◆ ~NetworkManager()

NetworkManager::~NetworkManager ( )
virtual

This is the destructor for the class which will clean up from the instantiation and operation of the class.

  1. Close any socket that is still open. Normally run() closes both sockets before it returns, but this guarantees the file descriptors are released even if the thread never ran to completion.

Member Function Documentation

◆ getSocketID()

int NetworkManager::getSocketID ( )

This method will return the socket ID for the given class.

Returns
The socket ID will be returned.

This method will return the socket ID for the given class.

Returns
The file descriptor of the connected socket, or -1 if no client is connected.

◆ processReceivedMessage()

int NetworkManager::processReceivedMessage ( networkMessageStruct &  receivedMessage)
protected

This method will process a received network message. When it does this, it will calculate out and verify the checksum. If the checksum is correct, the contents will then be enqueued to the correct queue.

Parameters
receivedMessageThis is a reference to the received message structure.
Returns
The calculated checksum is returned.

This method will process a received network message. When it does this, it will calculate out and verify the checksum. If the checksum is correct, the contents will then be enqueued to the correct queue.

Parameters
receivedMessageThis is a reference to the received message structure, in network byte order.
Returns
The calculated checksum is returned.
  1. Declare a variable for the calculated checksum with a value of 0.

  2. Convert the security mode to host byte order before examining it. Every field that arrives from the network must be converted before it is used.

  3. If the security mode of the given message is 0 (unsecured), process it.

    1. Convert the message to host byte order. Do this by converting each individual structure element and placing it back in the structure.

    2. Calculate the XOR checksum of the data received, not including the checksum field.

    3. Call the printNetworkMessageToConsole method, which will print the contents of the message if the preprocessor setup is configured to print debug info out to the console. See debug_cfg.h and NetworkDebugLibrary.

    4. Verify that the calculated checksum matches the checksum that was transmitted.

      1. If the values match, the message is valid. Enqueue it to the right queue if it is a COMMAND_MSG_TYPE and the destination queue is valid. Destinations are numbered starting at 1.

  4. Return the calculated checksum.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ receiveNetworkMessage()

bool NetworkManager::receiveNetworkMessage ( networkMessageStruct &  message)
protected

This method receives one complete networkMessageStruct from the connected client.

Parameters
messageThis is where the received message is stored. The fields are left in network byte order.
Returns
true if a complete message was received. false if the client closed the connection, only part of a message arrived, or an error occurred.

This method receives one complete networkMessageStruct from the connected client.

Parameters
messageThis is where the received message is stored. The fields are left in network byte order; conversion is done by processReceivedMessage() because it depends on the security mode of the message.
Returns
true if a complete message was received. false if the client closed the connection, only part of a message arrived, or an error occurred.
  1. Clear the message so that it never contains leftover memory.

  2. Read one structure's worth of bytes. TCP is a byte stream, so a single read could return only part of a message. MSG_WAITALL keeps waiting until the full size has arrived, unless the connection closes, an error occurs, or a signal interrupts the call.

  3. A negative return indicates an error. If a stop was requested, the error is expected (stopThreadExecution() shut the socket down), so only report it otherwise.

  4. A return of 0 means the client closed the connection.

  5. Anything short of a full structure means the stream is no longer aligned on message boundaries, so the connection cannot be trusted. Report it and treat it as a failure.

  6. A complete message was received.
Here is the caller graph for this function:

◆ reportNewClientConnection()

void NetworkManager::reportNewClientConnection ( const struct sockaddr_in &  clientAddress)
protected

This method will report across any queue whenever a new connection is made to this software.

Parameters
clientAddressThis is the ip address of the client device represented as a single 32 bit number. if there is no connection, the value will be 0.

This method will report across all queues whenever a new connection is made to this software.

Parameters
clientAddressThis is the address of the client device. If there is no connection, the IP address will be 0.
  1. Convert the IP address from network byte order to host byte order and store it in a local 32 bit integer.

  2. Build the command queue entry once, then broadcast it by enqueueing it on every queue.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

void NetworkManager::run ( )
virtual

This is the run method for the class. It contains the code that is to run periodically on the given thread.

This is the run method for the class. It contains the code that represents the running thread.

  1. Create a socket file descriptor. The socket is an IPv4 TCP socket. If there is an error, indicate that the socket failed and return from the method.

  2. Call setsockopt to set up the options on the socket at the socket level. Each option is a separate ID, not a bit flag, so each needs its own call. SO_REUSEADDR allows the port to be reused immediately after the program exits; SO_REUSEPORT allows multiple sockets to bind to the same port. If there is an error, print out an error message, close the socket, and return.

  3. Clear the address structure so that any fields not set below (such as the sin_zero padding) are zero rather than leftover garbage.

  4. Set up the server address to use the IPv4 Internet protocols and to accept connections on any of this device's network interfaces. The port must be converted to network endianness.

  5. Bind the listening socket to the correct port. Only one socket can be bound to a given port at a time (unless SO_REUSEPORT is set by all of them). If there is a failure, print out an error, close the socket, and return.

  6. Mark the socket as a listening socket so clients can connect to it. This is done once; the socket remains in the listening state for its lifetime. The backlog is the number of connections that may wait before accept() is called. If there is an error, print it out, close the socket, and return.

  7. Loop so long as the thread is to continue running (i.e. a call to stop on this class has not occurred.)

    1. Reset addrlen. accept() both reads it (to know how much room is in their_address) and overwrites it, so it must be reset before every call.

    2. Block until a client connects. accept() returns a new socket for talking to that client; server_fd stays open to accept future clients.

    3. If accept failed:

      1. If a stop was requested, stopThreadExecution() shut the socket down to unblock accept(). This is expected, so leave the loop quietly.
      2. If the call was interrupted by a signal, simply try again.
      3. Otherwise, print the error and leave the loop.

    4. Turn on keepalive for the client connection so that the system periodically checks that an idle connection is still alive. This applies to the connected socket, not the listening socket. A failure here is not fatal, so only print a warning.

    5. Report out the IP address of the client that has connected to this server.

    6. So long as the client remains connected and the thread continues running:

      1. Receive one complete networkMessageStruct from the client.
      2. If a complete message arrived, process it. Otherwise the client closed the connection or an error occurred, so stop reading from this client.

    7. Close the connection to the client and mark the connected socket as invalid.

    8. Set the IP address of the connected client to zero and broadcast this out, indicating that no client is connected.

  8. Close the listening socket before the thread exits.

Implements SWE4211RPi::RunnableClass.

Here is the call graph for this function:

◆ stopThreadExecution()

void NetworkManager::stopThreadExecution ( )
virtual

This method will override the default stop method. In doing so, it must call the base class's stop method prior to invoking it's own logic.

This method will override the default stop method. In doing so, it must call the base class's stop method prior to invoking its own logic.

  1. Call the parent's stop method.

  2. If a client is connected, shut down that connection. This unblocks a recv() that is waiting for data, so the thread does not hang until the client sends another message.

  3. Shut down the listening socket. This unblocks accept() if the thread is waiting for a client.

Reimplemented from SWE4211RPi::RunnableClass.

Here is the call graph for this function:

Member Data Documentation

◆ connectedSocket

int SWE4211RPi::NetworkManager::connectedSocket = -1
private

This is the connected socket of the network manager. This will be updated whenever a connection is made and it is used to send messages back to the master as well as to receive messages from the master.

◆ portNumber

unsigned short SWE4211RPi::NetworkManager::portNumber
private

This is the port that will be used for receiving messages over the network.

◆ referencequeues

CommandQueue** SWE4211RPi::NetworkManager::referencequeues
private

This is a pointer to the array of queues that will be used to communicate with other devices.

◆ server_fd

int SWE4211RPi::NetworkManager::server_fd = -1
private

This integer is the file descriptor for the socket that is going to be listened to for connections.


The documentation for this class was generated from the following files: