/* PSP Network function calls */ #include "../include/DebugRoutines.h" #include "../include/JNetwork.h" #if defined (WIN32) || defined (LINUX) #else #ifdef NETWORK_SUPPORT #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #endif #include #include "../include/JSocket.h" map JNetwork::sCommandMap; bool JNetwork::isConnected(){ if (connected_to_ap !=1 || !socket) return false; return socket->isConnected(); } void JNetwork::getServerIp(string& aString) { #ifdef WIN32 char ac[80]; if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) { DebugTrace("Error " << WSAGetLastError() << " when getting local host name.\n"); return; } DebugTrace( "Host name is " << ac << ".\n"); struct hostent *phe = gethostbyname(ac); if (phe == 0) { DebugTrace("Yow! Bad host lookup.\n"); return; } for (int i = 0; phe->h_addr_list[i] != 0; ++i) { struct in_addr addr; memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); aString = inet_ntoa(addr); } #else aString = "No clue"; #endif } JNetwork::JNetwork() : mpWorkerThread(NULL), socket(0) { #if (defined WIN32) || (defined LINUX) connected_to_ap = 1; #else connected_to_ap = 0; #endif } JNetwork::~JNetwork() { if(mpWorkerThread) { socket->Disconnect(); mpWorkerThread->join(); delete mpWorkerThread; } if(socket) delete socket; } bool JNetwork::sendCommand(const string& xString, const string& payload, const string& suffix) { string aString; boost::mutex::scoped_lock l(sendMutex); if(!socket) { DebugTrace("sendCommand failed: no socket"); return false; } aString = xString + suffix; if(sCommandMap.find(aString) == sCommandMap.end()) { DebugTrace("sendCommand failed: command not registered"); return false; } aString = "<" + aString + ">" + "\n" + payload + "\n" + "<" + aString + "/>"; toSend << aString; return true; } void JNetwork::registerCommand(string command, void* object, processCmd processCommand, processCmd processResponse) { CommandStruc struc; struc.object = object; struc.command = command; struc.processCommand = processCommand; sCommandMap[command + "Request"] = struc; struc.processCommand = processResponse; sCommandMap[command + "Response"] = struc; } void JNetwork::Update() { boost::mutex::scoped_lock r(receiveMutex); // Checking for some command to execute size_t begin_start_tag = received.str().find("<"); size_t end_start_tag = received.str().find(">"); string command = received.str().substr(begin_start_tag+1, end_start_tag-(begin_start_tag+1)); size_t begin_end_tag = received.str().find(command + "/>"); size_t end_end_tag = received.str().find("/>"); if(begin_start_tag != string::npos && begin_end_tag != string::npos ) { map::iterator ite = sCommandMap.find(command); if(ite != sCommandMap.end()) { DebugTrace("begin of command received : " + received.str() ); DebugTrace("begin of command toSend : " + toSend.str() ); processCmd theMethod = (ite)->second.processCommand; stringstream input(received.str().substr(end_start_tag+1, (begin_end_tag-1)-(end_start_tag+1))); stringstream output; theMethod((ite)->second.object, input, output); string aString = received.str().substr(end_end_tag+2, string::npos); received.str(aString); if(output.str().size()) sendCommand((ite)->second.command, output.str(), "Response"); DebugTrace("end of command received : "<< received.str() ); DebugTrace("end of command toSend : "<< toSend.str() ); } } } void JNetwork::ThreadProc(void* param) { JNetwork* pThis = reinterpret_cast(param); JSocket* pSocket = NULL; if (pThis->serverIP.size()) { DebugTrace("Starting Client Thread"); pThis->socket = new JSocket(pThis->serverIP); if(pThis->socket->isConnected()) pSocket = pThis->socket; } else { DebugTrace("Starting Server Thread"); pThis->socket = new JSocket(); // Wait for some client pSocket = pThis->socket->Accept(); } while(pSocket && pSocket->isConnected()) { char buff[4096]; { int len = pSocket->Read(buff, sizeof(buff)); if(len > 0) { boost::mutex::scoped_lock l(pThis->receiveMutex); DebugTrace("receiving " << len << " bytes : " << buff); pThis->received.str(pThis->received.str() + buff); DebugTrace("received " << pThis->received.str().size() << " bytes : " << pThis->received.str()); } } { boost::mutex::scoped_lock l(pThis->sendMutex); if(!pThis->toSend.str().empty()) { DebugTrace("sending " << pThis->toSend.str().size() << " bytes : " << pThis->toSend.str()); pSocket->Write((char*)pThis->toSend.str().c_str(), pThis->toSend.str().size()+1); pThis->toSend.str(""); } } boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } DebugTrace("Quitting Thread"); } #if defined (WIN32) || defined (LINUX) int JNetwork::connect(const string& ip) { if (mpWorkerThread) return 0; serverIP = ip; mpWorkerThread = new boost::thread(JNetwork::ThreadProc, this); return 42; } #else int JNetwork::connect(const string& serverIP){ #ifdef NETWORK_SUPPORT int err; char buffer[4096]; if(netthread) return 0; sceUtilityLoadNetModule(1); sceUtilityLoadNetModule(3); if((err = pspSdkInetInit())){ sprintf(buffer, "JGE Error, could not initialise the network %08X", err); printf(buffer); printf("\n"); error = buffer; return err; } if(JNetwork::connect_to_apctl(1)){ JNetwork::serverIP = serverIP; /* Create a user thread to do the real work */ netthread = sceKernelCreateThread("net_thread", net_thread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL); if(netthread < 0) { printf("Error, could not create thread\n"); sceKernelSleepThread(); } sceKernelStartThread(netthread, 0, NULL); return netthread; } #endif return 0; } /* Connect to an access point */ int JNetwork::connect_to_apctl(int config) { #ifdef NETWORK_SUPPORT int err; int stateLast = -1; char buffer[4096]; /* Connect using the first profile */ err = sceNetApctlConnect(config); if (err != 0) { sprintf(buffer, "JGE: sceNetApctlConnect returns %08X", err); printf(buffer);printf("\n"); error = buffer; return 0; } sprintf(buffer,"JGE: Connecting..."); printf(buffer);printf("\n"); error = buffer; while (1) { int state; err = sceNetApctlGetState(&state); if (err != 0) { sprintf(buffer,"JGE: sceNetApctlGetState returns $%x", err); printf(buffer);printf("\n"); error = buffer; break; } if (state > stateLast) { sprintf(buffer, " connection state %d of 4", state); printf(buffer);printf("\n"); error = buffer; stateLast = state; } if (state == 4){ connected_to_ap = 1; break; // connected with static IP } // wait a little before polling again sceKernelDelayThread(50*1000); // 50ms } printf("JGE: Connected!\n"); if(err != 0) { return 0; } #endif return 1; } #endif