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

Revision 82, 6.5 KB checked in by jtorres, 9 years ago (diff)

Added socket client to ATMSDriver. Added socket server to FEPSim

Line 
1#include "FEPSim.h"
2
3/**
4 * Constructor
5 *
6 * @param host The host rpc server ip address
7 * @param networkFile the xml network file
8 */
9FEPSim::FEPSim(char * ATMShost, char * xml) {
10    networkReader = new NetworkReader(xml);
11    this->ATMSHost = ATMShost;
12    updateATMS();
13}
14
15/**
16 * Destructor
17 */
18FEPSim::~FEPSim() {
19    cout << "Destroying client..." << endl;
20    clnt_destroy(clnt);
21}
22
23/**
24 * Handler for the ATMS RPC Response (to the client RPC Call)
25 * @param response pointer to fep_reply struct
26 */
27void FEPSim::handleCallResponse(void *response) {
28    /* If ATMS reply call fails */
29    if (response == NULL) {
30        clnt_perror(clnt, "RPC call failed");
31    }/* If ATMS reply is successful */
32    else {
33        cout << "Successful RPC call to ATMS..." << endl;
34    }
35}
36
37/**
38 * Sends an fep_reply for every line in the FEP.
39 */
40void FEPSim::updateATMS() {
41    int i, j; // i == line_index, j == lds_index
42    void *rv;
43    vector<FEP_LINE*> lines = networkReader->getLines();
44    vector<STATION*> ldsMap = networkReader->getStations();
45
46    // Send one reply for every "line" in the FEP
47    for (i = 0; i < lines.size(); i++) {
48        fep_reply fepReply;
49        cout << "Sending fepReply for line #" << lines.at(i)->lineNum << endl;
50        // populate reply
51        fepReply.reply = SHORTPOLL;
52        fepReply.schedule = lines.at(i)->schedule;
53        fepReply.lineinfo = lines.at(i)->lineInfo;
54        fepReply.kind = (enum polltype) 0;
55        fepReply.flag = (enum replykind) 0;
56
57        /***********************************
58                 This is an update to an extern, this should happen on the Java driver side??
59        lines.at(i).schedleSeq += 1;
60        lines.at(i).globalSeq += 51;
61         */
62
63        fepReply.schedule_sequence = lines.at(i)->schedleSeq;
64        fepReply.global_sequence = lines.at(i)->globalSeq;
65        /************************************
66                 Need to find out what appropriate schedule time is: look at uci_unix_simulation_time src code
67        fepReply.schedule_time =
68                uci_unix_simulation_time(uci_simulation_time());        // GMT time
69         */
70        fepReply.schedule_time = time(NULL);
71
72        fepReply.user_info1 = lines.at(i)->lineNum;
73        fepReply.user_info2 = lines.at(i)->lineNum;
74        fepReply.system_key = lines.at(i)->systemKey;
75
76        fepReply.answers.size = 1;
77        fepReply.answers.fep_answer_list_u.shortp.count = 1;
78
79        /* for each LDS in the Line.... (constructs the short_answer message) */
80        for (j = 0; j < lines.at(i)->lds.size(); j++) {
81            fep_shortanswer fsa;
82            int index = lines.at(i)->ldsIndex.at(j);
83            cout << "LDS index: " << index << endl;
84            // msg: oa, od, ldsMap.at(index).dataPack, od, ff
85            fsa.msg.message_len = ldsMap.at(index)->length + 2;
86            fsa.msg.message[0] = 0x0d;
87            fsa.msg.message[1] = 0x0a;
88            for (int k = 0; k < ldsMap.at(index)->length; k++)
89                fsa.msg.message[2 + k] = ldsMap.at(index)->dataPack[k];
90            int aa = ldsMap.at(index)->length;
91            fsa.msg.message[2 + aa] = 0x0d;
92            fsa.msg.message[3 + aa] = 0xff; //????????????? warning ?????
93
94            // info
95            fsa.info.poll_error_count = 0;
96            /***************************************
97                     Need to find out polltime uci time function src code
98            fsa.info.poll_time = uci_unix_simulation_time(uci_simulation_time());
99             */
100            fsa.info.poll_user_info1 = ldsMap.at(index)->drop; // drop number
101            fsa.info.poll_user_info2 = 1; //always 1
102            fsa.info.retries = 0;
103            fsa.info.status = (enum replystatus) 1;
104
105            //fepReply.answers.fep_answer_list_u.shortp.answers[j +1] = fsa;
106            fepReply.answers.fep_answer_list_u.shortp.answers[0] = fsa;
107
108            // send out data
109            printf("Transferring line=%d, lds_drop_no=%d...\n", lines.at(i)->lineNum, ldsMap.at(index)->drop);
110            rv = fep_reply_xfer_32(&fepReply, clnt);
111
112            /* Handle ATMS response to RPC Call */
113            printf("Handling ATMS response...\n");
114            handleCallResponse(rv);
115        }
116    }
117}
118
119/**
120 * Creates the RPC Client. If not successful, exit with status 1.
121 * @param host rpc server ip
122 */
123void FEPSim::createClient(char * host) {
124    /* Create RPC Client to communicate with ATMS */
125    cout << "Creating RPC Client" << endl;
126    clnt = clnt_create(host, /*100090,*/ 103121, 32, "tcp");
127    cout << "Client created" << endl;
128    /* Check if client creation failed */
129    if (clnt == (CLIENT *) NULL) {
130        cerr << "Can't create client to " << host << endl;
131        exit(1);
132    }
133}
134
135/**
136 * Main driver for ATMSCommunicator. Creates an RPC Client from command line args.
137 * @param argc
138 * @param argv
139 * @return
140 */
141int main(int argc, char *argv[]) {
142
143    int sockfd, newsockfd, portno, clilen;
144    char buffer[BUFF_SIZE];
145    struct sockaddr_in serv_addr, cli_addr;
146    int n;
147   
148    char *FEPSimHost = argv[1];
149    portno = atoi(argv[2]);
150
151    /* First call to socket() function */
152    sockfd = socket(AF_INET, SOCK_STREAM, 0);
153
154    if (sockfd < 0) {
155        perror("ERROR opening socket");
156        exit(1);
157    }
158
159    /* Initialize socket structure */
160    bzero((char *) &serv_addr, sizeof (serv_addr));
161
162    serv_addr.sin_family = AF_INET;
163    serv_addr.sin_addr.s_addr = INADDR_ANY;
164    serv_addr.sin_port = htons(portno);
165
166    /* Now bind the host address using bind() call.*/
167    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
168        perror("ERROR on binding");
169        exit(1);
170    }
171
172    /* Now start listening for the clients, here process will
173     * go in sleep mode and will wait for the incoming connection
174     */
175
176    listen(sockfd, 5);
177    clilen = sizeof (cli_addr);
178
179    /* Accept actual connection from the client */
180    while(1) {
181        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
182
183        if (newsockfd < 0) {
184            perror("ERROR on accept");
185            exit(1);
186        }
187
188        /* If connection is established then start communicating */
189        bzero(buffer, BUFF_SIZE);
190       
191        // NEEDS OUTER LOOP TO GET WHOLE MESSAGE FROM TCP CONN
192        n = read(newsockfd, buffer, sizeof(buffer));
193
194        if (n < 0) {
195            perror("ERROR reading from socket");
196            exit(1);
197        }
198       
199        /* Create RPC Client to send an fep_reply to ATMS */
200
201        FEPSim *client = new FEPSim(FEPSimHost, buffer);
202        delete client;
203    }
204
205    return 0;
206}
Note: See TracBrowser for help on using the repository browser.