Index: branches/SimpleFEPclient/fep_client.cpp
===================================================================
--- branches/SimpleFEPclient/fep_client.cpp	(revision 106)
+++ branches/SimpleFEPclient/fep_client.cpp	(revision 136)
@@ -1,5 +1,9 @@
+#include "fep_client.h"
 #include "fep.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <vector>
+#include "network.h"
+#include "DataPacker.h"
 
 /* Author: John A. Torres
@@ -8,115 +12,190 @@
    reply is sent, the ATMS Sends a response and the RPC Client
    is destroyed.
+   */
+void FEPClient::fep_program_32(char *host)
+{
+   CLIENT *clnt;
+
+   /* Declerations to construct an fep_reply */
+   fep_answer_info fai;
+   fep_answer_short_msg fasm;
+   fep_shortanswer fsa;
+   fep_reply  fep_reply; // the reply to be sent to ATMS
+
+   /* Var to recieve message back from ATMS */
+   void  *rv;
+
+   /* Create RPC Client to communicate with ATMS */
+   printf("Preparing to create RPC client\n");
+   clnt = clnt_create(host, FEP_PROGRAM, FEP_VERSION, "tcp");
+
+   /* Check if client creation failed */
+   if (clnt == (CLIENT *) NULL)
+   {
+      fprintf(stderr, "can't create client to %s\n", host);
+      /* Show why rpc handle couldn't be created */
+      clnt_pcreateerror("");
+      exit(1);
+   }
+
+   /* Populate fep_shortmessage data */
+   printf("setting reply values\n");
+
+   // DUMMY DATA FOR SINGLE GREEN DOT
+   // STATION
+   // lds_id  line    drop sch lineinfo       system_key      sch_seq glo_seq         count   freeway Dir     ca_pm   lds_name
+   // 1204666 45      10      11      11      1123005841      26484   1357646         19      5       N       20      LAKE FOR2
+
+   // LOOPS
+   // FWY     Dir     POSTMI  LDS_ID  VDS_ID  LOOP_ID LOC    LANE LOOP_LOC            PARAMICS_NAME  PARAMICS_LANE
+   // 
+
+   vector<LOOP*> loops;
+/*
+   LOOP * newLoopOne = new LOOP;
+   newLoopOne->loopID = 1210490;
+   newLoopOne->loop_loc = "ML_1";
+   newLoopOne->vol = 0;
+   newLoopOne->occ = 0;
+   newLoopOne->spd = 0;
+
+   LOOP * newLoopTwo = new LOOP;
+   newLoopTwo->loopID = 1210492;
+   newLoopTwo->loop_loc = "ML_2";
+   newLoopTwo->vol = 0;
+   newLoopTwo->occ = 0;
+   newLoopTwo->spd = 0;
+
+   LOOP * newLoopThree = new LOOP;
+   newLoopThree->loopID = 1210493;
+   newLoopThree->loop_loc = "ML_3";
+   newLoopThree->vol = 0;
+   newLoopThree->occ = 0;
+   newLoopThree->spd = 0;
+
+   LOOP * newLoopFour = new LOOP;
+   newLoopFour->loopID = 1210769;
+   newLoopFour->loop_loc = "RAMP_ON";
+   newLoopFour->vol = 0;
+   newLoopFour->occ = 0;
+   newLoopFour->spd = 0;
+
+   loops.push_back(newLoopOne);
+   loops.push_back(newLoopTwo);
+   loops.push_back(newLoopThree);
+   loops.push_back(newLoopFour);
 */
-void fep_program_32(char *host)
-{
-	CLIENT *clnt;
-
-    /* Declerations to construct an fep_reply */
-	fep_answer_info fai;
-	fep_pollerror fpe;
-	fep_answer_short_msg fasm;
-	fep_shortanswer fsa;
-	fep_reply  fep_reply_xfer_32_arg; // the reply to be sent to ATMS
-
-	/* Var to recieve message back from ATMS */
-	void  *rv;
-
-    /* Create RPC Client to communicate with ATMS */
-	printf("Preparing to create RPC client\n");
-	clnt = clnt_create(host, FEP_PROGRAM, FEP_VERSION, "tcp");
-
-	/* Check if client creation failed */
-	if (clnt == (CLIENT *) NULL)
-	{
-		fprintf(stderr, "can't create client to %s\n", host);
-        /* Show why rpc handle couldn't be created */
-        clnt_pcreateerror("");
-		exit(1);
-    }
-
-    /* Populate fep_shortmessage data */
-	printf("setting reply values\n");
-
-	fasm.message_len = 5;
-	fasm.message[0] = 0x0a;
-	fasm.message[1] = 0x0d;
-	fasm.message[2] = 0x11;
-	fasm.message[3] = 0x12;
-	fasm.message[4] = 0x13;
-
-	fpe.msgerror = (enum answererror) 0;
-	fpe.state = (enum Polling_FSM_States) 0x00;
-	fpe.perrno = 0;
-	fpe.termination = 0;
-	fpe.count = 0;
-
-	fai.poll_time = 1111443466;
-	fai.status = (enum replystatus) 1;
-	fai.poll_user_info1 = 1;
-	fai.poll_user_info2 = 2;
-	fai.retries = 0;
-	fai.poll_error_count = 1;
-	fai.pollerror[0] = fpe;
-
-	fsa.info = fai;
-	fsa.msg = fasm;
-
-	fep_reply_xfer_32_arg.reply = 0;
-	fep_reply_xfer_32_arg.schedule = 0;
-	fep_reply_xfer_32_arg.lineinfo = 0;
-	fep_reply_xfer_32_arg.kind = (enum polltype)0;
-	fep_reply_xfer_32_arg.flag = (enum replykind) 0;
-	fep_reply_xfer_32_arg.schedule_sequence = 0;
-	fep_reply_xfer_32_arg.global_sequence = 0;
-	fep_reply_xfer_32_arg.schedule_time = 1111443466;
-	fep_reply_xfer_32_arg.user_info1 = 0;
-	fep_reply_xfer_32_arg.user_info2 = 0;
-	fep_reply_xfer_32_arg.system_key = 0;
-	fep_reply_xfer_32_arg.answers.size = 0;
-	fep_reply_xfer_32_arg.answers.fep_answer_list_u.shortp.count = 1;
-	fep_reply_xfer_32_arg.answers.fep_answer_list_u.shortp.answers[0] = fsa;
-
-    /* Make RPC Call to transfer reply to ATMS */
-	printf("transferring data\n");
-	rv = fep_reply_xfer_32(&fep_reply_xfer_32_arg, clnt);
-	printf("checking reply`\n");
-
-	/* If ATMS reply call fails */
-	if (rv == (void *) NULL)
-	{
-		clnt_perror(clnt, "call failed");
-    }
-    /* If recieved reply is successful, but empty */
-	else if ((char *) rv == "")
-	{
-		printf("rv is empty\n");
-    }
-    /* If recieved reply is successful */
-	else
-	{
-		printf("Result = %s\n", (char *)rv);
-    }
-
-    /* Destroy client */
-	printf("destroying client\n");
-	clnt_destroy(clnt);
-	printf("returning to main\n");
+   STATION * dummyStation = new STATION;
+   dummyStation->lds = 1204666;
+   dummyStation->line_num = 45;
+   dummyStation->drop = 10;
+   // dummyStation->loops = loops;
+
+   dummyStation->MlTotVol = 0;
+   dummyStation->OppTotVol = 0;
+   dummyStation->length = dummyStation->loops.size() * 2 + 27 /* CONTROL_DATA_LEN */;
+
+   printf("Station length: %d\n", dummyStation->length);
+   // CHECK TO SEE IF I AM UPDATING THIS EVERY 30S
+   /*
+   for(int i = 0; i < 3; i++)
+   {
+      dummyStation->MlTotVol += loops.at(i)->vol;
+   }
+   */
+   printf("Station MLTOTVOL: %d\n", dummyStation->MlTotVol);
+
+   dummyStation->dataPack = DataPacker::packData(dummyStation);
+
+
+   fep_reply.reply = SHORTPOLL;
+   fep_reply.schedule = 0;
+   fep_reply.lineinfo = 0;
+   fep_reply.kind = (enum polltype) 0;
+   fep_reply.flag = (enum replykind) 0;
+
+   fep_reply.schedule_sequence = 0;
+   fep_reply.global_sequence = 0;
+
+   fep_reply.schedule_time = time(NULL);
+
+   fep_reply.user_info1 = dummyStation->line_num; // LINE NUM;
+   fep_reply.user_info2 = dummyStation->line_num; // LINE NUM;
+   fep_reply.system_key = 0;
+
+   fep_reply.answers.size = 1;
+   fep_reply.answers.fep_answer_list_u.shortp.count = 1;
+
+   fasm.message_len = dummyStation->length + 2; // MESSAGE LEN;
+   fasm.message[0] = 0x0d;
+   fasm.message[1] = 0x0a;
+
+   for (int k = 0; k < dummyStation->length; k++) {
+      printf("Adding: %d %02X\n", k, dummyStation->dataPack[k]); 
+      fasm.message[2 + k] = dummyStation->dataPack[k];
+   }
+
+   int length = dummyStation->length + 2; // NEED CORRECT LENGTH
+   fasm.message[length + 2] = 0x0d;
+   fasm.message[length + 3] = 0xff;
+
+   for(int l = 0; l < fasm.message_len + 2; l++)
+   {
+      printf("%02X", (unsigned char) fasm.message[l]);
+   }
+   printf("\n");
+
+   fai.poll_error_count = 0;
+   fai.poll_user_info1 = 0 ;// DROP NUMBER HERE
+   fai.poll_user_info2 = 1;
+   fai.retries = 0;
+   fai.status = (enum replystatus) 1;
+
+   fsa.info = fai;
+   fsa.msg = fasm;
+   fep_reply.answers.fep_answer_list_u.shortp.answers[0] = fsa;
+
+   /* Make RPC Call to transfer reply to ATMS */
+   printf("transferring data\n");
+   rv = fep_reply_xfer_32(&fep_reply, clnt);
+   printf("checking reply`\n");
+
+   /* If ATMS reply call fails */
+   if (rv == (void *) NULL)
+   {
+      clnt_perror(clnt, "call failed");
+   }
+   /* If recieved reply is successful, but empty */
+   else if ((char *) rv == "")
+   {
+      printf("rv is empty\n");
+   }
+   /* If recieved reply is successful */
+   else
+   {
+      printf("Result = %s\n", (char *)rv);
+   }
+
+   /* Destroy client */
+   printf("destroying client\n");
+   clnt_destroy(clnt);
+   printf("returning to main\n");
 }
 
 /* Creates a single client and sends an fep_reply to the ATMS */
 int main(int argc, char *argv[]) {
-	char *host;
-
-	if (argc < 2)
-	{
-		printf("usage:  %s server_host\n", argv[0]);
-		exit(1);
-    }
-
-    /* Create RPC Client to send an fep_reply to ATMS */
-	host = argv[1];
-	fep_program_32(host);
-
-	return 0;
+   char *host;
+
+   if (argc < 2)
+   {
+      printf("usage:  %s server_host\n", argv[0]);
+      exit(1);
+   }
+
+   /* Create RPC Client to send an fep_reply to ATMS */
+   host = argv[1];
+   FEPClient cli;
+   cli.fep_program_32(host);
+
+   return 0;
 }
Index: branches/SimpleFEPclient/fep_client.h
===================================================================
--- branches/SimpleFEPclient/fep_client.h	(revision 136)
+++ branches/SimpleFEPclient/fep_client.h	(revision 136)
@@ -0,0 +1,19 @@
+#ifndef __FEPCLIENT_H_INCLUDED__
+#define __FEPCLIENT_H_INCLUDED__
+
+#include "fep.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include "network.h"
+#include "DataPacker.h"
+
+class FEPClient
+{
+public:
+void fep_program_32(char *host);
+private:
+
+};
+
+#endif // __FEPCLIENT_H_INCLUDED__
Index: branches/SimpleFEPclient/build
===================================================================
--- branches/SimpleFEPclient/build	(revision 131)
+++ branches/SimpleFEPclient/build	(revision 136)
@@ -1,3 +1,3 @@
 #!/bin/bash
 
-gcc *.cpp *.c -o client
+g++ -w *.cpp *.c -o client
Index: branches/SimpleFEPclient/network.h
===================================================================
--- branches/SimpleFEPclient/network.h	(revision 136)
+++ branches/SimpleFEPclient/network.h	(revision 136)
@@ -0,0 +1,78 @@
+#ifndef __NETWORK_H_INCLUDED__
+#define __NETWORK_H_INCLUDED__
+
+#include <stdlib.h>
+#include <math.h>
+#include <vector>
+
+using namespace std;
+
+/*** CONSTANTS ***/
+const int Fixed_Byte_To_Checksum = 25; // the first byte is not considered in the calculation of "BYTE 2"
+const int CONTROL_DATA_LEN = 27;
+
+char * const dp5[8] = { "ML_1", "ML_2", "ML_3", "ML_4", "ML_5",
+                                                "ML_6", "HOV_Lane", "FYW_Conn"};
+char * const dp6[8] = { "OS_1", "OS_2", "OS_3", "OS_4", "OS_5",
+                                                "OS_6", "COLL_DIST_2", "COLL_DIST_OFF"};
+char * const dp7[8] = { "DEMAND", "PASSAGE", "QUEUE", "RAMP_ON",
+                                                "RAMP_OFF", "RAMP_HOV", "COLL_DIST_1", "COLL_DIST_ON"};
+char * const dp8[8] = { "SD_1", "SD_2", "SD_3", "SD_4", "SD_5",
+                                                "SD_6", "Pass_Vol_Count", "X"};
+
+// FEP line: has several lds
+typedef struct fep_line FEP_LINE;
+struct  fep_line
+{
+	int             lineNum;
+	vector<long>    lds;
+	vector<long>    ldsIndex;	// location in ldsMap
+
+	short   count;	// actual count from caltrans
+	int	schedule;
+	int	lineInfo;
+	long	systemKey;
+	long	globalSeq;
+	long	schedleSeq;
+};
+
+// Loop detector
+typedef struct loop LOOP;
+struct loop
+{
+    long loopID;
+    char *loop_loc;
+    
+    int vol;
+    float occ;
+    double spd;
+};
+
+// Loop detector station: has several loops
+typedef struct Station STATION;
+struct  Station
+{
+	// Each lds has its own line_num and drop (Caltrans use)
+	long	lds;
+	short	line_num;
+	short	drop;
+        
+        vector<LOOP*> loops;
+
+	// LDS data
+	unsigned char	*dataPack;
+	int		length;		// total length of data (max: 87)
+	int		pos;		// pointer for data preparation
+	int		MlTotVol;	// each 30 sec, the following will be updated
+	int		OppTotVol;	// each 30 sec, the following will be updated
+};
+
+typedef struct volOcc VOLOCC;
+struct  volOcc
+{
+   char high;
+   char low;
+};
+
+
+#endif
Index: branches/SimpleFEPclient/DataPacker.cpp
===================================================================
--- branches/SimpleFEPclient/DataPacker.cpp	(revision 136)
+++ branches/SimpleFEPclient/DataPacker.cpp	(revision 136)
@@ -0,0 +1,267 @@
+#include "DataPacker.h"
+#include <stdio.h>
+
+unsigned char * DataPacker::msg;
+
+unsigned char * DataPacker::packData(STATION *station) {
+    int pos = 26;
+    DataPacker packer;
+    msg = packer.staticDataPack(station);
+    pos = packer.dynamicDataPack(station, 5, pos);    
+    pos = packer.dynamicDataPack(station, 6, pos);
+    pos = packer.dynamicDataPack(station, 7, pos);
+    pos = packer.dynamicDataPack(station, 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
+    msg[23 - 1] = station->MlTotVol;
+
+    // byte 24: opposite total volume
+    msg[24 - 1] = station->OppTotVol;
+
+    // last BYTE: checksum 
+    msg[station->length - 1] =
+            packer.chksum(msg, station->length - 1 - 1);
+    
+    for (int j = 0; j < station->length; j++) {
+        printf("%02X", msg[j]);
+    }
+    printf("\n");
+
+    return msg;	
+}
+
+int DataPacker::dynamicDataPack(STATION *station, int packNo, int pos) {
+    int i, j, vol, occ, haveData;
+    //used for data byte 23 and 24
+    station->MlTotVol = 0;
+    station->OppTotVol = 0;
+
+    for (j = 1; j <= 8; j++) {
+        
+        if (DataAvail(msg[packNo - 1], j)) {
+            // loop at bit j has data
+            for (int lane = 0; lane < station->loops.size(); lane++) {
+                // what's the corresponding loop of bit j
+                char * currLoopLoc = station->loops.at(lane)->loop_loc;
+                if (packNo == 5)
+                    haveData = strcmp(currLoopLoc, dp5[j - 1]);
+                else if (packNo == 6)
+                    haveData = strcmp(currLoopLoc, dp6[j - 1]);
+                else if (packNo == 7)
+                    haveData = strcmp(currLoopLoc, dp7[j - 1]);
+                else if (packNo == 8)
+                    haveData = strcmp(currLoopLoc, dp8[j - 1]);
+                else
+                    return -1;
+
+                if (haveData == 0) {
+                    LOOP *currLoop = station->loops.at(lane);
+                    vol = currLoop->vol;
+                    occ = (int) (currLoop->occ * 900 + 0.5);
+
+                    VOLOCC packedVOLOCC = packVOLOCC(vol, occ);
+                    pos++;
+                    msg[pos - 1] = packedVOLOCC.high;
+                    pos++;
+                    msg[pos - 1] = packedVOLOCC.low;
+
+                    if (packNo == 5) {
+                        station->MlTotVol += vol;
+                    } else if (packNo == 6) {
+                        station->OppTotVol += vol;
+                    }
+                }
+            }
+        }
+    }
+    return pos;
+}
+
+unsigned char * DataPacker::staticDataPack(STATION *station) {
+    int j;
+    // Allocate memory for dataPack
+    unsigned char *dataPack = (unsigned char *) calloc(sizeof(unsigned char), station->length);
+
+    // dataPack 5-8: lane config
+    char d5 = 0, d6 = 0, d7 = 0, d8 = 0;
+    for (j = 0; j < station->loops.size(); j++) {
+        for (int k = 0; k < 8; k++) {
+            char * currLoopLoc = station->loops.at(j)->loop_loc;
+            if (strcmp(currLoopLoc, dp5[k]) == 0)
+                d5 += pow(2, k);
+            if (strcmp(currLoopLoc, dp6[k]) == 0)
+                d6 += pow(2, k);
+            if (strcmp(currLoopLoc, dp7[k]) == 0)
+                d7 += pow(2, k);
+            if (strcmp(currLoopLoc, 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] = station->drop;
+    // dataPack2 (2 bytes per loop)
+    dataPack[2 - 1] = station->loops.size() * 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 < station->loops.size(); j++) {
+        if (strcmp(station->loops.at(j)->loop_loc, "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/Opp traffic data; need to be updated every 30 sec
+    station->MlTotVol = 0;
+    station->OppTotVol = 0;
+    dataPack[23 - 1] = station->MlTotVol;
+    dataPack[24 - 1] = station->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;
+}
+
+bool DataPacker::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;
+}
+
+// checksum based on data from byte 1 (after 0DOA) to the second last byte (the 
+char DataPacker::chksum(unsigned char *dataptr, int len) {
+    int i;
+    unsigned char checksum = 0;
+
+    for (i = 0; i < len; i++)
+        checksum += dataptr[i];
+
+    return checksum;
+}
+
+// convert vol and occ data to a two-byte data packet
+VOLOCC DataPacker::packVOLOCC(int vol, int occ)
+{
+   int bit, i;
+   int   high, low; 
+   int high_high = 0, high_low = 0;
+   VOLOCC com;
+   
+   // occ data: 10 bits
+   low = 0;
+   for (i=9; i>=0; i--) 
+   {
+      if (i >= 8)
+      {
+         bit = ((occ >> i) & 1);
+         high_low += pow(2, (i - 8)) * bit; 
+      }
+      // lower byte
+      else
+      {
+         bit = ((occ >> i) & 1);
+         low += pow(2, i) * bit;
+      }
+   }
+
+   // vol: 6 bits (1. vol, shift to the left for two times; 2. combine data)
+   high_high = vol << 2;
+   high = high_high | high_low;
+
+   com.high = high;
+   com.low = low;
+
+   return com;
+}
Index: branches/SimpleFEPclient/runclient
===================================================================
--- branches/SimpleFEPclient/runclient	(revision 136)
+++ branches/SimpleFEPclient/runclient	(revision 136)
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+./client 192.168.251.27
Index: branches/SimpleFEPclient/DataPacker.h
===================================================================
--- branches/SimpleFEPclient/DataPacker.h	(revision 136)
+++ branches/SimpleFEPclient/DataPacker.h	(revision 136)
@@ -0,0 +1,47 @@
+/* 
+ * File:   DataPacker.h
+ *
+ * DataPacker has a single static public method packData(..) that returns the
+ * packed data message that is sent to the ATMS Server in the fep_reply struct
+ * via RPC.
+ * 
+ * @author John A. Torres
+ * @version 9/8/2017
+ */
+
+#ifndef DATAPACKER_H
+#define	DATAPACKER_H
+
+// Include dependencies
+#include "network.h"
+#include <iostream>
+#include <string.h>
+
+class DataPacker {
+    
+public:
+    /**
+     * Returns packed data message to be sent to ATMS Server in fep_reply via RPC
+     * 
+     * @param station The station for which the message is to be made
+     * @return The packed data message
+     */
+    static unsigned char * packData(STATION *station);
+
+private:
+    static unsigned char *msg;
+    // Packs the static data in message sent to ATMS
+    unsigned char * staticDataPack(STATION *station);
+    // Packs dynamic data in message sent to ATMS
+    int dynamicDataPack(STATION *station, int packNo, int pos);
+    // Sets last byte of message
+    char chksum(unsigned char *dataptr, int len);
+    // Tells whether or not data is available for specified lane
+    bool DataAvail(char flag, int num);
+    // Helper function: packs vol and occ into two byte data packet
+    VOLOCC packVOLOCC(int vol, int occ);
+
+};
+
+#endif	/* DATAPACKER_H */
+
