修改安卓端逻辑
This commit is contained in:
+136
-21
@@ -1,40 +1,87 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use jni::objects::{GlobalRef, JString, JValue};
|
||||
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
|
||||
use jni::{JNIEnv, JavaVM};
|
||||
use spki::der::pem::LineEnding;
|
||||
use spki::EncodePublicKey;
|
||||
|
||||
use vnt::handle::callback::ConnectInfo;
|
||||
use vnt::{DeviceInfo, ErrorInfo, HandshakeInfo, RegisterInfo, VntCallback};
|
||||
#[cfg(target_os = "android")]
|
||||
use vnt::handle::callback::DeviceConfig;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
use vnt::DeviceInfo;
|
||||
use vnt::{ErrorInfo, HandshakeInfo, PeerClientInfo, RegisterInfo, VntCallback};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CallBack {
|
||||
jvm: Arc<JavaVM>,
|
||||
this: GlobalRef,
|
||||
connect_info_class: GlobalRef,
|
||||
handshake_info_class: GlobalRef,
|
||||
error_info_class: GlobalRef,
|
||||
register_info_class: GlobalRef,
|
||||
#[cfg(target_os = "android")]
|
||||
device_config_class: GlobalRef,
|
||||
peer_client_info_class: GlobalRef,
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
device_info_class: GlobalRef,
|
||||
}
|
||||
|
||||
unsafe impl Send for CallBack {}
|
||||
|
||||
fn find_class_global_ref(env: &mut JNIEnv, class: &str) -> jni::errors::Result<GlobalRef> {
|
||||
let class = env.find_class(class)?;
|
||||
env.new_global_ref(class)
|
||||
}
|
||||
impl CallBack {
|
||||
pub fn new(jvm: JavaVM, this: GlobalRef) -> Self {
|
||||
Self {
|
||||
pub fn new(jvm: JavaVM, this: GlobalRef) -> jni::errors::Result<Self> {
|
||||
let mut env = jvm.attach_current_thread_as_daemon()?;
|
||||
let connect_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ConnectInfo")?;
|
||||
let handshake_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/HandshakeInfo")?;
|
||||
let error_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/ErrorInfo")?;
|
||||
let register_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/RegisterInfo")?;
|
||||
#[cfg(target_os = "android")]
|
||||
let device_config_class = crate::callback::find_class_global_ref(
|
||||
&mut env,
|
||||
"top/wherewego/vnt/jni/param/DeviceConfig",
|
||||
)?;
|
||||
let peer_client_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/PeerClientInfo")?;
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
let device_info_class =
|
||||
find_class_global_ref(&mut env, "top/wherewego/vnt/jni/param/DeviceInfo")?;
|
||||
Ok(Self {
|
||||
jvm: Arc::new(jvm),
|
||||
this,
|
||||
}
|
||||
connect_info_class,
|
||||
handshake_info_class,
|
||||
error_info_class,
|
||||
register_info_class,
|
||||
#[cfg(target_os = "android")]
|
||||
device_config_class,
|
||||
peer_client_info_class,
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
device_info_class,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CallBack {
|
||||
fn success0(&self) -> jni::errors::Result<()> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
env.call_method(&self.this, "success", "()V", &[])?;
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
fn create_tun0(&self, info: DeviceInfo) -> jni::errors::Result<()> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.device_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
"top/wherewego/vnt/jni/param/DeviceInfo",
|
||||
class,
|
||||
"(Ljava/lang/String;Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::Object(&env.new_string(info.name)?.into()),
|
||||
@@ -50,9 +97,10 @@ impl CallBack {
|
||||
Ok(())
|
||||
}
|
||||
fn connect0(&self, info: ConnectInfo) -> jni::errors::Result<()> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.connect_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
"top/wherewego/vnt/jni/param/ConnectInfo",
|
||||
class,
|
||||
"(JLjava/lang/String;)V",
|
||||
&[
|
||||
JValue::Long(info.count as _),
|
||||
@@ -68,7 +116,7 @@ impl CallBack {
|
||||
Ok(())
|
||||
}
|
||||
fn handshake0(&self, info: HandshakeInfo) -> jni::errors::Result<bool> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let public_key = if let Some(public_key) = info.public_key {
|
||||
match public_key.to_public_key_pem(LineEnding::CRLF) {
|
||||
Ok(public_key) => env.new_string(public_key)?,
|
||||
@@ -85,8 +133,10 @@ impl CallBack {
|
||||
} else {
|
||||
JString::default()
|
||||
};
|
||||
let class = unsafe { JClass::from_raw(self.handshake_info_class.as_raw()) };
|
||||
|
||||
let param = env.new_object(
|
||||
"top/wherewego/vnt/jni/param/HandshakeInfo",
|
||||
class,
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::Object(&public_key),
|
||||
@@ -103,14 +153,15 @@ impl CallBack {
|
||||
rs.z()
|
||||
}
|
||||
fn register0(&self, info: RegisterInfo) -> jni::errors::Result<bool> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.register_info_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
"top/wherewego/vnt/jni/param/RegisterInfo",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
class,
|
||||
"(III)V",
|
||||
&[
|
||||
JValue::Object(&env.new_string(info.virtual_ip.to_string())?.into()),
|
||||
JValue::Object(&env.new_string(info.virtual_netmask.to_string())?.into()),
|
||||
JValue::Object(&env.new_string(info.virtual_gateway.to_string())?.into()),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_ip) as _),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_netmask) as _),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_gateway) as _),
|
||||
],
|
||||
)?;
|
||||
let rs = env.call_method(
|
||||
@@ -121,16 +172,66 @@ impl CallBack {
|
||||
)?;
|
||||
rs.z()
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
fn generate_tun0(&self, info: DeviceConfig) -> jni::errors::Result<u32> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.device_config_class.as_raw()) };
|
||||
let param = env.new_object(
|
||||
class,
|
||||
"(IIII)V",
|
||||
&[
|
||||
JValue::Int(Into::<u32>::into(info.virtual_ip) as _),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_netmask) as _),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_gateway) as _),
|
||||
JValue::Int(Into::<u32>::into(info.virtual_network) as _),
|
||||
],
|
||||
)?;
|
||||
let rs = env.call_method(
|
||||
&self.this,
|
||||
"generateTun",
|
||||
"(Ltop/wherewego/vnt/jni/param/DeviceConfig;)I",
|
||||
&[JValue::Object(¶m)],
|
||||
)?;
|
||||
rs.i().map(|v| v as _)
|
||||
}
|
||||
fn peer_client_list0(&self, info_vec: Vec<PeerClientInfo>) -> jni::errors::Result<()> {
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.peer_client_info_class.as_raw()) };
|
||||
let object_array = env.new_object_array(info_vec.len() as _, &class, JObject::null())?;
|
||||
for (index, info) in info_vec.into_iter().enumerate() {
|
||||
let param = env.new_object(
|
||||
&class,
|
||||
"(ILjava/lang/String;ZZ)V",
|
||||
&[
|
||||
JValue::Int(Into::<u32>::into(info.virtual_ip) as _),
|
||||
JValue::Object(&env.new_string(info.name)?.into()),
|
||||
JValue::Bool(info.status.is_online() as _),
|
||||
JValue::Bool(info.client_secret as _),
|
||||
],
|
||||
)?;
|
||||
env.set_object_array_element(&object_array, index as _, ¶m)?;
|
||||
}
|
||||
|
||||
env.call_method(
|
||||
&self.this,
|
||||
"peerClientList",
|
||||
"([Ltop/wherewego/vnt/jni/param/PeerClientInfo;)V",
|
||||
&[JValue::Object(&object_array)],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn error0(&self, info: ErrorInfo) -> jni::errors::Result<()> {
|
||||
let code: u8 = info.code.into();
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
let class = unsafe { JClass::from_raw(self.error_info_class.as_raw()) };
|
||||
let msg = if let Some(msg) = info.msg {
|
||||
env.new_string(msg)?
|
||||
} else {
|
||||
JString::default()
|
||||
};
|
||||
let param = env.new_object(
|
||||
"top/wherewego/vnt/jni/param/ErrorInfo",
|
||||
class,
|
||||
"(ILjava/lang/String;)V",
|
||||
&[JValue::Int(code as _), JValue::Object(&msg.into())],
|
||||
)?;
|
||||
@@ -143,7 +244,7 @@ impl CallBack {
|
||||
Ok(())
|
||||
}
|
||||
fn stop0(&self) -> jni::errors::Result<()> {
|
||||
let env = &mut self.jvm.attach_current_thread()? as &mut JNIEnv;
|
||||
let mut env = self.jvm.attach_current_thread_as_daemon()?;
|
||||
env.call_method(&self.this, "stop", "()V", &[])?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -155,6 +256,7 @@ impl VntCallback for CallBack {
|
||||
log::warn!("success {:?}", e);
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
fn create_tun(&self, info: DeviceInfo) {
|
||||
if let Err(e) = self.create_tun0(info) {
|
||||
log::warn!("create_tun {:?}", e);
|
||||
@@ -180,6 +282,19 @@ impl VntCallback for CallBack {
|
||||
false
|
||||
})
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
fn generate_tun(&self, info: DeviceConfig) -> u32 {
|
||||
self.generate_tun0(info).unwrap_or_else(|e| {
|
||||
log::warn!("generate_tun {:?}", e);
|
||||
0
|
||||
})
|
||||
}
|
||||
|
||||
fn peer_client_list(&self, info: Vec<PeerClientInfo>) {
|
||||
if let Err(e) = self.peer_client_list0(info) {
|
||||
log::warn!("peer_client_list {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn error(&self, info: ErrorInfo) {
|
||||
if let Err(e) = self.error0(info) {
|
||||
|
||||
Reference in New Issue
Block a user