Index: /vtcross/trunk/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp
===================================================================
--- /vtcross/trunk/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp	(revision 390)
+++ /vtcross/trunk/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp	(revision 391)
@@ -29,8 +29,11 @@
 
 #define INTERFERENCE 0
+
+#define CHANNEL 1
+
+#define ENERGY 0
 #define COMMUNICATION_TIME 1
-#define CHANNEL 2
-#define ENERGY 3
-#define FITNESS 4
+
+#define UTILITY 4
 
 
@@ -111,8 +114,10 @@
     
     uint32_t numberColumns = 
-        radioInfo->numParameters +
-        radioInfo->numUtilities;
+        radioInfo->numParameters;
 
     uint32_t obsColumns = radioInfo->numObservables + 1;
+    uint32_t numberTotalColumns = radioInfo->numUtilities +
+        			radioInfo->numParameters +
+        			radioInfo->numObservables + 1;
 
     float valList[numberColumns];
@@ -120,4 +125,8 @@
     char *nameList[numberColumns];
     char *obsList[obsColumns];
+    char *searchNames[1];
+    float searchVals[1];
+    int searchOps[1];
+    float returnValues[numberTotalColumns];
 
     size_t columnObsIndex = 0;
@@ -126,5 +135,7 @@
         columnObsIndex++;
     }  
-    obsList[columnObsIndex] = "utility";
+   
+    std::string utility_name = "utility"; 
+    obsList[columnObsIndex] = (char*) utility_name.c_str();
 
     size_t columnIndex = 0;
@@ -133,8 +144,4 @@
         columnIndex++;
     }   
-    for (size_t i = 0; i < radioInfo->numUtilities; i++){
-        nameList[columnIndex] = (char*)uList[i].name.c_str();
-        columnIndex++;
-    }   
 
     size_t obsValueIndex = 0;
@@ -144,10 +151,37 @@
     }
 
+    /* Make sure we do not return any entries for the current channel */
+    std::string channel_name = "channel";
+    searchNames[0] = (char *) channel_name.c_str();
+    searchOps[0] = EQ;
+    searchVals[0] = parameters[0].value; 
+
+    /* Execute CBR search and put output into returnValues */
+    cbr_search(myCBR, searchNames, searchOps, searchVals,
+            1, returnValues);
+
     /* Calculate Utility */
-    float newUtilityValue = 0;
-
-    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
-        newUtilityValue = newUtilityValue + (uList[i].target - observables[i].value);
-    }
+    float oldUtilityValue = returnValues[UTILITY];
+    
+    // Set DSA utility to take into account both the previously sensed
+    //  energy and the average communication time.
+
+    
+
+    float newUtilityValue = oldUtilityValue + ( -observables[ENERGY].value + observables[COMMUNICATION_TIME].value);
+
+    // If communication time value is set, we know we need to change channels because of PU.
+    // So we should lower the utility for this channel.
+
+    if(observables[COMMUNICATION_TIME].value != 0) { 
+	newUtilityValue = newUtilityValue - 100;
+    } else {
+	newUtilityValue = newUtilityValue + 20;
+    }
+
+
+    if(newUtilityValue <= 0)
+	newUtilityValue = 0;
+
     obsVals[obsValueIndex] = newUtilityValue;
 
@@ -155,8 +189,4 @@
     for(size_t i = 0; i < radioInfo->numParameters; i++) {
         valList[returnValueIndex] = parameters[i].value;
-        returnValueIndex++;
-    }
-    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
-        valList[returnValueIndex] = uList[i].target;
         returnValueIndex++;
     }
@@ -641,6 +671,9 @@
     /* Put together the CBR search array */
 
+    uint32_t channel = 0;
     char *searchNames[1];
+    char *sumSearchName;
     float searchVals[1];
+    float utilArray[(int)pList[0].max];
     int searchOps[1];
     uint32_t numberColumns = radioInfo->numUtilities +
@@ -648,40 +681,80 @@
         			radioInfo->numObservables + 1;
 
-    /* Make sure we do not return any entries for the current channel */
-    searchNames[0] = "channel";
-    searchOps[0] = NE;
-    searchVals[0] = currentParameters[0].value; 
- 
     float returnValues[numberColumns];
