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

Revision 224, 6.4 KB checked in by jdalbey, 8 years ago (diff)

FEPSim.cpp Added a comment containing code to let ATMS server catch up.

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