blob: 71c2d8a57aa49c658ed43854c3b7e3f252c85b6a [file] [log] [blame]
San Mehat54962e02009-06-22 10:37:54 -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 */
16
17#include <stdio.h>
18#include <errno.h>
19#include <sys/types.h>
San Mehatc4a895b2009-06-23 21:10:57 -070020#include <sys/socket.h>
San Mehat54962e02009-06-22 10:37:54 -070021#include <arpa/inet.h>
San Mehatc4a895b2009-06-23 21:10:57 -070022#include <pthread.h>
San Mehat54962e02009-06-22 10:37:54 -070023
24#define LOG_TAG "DhcpClient"
25#include <cutils/log.h>
26#include <cutils/properties.h>
27
28#include <sysutils/ServiceManager.h>
29
Szymon Jakubczak8c85a002010-06-09 16:11:09 -040030#include <netutils/ifc.h>
31#include <netutils/dhcp.h>
32
San Mehat54962e02009-06-22 10:37:54 -070033#include "DhcpClient.h"
34#include "DhcpState.h"
35#include "DhcpListener.h"
36#include "IDhcpEventHandlers.h"
San Mehatc4a895b2009-06-23 21:10:57 -070037#include "Controller.h"
San Mehat54962e02009-06-22 10:37:54 -070038
San Mehat54962e02009-06-22 10:37:54 -070039DhcpClient::DhcpClient(IDhcpEventHandlers *handlers) :
San Mehatc4a895b2009-06-23 21:10:57 -070040 mState(DhcpState::INIT), mHandlers(handlers) {
San Mehat54962e02009-06-22 10:37:54 -070041 mServiceManager = new ServiceManager();
42 mListener = NULL;
San Mehatc4a895b2009-06-23 21:10:57 -070043 mListenerSocket = NULL;
44 mController = NULL;
45 mDoArpProbe = false;
46 pthread_mutex_init(&mLock, NULL);
San Mehat54962e02009-06-22 10:37:54 -070047}
48
49DhcpClient::~DhcpClient() {
50 delete mServiceManager;
51 if (mListener)
52 delete mListener;
53}
54
San Mehatc4a895b2009-06-23 21:10:57 -070055int DhcpClient::start(Controller *c) {
Steve Block8d66c492011-12-20 16:07:45 +000056 ALOGD("Starting DHCP service (arp probe = %d)", mDoArpProbe);
San Mehat54962e02009-06-22 10:37:54 -070057 char svc[PROPERTY_VALUE_MAX];
San Mehatc4a895b2009-06-23 21:10:57 -070058 snprintf(svc,
59 sizeof(svc),
60 "dhcpcd:%s%s",
61 (!mDoArpProbe ? "-A " : ""),
62 c->getBoundInterface());
San Mehat54962e02009-06-22 10:37:54 -070063
San Mehatc4a895b2009-06-23 21:10:57 -070064 pthread_mutex_lock(&mLock);
65
66 if (mController) {
67 pthread_mutex_unlock(&mLock);
68 errno = EBUSY;
69 return -1;
70 }
71 mController = c;
72
73 sockaddr_in addr;
74 if ((mListenerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
75 LOGE("Failed to create DHCP listener socket");
76 pthread_mutex_unlock(&mLock);
77 return -1;
78 }
79 memset(&addr, 0, sizeof(addr));
80 addr.sin_family = AF_INET;
81 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
82 addr.sin_port = htons(DhcpClient::STATUS_MONITOR_PORT);
83
84 if (bind(mListenerSocket, (struct sockaddr *) &addr, sizeof(addr))) {
85 LOGE("Failed to bind DHCP listener socket");
86 close(mListenerSocket);
87 mListenerSocket = -1;
88 pthread_mutex_unlock(&mLock);
San Mehat54962e02009-06-22 10:37:54 -070089 return -1;
90 }
91
San Mehatc4a895b2009-06-23 21:10:57 -070092 if (mServiceManager->start(svc)) {
93 LOGE("Failed to start dhcp service");
94 pthread_mutex_unlock(&mLock);
95 return -1;
96 }
97
98 mListener = new DhcpListener(mController, mListenerSocket, mHandlers);
San Mehat54962e02009-06-22 10:37:54 -070099 if (mListener->startListener()) {
100 LOGE("Failed to start listener");
101#if 0
San Mehatc4a895b2009-06-23 21:10:57 -0700102 mServiceManager->stop("dhcpcd");
San Mehat54962e02009-06-22 10:37:54 -0700103 return -1;
104#endif
105 delete mListener;
106 mListener = NULL;
San Mehatc4a895b2009-06-23 21:10:57 -0700107 pthread_mutex_unlock(&mLock);
San Mehat54962e02009-06-22 10:37:54 -0700108 }
109
San Mehatc4a895b2009-06-23 21:10:57 -0700110 pthread_mutex_unlock(&mLock);
San Mehat54962e02009-06-22 10:37:54 -0700111 return 0;
112}
113
114int DhcpClient::stop() {
San Mehatc4a895b2009-06-23 21:10:57 -0700115 pthread_mutex_lock(&mLock);
116 if (!mController) {
117 pthread_mutex_unlock(&mLock);
118 return 0;
119 }
120
San Mehat54962e02009-06-22 10:37:54 -0700121 if (mListener) {
122 mListener->stopListener();
123 delete mListener;
124 mListener = NULL;
125 }
San Mehatc4a895b2009-06-23 21:10:57 -0700126 close(mListenerSocket);
San Mehat54962e02009-06-22 10:37:54 -0700127
San Mehatc4a895b2009-06-23 21:10:57 -0700128 if (mServiceManager->stop("dhcpcd")) {
San Mehat54962e02009-06-22 10:37:54 -0700129 LOGW("Failed to stop DHCP service (%s)", strerror(errno));
San Mehatc4a895b2009-06-23 21:10:57 -0700130 // XXX: Kill it the hard way.. but its gotta go!
131 }
132
133 mController = NULL;
134 pthread_mutex_unlock(&mLock);
San Mehat54962e02009-06-22 10:37:54 -0700135 return 0;
136}
San Mehatc4a895b2009-06-23 21:10:57 -0700137
138void DhcpClient::setDoArpProbe(bool probe) {
139 mDoArpProbe = probe;
140}