-    
-    /* Execute CBR search and put output into returnValues */
-    uint32_t rc = cbr_search(myCBR, searchNames, searchOps, searchVals,
+    float sumRetVals[numberColumns];
+   
+    // Total sum of utilities in sumRetVals[0]
+
+    std::string channel_name = "channel";
+    std::string utility_name = "utility";
+
+    for( int i = 0 ; i < pList[0].max ; i++ ) {
+
+        searchNames[0] = (char*) pList[0].name.c_str();
+        searchOps[0] = EQ;
+        searchVals[0] = i+1; 
+    
+        uint32_t rc = cbr_search(myCBR, searchNames, searchOps, searchVals,
             1, returnValues);
 
-    if(rc == 0){
-        /* Similiar environment was found. Adapt the returned parameters to 
-           meet the objective */
-
-        LOG("Cognitive Engine:: Previous similar environment found\n");
-
-  	/* generate random channel */
-	returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min; 
+	if(rc == 31337) {
+		// No entry - must add
+		
+    		char *rowNames[numberColumns];
+    		size_t rowIndex = 0;
+    		for(size_t j = 0; j < radioInfo->numUtilities; j++) {
+        		rowNames[rowIndex] = (char*)uList[j].name.c_str();
+        		rowIndex++;
+    		}
+    		for(size_t j = 0; j < radioInfo->numParameters; j++) {
+        		rowNames[rowIndex] = (char*)pList[j].name.c_str();
+			if(pList[j].name == "channel")
+				returnValues[rowIndex] = i+1;
+        		rowIndex++;
+    		}
+    		for(size_t j = 0; j < radioInfo->numObservables; j++) {
+        		rowNames[rowIndex] = (char*)oList[j].name.c_str();
+        		rowIndex++;
+    		}
+   
+    		rowNames[rowIndex] = (char *) utility_name.c_str();
+		returnValues[rowIndex] = 500;
+
+                /* Add the new optimized set to the CBR database */
+
+    		cbr_add_row(myCBR, rowNames, returnValues, numberColumns);
+	}
+
+	utilArray[i] = returnValues[UTILITY]; 
+    }
+
+        printf("1: %f\t2: %f\t3: %f\t4: %f\n",utilArray[0],utilArray[1],utilArray[2],utilArray[3]);    
+    // Get sum of all the channel utilities.
+    sumSearchName = (char *) utility_name.c_str();
+    uint32_t rc = cbr_search_sum(myCBR, sumSearchName, sumRetVals);
+
+    // Psuedo random channel selection based upon utility.
+    int k = rand() % (int)sumRetVals[0];
+    int cdf_total(0);
+
+    for ( int i = 0; i < pList[0].max; i++ ) {
+        cdf_total += utilArray[i];
+        if(k < cdf_total) {
+		channel = i + 1;
+		break;
+	}
+    }
         
-        if(returnValues[numberColumns-1] < 0) {
-        
-        } else {
-       
-        }
-    } else if(rc == 31337) {
-        /* No previous similar solution was found, use default. */
-        LOG("Cognitive Engine:: No previous similar environment found.\n");
-     
-  	/* generate random channel */
-	returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min; 
-    } else {
-        LOG("Cognitive Engine:: Search return an invalid value.\n");
-    }
-
-
+    searchNames[0] = (char*) pList[0].name.c_str();
+    searchOps[0] = EQ;
+    searchVals[0] = channel; 
+  
+    rc = cbr_search(myCBR, searchNames, searchOps, searchVals,
+        1, returnValues);
+
+
+    //returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min; 
+    returnValues[CHANNEL] = channel;
+ 
     /* Package up the new set of parameters in order to add
        the new entry into the CBR database.  */
@@ -700,5 +773,5 @@
         returnValueIndex++;
     }
-    returnValues[returnValueIndex] = 0;
+    //returnValues[returnValueIndex] = 0;
 
     char *allNames[numberColumns];
@@ -715,11 +788,13 @@
     for(size_t i = 0; i < radioInfo->numObservables; i++) {
         allNames[allNameIndex] = (char*)oList[i].name.c_str();
-        returnValues[allNameIndex] = 0;
+    //    returnValues[allNameIndex] = 0;
         allNameIndex++;
     }
-    allNames[allNameIndex] = "utility";
+   
+    allNames[allNameIndex] = (char *) utility_name.c_str();
 
     /* Add the new optimized set to the CBR database */
     cbr_add_row(myCBR, allNames, returnValues, returnValueIndex+1);
