Index: branches/fep_rpc_client/NetworkReader.cpp
===================================================================
--- branches/fep_rpc_client/NetworkReader.cpp	(revision 77)
+++ branches/fep_rpc_client/NetworkReader.cpp	(revision 78)
@@ -1,9 +1,9 @@
 #include "NetworkReader.h"
+
 /**
  * Constructor
  * @param networkFileName input xml file
  */
-NetworkReader::NetworkReader(const char * networkFileName)
-{
+NetworkReader::NetworkReader(const char * networkFileName) {
     ldsIndex = 0;
     loadLines(networkFileName);
@@ -17,13 +17,12 @@
  * @return the new station
  */
-LDS_LOOP NetworkReader::parseStation(TiXmlElement *stationElem, FEP_LINE line)
-{
+LDS_LOOP NetworkReader::parseStation(TiXmlElement *stationElem, FEP_LINE *line) {
     LDS_LOOP station;
-    
+
     TiXmlElement *stationSubElem = stationElem->FirstChildElement();
     cout << "Station id: " << stationSubElem->GetText() << endl;
     station.lds = atol(stationSubElem->GetText());
-    line.lds.push_back(station.lds);
-    line.ldsIndex.push_back(ldsIndex++);
+    line->lds.push_back(station.lds);
+    line->ldsIndex.push_back(ldsIndex++);
     stationSubElem = stationSubElem->NextSiblingElement();
     station.line_num = atoi(stationSubElem->GetText());
@@ -42,19 +41,17 @@
     // Add loops to station
     TiXmlElement *loopsElem = stationSubElem->NextSiblingElement();
-    TiXmlElement *loopElem = loopsElem->FirstChildElement(); 
+    TiXmlElement *loopElem = loopsElem->FirstChildElement();
     TiXmlElement *saveLoopElem = loopElem;
     // get number of loops in station and assign to station.num
     station.num = 0;
-    for(loopElem; loopElem; loopElem = loopElem->NextSiblingElement())
-    {
+    for (loopElem; loopElem; loopElem = loopElem->NextSiblingElement()) {
         station.num += 1;
     }
-    
+
     // get loopIDS and locations
     long int loopIDS[station.num];
     char * loopLocs[station.num];
     int index = 0;
-    for(saveLoopElem; saveLoopElem; saveLoopElem = saveLoopElem->NextSiblingElement() )
-    {
+    for (saveLoopElem; saveLoopElem; saveLoopElem = saveLoopElem->NextSiblingElement()) {
         TiXmlElement *subLoopElem = saveLoopElem->FirstChildElement();
         loopIDS[index] = atoi(subLoopElem->GetText());
@@ -67,242 +64,336 @@
     // Data pack ATMS message
     station.length = station.num * 2 + CONTROL_DATA_LEN;
-    station.dataPack = msgDataPack(station);
-    
-    return station;
-}
-
-/**
- * Parses a "Line" xml element into an FEP_LINE
- * @param lineElem the xml element
- * @return FEP_LINE
+    station.dataPack = staticDataPack(station);
+/*
+    // fill in dynamic data to dataPack[]
+    for (i = 0; i < g_ldsNum; i++) {
+        // Loop detector data 
+        int pos = 26;
+        pos = pp_data_packing(i, 5, pos);
+        pos = pp_data_packing(i, 6, pos);
+        pos = pp_data_packing(i, 7, pos);
+        pos = pp_data_packing(i, 8, pos);
+
+        // Update data for BYTE 9, 16, 21, 22, 23, 24
+
+        // what is the current metering rate?
+        // check each LDS, if there is demand detector, the downstream node the
+        // ldsMap[i].dataPack[22-1] = ldsMap[i].dataPack[9-1] = ;
+
+        // will need to check if queue override is enabled (Currently, no queue
+        // ldsMap[i].dataPack[16-1] = ;
+
+        // byte 23: MAINLINE total volume
+        ldsMap[i].dataPack[23 - 1] = ldsMap[i].MlTotVol;
+
+        // byte 24: opposite total volume
+        ldsMap[i].dataPack[24 - 1] = ldsMap[i].OppTotVol;
+
+        // last BYTE: checksum 
+        ldsMap[i].dataPack[ldsMap[i].length - 1] =
+                chksum(ldsMap[i].dataPack, ldsMap[i].length - 1 - 1);
+
+        // print out
+        // print out
+        for (j = 0; j < ldsMap[i].length; j++) {
+            fprintf(fi_lds, "%02X", ldsMap[i].dataPack[j]);
+        }
+        fprintf(fi_lds, "\n");
+        fflush(fi_lds);
+*/
+
+        return station;
+    }
+
+    /**
+     * Parses a "Line" xml element into an FEP_LINE
+     * @param lineElem the xml element
+     * @return FEP_LINE
+     */
+    FEP_LINE NetworkReader::parseLine(TiXmlElement * lineElem) {
+        FEP_LINE line;
+        TiXmlElement *lineSubElem = lineElem->FirstChildElement();
+        line.lineNum = atoi(lineSubElem->GetText());
+        cout << "Line: " << line.lineNum << endl;
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.count = atoi(lineSubElem->GetText());
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.schedule = atoi(lineSubElem->GetText());
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.lineInfo = atoi(lineSubElem->GetText());
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.systemKey = atol(lineSubElem->GetText());
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.globalSeq = atol(lineSubElem->GetText());
+        lineSubElem = lineSubElem->NextSiblingElement();
+        line.schedleSeq = atol(lineSubElem->GetText());
+
+        TiXmlElement *stationsElem = lineSubElem->NextSiblingElement();
+        TiXmlElement *stationElem = stationsElem->FirstChildElement();
+        for (stationElem; stationElem; stationElem = stationElem->NextSiblingElement()) {
+            stations.push_back(parseStation(stationElem, &line));
+        }
+        return line;
+    }
+
+    /**
+     * Loads FEPLines from a specified xml file
+     * @param networkFileName the input xml file
+     */
+    void NetworkReader::loadLines(const char * networkFileName) {
+        // Load network xml file
+        TiXmlDocument doc(networkFileName);
+        if (!doc.LoadFile()) {
+            cerr << "TiXmlDocument did not load network file..." << endl;
+            return;
+        }
+
+        // grab <Network> element
+        TiXmlHandle hDoc(&doc);
+        TiXmlElement *networkElem = hDoc.FirstChildElement().Element();
+
+        // grab first <Line> element
+        TiXmlElement *lineElem = networkElem->FirstChildElement();
+
+        // iterate through each line element to create FEP_LINE list
+        for (lineElem; lineElem; lineElem = lineElem->NextSiblingElement()) {
+            lines.push_back(parseLine(lineElem));
+        }
+    }
+
+    // determine if a loop has data based on lane config data
+
+    bool NetworkReader::DataAvail(char flag, int num) {
+        int mag, fel;
+
+        // find mask value
+        if (num == 1)
+            mag = 0x01;
+        else if (num == 2)
+            mag = 0x02;
+        else if (num == 3)
+            mag = 0x04;
+        else if (num == 4)
+            mag = 0x08;
+        else if (num == 5)
+            mag = 0x10;
+        else if (num == 6)
+            mag = 0x20;
+        else if (num == 7)
+            mag = 0x40;
+        else if (num == 8)
+            mag = 0x80;
+
+        fel = flag & mag;
+        fel = fel >> (num - 1);
+
+        if (fel == 1)
+            return true;
+        else
+            return false;
+    }
+/*
+    int pp_data_packing(int index, int packNo, int pos) {
+        int i, j, k, vol, occ, lane, haveData;
+        LOOPAGG in;
+        DETECTOR *aaa;
+        VOLOCC bbb;
+        long loop;
+
+        i = index;
+
+        //used for data byte 23 and 24
+        ldsMap[i].MlTotVol = 0;
+        ldsMap[i].OppTotVol = 0;
+
+        for (j = 1; j <= 8; j++) {
+            if (DataAvail(ldsMap[i].dataPack[packNo - 1], j)) {
+                // loop at bit j has data
+                for (k = 0; k < ldsMap[i].num; k++) {
+                    // what's the corresponding loop of bit j
+                    if (packNo == 5)
+                        haveData = strcmp(ldsMap[i].loop_loc[k], dp5[j - 1]);
+                    else if (packNo == 6)
+                        haveData = strcmp(ldsMap[i].loop_loc[k], dp6[j - 1]);
+                    else if (packNo == 7)
+                        haveData = strcmp(ldsMap[i].loop_loc[k], dp7[j - 1]);
+                    else if (packNo == 8)
+                        haveData = strcmp(ldsMap[i].loop_loc[k], dp8[j - 1]);
+                    else
+                        return -1;
+
+                    if (haveData == 0) {
+                        loop = ldsMap[i].loopID[k];
+                        if (strcmp(chu[loop].paramicsName, "?") == 0) {
+                            {
+                                vol = 0;
+                                occ = 900;
+                            } else {
+                                aaa = qpg_NET_detector(chu[loop].paramicsName);
+                                Bool status = uci_loop_aggregation(qpg_DTC_index(aaa), POLLING
+                                if (status) {
+                                    if (chu[loop].paramicsLane == 0)
+                                            lane = 0;
+                                    else
+                                        lane = chu[loop].paramicsLane - 1;
+                                            vol = in.vol[lane];
+                                            occ = (int) (in.occ[lane] * 900 + 0.5);
+                                            //                   qps_GUI_printf("%d(%s), lane=%d, vol=%d(%d), occ=%.3f(%.3f,
+                                            //                      qpg_DTC_index(aaa), chu[loop].paramicsName, in.lane, in.
+                                            //                      vol, in.g_occ, in.occ[lane], occ);
+                                    } else
+                                    qps_GUI_printf("Data query error for %s\n", chu[loop].param
+                                }
+
+                            bbb = pp_vol_occ_word(vol, occ);
+                                    pos++;
+                                    ldsMap[i].dataPack[pos - 1] = bbb.high;
+                                    pos++;
+                                    ldsMap[i].dataPack[pos - 1] = bbb.low;
+
+                            if (packNo == 5) {
+                                ldsMap[i].MlTotVol += vol;
+                            } else if (packNo == 6) {
+
+                                ldsMap[i].OppTotVol += vol;
+                            }
+
+                            fprintf(fi_lds, "lds=%d, loop=%d, paramics=%s, lane=%d, vol=%d(%X
+                                    ldsMap[i].lds, loop, chu[loop].paramicsName, chu[loop].paramic
+                                    bbb.high, occ, bbb.low);
+                                    fflush(fi_lds);
+                        }
+                    }
+                }
+            }
+
+            return pos;
+        }
  */
-FEP_LINE NetworkReader::parseLine(TiXmlElement *lineElem)
-{
-    FEP_LINE line;
-    TiXmlElement *lineSubElem = lineElem->FirstChildElement();
-    line.lineNum = atoi(lineSubElem->GetText());
-    cout << "Line: " << line.lineNum << endl;
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.count = atoi(lineSubElem->GetText());
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.schedule = atoi(lineSubElem->GetText());
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.lineInfo = atoi(lineSubElem->GetText());
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.systemKey = atol(lineSubElem->GetText());
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.globalSeq = atol(lineSubElem->GetText());
-    lineSubElem = lineSubElem->NextSiblingElement();
-    line.schedleSeq = atol(lineSubElem->GetText());
-
-    TiXmlElement *stationsElem = lineSubElem->NextSiblingElement();
-    TiXmlElement *stationElem = stationsElem->FirstChildElement();
-    for(stationElem; stationElem; stationElem = stationElem->NextSiblingElement())
-    {
-        stations.push_back(parseStation(stationElem, line));
-    }
-    return line;
-}
-
-/**
- * Loads FEPLines from a specified xml file
- * @param networkFileName the input xml file
- */
-void NetworkReader::loadLines(const char * networkFileName)
-{
-    // Load network xml file
-    TiXmlDocument doc(networkFileName);
-    if(!doc.LoadFile())
-    {
-        cerr << "TiXmlDocument did not load network file..." << endl;
-        return;
-    }
-
-    // grab <Network> element
-    TiXmlHandle hDoc(&doc);
-    TiXmlElement *networkElem = hDoc.FirstChildElement().Element();
-
-    // grab first <Line> element
-    TiXmlElement *lineElem = networkElem->FirstChildElement();
-
-    // iterate through each line element to create FEP_LINE list
-    for(lineElem; lineElem; lineElem=lineElem->NextSiblingElement())
-    {
-        lines.push_back(parseLine(lineElem));
-    }
-}
-
-// determine if a loop has data based on lane config data
-bool NetworkReader::DataAvail(char flag, int num)
-{
-	int mag, fel;
-
-	// find mask value
-	if (num == 1)
-		mag = 0x01;
-	else if (num == 2)
-		mag = 0x02;
-	else if (num == 3)
-		mag = 0x04;
-	else if (num == 4)
-		mag = 0x08;
-	else if (num == 5)
-		mag = 0x10;
-	else if (num == 6)
-		mag = 0x20;
-	else if (num == 7)
-		mag = 0x40;
-	else if (num == 8)
-		mag = 0x80;
-
-	fel = flag & mag;
-	fel = fel >> (num - 1);
-
-	if (fel == 1)
-		return true;
-	else
-		return false;
-}
-
-// Initializes the LDS_LOOP dataPack with all necessary static data and default dynamic data
-unsigned char * NetworkReader::msgDataPack(LDS_LOOP loop)
-{
-	int j;
-	// Allocate memory for dataPack
-	unsigned char *dataPack = (unsigned char *) malloc(sizeof(unsigned char) * loop.length);
-
-	// dataPack 5-8: lane config
-	char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
-	for (j = 0; j < loop.num; j++)
-	{
-		for (int k = 0; k < 8; k++)
-		{
-			if (strcmp(loop.loop_loc[j], dp5[k]) == 0)
-				d5 += pow(2, k);
-			if (strcmp(loop.loop_loc[j], dp6[k]) == 0)
-				d6 += pow(2, k);
-			if (strcmp(loop.loop_loc[j], dp7[k]) == 0)
-				d7 += pow(2, k);
-			if (strcmp(loop.loop_loc[j], dp8[k]) == 0)
-				d8 += pow(2, k);
-		}
-	}
-	dataPack[5-1] = d5;
-	dataPack[6-1] = d6;
-	dataPack[7-1] = d7;
-	dataPack[8-1] = d8;
-
-	// dataPack 1: Drop number, i.e. station address
-	dataPack[1-1] = loop.drop;
-
-	// dataPack2 (2 bytes per loop)
-	dataPack[2-1] = loop.num * 2 + Fixed_Byte_To_Checksum;
-
-	// dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops)
-	int low = 0, high = 0;
-	for (j = 1; j <= 6; j++)
-	{
-		low += DataAvail(dataPack[5-1], j);
-		high += DataAvail(dataPack[6-1], j);
-	}
-	high = high << 4;
-	dataPack[3-1] = high | low;
-
-	// dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00)
-	dataPack[4-1] = 0xA0;
-
-	// dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec
-	dataPack[9-1] = 0;
-
-	// datadataPack 10-13: lane malfunction? Assuming all functional
-	dataPack[10-1] = 0;
-	dataPack[11-1] = 0;
-	dataPack[12-1] = 0;
-	dataPack[13-1] = 0;
-
-	// dataPack 14-22: ramp metering data
-	// BYTE 16 and 22 need to be updated every 30 sec
-	bool found = false;
-	for (j = 0; j < loop.num; j++)
-	{
-		if (strcmp(loop.loop_loc[j], "DEMAND") == 0)
-		{
-			found = true;
-			break;
-		}
-	}
-	if (found)
-	{
-		// BYTE 14: mostly 07, some are 05, 03, 00
-		dataPack[14-1] = 0x07;
-		// mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive)
-		dataPack[15-1] = 0x06;
-		// most 00, some are 01 (queue override) or 80(Meter ON sign)
-		dataPack[16-1] = 0x00;
-		// Field Manual Rate
-		dataPack[17-1] = 0xFF;
-		// TOC Manual Rate
-		dataPack[18-1] = 0xFF;
-		// PSO Manual Rate
-		dataPack[19-1] = 0xFF;
-		// CORM Rate
-		dataPack[20-1] = 0xFF;
-		// Local Responsive Rate. DON'T UNDERSTAND YET
-		dataPack[21-1] = 0x00;
-		// TOD Rate: need to query RAMP plugin!
-		dataPack[22-1] = 0x00;
-	}
-	// LDS: NO Metering
-	else
-	{
-		dataPack[14-1] = 0x00;
-		dataPack[15-1] = 0x0B;
-		dataPack[16-1] = 0x00;
-		dataPack[17-1] = 0xFF;
-		dataPack[18-1] = 0xFF;
-		dataPack[19-1] = 0xFF;
-		dataPack[20-1] = 0xFF;
-		dataPack[21-1] = 0x00;
-		dataPack[22-1] = 0x00;
-	}
-
-	// dataPack 23-24: sum of mainline/Oppsite traffic data; need to be updated every 30 sec
-	loop.MlTotVol = 0;
-	loop.OppTotVol = 0;
-	dataPack[23-1] = loop.MlTotVol;
-	dataPack[24-1] = loop.OppTotVol;
-
-	// dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84
-	dataPack[25-1] = 0x03;
-	dataPack[26-1] = 0x84;
-
-	/* printf("lds=%d (%d), p1=%2X, p2=%2X, p3=%2X, p5=%2X, p6=%X, p7=%X, p8=%2X\n",
-		loop.lds, loop.length, dataPack[1-1], dataPack[2-1],
-		dataPack[3-1], dataPack[5-1],
-		dataPack[6-1], dataPack[7-1], dataPack[8-1]);
-    */
-	return dataPack;
-}
-
-/**
- * Getter for lines
- * @return List of FEP_LINES
- */
-vector<FEP_LINE> NetworkReader::getLines()
-{
-    return lines;
-}
-
-/**
- * Getter for stations
- * @return List of LDS_LOOPs
- */
-vector<LDS_LOOP> NetworkReader::getStations()
-{
-    return stations;
-}
-
-NetworkReader::~NetworkReader()
-{
-
-}
+        // Initializes the LDS_LOOP dataPack with all necessary static data and default dynamic data
+        unsigned char * NetworkReader::staticDataPack(LDS_LOOP loop) {
+            int j;
+                    // Allocate memory for dataPack
+                    unsigned char *dataPack = (unsigned char *) calloc(1, sizeof (unsigned char) * loop.length);
+
+                    // dataPack 5-8: lane config
+                    char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
+            for (j = 0; j < loop.num; j++) {
+                for (int k = 0; k < 8; k++) {
+                    if (strcmp(loop.loop_loc[j], dp5[k]) == 0)
+                            d5 += pow(2, k);
+                        if (strcmp(loop.loop_loc[j], dp6[k]) == 0)
+                                d6 += pow(2, k);
+                            if (strcmp(loop.loop_loc[j], dp7[k]) == 0)
+                                    d7 += pow(2, k);
+                                if (strcmp(loop.loop_loc[j], dp8[k]) == 0)
+                                        d8 += pow(2, k);
+                                }
+            }
+            dataPack[5 - 1] = d5;
+                    dataPack[6 - 1] = d6;
+                    dataPack[7 - 1] = d7;
+                    dataPack[8 - 1] = d8;
+
+                    // dataPack 1: Drop number, i.e. station address
+                    dataPack[1 - 1] = loop.drop;
+
+                    // dataPack2 (2 bytes per loop)
+                    dataPack[2 - 1] = loop.num * 2 + Fixed_Byte_To_Checksum;
+
+                    // dataPacket 3 (lowbyte: # of mainline loops, highbyte: # of opposite loops)
+                    int low = 0, high = 0;
+            for (j = 1; j <= 6; j++) {
+                low += DataAvail(dataPack[5 - 1], j);
+                        high += DataAvail(dataPack[6 - 1], j);
+            }
+            high = high << 4;
+                    dataPack[3 - 1] = high | low;
+
+                    // dataPack4 (Miscl. flags: samples are: 80, A0, E0, 00)
+                    dataPack[4 - 1] = 0xA0;
+
+                    // dataPack 9: initialized as 00 (meaning no metering); need to be updated every 30 sec
+                    dataPack[9 - 1] = 0;
+
+                    // datadataPack 10-13: lane malfunction? Assuming all functional
+                    dataPack[10 - 1] = 0;
+                    dataPack[11 - 1] = 0;
+                    dataPack[12 - 1] = 0;
+                    dataPack[13 - 1] = 0;
+
+                    // dataPack 14-22: ramp metering data
+                    // BYTE 16 and 22 need to be updated every 30 sec
+                    bool found = false;
+            for (j = 0; j < loop.num; j++) {
+                if (strcmp(loop.loop_loc[j], "DEMAND") == 0) {
+                    found = true;
+                    break;
+                }
+            }
+            if (found) {
+                // BYTE 14: mostly 07, some are 05, 03, 00
+                dataPack[14 - 1] = 0x07;
+                        // mostly 06(TOD table 1); some are 0B (No metering) or 05(traffic responsive)
+                        dataPack[15 - 1] = 0x06;
+                        // most 00, some are 01 (queue override) or 80(Meter ON sign)
+                        dataPack[16 - 1] = 0x00;
+                        // Field Manual Rate
+                        dataPack[17 - 1] = 0xFF;
+                        // TOC Manual Rate
+                        dataPack[18 - 1] = 0xFF;
+                        // PSO Manual Rate
+                        dataPack[19 - 1] = 0xFF;
+                        // CORM Rate
+                        dataPack[20 - 1] = 0xFF;
+                        // Local Responsive Rate. DON'T UNDERSTAND YET
+                        dataPack[21 - 1] = 0x00;
+                        // TOD Rate: need to query RAMP plugin!
+                        dataPack[22 - 1] = 0x00;
+            }                // LDS: NO Metering
+            else {
+                dataPack[14 - 1] = 0x00;
+                        dataPack[15 - 1] = 0x0B;
+                        dataPack[16 - 1] = 0x00;
+                        dataPack[17 - 1] = 0xFF;
+                        dataPack[18 - 1] = 0xFF;
+                        dataPack[19 - 1] = 0xFF;
+                        dataPack[20 - 1] = 0xFF;
+                        dataPack[21 - 1] = 0x00;
+                        dataPack[22 - 1] = 0x00;
+            }
+
+            // dataPack 23-24: sum of mainline/Oppsite traffic data; need to be updated every 30 sec
+            loop.MlTotVol = 0;
+                    loop.OppTotVol = 0;
+                    dataPack[23 - 1] = loop.MlTotVol;
+                    dataPack[24 - 1] = loop.OppTotVol;
+
+                    // dataPack 25-26: BYTE 25 is fixed, i.e. 03; BYTE 26 is either 0xA2 or 0x84
+                    dataPack[25 - 1] = 0x03;
+                    dataPack[26 - 1] = 0x84;
+
+            return dataPack;
+        }
+
+        /**
+         * Getter for lines
+         * @return List of FEP_LINES
+         */
+        vector<FEP_LINE> NetworkReader::getLines() {
+
+            return lines;
+        }
+
+        /**
+         * Getter for stations
+         * @return List of LDS_LOOPs
+         */
+        vector<LDS_LOOP> NetworkReader::getStations() {
+
+            return stations;
+        }
+
+        NetworkReader::~NetworkReader() {
+
+        }
