netd: Add initial interface driver command support
Change-Id: I1d34e43fc6a3336d0cd06e9db1069467382f210f
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/InterfaceController.cpp b/InterfaceController.cpp
new file mode 100644
index 0000000..a20b13f
--- /dev/null
+++ b/InterfaceController.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define LOG_TAG "InterfaceController"
+#include <cutils/log.h>
+#include <netutils/ifc.h>
+#include <private/android_filesystem_config.h>
+
+#include "InterfaceController.h"
+
+InterfaceController::InterfaceController() {
+ iSock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (iSock < 0)
+ ALOGE("Failed to open socket");
+ iBuf = (char *)malloc(INTERFACE_MAX_BUFFER_SIZE);
+ if (!iBuf)
+ ALOGE("Failed to allocate buffer");
+}
+
+InterfaceController::~InterfaceController() {
+ if (iSock >= 0)
+ close(iSock);
+ if (iBuf)
+ free(iBuf);
+}
+
+int InterfaceController::sendCommand(char *iface, char *cmd, char *buf, int buf_len) {
+ struct ifreq ifr;
+ android_wifi_priv_cmd priv_cmd;
+ int ret;
+
+ if (!iface || !cmd)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+ memset(&priv_cmd, 0, sizeof(priv_cmd));
+ strncpy(ifr.ifr_name, iface, IFNAMSIZ);
+ memcpy(buf, cmd, strlen(cmd) + 1);
+
+ priv_cmd.buf = buf;
+ priv_cmd.used_len = buf_len;
+ priv_cmd.total_len = buf_len;
+ ifr.ifr_data = &priv_cmd;
+
+ if ((ret = ioctl(iSock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
+ ALOGE("Failed to execute command: %s", cmd);
+ } else {
+ if (buf[0] == '\0') {
+ snprintf(buf, buf_len, "OK");
+ }
+ }
+ return ret;
+}
+
+/*
+ * Arguments:
+ * argv[2] - wlan interface
+ * argv[3] - command
+ * argv[4] - argument
+ * rbuf - returned buffer
+ */
+int InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) {
+ char cmd[INTERFACE_MAX_BUFFER_SIZE];
+ unsigned int bc = 0;
+ int ret;
+ int i;
+
+ if ((iSock < 0) || !iBuf || (argc < 4))
+ return -1;
+
+ for (i=3; i < argc; i++) {
+ bc += snprintf(&cmd[bc], sizeof(cmd) - bc, "%s ", argv[i]);
+ }
+ if (bc >= sizeof(cmd))
+ bc = sizeof(cmd) - 1;
+ cmd[bc] = '\0';
+ ret = sendCommand(argv[2], cmd, iBuf, INTERFACE_MAX_BUFFER_SIZE);
+ if (rbuf)
+ *rbuf = iBuf;
+ return ret;
+}