+
 
     /* Return the set of new parameter values.  */
@@ -764,15 +839,24 @@
         columnIndex++;
     }   
+
+    char *paramCols[radioInfo->numParameters];
+    size_t paramColumnIndex = 0;
+    // Also need to make parameters the unique key 
     for (size_t i = 0; i < radioInfo->numParameters; i++){
         cols[columnIndex] = (char*)pList[i].name.c_str();
+        paramCols[paramColumnIndex] = (char*)pList[i].name.c_str();
         columnIndex++;
-    }   
+        paramColumnIndex++;
+    }  
+
     for (size_t i = 0; i < radioInfo->numObservables; i++){
         cols[columnIndex] = (char*)oList[i].name.c_str();
         columnIndex++;
     }   
-    cols[columnIndex] = "utility";
-
-    myCBR = cbr_create(filename, tablename, cols, numberColumns);
-}
-
+   
+    std::string utility_name = "utility"; 
+    cols[columnIndex] = (char *)utility_name.c_str();
+
+    myCBR = cbr_create_with_primary(filename, tablename, cols, paramCols, numberColumns, radioInfo->numParameters);
+}
+
Index: /vtcross/trunk/src/cognitive_engines/DSA_CE/cbr.c
===================================================================
--- /vtcross/trunk/src/cognitive_engines/DSA_CE/cbr.c	(revision 390)
+++ /vtcross/trunk/src/cognitive_engines/DSA_CE/cbr.c	(revision 391)
@@ -57,5 +57,5 @@
     char *zErrMsg = 0;
 
-    printf("command: %s\n", _cbr->command);
+    //printf("command: %s\n", _cbr->command);
     rc = sqlite3_exec(_cbr->db, _cbr->command, callback, 0, &zErrMsg);
     if( rc!=SQLITE_OK){
@@ -93,4 +93,53 @@
 }
 
+// create database
+cbr cbr_create_with_primary(char * _filename, char * _tablename, 
+	char * _cols[], char * _primcols[], unsigned int _len,
+	unsigned int _primlen)
+{
+    // cbr is a pointer to struct cbr_s
+    cbr _cbr = (cbr) malloc(sizeof(struct cbr_s));
+
+    // create database
+
+    // copy filename
+    unsigned int i=0;
+    strcpy(_cbr->filename, _filename);
+
+    // execute create database command
+    // database handle
+    //_cbr->db = NULL;
+    OpenDatabase(_cbr);
+
+    // create table
+
+    // copy tablename
+    strcpy(_cbr->tablename, _tablename);
+
+    // number of columns in the table
+    _cbr->num_columns = _len;
+
+    // generate command
+    strcpy(_cbr->command, "CREATE TABLE ");
+    strcat(_cbr->command, _cbr->tablename);
+    strcat(_cbr->command, "(");
+    for (i=0; i<_cbr->num_columns; i++) {
+        strcat(_cbr->command, _cols[i]);
+        strcat(_cbr->command, " FLOAT");
+        strcat(_cbr->command, ", ");
+    }
+   strcat(_cbr->command, "PRIMARY KEY (");
+    for (i=0; i<_primlen; i++) {
+        strcat(_cbr->command, _primcols[i]);
+        if (i != _primlen-1) // not last entry
+            strcat(_cbr->command, ", ");
+    }
+    strcat(_cbr->command, "));");
+
+    // execute create table command
+    ExecuteCommand(_cbr);
+
+    return _cbr;
+}
 
 // create database
@@ -181,4 +230,82 @@
 const char * ops_str[] = {
     "==", "!=", ">", ">=", "<", "<="};
