#include "Behavior.hh" Behavior::Behavior (char* name, priority_t priorityLevel, int levelID, char* serverHostname, int serverPort) //: // wxThread (wxTHREAD_JOINABLE) { this->name = name; this->priorityLevel = priorityLevel; this->levelID = levelID; this->serverHostname = serverHostname; this->serverPort = serverPort; this->sem = new Semaphore(0); } Behavior::~Behavior () { delete this->sem; } void Behavior::Pause () { sem->bdown (); } void Behavior::Resume () { sem->up (); } void* Behavior::Entry (void* arg) { Behavior* beh = (Behavior*)arg; cout << beh->name << ": Setting up networking." << endl; beh->initializeNetworking (); // setup networking cout << beh->name << ": Registering with manager." << endl; beh->registerWithServer (); // tell the manager that we're alive beh->run (); // get down to business close (beh->server); // do a little cleanup ... cout << beh->name << ": exiting." << endl; return arg; } void Behavior::initializeNetworking () { /************ Begin Client Socket Initialization Section ***************/ hostEntry = gethostbyname (serverHostname); if (hostEntry == NULL) { /* cerr << name.data () << ": Error resolving " << serverHostname.data () << ". Exiting." << endl; */ //exit (1); // ##TODO: this should be changed ... return; } bzero (&ServerAddress, sizeof (ServerAddress)); ServerAddress.sin_family = AF_INET; ServerAddress.sin_port = htons (serverPort); ServerAddress.sin_addr = *((struct in_addr*)hostEntry->h_addr); ServerAddressLength = sizeof (struct sockaddr); /************ End Client Socket Initialization Section ****************/ /************ Begin Server Socket Initialization Section **************/ clientServer = socket (AF_INET, SOCK_STREAM, 0); clientPort = priorityLevel+1024; if (clientPort > 65535) { clientPort = clientPort - 65536 + 1024; } if (clientServer < 0) { /* cerr << name.data () << ": Error creating client server socket." << endl; */ return; } bzero (&ClientServerAddress, sizeof (ClientServerAddress)); ClientServerAddress.sin_family = AF_INET; ClientServerAddress.sin_port = htons (clientPort); ClientServerAddress.sin_addr.s_addr = INADDR_ANY; ClientServerAddressLength = sizeof (ClientServerAddress); ClientAddressLength = sizeof (ClientAddress); if (bind (clientServer, (struct sockaddr*)&ClientServerAddress, ClientServerAddressLength) < 0) { /* cerr << name.data () << ": Error binding to client server socket." << endl; */ return; } if (listen (clientServer, 20) < 0) { /* cerr << name.data () << ": Error listening on client server socket." << endl; */ return; } /************* End Server Socket Initialization Section ***************/ } void Behavior::registerWithServer() { if (sendCommand (REGISTER) != WRITE_OKAY) { /* cerr << name.data () << ": Error registering with server." << endl; */ return; } else { int add = (int)sem; if (write (server, &add, sizeof (&add)) != sizeof (&add)) { /* cerr << name.data () << ": Error registering with server." << endl; */ return; } cerr << name << ": Registered with server." << endl; } } int Behavior::run () { cout << name << ": In base class run()" << endl; return 0; } int Behavior::sendCommand (command_t command) { server = socket (AF_INET, SOCK_STREAM, 0); if (server < 0) { /* cerr << name.data () << ": Error creating client socket (" << server << ")" << endl; */ return PARTIAL_WRITE; } if (connect (server, (struct sockaddr*)&ServerAddress, ServerAddressLength) < 0) { /* cerr << name.data () << ": Error connecting to the Behavior Server." << endl; */ return PARTIAL_WRITE; } if (write (server, &priorityLevel, sizeof (priorityLevel)) != sizeof (priorityLevel)) { /* cerr << name.data () << ": Error sending priority level." << endl; */ close (server); return PARTIAL_WRITE; } if (write (server, &levelID, sizeof (levelID)) != sizeof (levelID)) { //cerr << name.data () << ": Error sending level id." << endl; close (server); return PARTIAL_WRITE; } if (write (server, &command, sizeof (command)) != sizeof(command)) { //cerr << name.data () << ": Error sending command." << endl; close (server); return PARTIAL_WRITE; } /* cerr << name.data () << ": sent (levelID,priorityLevel,command) = (" << levelID << "," << priorityLevel << "," << command << ")" << endl; */ if (command != TESTSUSPEND && command != REGISTER) // Do this just so we can listen back for // something from the server without having // to open up a new socket and stuff ... { close (server); } return WRITE_OKAY; } bool Behavior::testSuspend () { if (sendCommand (TESTSUSPEND) != WRITE_OKAY) { //cerr << name.data () << ": didn't get suspend, continuing" << endl; return false; } int suspend; if (read (server, &suspend, sizeof (suspend)) != sizeof (suspend)) { cerr << name << ": error reading suspend" << endl; return false; } close (server); if (suspend) { //cerr << name.data () << ": got suspend == 1, going to sleep." << endl; onSuspend(); Pause(); onResume(); // TestDestroy (); return true; } else { //cerr << name.data () << ": got suspend == 0, continuing." << endl; } return false; } void Behavior::onSuspend () { //cerr << name.data () << ": Getting suspended. Nothing to do." << endl; } void Behavior::onResume () { cerr << name << ": Getting resumed. Nothing to do." << endl; }