From 329c3b4681e2ca4831adc7c8cf257e9e32971710 Mon Sep 17 00:00:00 2001 From: Sasha Levitskiy Date: Mon, 30 Jul 2012 16:11:23 -0700 Subject: [PATCH] Changes the interface command API from static lib to a dynamic one Change-Id: I9116491a3f5dfc4590ffab367a224fde37a4fd50 --- Android.mk | 2 +- InterfaceController.cpp | 116 +++++++++++++++++++++++------------------------- InterfaceController.h | 27 +++++------ 3 files changed, 70 insertions(+), 75 deletions(-) diff --git a/Android.mk b/Android.mk index 811e875..582f0a6 100644 --- a/Android.mk +++ b/Android.mk @@ -42,7 +42,7 @@ LOCAL_C_INCLUDES := $(KERNEL_HEADERS) \ LOCAL_CFLAGS := -Werror=format LOCAL_SHARED_LIBRARIES := libstlport libsysutils libcutils libnetutils \ - libcrypto libhardware_legacy libmdnssd + libcrypto libhardware_legacy libmdnssd libdl ifeq ($(BOARD_HAVE_BLUETOOTH),true) LOCAL_SHARED_LIBRARIES := $(LOCAL_SHARED_LIBRARIES) libbluedroid diff --git a/InterfaceController.cpp b/InterfaceController.cpp index a20b13f..25200e9 100644 --- a/InterfaceController.cpp +++ b/InterfaceController.cpp @@ -5,7 +5,7 @@ * 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 + * 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, @@ -19,6 +19,8 @@ #include #include +#include + #include #include #include @@ -34,74 +36,66 @@ #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"); -} +char if_cmd_lib_file_name[] = "/system/lib/libnetcmdiface.so"; +char set_cmd_func_name[] = "net_iface_send_command"; +char set_cmd_init_func_name[] = "net_iface_send_command_init"; +char set_cmd_fini_func_name[] = "net_iface_send_command_fini"; -InterfaceController::~InterfaceController() { - if (iSock >= 0) - close(iSock); - if (iBuf) - free(iBuf); +InterfaceController::InterfaceController() + : sendCommand_(NULL) { + libh_ = dlopen(if_cmd_lib_file_name, RTLD_NOW | RTLD_LOCAL); + if (libh_ == NULL) { + const char *err_str = dlerror(); + ALOGE("Error (%s) while opening the net interface command library", err_str ? err_str : "unknown"); + } else { + sendCommandInit_ = (int (*)(void))dlsym(libh_, set_cmd_init_func_name); + if (sendCommandInit_ == NULL) { + const char *err_str = dlerror(); + ALOGW("Error (%s) while searching for the interface command init function", err_str ? err_str : "unknown"); + } else if (sendCommandInit_()) { + ALOGE("Can't init the interface command API"); + return; + } + sendCommandFini_ = (int (*)(void))dlsym(libh_, set_cmd_fini_func_name); + if (sendCommandFini_ == NULL) { + const char *err_str = dlerror(); + ALOGW("Error (%s) while searching for the interface command fini function", err_str ? err_str : "unknown"); + } + sendCommand_ = (int (*)(int, char **, char **))dlsym(libh_, set_cmd_func_name); + if (sendCommand_ == NULL) { + const char *err_str = dlerror(); + ALOGE("Error (%s) while searching for the interface command function", err_str ? err_str : "unknown"); + return; + } + } } -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; +InterfaceController::~InterfaceController() { + if (sendCommandFini_) { + if (sendCommandFini_()) { + ALOGE("Can't shutdown the interface command API"); + } + } + if (libh_) { + int err = dlclose(libh_); + if (err) { + const char *err_str = dlerror(); + ALOGE("Error (%s) while closing the net interface command library", err_str ? err_str : "unknown"); + } + } } /* * Arguments: - * argv[2] - wlan interface - * argv[3] - command - * argv[4] - argument - * rbuf - returned buffer + * 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; + int ret = -ENOSYS; + if (sendCommand_) + ret = sendCommand_(argc, argv, rbuf); - 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; + return ret; } diff --git a/InterfaceController.h b/InterfaceController.h index dbedc13..e31cc11 100644 --- a/InterfaceController.h +++ b/InterfaceController.h @@ -5,7 +5,7 @@ * 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 + * 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, @@ -21,23 +21,24 @@ #include typedef struct android_wifi_priv_cmd { - char *buf; - int used_len; - int total_len; + char *buf; + int used_len; + int total_len; } android_wifi_priv_cmd; #define INTERFACE_MAX_BUFFER_SIZE 256 class InterfaceController { - int iSock; - char *iBuf; - - int sendCommand(char *iface, char *cmd, char *buf, int buf_len); -public: - InterfaceController(); - virtual ~InterfaceController(); - - int interfaceCommand(int argc, char *argv[], char **rbuf); + public: + InterfaceController(); + virtual ~InterfaceController(); + int interfaceCommand(int argc, char *argv[], char **rbuf); + + private: + void *libh_; + int (*sendCommand_)(int argc, char *argv[], char **rbuf); + int (*sendCommandInit_)(void); + int (*sendCommandFini_)(void); }; #endif -- 2.11.0