2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 #include "network_manager.h"
17 #include "../android_jni.h"
18 #include "../charonservice.h"
19 #include <utils/debug.h>
20 #include <threading/mutex.h>
22 typedef struct private_network_manager_t private_network_manager_t
;
24 struct private_network_manager_t
{
29 network_manager_t
public;
32 * Reference to NetworkManager object
37 * Java class for NetworkManager
50 * Mutex to access callback
55 METHOD(network_manager_t
, get_local_address
, host_t
*,
56 private_network_manager_t
*this, bool ipv4
)
64 androidjni_attach_thread(&env
);
65 method_id
= (*env
)->GetMethodID(env
, this->cls
, "getLocalAddress",
66 "(Z)Ljava/lang/String;");
71 jaddr
= (*env
)->CallObjectMethod(env
, this->obj
, method_id
, ipv4
);
72 if (!jaddr
|| androidjni_exception_occurred(env
))
76 addr
= androidjni_convert_jstring(env
, jaddr
);
77 androidjni_detach_thread();
78 host
= host_create_from_string(addr
, 0);
83 androidjni_exception_occurred(env
);
84 androidjni_detach_thread();
88 METHOD(network_manager_t
, get_interface
, bool,
89 private_network_manager_t
*this, host_t
*ip
, char **name
)
96 if (ip
->is_anyaddr(ip
))
101 androidjni_attach_thread(&env
);
103 method_id
= (*env
)->GetMethodID(env
, this->cls
, "getInterface",
104 "([B)Ljava/lang/String;");
109 jaddr
= byte_array_from_chunk(env
, ip
->get_address(ip
));
110 jinterface
= (*env
)->CallObjectMethod(env
, this->obj
, method_id
, jaddr
);
111 if (!jinterface
|| androidjni_exception_occurred(env
))
117 *name
= androidjni_convert_jstring(env
, jinterface
);
119 androidjni_detach_thread();
123 androidjni_exception_occurred(env
);
124 androidjni_detach_thread();
128 JNI_METHOD(NetworkManager
, networkChanged
, void,
131 private_network_manager_t
*nm
;
133 nm
= (private_network_manager_t
*)charonservice
->get_network_manager(
135 nm
->mutex
->lock(nm
->mutex
);
136 if (nm
->connectivity_cb
.cb
)
138 nm
->connectivity_cb
.cb(nm
->connectivity_cb
.data
, disconnected
);
140 nm
->mutex
->unlock(nm
->mutex
);
143 METHOD(network_manager_t
, add_connectivity_cb
, void,
144 private_network_manager_t
*this, connectivity_cb_t cb
, void *data
)
146 this->mutex
->lock(this->mutex
);
147 if (!this->connectivity_cb
.cb
)
152 androidjni_attach_thread(&env
);
153 method_id
= (*env
)->GetMethodID(env
, this->cls
, "Register", "()V");
156 androidjni_exception_occurred(env
);
160 (*env
)->CallVoidMethod(env
, this->obj
, method_id
);
161 if (!androidjni_exception_occurred(env
))
163 this->connectivity_cb
.cb
= cb
;
164 this->connectivity_cb
.data
= data
;
166 androidjni_detach_thread();
169 this->mutex
->unlock(this->mutex
);
173 * Unregister the NetworkManager via JNI.
175 * this->mutex has to be locked
177 static void unregister_network_manager(private_network_manager_t
*this)
182 androidjni_attach_thread(&env
);
183 method_id
= (*env
)->GetMethodID(env
, this->cls
, "Unregister", "()V");
186 androidjni_exception_occurred(env
);
190 (*env
)->CallVoidMethod(env
, this->obj
, method_id
);
191 androidjni_exception_occurred(env
);
193 androidjni_detach_thread();
196 METHOD(network_manager_t
, remove_connectivity_cb
, void,
197 private_network_manager_t
*this, connectivity_cb_t cb
)
199 this->mutex
->lock(this->mutex
);
200 if (this->connectivity_cb
.cb
== cb
)
202 this->connectivity_cb
.cb
= NULL
;
203 unregister_network_manager(this);
205 this->mutex
->unlock(this->mutex
);
208 METHOD(network_manager_t
, destroy
, void,
209 private_network_manager_t
*this)
213 this->mutex
->lock(this->mutex
);
214 if (this->connectivity_cb
.cb
)
216 this->connectivity_cb
.cb
= NULL
;
217 unregister_network_manager(this);
219 this->mutex
->unlock(this->mutex
);
221 androidjni_attach_thread(&env
);
224 (*env
)->DeleteGlobalRef(env
, this->obj
);
228 (*env
)->DeleteGlobalRef(env
, this->cls
);
230 androidjni_detach_thread();
231 this->mutex
->destroy(this->mutex
);
236 * Described in header.
238 network_manager_t
*network_manager_create(jobject context
)
240 private_network_manager_t
*this;
248 .get_local_address
= _get_local_address
,
249 .get_interface
= _get_interface
,
250 .add_connectivity_cb
= _add_connectivity_cb
,
251 .remove_connectivity_cb
= _remove_connectivity_cb
,
254 .mutex
= mutex_create(MUTEX_TYPE_DEFAULT
),
257 androidjni_attach_thread(&env
);
258 cls
= (*env
)->FindClass(env
, JNI_PACKAGE_STRING
"/NetworkManager");
263 this->cls
= (*env
)->NewGlobalRef(env
, cls
);
264 method_id
= (*env
)->GetMethodID(env
, cls
, "<init>",
265 "(Landroid/content/Context;)V");
270 obj
= (*env
)->NewObject(env
, cls
, method_id
, context
);
275 this->obj
= (*env
)->NewGlobalRef(env
, obj
);
276 androidjni_detach_thread();
277 return &this->public;
280 DBG1(DBG_KNL
, "failed to build NetworkManager object");
281 androidjni_exception_occurred(env
);
282 androidjni_detach_thread();