bool CClientsHandler::SendPing(CClient* client) { CLock lock(m_mutex); //check if any light is used int lightsused = 0; for (unsigned int i = 0; i < client->m_lights.size(); ++i) { if (client->m_lights[i].GetNrUsers() > 0) { lightsused = 1; break; //if one light is used we have enough info } } lock.Leave(); CTcpData data; data.SetData("ping " + ToString(lightsused) + "\n"); if (client->m_socket.Write(data) != SUCCESS) { Log("%s", client->m_socket.GetError().c_str()); return false; } return true; }
//sends light info, like name and area bool CClientsHandler::SendLights(CClient* client) { CTcpData data; //build up messages by appending to CTcpData data.SetData("lights " + ToString(client->m_lights.size()) + "\n"); for (int i = 0; i < client->m_lights.size(); ++i) { data.SetData("light " + client->m_lights[i].GetName() + " ", true); data.SetData("scan ", true); data.SetData(ToString(client->m_lights[i].GetVscan()[0]) + " ", true); data.SetData(ToString(client->m_lights[i].GetVscan()[1]) + " ", true); data.SetData(ToString(client->m_lights[i].GetHscan()[0]) + " ", true); data.SetData(ToString(client->m_lights[i].GetHscan()[1]), true); data.SetData("\n", true); } if (client->m_socket.Write(data) != SUCCESS) { Log("%s", client->m_socket.GetError().c_str()); return false; } return true; }
//parses client messages bool CClientsHandler::ParseMessage(CClient* client, CMessage& message) { CTcpData data; string messagekey; const char *messageString = message.message.c_str(); if (messageString[0] == 'h') { // hello Log("%s:%i said hello", client->m_socket.GetAddress().c_str(), client->m_socket.GetPort()); data.SetData("hello\n"); if (client->m_socket.Write(data) != SUCCESS) { Log("%s", client->m_socket.GetError().c_str()); return false; } CLock lock(m_mutex); if (client->m_connecttime == -1) client->m_connecttime = message.time; } else if (messageString[0] == 'p') { // ping return SendPing(client); } else if (messageString[0] == 'g') { // get messageString = messageString + 4; return ParseGet(client, messageString, message); } else if (messageString[0] == 's' && messageString[1] == 'e') { // set messageString = messageString + 4; return ParseSet(client, messageString, message); } else if (messageString[0] == 's' && messageString[1] == 'y') { // sync return ParseSync(client); } else { LogError("%s:%i sent gibberish", client->m_socket.GetAddress().c_str(), client->m_socket.GetPort()); return false; } return true; }
//this is used to check that boblightd and libboblight have the same protocol version //the check happens in libboblight bool CClientsHandler::SendVersion(CClient* client) { CTcpData data; data.SetData("version " + static_cast<string>(PROTOCOLVERSION) + "\n"); if (client->m_socket.Write(data) != SUCCESS) { Log("%s", client->m_socket.GetError().c_str()); return false; } return true; }
//parses client messages bool CClientsHandler::ParseMessage(CClient* client, CMessage& message) { CTcpData data; string messagekey; //an empty message is invalid if (!GetWord(message.message, messagekey)) { LogError("%s:%i sent gibberish", client->m_socket.GetAddress().c_str(), client->m_socket.GetPort()); return false; } if (messagekey == "hello") { Log("%s:%i said hello", client->m_socket.GetAddress().c_str(), client->m_socket.GetPort()); data.SetData("hello\n"); if (client->m_socket.Write(data) != SUCCESS) { Log("%s", client->m_socket.GetError().c_str()); return false; } CLock lock(m_mutex); if (client->m_connecttime == -1) client->m_connecttime = message.time; } else if (messagekey == "ping") { return SendPing(client); } else if (messagekey == "get") { return ParseGet(client, message); } else if (messagekey == "set") { return ParseSet(client, message); } else if (messagekey == "sync") { return ParseSync(client); } else { LogError("%s:%i sent gibberish", client->m_socket.GetAddress().c_str(), client->m_socket.GetPort()); return false; } return true; }
//called by the connection handler void CClientsHandler::AddClient(CClient* client) { CLock lock(m_mutex); if (m_clients.size() >= FD_SETSIZE) //maximum number of clients reached { LogError("number of clients reached maximum %i", FD_SETSIZE); CTcpData data; data.SetData("full\n"); client->m_socket.Write(data); delete client; return; } //assign lights and put the pointer in the clients vector client->m_lights = m_lights; m_clients.push_back(client); }