+
+
+// cbr search for a sum
+int cbr_search_sum(
+    cbr _cbr,
+    char *_name,
+    float *_retvals)
+{   
+    int rc;
+    // generate command
+    strcpy(_cbr->command, "select SUM( ");
+    strcat(_cbr->command, _cbr->tablename);
+    strcat(_cbr->command, ".");
+    strcat(_cbr->command, _name);
+    strcat(_cbr->command, ") from ");
+    strcat(_cbr->command, _cbr->tablename);
+    strcat(_cbr->command, ";");
+
+    //printf("search command: %s\n", _cbr->command);
+
+    rc = ExecuteSearchCommand(_cbr, _retvals);
+    /*printf("search result: ");
+    for (int i=0; i<_cbr->num_columns; i++)
+        printf("%f, ",_retvals[i]);
+    printf("\n");
+    */
+    return rc;
+}
+
+
+// cbr search
+int cbr_search_rand(
+    cbr _cbr,
+    char *_names[],
+    int * _ops,
+    float *_vals,
+    unsigned int _n,
+    float *_retvals)
+{   
+    int rc;
+    // generate command
+    strcpy(_cbr->command, "select ");
+    strcat(_cbr->command, _cbr->tablename);
+    strcat(_cbr->command, ".* from ");
+    strcat(_cbr->command, _cbr->tablename);
+    strcat(_cbr->command, " where ");
+
+    unsigned int i;
+    char str_buffer[64];
+    for (i=0; i<_n; i++) {
+        // ensure valid ops value
+        if (_ops[i] < 0 || _ops[i] > 5) {
+            printf("error: cbr_search(), invalid ops id : %d\n", _ops[i]);
+            exit(1);
+        }
+
+        strcat(_cbr->command, _names[i]);
+        strcat(_cbr->command, ops_str[_ops[i]]);
+        sprintf(str_buffer, "%E", _vals[i]);
+        strcat(_cbr->command, str_buffer);
+
+        if (i<_n-1)
+            strcat(_cbr->command, " AND ");
+        else
+            strcat(_cbr->command, " order by RAND();");
+    }
+
+    //printf("search command: %s\n", _cbr->command);
+
+    rc = ExecuteSearchCommand(_cbr, _retvals);
+    
+    /*printf("search result: ");
+    for (i=0; i<_cbr->num_columns; i++)
+        printf("%f, ",_retvals[i]);
+    printf("\n");
+*/
+    return rc;
+}
 
 
@@ -220,5 +347,5 @@
     }
 
-    printf("search command: %s\n", _cbr->command);
+    //printf("search command: %s\n", _cbr->command);
 
     rc = ExecuteSearchCommand(_cbr, _retvals);
@@ -279,5 +406,5 @@
     // generate command
     //printf("%s\n", _cbr->command);
-    strcpy(_cbr->command, "insert into ");
+    strcpy(_cbr->command, "replace into ");
     strcat(_cbr->command, _cbr->tablename);
     
Index: /vtcross/trunk/src/cognitive_engines/DSA_CE/examples/gnuradio-examples/dsa.py
===================================================================
--- /vtcross/trunk/src/cognitive_engines/DSA_CE/examples/gnuradio-examples/dsa.py	(revision 390)
+++ /vtcross/trunk/src/cognitive_engines/DSA_CE/examples/gnuradio-examples/dsa.py	(revision 391)
@@ -39,9 +39,14 @@
 def main():
 
-   	global n_rcvd, n_right,sync_status,mode,ch,traffic_flag,n_attempts,return_flag
+   	global stats_array, count_array, time_array, n_rcvd, n_right,sync_status,mode,ch,traffic_flag,n_attempts,return_flag
     	n_rcvd = 0
     	n_right = 0
 	n_attempts = 5
 	return_flag = 0
+
+	count_array = [ 0, 0, 0, 0, 0]
+	time_array = [ 0, 0, 0, 0, 0]
+	stats_array = [ 0, 0, 0, 0, 0]
+
 
     	def send_pkt(self, payload='', eof=False):
@@ -63,4 +68,13 @@
 		return real_channel
 
+	def get_average_time(channel,absent_time):
+
+		global count_array, time_array
+
+		count_array[channel] = count_array[channel] + 1
+		average_time = (time_array[channel] + absent_time) / count_array[channel]	
+	
+		return average_time
+
 	def get_freq(hop_freq,probe_level,absent_time):
 
@@ -76,16 +90,30 @@
 			channel = 4
 
-		p = Parameter(1)
 		currentParameters = Parameter(1)
-		o = Observable(1)
-
+		currentParameters[0].name = "channel"
+		currentParameters[0].value = channel
+
+		o = Observable(2)
 		o[0].value = probe_level
 		o[0].name = "energy"
