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