InterfaceController.cpp revision 2eab1f762badb7ba46b95716e62ea4548a979903
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdlib.h>
18#include <errno.h>
19#include <fcntl.h>
20#include <string.h>
21
22#include <sys/socket.h>
23#include <sys/stat.h>
24#include <sys/ioctl.h>
25#include <sys/types.h>
26
27#include <netinet/in.h>
28#include <arpa/inet.h>
29
30#define LOG_TAG "InterfaceController"
31#include <cutils/log.h>
32#include <netutils/ifc.h>
33#include <private/android_filesystem_config.h>
34
35#include "InterfaceController.h"
36
37InterfaceController::InterfaceController() {
38    iSock = socket(AF_INET, SOCK_DGRAM, 0);
39    if (iSock < 0)
40        ALOGE("Failed to open socket");
41    iBuf = (char *)malloc(INTERFACE_MAX_BUFFER_SIZE);
42    if (!iBuf)
43        ALOGE("Failed to allocate buffer");
44}
45
46InterfaceController::~InterfaceController() {
47    if (iSock >= 0)
48        close(iSock);
49    if (iBuf)
50        free(iBuf);
51}
52
53int InterfaceController::sendCommand(char *iface, char *cmd, char *buf, int buf_len) {
54    struct ifreq ifr;
55    android_wifi_priv_cmd priv_cmd;
56    int ret;
57
58    if (!iface || !cmd)
59        return -1;
60
61    memset(&ifr, 0, sizeof(ifr));
62    memset(&priv_cmd, 0, sizeof(priv_cmd));
63    strncpy(ifr.ifr_name, iface, IFNAMSIZ);
64    memcpy(buf, cmd, strlen(cmd) + 1);
65
66    priv_cmd.buf = buf;
67    priv_cmd.used_len = buf_len;
68    priv_cmd.total_len = buf_len;
69    ifr.ifr_data = &priv_cmd;
70
71    if ((ret = ioctl(iSock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
72        ALOGE("Failed to execute command: %s", cmd);
73    } else {
74        if (buf[0] == '\0') {
75            snprintf(buf, buf_len, "OK");
76        }
77    }
78    return ret;
79}
80
81/*
82 * Arguments:
83 *      argv[2] - wlan interface
84 *      argv[3] - command
85 *      argv[4] - argument
86 *      rbuf    - returned buffer
87 */
88int InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) {
89    char cmd[INTERFACE_MAX_BUFFER_SIZE];
90    unsigned int bc = 0;
91    int ret;
92    int i;
93
94    if ((iSock < 0) || !iBuf || (argc < 4))
95        return -1;
96
97    for (i=3; i < argc; i++) {
98        bc += snprintf(&cmd[bc], sizeof(cmd) - bc, "%s ", argv[i]);
99    }
100    if (bc >= sizeof(cmd))
101        bc = sizeof(cmd) - 1;
102    cmd[bc] = '\0';
103    ret = sendCommand(argv[2], cmd, iBuf, INTERFACE_MAX_BUFFER_SIZE);
104    if (rbuf)
105        *rbuf = iBuf;
106    return ret;
107}
108