| 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 | */ |
|---|
| 9 | FEPSim::FEPSim(char * ATMShost, char * xml) { |
|---|
| 10 | networkReader = new NetworkReader(xml); |
|---|
| 11 | this->ATMSHost = ATMShost; |
|---|
| 12 | updateATMS(); |
|---|
| 13 | } |
|---|
| 14 | |
|---|
| 15 | /** |
|---|
| 16 | * Destructor |
|---|
| 17 | */ |
|---|
| 18 | FEPSim::~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 | */ |
|---|
| 27 | void 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 | */ |
|---|
| 40 | void 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 | */ |
|---|
| 123 | void 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 | */ |
|---|
| 141 | int 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 | } |
|---|