]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/jni/libandroidbridge/kernel/network_manager.c
Moved debug.[ch] to utils folder
[thirdparty/strongswan.git] / src / frontends / android / jni / libandroidbridge / kernel / network_manager.c
CommitLineData
8f092a22
TB
1/*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
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
12 * for more details.
13 */
14
15#include "network_manager.h"
16
17#include "../android_jni.h"
ef3d1a1b 18#include "../charonservice.h"
f05b4272 19#include <utils/debug.h>
ef3d1a1b 20#include <threading/mutex.h>
8f092a22
TB
21
22typedef struct private_network_manager_t private_network_manager_t;
23
24struct private_network_manager_t {
25
26 /**
27 * Public interface
28 */
29 network_manager_t public;
30
31 /**
32 * Reference to NetworkManager object
33 */
34 jobject obj;
35
36 /**
37 * Java class for NetworkManager
38 */
39 jclass cls;
ef3d1a1b
TB
40
41 /**
42 * Registered callback
43 */
44 struct {
45 connectivity_cb_t cb;
46 void *data;
47 } connectivity_cb;
48
49 /**
50 * Mutex to access callback
51 */
52 mutex_t *mutex;
8f092a22
TB
53};
54
55METHOD(network_manager_t, get_local_address, host_t*,
56 private_network_manager_t *this, bool ipv4)
57{
58 JNIEnv *env;
59 jmethodID method_id;
60 jstring jaddr;
61 char *addr;
62 host_t *host;
63
64 androidjni_attach_thread(&env);
65 method_id = (*env)->GetMethodID(env, this->cls, "getLocalAddress",
66 "(Z)Ljava/lang/String;");
67 if (!method_id)
68 {
69 goto failed;
70 }
71 jaddr = (*env)->CallObjectMethod(env, this->obj, method_id, ipv4);
72 if (!jaddr)
73 {
74 goto failed;
75 }
76 addr = androidjni_convert_jstring(env, jaddr);
77 androidjni_detach_thread();
78 host = host_create_from_string(addr, 0);
79 free(addr);
80 return host;
81
82failed:
83 androidjni_exception_occurred(env);
84 androidjni_detach_thread();
85 return NULL;
86}
87
ef3d1a1b
TB
88JNI_METHOD(NetworkManager, networkChanged, void,
89 bool disconnected)
90{
91 private_network_manager_t *nm;
92
93 nm = (private_network_manager_t*)charonservice->get_network_manager(
94 charonservice);
95 nm->mutex->lock(nm->mutex);
96 if (nm->connectivity_cb.cb)
97 {
98 nm->connectivity_cb.cb(nm->connectivity_cb.data, disconnected);
99 }
100 nm->mutex->unlock(nm->mutex);
101}
102
103METHOD(network_manager_t, add_connectivity_cb, void,
104 private_network_manager_t *this, connectivity_cb_t cb, void *data)
105{
106 this->mutex->lock(this->mutex);
107 if (!this->connectivity_cb.cb)
108 {
109 JNIEnv *env;
110 jmethodID method_id;
111
112 androidjni_attach_thread(&env);
113 method_id = (*env)->GetMethodID(env, this->cls, "Register", "()V");
114 if (!method_id)
115 {
116 androidjni_exception_occurred(env);
117 }
118 else
119 {
120 (*env)->CallVoidMethod(env, this->obj, method_id);
121 if (!androidjni_exception_occurred(env))
122 {
123 this->connectivity_cb.cb = cb;
124 this->connectivity_cb.data = data;
125 }
126 androidjni_detach_thread();
127 }
128 }
129 this->mutex->unlock(this->mutex);
130}
131
132/**
133 * Unregister the NetworkManager via JNI.
134 *
135 * this->mutex has to be locked
136 */
137static void unregister_network_manager(private_network_manager_t *this)
138{
139 JNIEnv *env;
140 jmethodID method_id;
141
142 androidjni_attach_thread(&env);
143 method_id = (*env)->GetMethodID(env, this->cls, "Unregister", "()V");
144 if (!method_id)
145 {
146 androidjni_exception_occurred(env);
147 }
148 else
149 {
150 (*env)->CallVoidMethod(env, this->obj, method_id);
151 androidjni_exception_occurred(env);
152 }
153 androidjni_detach_thread();
154}
155
156METHOD(network_manager_t, remove_connectivity_cb, void,
157 private_network_manager_t *this, connectivity_cb_t cb)
158{
159 this->mutex->lock(this->mutex);
160 if (this->connectivity_cb.cb == cb)
161 {
162 this->connectivity_cb.cb = NULL;
163 unregister_network_manager(this);
164 }
165 this->mutex->unlock(this->mutex);
166}
167
8f092a22
TB
168METHOD(network_manager_t, destroy, void,
169 private_network_manager_t *this)
170{
171 JNIEnv *env;
172
ef3d1a1b
TB
173 this->mutex->lock(this->mutex);
174 if (this->connectivity_cb.cb)
175 {
176 this->connectivity_cb.cb = NULL;
177 unregister_network_manager(this);
178 }
179 this->mutex->unlock(this->mutex);
180
8f092a22
TB
181 androidjni_attach_thread(&env);
182 if (this->obj)
183 {
184 (*env)->DeleteGlobalRef(env, this->obj);
185 }
186 if (this->cls)
187 {
188 (*env)->DeleteGlobalRef(env, this->cls);
189 }
190 androidjni_detach_thread();
ef3d1a1b 191 this->mutex->destroy(this->mutex);
8f092a22
TB
192 free(this);
193}
194
195/*
196 * Described in header.
197 */
ef3d1a1b 198network_manager_t *network_manager_create(jobject context)
8f092a22
TB
199{
200 private_network_manager_t *this;
201 JNIEnv *env;
202 jmethodID method_id;
203 jobject obj;
204 jclass cls;
205
206 INIT(this,
207 .public = {
208 .get_local_address = _get_local_address,
ef3d1a1b
TB
209 .add_connectivity_cb = _add_connectivity_cb,
210 .remove_connectivity_cb = _remove_connectivity_cb,
8f092a22
TB
211 .destroy = _destroy,
212 },
ef3d1a1b 213 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
8f092a22
TB
214 );
215
216 androidjni_attach_thread(&env);
217 cls = (*env)->FindClass(env, JNI_PACKAGE_STRING "/NetworkManager");
218 if (!cls)
219 {
220 goto failed;
221 }
222 this->cls = (*env)->NewGlobalRef(env, cls);
223 method_id = (*env)->GetMethodID(env, cls, "<init>",
ef3d1a1b 224 "(Landroid/content/Context;)V");
8f092a22
TB
225 if (!method_id)
226 {
227 goto failed;
228 }
ef3d1a1b 229 obj = (*env)->NewObject(env, cls, method_id, context);
8f092a22
TB
230 if (!obj)
231 {
232 goto failed;
233 }
234 this->obj = (*env)->NewGlobalRef(env, obj);
235 androidjni_detach_thread();
236 return &this->public;
237
238failed:
239 DBG1(DBG_KNL, "failed to build NetworkManager object");
240 androidjni_exception_occurred(env);
241 androidjni_detach_thread();
242 destroy(this);
243 return NULL;
244};