InterfaceController.cpp revision 2eab1f762badb7ba46b95716e62ea4548a979903
12eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/*
22eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Copyright (C) 2012 The Android Open Source Project
32eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *
42eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License");
52eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * you may not use this file except in compliance with the License.
62eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * You may obtain a copy of the License at
72eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *
82eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *      http://www.apache.org/licenses/LICENSE-2.0
92eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *
102eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software
112eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS,
122eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * See the License for the specific language governing permissions and
142eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * limitations under the License.
152eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */
162eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
172eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <stdlib.h>
182eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <errno.h>
192eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <fcntl.h>
202eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <string.h>
212eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
222eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/socket.h>
232eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/stat.h>
242eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/ioctl.h>
252eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <sys/types.h>
262eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
272eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netinet/in.h>
282eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <arpa/inet.h>
292eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
302eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#define LOG_TAG "InterfaceController"
312eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <cutils/log.h>
322eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <netutils/ifc.h>
332eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <private/android_filesystem_config.h>
342eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
352eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include "InterfaceController.h"
362eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
372eab1f762badb7ba46b95716e62ea4548a979903Dmitry ShmidtInterfaceController::InterfaceController() {
382eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    iSock = socket(AF_INET, SOCK_DGRAM, 0);
392eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (iSock < 0)
402eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        ALOGE("Failed to open socket");
412eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    iBuf = (char *)malloc(INTERFACE_MAX_BUFFER_SIZE);
422eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (!iBuf)
432eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        ALOGE("Failed to allocate buffer");
442eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt}
452eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
462eab1f762badb7ba46b95716e62ea4548a979903Dmitry ShmidtInterfaceController::~InterfaceController() {
472eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (iSock >= 0)
482eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        close(iSock);
492eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (iBuf)
502eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        free(iBuf);
512eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt}
522eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
532eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidtint InterfaceController::sendCommand(char *iface, char *cmd, char *buf, int buf_len) {
542eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    struct ifreq ifr;
552eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    android_wifi_priv_cmd priv_cmd;
562eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    int ret;
572eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
582eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (!iface || !cmd)
592eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        return -1;
602eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
612eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    memset(&ifr, 0, sizeof(ifr));
622eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    memset(&priv_cmd, 0, sizeof(priv_cmd));
632eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    strncpy(ifr.ifr_name, iface, IFNAMSIZ);
642eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    memcpy(buf, cmd, strlen(cmd) + 1);
652eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
662eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    priv_cmd.buf = buf;
672eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    priv_cmd.used_len = buf_len;
682eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    priv_cmd.total_len = buf_len;
692eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    ifr.ifr_data = &priv_cmd;
702eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
712eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if ((ret = ioctl(iSock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
722eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        ALOGE("Failed to execute command: %s", cmd);
732eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    } else {
742eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        if (buf[0] == '\0') {
752eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt            snprintf(buf, buf_len, "OK");
762eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        }
772eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    }
782eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    return ret;
792eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt}
802eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
812eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/*
822eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Arguments:
832eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *      argv[2] - wlan interface
842eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *      argv[3] - command
852eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *      argv[4] - argument
862eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt *      rbuf    - returned buffer
872eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */
882eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidtint InterfaceController::interfaceCommand(int argc, char *argv[], char **rbuf) {
892eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    char cmd[INTERFACE_MAX_BUFFER_SIZE];
902eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    unsigned int bc = 0;
912eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    int ret;
922eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    int i;
932eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
942eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if ((iSock < 0) || !iBuf || (argc < 4))
952eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        return -1;
962eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt
972eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    for (i=3; i < argc; i++) {
982eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        bc += snprintf(&cmd[bc], sizeof(cmd) - bc, "%s ", argv[i]);
992eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    }
1002eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (bc >= sizeof(cmd))
1012eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        bc = sizeof(cmd) - 1;
1022eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    cmd[bc] = '\0';
1032eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    ret = sendCommand(argv[2], cmd, iBuf, INTERFACE_MAX_BUFFER_SIZE);
1042eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    if (rbuf)
1052eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt        *rbuf = iBuf;
1062eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt    return ret;
1072eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt}
108