-
-		currentParameters[0].name = "channel"
-		currentParameters[0].value = channel;
-
-		p = GetOptimalParameters(o,1,currentParameters,1);
-		print p[0].value
+		
+		o[1].value = absent_time 
+		o[1].name = "communication_time"
+		
+		# If time == 0 then we are scanning and we dont want to 
+		#  use this time in the averaging process.
+
+		if absent_time != 0:
+		    UpdateParameterPerformance(currentParameters,1,o,1)
+
+		else:
+		    # Get the average communication time
+		    average_time = get_average_time(channel, absent_time)
+		    o[1].value = average_time 
+		    o[1].name = "communication_time"
+		    UpdateParameterPerformance(currentParameters,1,o,2)
+
+		p = Parameter(1)
+		p = GetOptimalParameters(o,2,currentParameters,1);
 		
 		channel = get_real_channel(int(p[0].value))
@@ -96,4 +124,6 @@
 			hop_freq = float(1e6 * (467.5625+(channel-8)*0.025))#setting the centre freq frequency for sending packets	
 
+		stats_array[int(p[0].value)] = stats_array[int(p[0].value)] + 1
+		print "Stats:: 1..",stats_array[1]," 2..",stats_array[2]," 3..",stats_array[3]," 4..",stats_array[4] 
 		return channel,hop_freq #returning the channel number and hop frequency
 	
@@ -154,6 +184,7 @@
 
     	parser_tx = OptionParser(option_class=eng_option, conflict_handler="resolve")
-    	expert_grp_tx = parser_tx.add_option_group("Expert_tx")
-
+        parser_tx.add_option("", "--vtcross", action="store_true", default=False,
+				help="Use the CROSS engine for DSA decisions: default is random.")
+  
     	parser_tx.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
                       	default='gmsk',
@@ -166,12 +197,15 @@
                       	help="set megabytes to transmit [default=%default]")
     	parser_tx.add_option("","--discontinuous", action="store_true", default=False,
-                      	help="enable discontinous transmission (bursts of 5 packets)")
+                      	help="enable discontinous transmission (bursts of 5 packets)") 
     	parser_tx.add_option("","--from-file", default=None,
                       	help="use file for packet contents")
-    	
+ 
+    	expert_grp_tx = parser_tx.add_option_group("Expert_tx")
+
         transmit_path.add_options(parser_tx, expert_grp_tx)
 
     	for mod in mods.values():
         	mod.add_options(expert_grp_tx)
+
 
     	(options_tx, args_tx) = parser_tx.parse_args ()
@@ -188,5 +222,5 @@
     	options_tx.fusb_nblocks = 16
     	options_tx.bitrate = 0.0125e6
-    	#############
+	#############
 
     	if options_tx.tx_freq is None:
@@ -195,24 +229,24 @@
         	sys.exit(1)
 
-    	if options_tx.from_file is not None:
-        	source_file = open(options_tx.from_file, 'r')
+    	#if options_tx.from_file is not None:
+        #	source_file = open(options_tx.from_file, 'r')
     	    
     	parser_rx = OptionParser (option_class=eng_option, conflict_handler="resolve")
     	expert_grp_rx = parser_rx.add_option_group("Expert_rx")
-    	parser_rx.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
-                      	default='gmsk',
-                      	help="Select modulation from: %s [default=%%default]"
-                            	% (', '.join(demods.keys()),))
+    	#parser_rx.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
+        #              	default='gmsk',
+        #              	help="Select modulation from: %s [default=%%default]"
+        #                    	% (', '.join(demods.keys()),))
     	
     	receive_path.add_options(parser_rx, expert_grp_rx)
 
-    	for mod in demods.values():
-        	mod.add_options(expert_grp_rx)
+    	#for mod in demods.values():
+        #	mod.add_options(expert_grp_rx)
 
     	(options_rx, args_rx) = parser_rx.parse_args ()
 
-    	if len(args_rx) != 0:
-        	parser_rx.print_help(sys.stderr)
-        	sys.exit(1)
+    	#if len(args_rx) != 0:
+        #	parser_rx.print_help(sys.stderr)
+        #	sys.exit(1)
     	############# Setting some default values for rx side of the block
     	options_rx.rx_freq = 462.5625e6 #setting default rx_freq value
@@ -224,8 +258,8 @@
     	#############
 
-    	if options_rx.rx_freq is None:
-        	sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
-        	parser_rx.print_help(sys.stderr)
-        	sys.exit(1)
+    	#if options_rx.rx_freq is None:
+        #	sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
+        #	parser_rx.print_help(sys.stderr)
+        #	sys.exit(1)
     	
 	# build the graph
@@ -248,4 +282,5 @@
 
 	# Scan all channels first for inital data
+	time.sleep(0.1)
 
 	while running:
