Index: vtcross/branches/wrodgers/ServiceManagementLayer.cpp
===================================================================
--- vtcross/trunk/src/service_management_layer/ServiceManagementLayer.cpp	(revision 206)
+++ vtcross/branches/wrodgers/ServiceManagementLayer.cpp	(revision 247)
@@ -6,5 +6,5 @@
 
 /* DESCRIPTION OF FILE.
- */
+ */ multiple clients
 
 
@@ -13,10 +13,14 @@
 #include <stdint.h>
 
-#include "vtcross/common.h"
-#include "vtcross/components.h"
-#include "vtcross/containers.h"
-#include "vtcross/debug.h"
-#include "vtcross/error.h"
-#include "vtcross/socketcomm.h"
+#include "../include/vtcross/common.h"
+#include "../include/vtcross/components.h"
+#include "../include/vtcross/containers.h"
+#include "../include/vtcross/debug.h"
+#include "../include/vtcross/error.h"
+#include "../include/vtcross/socketcomm.h"
+
+uint32_t Current_ID = 0;
+uint32_t numCogEnginesPresent = 0;
+bool cogEnginePresent = false;
 
 
@@ -40,4 +44,5 @@
 
     ConnectToShell(serverName, serverPort);
+    CE_List = new CE_Reg[10];
 
     LoadConfiguration();
@@ -64,39 +69,81 @@
 
 void 
-ServiceManagementLayer::WaitForSignal()
+ServiceManagementLayer::ShellSignalHandler()
 {
     char buffer[256];
 
-    while(true) {
-        memset(buffer, 0, 256);
-       
-        ReadMessage(shellSocketFD, buffer);
-
-        // TODO
-        // If we send integer op codes rather than strings, this process will be
-        // MUCH faster since instead of donig string compares we can simply
-        // switch on the integer value...
-        if(strcmp(buffer, "register_service") == 0) {
-            if(strcmp(buffer, "policy_geo") == 0) {
-            }
-            else if(strcmp(buffer, "policy_time") == 0) {
-            }
-            else if(strcmp(buffer, "policy_spectrum") == 0) {
-            }
-            else if(strcmp(buffer, "policy_spacial") == 0) {
-            }
-        }
-        else if(strcmp(buffer, "deregister_service") == 0) {
-            if(strcmp(buffer, "policy_geo") == 0) {
-            }
-            else if(strcmp(buffer, "policy_time") == 0) {
-            }
-            else if(strcmp(buffer, "policy_spectrum") == 0) {
-            }
-            else if(strcmp(buffer, "policy_spacial") == 0) {
-            }
-        }
-        else if(strcmp(buffer, "query_component_type") == 0) {
-            SendComponentType();
+    memset(buffer, 0, 256); 
+    ReadMessage(shellSocketFD, buffer);
+
+    // TODO
+    // If we send integer op codes rather than strings, this process will be
+    // MUCH faster since instead of donig string compares we can simply
+    // switch on the integer value...
+    if(strcmp(buffer, "register_service") == 0) {
+        if(strcmp(buffer, "policy_geo") == 0) {
+        }
+        else if(strcmp(buffer, "policy_time") == 0) {
+        }
+        else if(strcmp(buffer, "policy_spectrum") == 0) {
+        }
+        else if(strcmp(buffer, "policy_spacial") == 0) {
+        }
+    }
+    else if(strcmp(buffer, "deregister_service") == 0) {
+        if(strcmp(buffer, "policy_geo") == 0) {
+        }
+        else if(strcmp(buffer, "policy_time") == 0) {
+        }
+        else if(strcmp(buffer, "policy_spectrum") == 0) {
+        }
+        else if(strcmp(buffer, "policy_spacial") == 0) {
+        }
+    }
+    else if(strcmp(buffer, "query_component_type") == 0) {
+        SendComponentType();
+     }
+}
+
+void
+ServiceManagementLayer::CESignalHandler(int32_t ID)
+{
+   char buffer[256];	
+   memset(buffer, 0, 256);     
+   //
+   ReadMessage(cogEngSrv, buffer);
+   if(strcmp(buffer, "register_engine_cognitive") == 0) {
+   	RegisterCognitiveEngine(ID);
+   }
+
+
+}
+
+void
+CognitiveRadioShell::RegisterCognitiveEngine(int32_t ID)
+{
+    LOG("Cognitive Radio Shell:: Received registration message from Cognitive Engine.\n");
+   
+    TransferRadioConfiguration(ID);
+    TransferRadioExperience(ID);
+
+    numberOfCognitiveEngines++;
+    CE_present = true;
+}
+
+
+void 
+CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
+{
+    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
+
+    numberOfCognitiveEngines--;
+    if(numberOfCognitiveEngines == 0)
+        CE_present = false;
+
+    SendMessage(socketFD, "deregister_ack");
+    shutdown(socketFD, 2);
+    close(socketFD);
+    LOG("Cognitive Radio Shell:: Socket closed.\n");
+}
         }
         else if(strcmp(buffer, "reset_sml") == 0) {
@@ -147,11 +194,11 @@
 
 void 
-ServiceManagementLayer::TransferRadioConfiguration()
-{
-}
-
-
-void 
-ServiceManagementLayer::TransferExperience()
+ServiceManagementLayer::TransferRadioConfiguration(int32_t ID)
+{
+}
+
+
+void 
+ServiceManagementLayer::TransferExperience(int32_t ID)
 {
 }
@@ -189,2 +236,145 @@
 }
 
+void
+CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
+{
+    SendMessage(commandSocketFD, "register_engine_cognitive");
+    LOG("Cognitive Engine:: Registration message sent to shell.\n");
+
+    TransferRadioConfiguration(socketFD);
+    TransferRadioExperience(socketFD);
+
+    numberOfCognitiveEngines++;
+    CE_present = true;
+}
+
+
+void 
+CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
+{
+    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
+
+    numberOfCognitiveEngines--;
+    if(numberOfCognitiveEngines == 0)
+        CE_present = false;
+
+    SendMessage(socketFD, "deregister_ack");
+    shutdown(socketFD, 2);
+    close(socketFD);
+    LOG("Cognitive Radio Shell:: Socket closed.\n");
+}
+
+void
+CognitiveRadioShell::StartSMLServer()
+{
+    struct timeval selTimeout;
+    int32_t running = 1;
+    int32_t port, rc, new_sd = 1;
+    int32_t desc_ready = 1;
+    int32_t timeout = 10;
+    fd_set sockSet[1];
+
+    cogEngSrv = CreateTCPServerSocket(CEPort);
+    int32_t maxDescriptor = cogEngSrv;
+
+    if(InitializeTCPServerPort(cogEngSrv) == -1)
+        ERROR(1,"Error initializing primary port\n");
+
+    while (running) {
+        /* Zero socket descriptor vector and set for server sockets */
+        /* This must be reset every time select() is called */
+        FD_ZERO(&sockSet);
+        FD_SET(cogEngSrv, &sockSet);
+
+        /* Timeout specification */
+        /* This must be reset every time select() is called */
+        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
+        selTimeout.tv_usec = 0;            /* 0 microseconds */
+
+        //Check if there is a message on the socket waiting to be read
+	rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout);
+        if(rc == 0){
+	    //If not, log that fact and check instead for messages from the shell
+            LOG("No echo requests for %i secs...Server still alive\n", timeout);
+	    ShellSignalHandler();	
+	}
+        else {
+	    //If so, process the address information and pass the component ID on to the handler
+	    char buffer[256];
+	    memset(buffer, 0, 256);
+	    sockaddr_in sock_addr = new sockaddr_in;
+	    //Peak at the next message on the socket to determine its address of orgin
+            recvfrom(cogEngSrv, buffer, 256, MSG_PEAK, (struct sockaddr*) &sock_addr, NULL);
+	    bool found = false;
+	    //Is it from a previously logged address?
+	    for(int i = 0; i < Current_ID; i++){
+		if(CE_List[i].(*sock_ptr).sin_addr.s_addr == sock_addr.sin_addr.s_addr){
+			//If so, pass the ID number of that component into the signal handler to process the message
+			CESignalHandler(i);
+			found=true;
+		}
+	    }
+	    //If not, log the address and pass the ID number of that component into the signal handler
+	    if(!found){
+		CE_List[Current_ID].sock_ptr = &sock_addr;
+		CE_List[Current_ID].ID_num = Current_ID;
+		CESignalHandler(Current_ID);
+		CurrentID++;
+	    }
+        }
+    }        
+
+    /* Close sockets */
+    close(cogEngSrv);
+
+    return;
+}
+
+/*
+
+
+
+rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout); 
+        if(rc == 0){
+            LOG("No echo requests for %i secs...Server still alive\n", timeout);
+	    ShellSignalHandler();	
+	}
+        else {
+            desc_ready = rc;
+
+            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
+                if(FD_ISSET(port, &sockSet)) {
+                    desc_ready -= 1;
+
+                    //Check if request is new or on an existing open descriptor
+                    if(port == cogEngSrv) { 
+                        do {
+                            new_sd = AcceptTCPConnection(port);
+                            if(new_sd < 0) 
+                                break;
+                           
+                            CE_List[Current_ID].FD = new_sd;
+			    CE_List[Current_ID].IDNum = Current_ID;
+                            HandleMessage(CE_List[Current_ID]);
+			    Current_ID++;
+	
+                            FD_SET(new_sd,&sockSet);
+                            if(new_sd > maxDescriptor) 
+                                maxDescriptor = new_sd;
+                            //LOG("New incoming connection - %i\n\n",new_sd);
+                        } while(new_sd != -1);
+                    } 
+                    else {
+                        //LOG("Request on already open descriptor.\n\n");
+			for(int16_t i = 0; i < Current_ID; i++)
+			{
+				if(CE_List[i].FD == port)
+					HandleMessage(CE_List[i]);
+			}
+                    }
+                }
+            }
+    }
+*/
+
+
