am 329c3b46: Changes the interface command API from static lib to a dynamic one
* commit '329c3b4681e2ca4831adc7c8cf257e9e32971710':
Changes the interface command API from static lib to a dynamic one
diff --git a/Android.mk b/Android.mk
index 811e875..582f0a6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -42,7 +42,7 @@
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 <fcntl.h>
#include <string.h>
+#include <dlfcn.h>
+
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -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()
+ : 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;
+ }
+ }
}
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;
+ 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;
+ int ret = -ENOSYS;
+ if (sendCommand_)
+ ret = sendCommand_(argc, argv, rbuf);
- 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;
+ 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 <net/if.h>
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;
+ public:
+ InterfaceController();
+ virtual ~InterfaceController();
+ int interfaceCommand(int argc, char *argv[], char **rbuf);
- int sendCommand(char *iface, char *cmd, char *buf, int buf_len);
-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