bool CMessageBrokerController::checkMessage(Json::Value& root, Json::Value& error) { DBG_MSG(("CMessageBrokerController::checkMessage()\n")); Json::Value err; try { /* check the JSON-RPC version => 2.0 */ if (!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0") { error["id"] = Json::Value::null; error["jsonrpc"] = "2.0"; err["code"] = NsMessageBroker::INVALID_REQUEST; err["message"] = "Invalid MessageBroker request."; error["error"] = err; return false; } if (root.isMember("id") && (root["id"].isArray() || root["id"].isObject())) { error["id"] = Json::Value::null; error["jsonrpc"] = "2.0"; err["code"] = NsMessageBroker::INVALID_REQUEST; err["message"] = "Invalid MessageBroker request."; error["error"] = err; return false; } if (root.isMember("method")) { if (!root["method"].isString()) { error["id"] = Json::Value::null; error["jsonrpc"] = "2.0"; err["code"] = NsMessageBroker::INVALID_REQUEST; err["message"] = "Invalid MessageBroker request."; error["error"] = err; return false; } /* Check the params is an object*/ if (root.isMember("params") && !root["params"].isObject()) { error["id"] = Json::Value::null; error["jsonrpc"] = "2.0"; err["code"] = INVALID_REQUEST; err["message"] = "Invalid JSONRPC params."; error["error"] = err; return false; } } else if (!root.isMember("result") && !root.isMember("error")) { return false; } return true; } catch (...) { DBG_MSG_ERROR(("CMessageBrokerController::checkMessage() EXCEPTION has been caught!\n")); return false; } }
void CMessageBrokerController::onMessageReceived(Json::Value message) { // Determine message type and process... Json::Value error; if (checkMessage(message, error)) { if (isNotification(message)) { DBG_MSG(("Message is notification!\n")); processNotification(message); } else if (isResponse(message)) { std::string id = message["id"].asString(); std::string method = findMethodById(id); DBG_MSG(("Message is response on: %s\n", method.c_str())); if ("" != method) { if ("MB.registerComponent" == method) { // initialize mControllersIdStart if (message.isMember("result") && message["result"].isInt()) { mControllersIdStart = message["result"].asInt(); } else { DBG_MSG_ERROR(("Not possible to initialize mControllersIdStart!\n")); } } else if ("MB.subscribeTo" == method || "MB.unregisterComponent" == method || "MB.unsubscribeFrom" == method) { //nothing to do for now } else { processResponse(method, message); } } else { DBG_MSG_ERROR(("Request with id %s has not been found!\n", id.c_str())); } } else { DBG_MSG(("Message is request!\n")); processRequest(message); } } else { DBG_MSG_ERROR(("Message contains wrong data!\n")); } }
void CMessageBrokerControllerPhone::processRequest(Json::Value& root) { DBG_MSG(("CMessageBrokerControllerPhone::processRequest()\n")); if (getControllersName() == getDestinationComponentName(root)) { Json::Value response; response["jsonrpc"] = root["jsonrpc"]; response["id"] = root["id"]; if ("makeCall" == getMethodName(root)) { if (root.isMember("params")) { Json::Value params = root["params"]; if (params.isMember("phoneNumber") && params["phoneNumber"].isString()) { makeCall(params["phoneNumber"].asString(), response); } else { DBG_MSG_ERROR(("Wrong params!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params!", response); } } else { DBG_MSG_ERROR(("Not possible to parse phone number!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Not possible to parse phone number!", response); } } else if ("endCall" == getMethodName(root)) { endCall(root["params"].asString(), response); } else if ("holdCall" == getMethodName(root)) { holdCall(root["params"].asString(), response); } else if ("getContacts" == getMethodName(root)) { if (root.isMember("params")) { Json::Value params = root["params"]; if (params.isMember("firstLetter") && params["firstLetter"].isString() && params.isMember("offset") && params["offset"].isInt() && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) { getContacts(params["firstLetter"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); } else { DBG_MSG_ERROR(("Wrong params of getContacts()!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getContacts()!", response); } } else { DBG_MSG_ERROR(("Params is not an object!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); } } else if ("getHistory" == getMethodName(root)) { if (root.isMember("params")) { Json::Value params = root["params"]; if (params.isMember("typeOfContacts") && params["typeOfContacts"].isString() && params.isMember("offset") && params["offset"].isInt() && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) { getHistory(params["typeOfContacts"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); } else { DBG_MSG_ERROR(("Wrong params of getHistory()!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getHistory()!", response); } } else { DBG_MSG_ERROR(("Params is not an object!\n")); prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); } } else { DBG_MSG_ERROR(("Method has not been found!\n")); Json::Value err; err["code"] = NsMessageBroker::INVALID_REQUEST; err["message"] = "Method has not been found."; response["error"] = err; } sendJsonMessage(response); } else { DBG_MSG_ERROR(("Wrong message destination!\n")); } }
int CWebSocketHandler::parseWebSocketData(char* Buffer, unsigned int& b_size) { // Please see RFC6455 standard protocol specification: //http://tools.ietf.org/html/rfc6455 // Chapter 5.2 DBG_MSG(("CWebSocketHandler::parseWebSocketData()b_size = %d\n", b_size)); char* recBuffer = Buffer; unsigned int parsedBufferPosition = 0; unsigned char position = 0; // current buffer position unsigned int size = b_size; static uint32_t minimum_heade_size = 4; while (minimum_heade_size < size) { bool fin = ((recBuffer[0] & 0x80) | (recBuffer[0] & 0x01)) == 0x81; bool rsv1 = (recBuffer[0] & 0x40) == 0x40; bool rsv2 = (recBuffer[0] & 0x20) == 0x20; bool rsv3 = (recBuffer[0] & 0x10) == 0x10; unsigned char opCode = ((recBuffer[0] & 0x08) | (recBuffer[0] & 0x04) | (recBuffer[0] & 0x02) | (recBuffer[0] & 0x01)); bool mask = (recBuffer[1] & 0x80) == 0x80; DBG_MSG(("CWebSocketHandler::fin = %d recBuffer[0] = 0x%02X\n" " parsedlength = %d b_size= %d parsedBufferPosition = %d\n" "rsv1 = %d, rsv2 = %d, rsv3 = %d, opCode = %u\n", fin, recBuffer[0], parsedBufferPosition + position, size, parsedBufferPosition, rsv1, rsv2, rsv3, opCode)); if ((rsv1)|(rsv2)|(rsv3)) { DBG_MSG(("rsv1 or rsv2 or rsv3 is 0 \n")); break; } switch(opCode) { case 0x0: break; //Continuation frame case 0x1: break; //Text Frame case 0x2: break; //Binary Frame case 0x8: break; //Connection close Frame case 0x9: break; //ping Frame case 0xA: break; //Pong Frame default: break; //Unknown frame } if (false == fin) { break; } unsigned char payload = (unsigned char) ((recBuffer[1] & 0x40) | (recBuffer[1] & 0x20) | (recBuffer[1] & 0x10) | (recBuffer[1] & 0x08) | (recBuffer[1] & 0x04) | (recBuffer[1] & 0x02) | (recBuffer[1] & 0x01)); unsigned long length = parseWebSocketDataLength(recBuffer, size); position = 2; if (length > size) { DBG_MSG_ERROR(("Incomplete message")); break; } switch(payload) { case 126: { position +=2; break; } case 127: { position +=8; break; } default: { break; } } if (mask) { unsigned char maskKeys[4]; maskKeys[0] = recBuffer[position++]; maskKeys[1] = recBuffer[position++]; maskKeys[2] = recBuffer[position++]; maskKeys[3] = recBuffer[position++]; DBG_MSG(("CWebSocketHandler::parseWebSocketData()maskKeys[0]:0x%02X;" "maskKeys[1]:0x%02X; maskKeys[2]:0x%02X; maskKeys[3]:0x%02X\n" , maskKeys[0], maskKeys[1], maskKeys[2], maskKeys[3])); for (unsigned long i = position; i < position+length; i++) { recBuffer[i] = recBuffer[i] ^ maskKeys[(i-position)%4]; } } DBG_MSG(("CWebSocketHandler::parseWebSocketData()length:%d; size:%d;" " position:%d\n", (int)length, size, position)); for (unsigned long i = 0; (i < size); i++) { Buffer[parsedBufferPosition + i] = recBuffer[i+position]; } b_size -= position; parsedBufferPosition += length; recBuffer += length; size -= length+position; } return b_size; }
bool TcpServer::Recv(int fd) { DBG_MSG(("TcpServer::Recv(%d)\n", fd)); std::string* pReceivingBuffer = getBufferFor(fd); bool buffer_was_not_empty = pReceivingBuffer->size() > 0; std::vector<char> buf; buf.reserve(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); DBG_MSG(("Left in pReceivingBuffer: %d \n", pReceivingBuffer->size())); buf.assign(pReceivingBuffer->c_str(), pReceivingBuffer->c_str() + pReceivingBuffer->size()); buf.resize(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); int received_bytes = recv(fd, &buf[pReceivingBuffer->size()], MAX_RECV_DATA, 0); if (received_bytes <= 0) { DBG_MSG(("Received %d bytes from %d; error = %d\n", received_bytes, fd, errno)); m_purge.push_back(fd); return false; } unsigned int nb = received_bytes; std::vector<char> last_msg_buf(buf.begin()+pReceivingBuffer->size(), buf.begin()+pReceivingBuffer->size()+nb); DBG_MSG(("Recieved %d from %d\n", nb, fd)); nb += static_cast<unsigned int>(pReceivingBuffer->size()); DBG_MSG(("Recieved with buffer %d from %d\n", nb, fd)); if (nb > 0) { // This is redundant if (isWebSocket(fd)) { const unsigned int data_length = mWebSocketHandler.parseWebSocketDataLength(&buf[0], nb); DBG_MSG(("Received %d actual data length %d\n", nb, data_length)); if (data_length > nb) { DBG_MSG_ERROR(("Received %d actual data length %d\n", nb, data_length)); DBG_MSG_ERROR(("Incomplete message")); *pReceivingBuffer = std::string(&buf[0], nb); return false; } mWebSocketHandler.parseWebSocketData(&buf[0], nb); } *pReceivingBuffer = std::string(&buf[0], nb); DBG_MSG(("pReceivingBuffer before onMessageReceived:%d : %s\n", pReceivingBuffer->size(), pReceivingBuffer->c_str())); // we need to check for websocket handshake if (!checkWebSocketHandShake(fd, pReceivingBuffer)) { //JSON MESSAGE received. Send data in CMessageBroker. if (mpMessageBroker) { size_t buffer_size_before = pReceivingBuffer->size(); mpMessageBroker->onMessageReceived(fd, *pReceivingBuffer, true); if (buffer_was_not_empty && (pReceivingBuffer->size() == buffer_size_before)) { /* We couldn't parse the buffer (with the last message at the end) * Try to parse ONLY the last message */ DBG_MSG_ERROR(("Couldn't parse the whole buffer! Try only the last message.\n")); nb = static_cast<unsigned int>(last_msg_buf.size()); if (isWebSocket(fd)) { const unsigned int data_length = mWebSocketHandler.parseWebSocketDataLength(&last_msg_buf[0], nb); if (data_length > nb) { DBG_MSG_ERROR(("The last message may be incomplete. Don't do anything.\n")); /* Should we replace the buffer with the last message? * Probably not. It may not be a real websocket message. * Wait for a full message. */ return false; } mWebSocketHandler.parseWebSocketData(&last_msg_buf[0], nb); } std::string last_message = std::string(&last_msg_buf[0], nb); buffer_size_before = last_message.size(); mpMessageBroker->onMessageReceived(fd, last_message, false); if ( last_message.size() < buffer_size_before ) { /* Parsing last message successful! Discard the old data and * keep only what is left from the last message */ DBG_MSG_ERROR(("Parsing last message successful! Discard the old data.\n")); *pReceivingBuffer = last_message; } } } else { return false; } } else { // message is a websocket handshake ssize_t webSocketKeyPos = pReceivingBuffer->find("Sec-WebSocket-Key: "); if (-1 != webSocketKeyPos) { std::string handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\n" "Connection: Upgrade\r\nSec-WebSocket-Accept: "; std::string wsKey = pReceivingBuffer->substr(webSocketKeyPos + 19, 24); mWebSocketHandler.handshake_0405(wsKey); handshakeResponse += wsKey; handshakeResponse += "\r\n\r\n"; pReceivingBuffer->clear(); std::list<int>::iterator acceptedClientIt = find(m_AcceptedClients.begin(), m_AcceptedClients.end(), fd); if (m_AcceptedClients.end() != acceptedClientIt) { m_AcceptedClients.erase(acceptedClientIt); } Send(fd, handshakeResponse); m_WebSocketClients.push_back(fd); } } } return true; }