#include "FEPSim.h" /** * Constructor * * @param host The host rpc server ip address * @param networkFile the xml network file */ FEPSim::FEPSim(char * ATMShost, char * xml) { networkReader = new NetworkReader(xml); this->ATMSHost = ATMShost; updateATMS(); } /** * Destructor */ FEPSim::~FEPSim() { cout << "Destroying client..." << endl; clnt_destroy(clnt); } /** * Handler for the ATMS RPC Response (to the client RPC Call) * @param response pointer to fep_reply struct */ void FEPSim::handleCallResponse(void *response) { /* If ATMS reply call fails */ if (response == NULL) { clnt_perror(clnt, "RPC call failed"); }/* If ATMS reply is successful */ else { cout << "Successful RPC call to ATMS..." << endl; } } /** * Sends an fep_reply for every line in the FEP. */ void FEPSim::updateATMS() { int i, j; // i == line_index, j == lds_index void *rv; vector lines = networkReader->getLines(); vector ldsMap = networkReader->getStations(); // Send one reply for every "line" in the FEP for (i = 0; i < lines.size(); i++) { fep_reply fepReply; cout << "Sending fepReply for line #" << lines.at(i)->lineNum << endl; // populate reply fepReply.reply = SHORTPOLL; fepReply.schedule = lines.at(i)->schedule; fepReply.lineinfo = lines.at(i)->lineInfo; fepReply.kind = (enum polltype) 0; fepReply.flag = (enum replykind) 0; /*********************************** This is an update to an extern, this should happen on the Java driver side?? lines.at(i).schedleSeq += 1; lines.at(i).globalSeq += 51; */ fepReply.schedule_sequence = lines.at(i)->schedleSeq; fepReply.global_sequence = lines.at(i)->globalSeq; /************************************ Need to find out what appropriate schedule time is: look at uci_unix_simulation_time src code fepReply.schedule_time = uci_unix_simulation_time(uci_simulation_time()); // GMT time */ fepReply.schedule_time = time(NULL); fepReply.user_info1 = lines.at(i)->lineNum; fepReply.user_info2 = lines.at(i)->lineNum; fepReply.system_key = lines.at(i)->systemKey; fepReply.answers.size = 1; fepReply.answers.fep_answer_list_u.shortp.count = 1; /* for each LDS in the Line.... (constructs the short_answer message) */ for (j = 0; j < lines.at(i)->lds.size(); j++) { fep_shortanswer fsa; int index = lines.at(i)->ldsIndex.at(j); cout << "LDS index: " << index << endl; // msg: oa, od, ldsMap.at(index).dataPack, od, ff fsa.msg.message_len = ldsMap.at(index)->length + 2; fsa.msg.message[0] = 0x0d; fsa.msg.message[1] = 0x0a; for (int k = 0; k < ldsMap.at(index)->length; k++) fsa.msg.message[2 + k] = ldsMap.at(index)->dataPack[k]; int aa = ldsMap.at(index)->length; fsa.msg.message[2 + aa] = 0x0d; fsa.msg.message[3 + aa] = 0xff; //????????????? warning ????? // info fsa.info.poll_error_count = 0; /*************************************** Need to find out polltime uci time function src code fsa.info.poll_time = uci_unix_simulation_time(uci_simulation_time()); */ fsa.info.poll_user_info1 = ldsMap.at(index)->drop; // drop number fsa.info.poll_user_info2 = 1; //always 1 fsa.info.retries = 0; fsa.info.status = (enum replystatus) 1; //fepReply.answers.fep_answer_list_u.shortp.answers[j +1] = fsa; fepReply.answers.fep_answer_list_u.shortp.answers[0] = fsa; // send out data printf("Transferring line=%d, lds_drop_no=%d...\n", lines.at(i)->lineNum, ldsMap.at(index)->drop); rv = fep_reply_xfer_32(&fepReply, clnt); /* Handle ATMS response to RPC Call */ printf("Handling ATMS response...\n"); handleCallResponse(rv); } } } /** * Creates the RPC Client. If not successful, exit with status 1. * @param host rpc server ip */ void FEPSim::createClient(char * host) { /* Create RPC Client to communicate with ATMS */ cout << "Creating RPC Client" << endl; clnt = clnt_create(host, /*100090,*/ 103121, 32, "tcp"); cout << "Client created" << endl; /* Check if client creation failed */ if (clnt == (CLIENT *) NULL) { cerr << "Can't create client to " << host << endl; exit(1); } } /** * Main driver for ATMSCommunicator. Creates an RPC Client from command line args. * @param argc * @param argv * @return */ int main(int argc, char *argv[]) { int sockfd, newsockfd, portno, clilen; char buffer[BUFF_SIZE]; struct sockaddr_in serv_addr, cli_addr; int n; char *FEPSimHost = argv[1]; portno = atoi(argv[2]); /* First call to socket() function */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } /* Initialize socket structure */ bzero((char *) &serv_addr, sizeof (serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); /* Now bind the host address using bind() call.*/ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) { perror("ERROR on binding"); exit(1); } /* Now start listening for the clients, here process will * go in sleep mode and will wait for the incoming connection */ listen(sockfd, 5); clilen = sizeof (cli_addr); /* Accept actual connection from the client */ while(1) { newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen); if (newsockfd < 0) { perror("ERROR on accept"); exit(1); } /* If connection is established then start communicating */ bzero(buffer, BUFF_SIZE); // NEEDS OUTER LOOP TO GET WHOLE MESSAGE FROM TCP CONN n = read(newsockfd, buffer, sizeof(buffer)); if (n < 0) { perror("ERROR reading from socket"); exit(1); } /* Create RPC Client to send an fep_reply to ATMS */ FEPSim *client = new FEPSim(FEPSimHost, buffer); delete client; } return 0; }