source: tmcsimulator/branches/FEPSimulator/FEPSim.cpp @ 233

Revision 233, 7.4 KB checked in by jtorres, 8 years ago (diff)

FEPSim: finalized comments, added to both header and source files.

Line 
1#include "FEPSim.h"
2
3/**
4 * Constructor. Sets data values for RPC Client and socket server.
5 *
6 * @param ATMSHost The IP of ATMS Server
7 * @param FEP RPC program number
8 * @param FEP RPC program revision number
9 * @param Socket Server listen port
10 */
11FEPSim::FEPSim(char * ATMShost, int FEP_PROG, int FEP_REV, int SOCK_PORT) {
12    this->ATMSHost = ATMShost;
13    this->FEP_PROG = FEP_PROG;
14    this->FEP_REV = FEP_REV;
15    this->SOCK_PORT = SOCK_PORT;
16    this->FEPLogFileName = "FEPSimLog.txt";   
17    // clear log file
18    FEPLogFile.open(FEPLogFileName, ios::trunc);
19    FEPLogFile.close();
20}
21
22/**
23 * Destructor: closes the log file if open
24 */
25FEPSim::~FEPSim() {
26    FEPLogFile.close();
27}
28
29/**
30 * Handler for the ATMS RPC Response (to the client RPC Call)
31 * @param response pointer to fep_reply struct
32 */
33void FEPSim::handleCallResponse(void *response) {
34    // Failed RPC Call
35    if (response == NULL) { 
36        clnt_perror(clnt, "RPC call failed");
37    }
38    // Successful RPC Call
39    else { 
40        FEPLogFile << "Successful RPC call to ATMS..." << endl;
41    }
42}
43
44/**
45 * Sends an fep_reply for each station on the FEPLine.
46 * Gets highway status from recieved socket msg.
47 *
48 * @param buffer The recieved highway status msg.
49 */
50void FEPSim::sendReplys(char * buffer) {
51    HighwaysParser highwaysParser = HighwaysParser(buffer);
52    vector<FEP_LINE*> lines = highwaysParser.lines;
53    vector<STATION*> ldsMap = highwaysParser.stations;
54
55    cout << "Starting sendReplys for " << lines.size() << " lines." << endl;
56    // Send one reply for every FEPLine
57    for (int i = 0; i < lines.size(); i++) {
58        fep_reply fepReply;
59        FEP_LINE * currLine = lines.at(i);
60        // populate reply
61        fepReply.reply = SHORTPOLL;
62        fepReply.schedule = currLine->schedule;
63        fepReply.lineinfo = currLine->lineInfo;
64        fepReply.kind = (enum polltype) 0;
65        fepReply.flag = (enum replykind) 0;
66
67        fepReply.schedule_sequence = currLine->schedleSeq;
68        fepReply.global_sequence = currLine->globalSeq;
69
70        // using current unix time, may need to look at later
71        fepReply.schedule_time = time(NULL);
72
73        fepReply.user_info1 = currLine->lineNum;
74        fepReply.user_info2 = currLine->lineNum;
75        fepReply.system_key = currLine->systemKey;
76
77        fepReply.answers.size = 1;
78        fepReply.answers.fep_answer_list_u.shortp.count = 1;
79       
80        // construct a shortanswer for each station in line
81        for (int j = 0; j < currLine->lds.size(); j++) {
82            fep_shortanswer fsa;
83            STATION * currStation = ldsMap.at(currLine->ldsIndex.at(j));
84
85            // msg: oa, od, currStation.dataPack, od, ff
86            fsa.msg.message_len = currStation->length + 2;
87            fsa.msg.message[0] = 0x0d;
88            fsa.msg.message[1] = 0x0a;
89            for (int k = 0; k < currStation->length; k++) {
90                //printf("Adding: %d %02X\n", k, currStation->dataPack[k]);     
91                fsa.msg.message[2 + k] = currStation->dataPack[k];
92            }
93            int aa = currStation->length;
94            fsa.msg.message[2 + aa] = 0x0d;
95            fsa.msg.message[3 + aa] = 0xff;
96           
97            /*for(int l = 0; l < fsa.msg.message_len + 2; l++)
98            {
99                printf("%02X", (unsigned char) fsa.msg.message[l]);
100            }
101            printf("\n");*/
102           
103            // info
104            fsa.info.poll_error_count = 0;
105            fsa.info.poll_time = time(NULL);
106            fsa.info.poll_user_info1 = currStation->drop; // drop number
107            fsa.info.poll_user_info2 = 1; //always 1
108            fsa.info.retries = 0;
109            fsa.info.status = (enum replystatus) 1;
110
111            fepReply.answers.fep_answer_list_u.shortp.answers[0] = fsa;
112            // send out data
113           
114            FEPLogFile << "Sending fepReply for line #" << currLine->lineNum
115                    << " station number #" 
116                    << ldsMap.at(currLine->ldsIndex.at(j)) << endl;
117           
118            // Transfer the station data to ATMS and listen for response
119            handleCallResponse(fep_reply_xfer_32(&fepReply, clnt));
120        }
121        // pause to let ATMS server catch up
122        //unsigned int sleepseconds = 220000;
123        //usleep(sleepseconds);
124    }
125    cout << "Finished." << endl;
126}
127
128/**
129 * Creates an RPC Client, and on successful creation, sends fep_replys to ATMS.
130 * @param The recieved highway status msg.
131 */
132void FEPSim::manageClientConnection(char * buffer) 
133{
134    // Attempt to create RPC client
135    if (createClient()) 
136    {
137        // Prepare and send the highway status as FEP replies
138        sendReplys(buffer);
139        FEPLogFile << "Destroying client..." << endl;
140        clnt_destroy(clnt);
141        int startTime = time(NULL);
142        FEPLogFile << "time is: " << startTime << endl;
143    }
144}
145
146/**
147  * Creates an RPC Client to the ATMS Server. If unsuccessful, returns false
148  * @return bool success
149  */
150bool FEPSim::createClient() {
151    /* Create RPC Client to communicate with ATMS */
152    bool success = true;
153
154    clnt = clnt_create(this->ATMSHost, FEP_PROG, FEP_REV, "tcp");
155    /* Check if client creation failed */
156    if (clnt == (CLIENT *) NULL) {
157        cerr << "Can't create client to " << this->ATMSHost << endl;
158        cerr << "Verify you are connected to ATL network." << endl;
159        success = false;
160    } else {
161        FEPLogFile << "Client created" << endl;
162    }
163    return success;
164}
165
166/**
167 * Creates a socket server and awaits the highway status message from the
168 * ATMS Driver. Upon receipt of the highway status message, creates an RPC
169 * client and sends the fep_replys to the ATMS.
170 */
171void FEPSim::runSockServer() {
172    int sockfd, newsockfd, portno, clilen;
173    char buffer[BUFF_SIZE];
174    struct sockaddr_in serv_addr, cli_addr;
175    int n;
176    portno = this->SOCK_PORT;
177
178    /* First call to socket() function */
179    sockfd = socket(AF_INET, SOCK_STREAM, 0);
180
181    if (sockfd < 0) {
182        perror("ERROR opening socket");
183        exit(1);
184    }
185
186    /* Initialize socket structure */
187    bzero((char *) &serv_addr, sizeof (serv_addr));
188
189    serv_addr.sin_family = AF_INET;
190    serv_addr.sin_addr.s_addr = INADDR_ANY;
191    serv_addr.sin_port = htons(portno);
192
193    /* Now bind the host address using bind() call.*/
194    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
195        perror("ERROR on binding");
196        exit(1);
197    }
198
199    /* Now start listening for the clients, here process will
200     * go in sleep mode and will wait for the incoming connection
201     */
202
203    listen(sockfd, 5);
204    clilen = sizeof (cli_addr);
205
206    /* Accept actual connections from the client */
207    while (1) {
208        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *) & clilen);
209
210        if (newsockfd < 0) {
211            perror("ERROR on accept");
212            exit(1);
213        }
214
215        /* If connection is established then start communicating */
216        // zero out buffer
217        bzero(buffer, BUFF_SIZE);
218       
219        // read XML from socket
220        int totBytes = 0;
221        while ((n = recv(newsockfd, &buffer[totBytes], sizeof (buffer), 0)) > 0) {
222            totBytes += n;
223        }
224
225        if (n < 0) {
226            perror("ERROR reading from socket");
227            exit(1);
228        }
229        // open log file
230        FEPLogFile.open(FEPLogFileName, ios::app);
231        // send data to atms
232        manageClientConnection(buffer);
233        // close log file
234        FEPLogFile.close();
235        close(newsockfd);
236    }
237}
Note: See TracBrowser for help on using the repository browser.