buffet: Add an XMPP client class This is a relatively simple XMPP client class, which at this point, is only used to keep the XMPP connection open to GCD. TEST=FEATURES=test emerge buffet BUG=brillo:95 Change-Id: I2e7c8d7352892bd7c94e630cc7872f32f2298ae4 Reviewed-on: https://chromium-review.googlesource.com/248351 Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Nathan Bullock <nathanbullock@google.com> Tested-by: Nathan Bullock <nathanbullock@google.com>
diff --git a/buffet/xmpp/xmpp_connection.cc b/buffet/xmpp/xmpp_connection.cc new file mode 100644 index 0000000..8799493 --- /dev/null +++ b/buffet/xmpp/xmpp_connection.cc
@@ -0,0 +1,72 @@ +// Copyright 2015 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "buffet/xmpp/xmpp_connection.h" + +#include <arpa/inet.h> +#include <netdb.h> +#include <netinet/in.h> +#include <unistd.h> + +#include <string> + +#include <base/files/file_util.h> +#include <chromeos/syslog_logging.h> + +namespace buffet { + +XmppConnection::~XmppConnection() { + if (fd_ > 0) { + close(fd_); + } +} + +bool XmppConnection::Initialize() { + LOG(INFO) << "Opening XMPP connection"; + + fd_ = socket(AF_INET, SOCK_STREAM, 0); + + // TODO(nathanbullock): Use gethostbyname_r. + struct hostent* server = gethostbyname("talk.google.com"); + if (server == NULL) { + LOG(WARNING) << "Failed to find host talk.google.com"; + return false; + } + + sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy(server->h_addr, &(serv_addr.sin_addr), server->h_length); + serv_addr.sin_port = htons(5222); + + if (connect(fd_, (struct sockaddr*)&serv_addr, sizeof(sockaddr)) < 0) { + LOG(WARNING) << "Failed to connect to talk.google.com:5222"; + return false; + } + + return true; +} + +bool XmppConnection::Read(std::string* msg) const { + char buffer[4096]; // This should be large enough for our purposes. + ssize_t bytes = HANDLE_EINTR(read(fd_, buffer, sizeof(buffer))); + if (bytes < 0) { + LOG(WARNING) << "Failure reading"; + return false; + } + *msg = std::string{buffer, static_cast<size_t>(bytes)}; + VLOG(1) << "READ: (" << msg->size() << ")" << *msg; + return true; +} + +bool XmppConnection::Write(const std::string& msg) const { + VLOG(1) << "WRITE: (" << msg.size() << ")" << msg; + if (!base::WriteFileDescriptor(fd_, msg.c_str(), msg.size())) { + LOG(WARNING) << "Failure writing"; + return false; + } + return true; +} + +} // namespace buffet