blob: f6a24361cf05a6cba3da378f0e342adf26cdadfa [file] [log] [blame]
San Mehatdc266072009-05-06 11:16:52 -07001/*
2 * Copyright (C) 2008 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 */
San Mehat3c5a6f02009-05-22 15:36:13 -070016
San Mehatdc266072009-05-06 11:16:52 -070017#include <stdio.h>
San Mehat48765672009-05-20 15:28:43 -070018#include <stdlib.h>
San Mehatdc266072009-05-06 11:16:52 -070019#include <string.h>
20#include <fcntl.h>
21#include <unistd.h>
22#include <malloc.h>
23#include <errno.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27
28#define LOG_TAG "Controller"
29
30#include <cutils/log.h>
31
32#include "Controller.h"
San Mehatc4a895b2009-06-23 21:10:57 -070033#include "InterfaceConfig.h"
San Mehatdc266072009-05-06 11:16:52 -070034
35extern "C" int init_module(void *, unsigned int, const char *);
36extern "C" int delete_module(const char *, unsigned int);
37
San Mehat3aff2d12009-06-15 14:10:44 -070038Controller::Controller(const char *name, PropertyManager *propMngr,
39 IControllerHandler *handlers) {
San Mehat3c5a6f02009-05-22 15:36:13 -070040 mPropMngr = propMngr;
41 mName = strdup(name);
San Mehat3aff2d12009-06-15 14:10:44 -070042 mHandlers = handlers;
San Mehat3c5a6f02009-05-22 15:36:13 -070043 mBoundInterface = NULL;
44}
San Mehat48765672009-05-20 15:28:43 -070045
San Mehat3c5a6f02009-05-22 15:36:13 -070046Controller::~Controller() {
47 if (mBoundInterface)
48 free(mBoundInterface);
49 if (mName)
50 free(mName);
San Mehatdc266072009-05-06 11:16:52 -070051}
52
53int Controller::start() {
54 return 0;
55}
56
57int Controller::stop() {
58 return 0;
59}
60
61int Controller::loadKernelModule(char *modpath, const char *args) {
62 void *module;
63 unsigned int size;
64
San Mehatdc266072009-05-06 11:16:52 -070065 module = loadFile(modpath, &size);
66 if (!module) {
67 errno = -EIO;
68 return -1;
69 }
70
71 int rc = init_module(module, size, args);
72 free (module);
73 return rc;
74}
75
76int Controller::unloadKernelModule(const char *modtag) {
77 int rc = -1;
78 int retries = 10;
79
San Mehatdc266072009-05-06 11:16:52 -070080 while (retries--) {
81 rc = delete_module(modtag, O_NONBLOCK | O_EXCL);
82 if (rc < 0 && errno == EAGAIN)
83 usleep(1000*500);
84 else
85 break;
86 }
87
88 if (rc != 0) {
San Mehat3c5a6f02009-05-22 15:36:13 -070089 LOGW("Unable to unload kernel driver '%s' (%s)", modtag,
San Mehatdc266072009-05-06 11:16:52 -070090 strerror(errno));
91 }
92 return rc;
93}
94
95bool Controller::isKernelModuleLoaded(const char *modtag) {
96 FILE *fp = fopen("/proc/modules", "r");
97
98 if (!fp) {
99 LOGE("Unable to open /proc/modules (%s)", strerror(errno));
100 return false;
101 }
102
103 char line[255];
104 while(fgets(line, sizeof(line), fp)) {
105 char *endTag = strchr(line, ' ');
106
107 if (!endTag) {
108 LOGW("Unable to find tag for line '%s'", line);
109 continue;
110 }
111 if (!strncmp(line, modtag, (endTag - line))) {
112 fclose(fp);
113 return true;
114 }
115 }
116
117 fclose(fp);
118 return false;
119}
120
San Mehatdc266072009-05-06 11:16:52 -0700121void *Controller::loadFile(char *filename, unsigned int *_size)
122{
123 int ret, fd;
124 struct stat sb;
125 ssize_t size;
126 void *buffer = NULL;
127
128 /* open the file */
129 fd = open(filename, O_RDONLY);
130 if (fd < 0)
131 return NULL;
132
133 /* find out how big it is */
134 if (fstat(fd, &sb) < 0)
135 goto bail;
136 size = sb.st_size;
137
138 /* allocate memory for it to be read into */
139 buffer = malloc(size);
140 if (!buffer)
141 goto bail;
142
143 /* slurp it into our buffer */
144 ret = read(fd, buffer, size);
145 if (ret != size)
146 goto bail;
147
148 /* let the caller know how big it is */
149 *_size = size;
150
151bail:
152 close(fd);
153 return buffer;
154}
San Mehat3c5a6f02009-05-22 15:36:13 -0700155
156int Controller::bindInterface(const char *ifname) {
157 mBoundInterface = strdup(ifname);
San Mehat3c5a6f02009-05-22 15:36:13 -0700158 return 0;
159}
160
161int Controller::unbindInterface(const char *ifname) {
162 free(mBoundInterface);
163 mBoundInterface = NULL;
San Mehat3c5a6f02009-05-22 15:36:13 -0700164 return 0;
165}