Compare commits

...

8 Commits
v0.4.2 ... main

11 changed files with 1039 additions and 453 deletions

219
Cargo.lock generated
View File

@ -8,6 +8,35 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bindgen"
version = "0.65.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn 2.0.22",
"which",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.2" version = "0.10.2"
@ -17,6 +46,15 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -36,6 +74,17 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "clang-sys"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.1" version = "0.2.1"
@ -76,7 +125,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn", "syn 1.0.85",
] ]
[[package]] [[package]]
@ -87,7 +136,7 @@ checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn", "syn 1.0.85",
] ]
[[package]] [[package]]
@ -100,6 +149,12 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "either"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -116,6 +171,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]] [[package]]
name = "hex-literal" name = "hex-literal"
version = "0.3.4" version = "0.3.4"
@ -135,15 +196,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]] [[package]]
name = "libc" name = "lazy_static"
version = "0.2.112" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]] [[package]]
name = "libcwtch" name = "libcwtch"
version = "0.4.2" version = "0.8.0"
dependencies = [ dependencies = [
"bindgen",
"chrono", "chrono",
"hex-literal", "hex-literal",
"libc", "libc",
@ -154,6 +228,44 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "log"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.45" version = "0.1.45"
@ -174,23 +286,66 @@ dependencies = [
] ]
[[package]] [[package]]
name = "proc-macro2" name = "once_cell"
version = "1.0.36" version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "prettyplease"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
dependencies = [ dependencies = [
"unicode-xid", "proc-macro2",
"syn 2.0.22",
]
[[package]]
name = "proc-macro2"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
dependencies = [
"unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.14" version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "regex"
version = "1.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.6" version = "1.0.6"
@ -220,7 +375,7 @@ checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 1.0.85",
] ]
[[package]] [[package]]
@ -242,7 +397,7 @@ checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 1.0.85",
] ]
[[package]] [[package]]
@ -265,7 +420,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 1.0.85",
] ]
[[package]] [[package]]
@ -279,6 +434,12 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "shlex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.10.0"
@ -296,6 +457,17 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "syn"
version = "2.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.44" version = "0.1.44"
@ -313,6 +485,12 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "unicode-ident"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.2" version = "0.2.2"
@ -331,6 +509,17 @@ version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "which"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
dependencies = [
"either",
"libc",
"once_cell",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "libcwtch" name = "libcwtch"
version = "0.4.2" version = "0.8.0"
authors = ["Dan Ballard <dan@mindstab.net>"] authors = ["Dan Ballard <dan@mindstab.net>"]
edition = "2018" edition = "2018"
license = "MIT" license = "MIT"
@ -12,6 +12,7 @@ documentation = "https://docs.rs/libcwtch/"
[build-dependencies] [build-dependencies]
hex-literal = "0.3.4" hex-literal = "0.3.4"
sha2 = "0.10.1" sha2 = "0.10.1"
bindgen = "0.65.1"
[dependencies] [dependencies]
libc = "0.2" libc = "0.2"

View File

@ -1,6 +1,6 @@
# libCwtch-rs # libCwtch-rs
Rust bindings for [libCwtch](https://git.openprivacy.ca/cwtch.im/libcwtch-go/) Rust bindings for [libCwtch autobindings](https://git.openprivacy.ca/cwtch.im/autobindings/)
Example echobot in examples/echobot.rs (`cargo run --example echobot` -- assumes tor is on $PATH) Example echobot in examples/echobot.rs (`cargo run --example echobot` -- assumes tor is on $PATH)
@ -8,21 +8,12 @@ Example echobot in examples/echobot.rs (`cargo run --example echobot` -- assumes
### Updating libCwtch and bingings.rs with Bindgen ### Updating libCwtch and bingings.rs with Bindgen
```sh
cargo install bindgen
```
libCwtch.so version is specified in build.rs. If updating, also download the corresponding libCwtch.h and delete libCwtch.so version is specified in build.rs. If updating, also download the corresponding libCwtch.h and delete
the 'preamble from import "C"' section as it imports headers required for the C lib to compile the 'preamble from import "C"' section as it imports headers required for the C lib to compile
but that we don't want to create rust bindings for (like importing stdlib.h). Then: but that we don't want to create rust bindings for (like importing stdlib.h). `cargo build` automatically calls
`bindgen` for us and will regenerate `src/cwtchlib_go/bindings.rs` if libCwtch.h has changed.
```sh
bindgen libCwtch.h -o src/cwtchlib_go/bindings.rs
```
While developing you can use the `LCG_DIR` environment variable to specify the directory containing a local `libCwtch.so` While developing you can use the `LCG_DIR` environment variable to specify the directory containing a local `libCwtch.so`
library to override the default one. library to override the default one.
This is useful in cases where you are adding or updating APIs prior to a release. This is useful in cases where you are adding or updating APIs prior to a release.
### Todo

View File

@ -1,6 +1,6 @@
use std::{env, io}; use std::{env, io};
use std::fs; use std::fs;
use std::path::Path; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use hex_literal::hex; use hex_literal::hex;
@ -18,22 +18,43 @@ fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=libCwtch.h"); println!("cargo:rerun-if-changed=libCwtch.h");
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("libCwtch.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from("src/cwtchlib_go");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so"); let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so");
if std::env::var("LCG_DIR").is_err() { if std::env::var("LCG_DIR").is_err() {
// https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.7.1 Command::new("wget")
Command::new("wget") .arg("https://git.openprivacy.ca/cwtch.im/autobindings/releases/download/v0.0.12/libCwtch.x64.so")
.arg("https://git.openprivacy.ca/attachments/98184e9c-1dc7-431a-9601-91a9e763e8fc")
.arg("-O") .arg("-O")
.arg(lib_cwtch_path.clone()) .arg(lib_cwtch_path.clone())
.output() .output()
.expect("failed to download libCwtch.so"); .expect("failed to download libCwtch.x64.so");
let mut hasher = Sha512::new(); let mut hasher = Sha512::new();
let mut file = fs::File::open(&lib_cwtch_path).expect("could not open lib to hash"); let mut file = fs::File::open(&lib_cwtch_path).expect("could not open lib to hash");
io::copy(&mut file, &mut hasher).expect("failed to copy file into hasher"); io::copy(&mut file, &mut hasher).expect("failed to copy file into hasher");
let hash_bytes = hasher.finalize(); let hash_bytes = hasher.finalize();
assert_eq!(hash_bytes[..], hex!("cb4368d72a46f8046261c50e6e9ecf170d8e606871d5de2c1e9e34303533c344f92f5d946d7e12614581dfa3ae8e638512af7f4623ed91b1ceb1570de14bf192")[..]); assert_eq!(hash_bytes[..], hex!("a3742e0cdedc00eb3673063b100b7596b05bdc9bb68a0fba6fd2423c9a41f1653597c4d44ba3877be08cbb5bba2806435830061ab3517cdd4472a18c7557d9c7")[..]);
} else { } else {
let local_lcg = Path::new(std::env::var("LCG_DIR").unwrap().as_str()).join("libCwtch.so"); let local_lcg = Path::new(std::env::var("LCG_DIR").unwrap().as_str()).join("libCwtch.so");
fs::copy(local_lcg, lib_cwtch_path).expect("could not find local lcg"); fs::copy(local_lcg, lib_cwtch_path).expect("could not find local lcg");

View File

@ -27,7 +27,7 @@ fn main() {
Event::CwtchStarted => { Event::CwtchStarted => {
println!("event CwtchStarted!"); println!("event CwtchStarted!");
println!("Creating bot"); println!("Creating bot");
cwtch.create_profile("Echobot", "be gay do crime"); cwtch.create_profile("Echobot", "be gay do crime", true);
} }
Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => { Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {
println!( println!(
@ -40,7 +40,7 @@ fn main() {
print!("profile: {:?}", profile); print!("profile: {:?}", profile);
} }
Event::NewMessageFromPeer { profile_id, conversation_id, contact_id: contact, nick, timestamp_received, message, notification, picture } => { Event::NewMessageFromPeer { profile_id, conversation_id, contact_id: contact, nick, timestamp_received, message, notification, picture } => {
let response = Message { o: message.o.into(), d: message.d }; let response = MessageWrapper { o: message.o.into(), d: message.d };
cwtch.send_message( &profile_id, conversation_id, &response); cwtch.send_message( &profile_id, conversation_id, &response);
} }
_ => eprintln!("unhandled event!"), _ => eprintln!("unhandled event!"),

View File

@ -1,11 +1,11 @@
/* Code generated by cmd/cgo; DO NOT EDIT. */ /* Code generated by cmd/cgo; DO NOT EDIT. */
/* package git.openprivacy.ca/cwtch.im/libcwtch-go */ /* package git.openprivacy.ca/cwtch.im/cwtch-autobindings */
#line 1 "cgo-builtin-export-prolog" #line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */ #include <stddef.h>
#ifndef GO_CGO_EXPORT_PROLOGUE_H #ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H #define GO_CGO_EXPORT_PROLOGUE_H
@ -32,11 +32,17 @@ typedef long long GoInt64;
typedef unsigned long long GoUint64; typedef unsigned long long GoUint64;
typedef GoInt64 GoInt; typedef GoInt64 GoInt;
typedef GoUint64 GoUint; typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr; typedef size_t GoUintptr;
typedef float GoFloat32; typedef float GoFloat32;
typedef double GoFloat64; typedef double GoFloat64;
#ifdef _MSC_VER
#include <complex.h>
typedef _Fcomplex GoComplex64;
typedef _Dcomplex GoComplex128;
#else
typedef float _Complex GoComplex64; typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128; typedef double _Complex GoComplex128;
#endif
/* /*
static assertion to make sure the file is being used on architecture static assertion to make sure the file is being used on architecture
@ -60,69 +66,73 @@ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
extern "C" { extern "C" {
#endif #endif
extern int c_StartCwtch(char* dir_c, int len, char* tor_c, int torLen);
extern int c_Started();
extern void c_ReconnectCwtchForeground();
// A generic method for Rebroadcasting App Events from a UI
extern void c_SendAppEvent(char* json_ptr, int json_len);
// A generic method for Rebroadcasting Profile Events from a UI
extern void c_SendProfileEvent(char* onion_ptr, int onion_len, char* json_ptr, int json_len);
// the pointer returned from this function **must** be freed using c_Free
extern char* c_GetAppBusEvent();
extern void c_CreateProfile(char* nick_ptr, int nick_len, char* pass_ptr, int pass_len);
extern void c_LoadProfiles(char* passwordPtr, int passwordLen);
extern void c_AcceptConversation(char* profilePtr, int profileLen, int conversation_id);
extern void c_BlockContact(char* profilePtr, int profileLen, int conversation_id);
extern void c_UnblockContact(char* profilePtr, int profileLen, int conversation_id);
// the pointer returned from this function **must** be Freed by c_Free
extern char* c_GetMessage(char* profile_ptr, int profile_len, int conversation_id, int message_index);
// the pointer returned from this function **must** be Freed by c_Free
extern char* c_GetMessageByID(char* profile_ptr, int profile_len, int conversation_id, int message_index);
// the pointer returned from this function **must** be freed by calling c_Free
extern char* c_GetMessagesByContentHash(char* profile_ptr, int profile_len, int conversation_id, char* contenthash_ptr, int contenthash_len);
// the pointer returned from this function **must** be Freed by c_Free
extern char* c_GetMessages(char* profile_ptr, int profile_len, int conversation_id, int message_index, int count);
// Dangerous function. Should only be used as documented in `MEMORY.md` // Dangerous function. Should only be used as documented in `MEMORY.md`
//
extern void c_FreePointer(char* ptr); extern void c_FreePointer(char* ptr);
extern char* c_SendMessage(char* profile_ptr, int profile_len, int conversation_id, char* msg_ptr, int msg_len); extern int c_Started();
extern char* c_SendInvitation(char* profile_ptr, int profile_len, int conversation_id, int target_id); extern int c_StartCwtch(char* dir_c, int len, char* tor_c, int torLen);
extern char* c_ShareFile(char* profile_ptr, int profile_len, int conversation_id, char* filepath_ptr, int filepath_len);
extern void c_DownloadFile(char* profile_ptr, int profile_len, int conversation_id, char* filepath_ptr, int filepath_len, char* manifestpath_ptr, int manifestpath_len, char* filekey_ptr, int filekey_len); // the pointer returned from this function **must** be freed using c_Free
extern void c_CheckDownloadStatus(char* profilePtr, int profileLen, char* fileKeyPtr, int fileKeyLen); //
extern void c_VerifyOrResumeDownload(char* profile_ptr, int profile_len, int conversation_id, char* filekey_ptr, int filekey_len); extern char* c_GetAppBusEvent();
extern void c_ResetTor(); extern void c_ReconnectCwtchForeground();
extern void c_CreateGroup(char* profile_ptr, int profile_len, char* server_ptr, int server_len, char* name_ptr, int name_len); extern void c_ShutdownCwtch();
extern void c_DeleteProfile(char* profile_ptr, int profile_len, char* password_ptr, int password_len);
extern void c_ArchiveConversation(char* profile_ptr, int profile_len, int conversation_id);
extern void c_DeleteContact(char* profile_ptr, int profile_len, int conversation_id);
extern void c_ImportBundle(char* profile_ptr, int profile_len, char* bundle_ptr, int bundle_len);
extern void c_SetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len, char* val_ptr, int val_len); extern void c_SetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len, char* val_ptr, int val_len);
extern char* c_GetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len); extern char* c_GetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len);
extern void c_SetConversationAttribute(char* profile_ptr, int profile_len, int conversation_id, char* key_ptr, int key_len, char* val_ptr, int val_len); extern void c_SetConversationAttribute(char* profile_ptr, int profile_len, int conversation_id, char* key_ptr, int key_len, char* val_ptr, int val_len);
extern char* c_GetConversationAttribute(char* profile_ptr, int profile_len, int conversation_id, char* key_ptr, int key_len); extern char* c_GetConversationAttribute(char* profile_ptr, int profile_len, int conversation_id, char* key_ptr, int key_len);
extern void c_SetMessageAttribute(char* profile_ptr, int profile_len, int conversation_id, int channel_id, int message_id, char* key_ptr, int key_len, char* val_ptr, int val_len); extern void c_ResetTor();
extern void c_ChangePassword(char* profile_ptr, int profile_len, char* oldpassword_ptr, int oldpassword_len, char* newpassword_ptr, int newpassword_len, char* newpassword_again_ptr, int newpassword_again_len); extern void c_UpdateSettings(char* json_ptr, int json_len);
extern void c_ExportProfile(char* profile_ptr, int profile_len, char* file_ptr, int file_len); extern char* c_GetDebugInfo();
extern char* c_ImportProfile(char* file_ptr, int file_len, char* passwordPtr, int passwordLen); extern void c_ActivatePeerEngine(char* onion_ptr, int onion_len);
extern void c_ShutdownCwtch(); extern void c_DeactivatePeerEngine(char* onion_ptr, int onion_len);
extern void c_LoadServers(char* passwordPtr, int passwordLen); extern void c_ConfigureConnections(char* onion_ptr, int onion_len, char listen1, char peers2, char servers3);
extern void c_CreateServer(char* passwordPtr, int passwordLen, char* descPtr, int descLen, char autostart); extern void c_CreateProfile(char* name_ptr, int name_len, char* password_ptr, int password_len, char autostart4);
extern void c_DeleteServer(char* onionPtr, int onionLen, char* currentPasswordPtr, int currentPasswordLen); extern void c_LoadProfiles(char* password_ptr, int password_len);
extern void c_DeleteProfile(char* onion_ptr, int onion_len, char* password_ptr, int password_len);
extern char* c_ImportProfile(char* file5_ptr, int file5_len, char* password_ptr, int password_len);
extern void c_ChangePassword(char* onion_ptr, int onion_len, char* current6_ptr, int current6_len, char* newPassword7_ptr, int newPassword7_len, char* newPasswordAgain8_ptr, int newPasswordAgain8_len);
extern void c_ExportProfile(char* onion_ptr, int onion_len, char* file9_ptr, int file9_len);
extern char* c_ImportBundle(char* onion_ptr, int onion_len, char* bundle10_ptr, int bundle10_len);
extern void c_ArchiveConversation(char* onion_ptr, int onion_len, int conversation);
extern void c_AcceptConversation(char* onion_ptr, int onion_len, int conversation);
extern void c_BlockConversation(char* onion_ptr, int onion_len, int conversation);
extern void c_UnblockConversation(char* onion_ptr, int onion_len, int conversation);
extern void c_DeleteConversation(char* onion_ptr, int onion_len, int conversation);
extern void c_PeerWithOnion(char* onion_ptr, int onion_len, char* handle11_ptr, int handle11_len);
extern void c_DisconnectFromPeer(char* onion_ptr, int onion_len, char* handle12_ptr, int handle12_len);
extern char* c_GetConversationAccessControlList(char* onion_ptr, int onion_len, int conversation);
extern void c_UpdateConversationAccessControlList(char* onion_ptr, int onion_len, int conversation, char* json13_ptr, int json13_len);
extern char* c_SearchConversations(char* onion_ptr, int onion_len, char* pattern14_ptr, int pattern14_len);
extern char* c_SendMessage(char* onion_ptr, int onion_len, int conversation, char* msg15_ptr, int msg15_len);
extern char* c_GetMessageById(char* onion_ptr, int onion_len, int conversation, int message_id);
extern char* c_GetMessageByContentHash(char* onion_ptr, int onion_len, int conversation, char* contentHash16_ptr, int contentHash16_len);
extern char* c_GetMessages(char* onion_ptr, int onion_len, int conversation, int index, unsigned int count);
extern char* c_SendInviteMessage(char* onion_ptr, int onion_len, int conversation, int target);
extern void c_UpdateMessageAttribute(char* onion_ptr, int onion_len, int conversation, int channel_id, int message_id, char* attributeKey17_ptr, int attributeKey17_len, char* attributeValue18_ptr, int attributeValue18_len);
extern void c_StartGroup(char* onion_ptr, int onion_len, char* name19_ptr, int name19_len, char* server20_ptr, int server20_len);
extern void c_QueueJoinServer(char* onion_ptr, int onion_len, char* handle21_ptr, int handle21_len);
extern void c_DisconnectFromServer(char* onion_ptr, int onion_len, char* handle22_ptr, int handle22_len);
extern void c_PublishServerUpdate(char* onion_ptr, int onion_len);
extern void c_GetServerInfoList(char* onion_ptr, int onion_len);
extern void c_DeleteServerInfo(char* onion_ptr, int onion_len, char* serverOnion23_ptr, int serverOnion23_len);
extern void c_DownloadFileDefaultLimit(char* onion_ptr, int onion_len, int conversation, char* filepath24_ptr, int filepath24_len, char* manifest25_ptr, int manifest25_len, char* filekey26_ptr, int filekey26_len);
extern void c_RestartFileShare(char* onion_ptr, int onion_len, char* filekey27_ptr, int filekey27_len);
extern void c_StopFileShare(char* onion_ptr, int onion_len, char* filekey28_ptr, int filekey28_len);
extern void c_CheckDownloadStatus(char* onion_ptr, int onion_len, char* filekey29_ptr, int filekey29_len);
extern void c_VerifyOrResumeDownloadDefaultLimit(char* onion_ptr, int onion_len, int conversation, char* filekey30_ptr, int filekey30_len);
extern char* c_ShareFile(char* onion_ptr, int onion_len, int conversation, char* filepath31_ptr, int filepath31_len);
extern char* c_GetSharedFiles(char* onion_ptr, int onion_len, int conversation);
extern void c_CreateServer(char* password_ptr, int password_len, char* description32_ptr, int description32_len, char autostart33);
extern void c_SetServerAttribute(char* handle34_ptr, int handle34_len, char* key35_ptr, int key35_len, char* val36_ptr, int val36_len);
extern void c_LoadServers(char* password_ptr, int password_len);
extern void c_LaunchServers(); extern void c_LaunchServers();
extern void c_LaunchServer(char* onionPtr, int onionLen); extern void c_LaunchServer(char* handle37_ptr, int handle37_len);
extern void c_StopServer(char* onionPtr, int onionLen); extern void c_StopServer(char* handle38_ptr, int handle38_len);
extern void c_StopServers(); extern void c_StopServers();
extern void c_DestroyServers(); extern void c_DestroyServers();
extern void c_SetServerAttribute(char* onionPtr, int onionLen, char* keyPtr, int keyLen, char* valPtr, int valLen); extern void c_DeleteServer(char* handle39_ptr, int handle39_len, char* password_ptr, int password_len);
extern char* c_GetDebugInfo();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -11,8 +11,18 @@ use crate::cwtchlib_go::bindings;
use crate::{ConversationID, CwtchError, FileKey, ProfileIdentity, ServerIdentity, structs::*}; use crate::{ConversationID, CwtchError, FileKey, ProfileIdentity, ServerIdentity, structs::*};
use crate::event::Event; use crate::event::Event;
type c_bool = core::ffi::c_char;
fn from_c_bool(b: c_bool) -> bool {
b == 1
}
fn to_c_bool(b: bool) -> c_bool {
if b { 1 } else { 0 }
}
struct c_str_wrap { struct c_str_wrap {
raw: *mut i8, raw: *mut core::ffi::c_char,
len: i32, len: i32,
} }
@ -85,33 +95,50 @@ pub struct CwtchLibGo {}
// Some bindings are going to be wrapped so we can handle their returns and give most rust idiomatic returns (esp for json returning apis) // Some bindings are going to be wrapped so we can handle their returns and give most rust idiomatic returns (esp for json returning apis)
// so we pre define the real binding here as a _helper function and in the impl for CwtchLib define the wrapper // so we pre define the real binding here as a _helper function and in the impl for CwtchLib define the wrapper
impl CwtchLibGo { impl CwtchLibGo {
c_bind!(_peer_with(profile: &str, new_peer: &str;;) c_PeerWithOnion);
c_bind!(_update_settings(settings_json: &str;;) c_UpdateSettings);
c_bind!(_get_profile_attribute(profile: &str, key: &str;;) c_GetProfileAttribute -> String); c_bind!(_get_profile_attribute(profile: &str, key: &str;;) c_GetProfileAttribute -> String);
c_bind!(_get_conversation_attribute(profile: &str; conversation_id: i32; key: &str) c_GetConversationAttribute -> String); c_bind!(_get_conversation_attribute(profile: &str; conversation_id: i32; key: &str) c_GetConversationAttribute -> String);
c_bind!(_get_appbus_event(;;) c_GetAppBusEvent -> String); c_bind!(_get_appbus_event(;;) c_GetAppBusEvent -> String);
c_bind!(_send_profile_event(profile: &str, event_jason: &str;;) c_SendProfileEvent); c_bind!(_configure_connections(profile: &str; listen: c_bool, peers: c_bool, servers: c_bool;) c_ConfigureConnections);
c_bind!(_accept_conversation(profile: &str ; conversation_id: i32 ;) c_AcceptConversation); c_bind!(_create_profile(nick: &str, pass: &str; autostart: c_bool;) c_CreateProfile);
c_bind!(_block_contact(profile: &str ; conversation_id: i32; ) c_BlockContact); c_bind!(_activate_peer_engine(profile: &str;;) c_ActivatePeerEngine);
c_bind!(_unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); c_bind!(_deactivate_peer_engine(profile: &str;;) c_DeactivatePeerEngine);
c_bind!(_get_message(profile: &str; conversation_id: i32, message_index: i32 ;) c_GetMessage -> String); c_bind!(_accept_conversation(profile: &str ; conversation_id: i32; ) c_AcceptConversation);
c_bind!(_get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageByID -> String); c_bind!(_block_conversation(profile: &str ; conversation_id: i32; ) c_BlockConversation);
c_bind!(_get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessagesByContentHash -> String); c_bind!(_unblock_conversation(profile: &str ; conversation_id: i32; ) c_UnblockConversation);
c_bind!(_get_messages(profile: &str; conversation_id: i32, message_index: i32, count: i32 ;) c_GetMessages -> String); c_bind!(_disconnect_from_peer(profile: &str, peer_address: &str;;) c_DisconnectFromPeer);
c_bind!(_search_conversations(profile: &str, pattern: &str;;) c_SearchConversations -> String);
c_bind!(_get_conversation_access_control_list(profile: &str; conversation_id: i32;) c_GetConversationAccessControlList -> String);
c_bind!(_update_conversation_access_control_list(profile: &str; conversation_id: i32; acl: &str) c_UpdateConversationAccessControlList);
c_bind!(_get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageById -> String);
c_bind!(_get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessageByContentHash -> String);
c_bind!(_get_messages(profile: &str; conversation_id: i32, message_index: i32, count: u32 ;) c_GetMessages -> String);
c_bind!(_send_message(profile: &str; conversation_id: i32; msg: &str) c_SendMessage -> String); c_bind!(_send_message(profile: &str; conversation_id: i32; msg: &str) c_SendMessage -> String);
c_bind!(_send_invitation(profile: &str; conversation_id: i32, target_id: i32;) c_SendInvitation -> String); c_bind!(_send_invite_message(profile: &str; conversation_id: i32, target_id: i32;) c_SendInviteMessage -> String);
c_bind!(_share_file(profile: &str; conversation_id: i32; file_path: &str) c_ShareFile -> String); c_bind!(_share_file(profile: &str; conversation_id: i32; file_path: &str) c_ShareFile -> String);
c_bind!(_download_file(profile: &str; conversation_id: i32; file_path: &str, manifest_path: &str, file_key: &str) c_DownloadFile); c_bind!(_get_shared_files(profile: &str; conversaion_id: i32;) c_GetSharedFiles -> String);
c_bind!(_restart_fileshare(profile: &str, file_key: &str;;) c_RestartFileShare);
c_bind!(_stop_fileshare(profile: &str, file_key: &str;;) c_StopFileShare);
c_bind!(_download_file_default_limit(profile: &str; conversation_id: i32; file_path: &str, manifest_path: &str, file_key: &str) c_DownloadFileDefaultLimit);
c_bind!(_check_download_status(profile: &str, file_key: &str;;) c_CheckDownloadStatus); c_bind!(_check_download_status(profile: &str, file_key: &str;;) c_CheckDownloadStatus);
c_bind!(_verify_or_resume_download(profile: &str; conversation_id: i32; file_key: &str) c_VerifyOrResumeDownload); c_bind!(_verify_or_resume_download(profile: &str; conversation_id: i32; file_key: &str) c_VerifyOrResumeDownloadDefaultLimit);
c_bind!(_create_group(profile: &str, server: &str, name: &str;;) c_CreateGroup); c_bind!(_start_group(profile: &str, name: &str, server: &str;;) c_StartGroup);
c_bind!(_queue_join_server(profile: &str, server: &str;;) c_QueueJoinServer);
c_bind!(_disconnect_from_server(profile: &str, server: &str;;) c_DisconnectFromServer);
c_bind!(_publish_server_update(profile: &str;;) c_PublishServerUpdate);
c_bind!(_get_server_info_list(profile: &str;;) c_GetServerInfoList);
c_bind!(_delete_server_info(profile: &str, server: &str;;) c_DeleteServerInfo);
c_bind!(_delete_profile(profile: &str, pass: &str;;) c_DeleteProfile); c_bind!(_delete_profile(profile: &str, pass: &str;;) c_DeleteProfile);
c_bind!(_archive_conversation(profile: &str; conversation_id: i32;) c_ArchiveConversation); c_bind!(_archive_conversation(profile: &str; conversation_id: i32;) c_ArchiveConversation);
c_bind!(_delete_contact(profile: &str; conversation_id: i32;) c_DeleteContact); c_bind!(_delete_conversation(profile: &str; conversation_id: i32;) c_DeleteConversation);
c_bind!(_import_bundle(profile: &str, bundle: &str;;) c_ImportBundle); c_bind!(_import_bundle(profile: &str, bundle: &str;;) c_ImportBundle);
c_bind!(_set_profile_attribute(profile: &str, key: &str, val: &str;;) c_SetProfileAttribute); c_bind!(_set_profile_attribute(profile: &str, key: &str, val: &str;;) c_SetProfileAttribute);
c_bind!(_set_conversation_attribute(profile: &str; conversation_id: i32; key: &str, val: &str) c_SetConversationAttribute); c_bind!(_set_conversation_attribute(profile: &str; conversation_id: i32; key: &str, val: &str) c_SetConversationAttribute);
c_bind!(_set_message_attribute(profile: &str; conversation_id: i32, channel_id: i32, message_id: i32; key: &str, val: &str) c_SetMessageAttribute); c_bind!(_update_message_attribute(profile: &str; conversation_id: i32, channel_id: i32, message_id: i32; key: &str, val: &str) c_UpdateMessageAttribute);
c_bind!(_change_password(profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str;;) c_ChangePassword); c_bind!(_change_password(profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str;;) c_ChangePassword);
c_bind!(_export_profile(profile: &str, filename: &str;;) c_ExportProfile); c_bind!(_export_profile(profile: &str, filename: &str;;) c_ExportProfile);
c_bind!(_create_server(password: &str, description: &str; autostart: c_bool;) c_CreateServer);
c_bind!(_delete_server(server: &str, current_password: &str;;) c_DeleteServer); c_bind!(_delete_server(server: &str, current_password: &str;;) c_DeleteServer);
c_bind!(_launch_server(server: &str;;) c_LaunchServer); c_bind!(_launch_server(server: &str;;) c_LaunchServer);
c_bind!(_stop_server(server: &str;;) c_StopServer); c_bind!(_stop_server(server: &str;;) c_StopServer);
@ -121,56 +148,111 @@ impl CwtchLibGo {
impl CwtchLib for CwtchLibGo { impl CwtchLib for CwtchLibGo {
c_bind!(start_cwtch(app_dir: &str, tor_path: &str;;) c_StartCwtch -> i32); c_bind!(start_cwtch(app_dir: &str, tor_path: &str;;) c_StartCwtch -> i32);
c_bind!(started(;;) c_Started -> i32); c_bind!(started(;;) c_Started -> i32);
c_bind!(send_app_event(event_json: &str;;) c_SendAppEvent); fn update_settings(&self, settings: &Settings) {
fn send_profile_event(&self, profile: &ProfileIdentity, event_jason: &str) { let settings_json = match serde_json::to_string(settings) {
self._send_profile_event(profile.as_str(), event_jason) Ok(s) => s,
Err(_) => return,
};
self._update_settings(&settings_json)
} }
c_bind!(create_profile(nick: &str, pass: &str;;) c_CreateProfile); c_bind!(reconnect_cwtch_foreground(;;) c_ReconnectCwtchForeground);
fn create_profile(&self, nick: &str, pass: &str, autostart: bool) {
self._create_profile(nick, pass, to_c_bool(autostart))
}
fn activate_peer_engine(&self, profile: &ProfileIdentity) {
self._activate_peer_engine(profile.as_str())
}
fn deactivate_peer_engine(&self, profile: &ProfileIdentity) {
self._deactivate_peer_engine(profile.as_str())
}
fn configure_connections(&self, profile: &ProfileIdentity, listen: bool, peers: bool, servers: bool) {
self._configure_connections(profile.as_str(), to_c_bool(listen), to_c_bool(peers), to_c_bool(servers))
}
fn search_conversations(&self, profile: &ProfileIdentity, pattern: &str) -> String {
self._search_conversations(profile.as_str(), pattern)
}
fn get_conversation_access_control_list(&self, profile: &ProfileIdentity, conversation_id: ConversationID) -> Result<ACL, CwtchError> {
let json = self._get_conversation_access_control_list(profile.as_str(), conversation_id.into());
match serde_json::from_str(&json) {
Ok(acl) => Ok(acl),
Err(e) => Err(e.to_string()),
}
}
fn update_conversation_access_control_list(&self, profile: &ProfileIdentity, conversation_id: ConversationID, acl: ACL) {
match serde_json::to_string(&acl) {
Ok(acl_json) => self._update_conversation_access_control_list(profile.as_str(), conversation_id.into(), &acl_json),
Err(_) => return,
};
}
c_bind!(load_profiles(pass: &str;;) c_LoadProfiles); c_bind!(load_profiles(pass: &str;;) c_LoadProfiles);
fn accept_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) { fn accept_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._accept_conversation(profile.as_str(), conversation_id.into()) self._accept_conversation(profile.as_str(), conversation_id.into())
} }
fn block_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._block_contact(String::from(profile).as_str(), conversation_id.into()) fn peer_with(&self, profile: &ProfileIdentity, new_peer_address: &str) {
self._peer_with(profile.as_str(), new_peer_address)
} }
fn unblock_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._unblock_contact(String::from(profile).as_str(), conversation_id.into()) fn block_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._block_conversation(String::from(profile).as_str(), conversation_id.into())
} }
fn get_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32) -> String { fn unblock_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._get_message(String::from(profile).as_str(), conversation_id.into(), message_index) self._unblock_conversation(String::from(profile).as_str(), conversation_id.into())
} }
fn disconnect_from_peer(&self, profile: &ProfileIdentity, peer_id: &str) {
self._disconnect_from_peer(profile.as_str(), peer_id)
}
fn get_message_by_id(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String { fn get_message_by_id(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String {
self._get_message_by_id(String::from(profile).as_str(), conversation_id.into(), message_id) self._get_message_by_id(String::from(profile).as_str(), conversation_id.into(), message_id)
} }
fn get_message_by_content_hash(&self, profile: &ProfileIdentity, conversation_id: ConversationID, hash: &str) -> String { fn get_message_by_content_hash(&self, profile: &ProfileIdentity, conversation_id: ConversationID, hash: &str) -> String {
self._get_message_by_content_hash(String::from(profile).as_str(), conversation_id.into(), hash) self._get_message_by_content_hash(String::from(profile).as_str(), conversation_id.into(), hash)
} }
fn get_messages(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: i32) -> String { fn get_messages(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: u32) -> String {
self._get_messages(String::from(profile).as_str(), conversation_id.into(), message_index, count) self._get_messages(String::from(profile).as_str(), conversation_id.into(), message_index, count)
} }
fn send_message_raw(&self, profile: &ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String { fn send_message_raw(&self, profile: &ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String {
self._send_message(String::from(profile).as_str(), conversation_id.into(), msg) self._send_message(String::from(profile).as_str(), conversation_id.into(), msg)
} }
fn send_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message: &Message) -> Result<String, CwtchError> { fn send_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message: &MessageWrapper) -> Result<String, CwtchError> {
match serde_json::to_string(&message) { match serde_json::to_string(&message) {
Ok(message_json) => Ok(self._send_message(&String::from(profile), conversation_id.into(), &message_json)), Ok(message_json) => Ok(self._send_message(&String::from(profile), conversation_id.into(), &message_json)),
Err(e) => Err(format!("Error parsing json response: {}", e.to_string())) Err(e) => Err(format!("Error parsing json response: {}", e.to_string()))
} }
} }
fn send_invitation(&self, profile: &ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String { fn send_invite_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String {
self._send_invitation(String::from(profile).as_str(), conversation_id.into(), target_id) self._send_invite_message(String::from(profile).as_str(), conversation_id.into(), target_id)
} }
fn share_file(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String { fn share_file(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String {
self._share_file(String::from(profile).as_str(), conversation_id.into(), file_path) self._share_file(String::from(profile).as_str(), conversation_id.into(), file_path)
} }
fn download_file(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str, manifest_path: &str, file_key: FileKey) { fn get_shared_files(&self, profile: &ProfileIdentity, conversaion_id: ConversationID) -> Vec<SharedFile> {
self._download_file(String::from(profile).as_str(), conversation_id.into(), file_path, manifest_path, String::from(file_key).as_str()) let json = self._get_shared_files(profile.as_str(), conversaion_id.into());
match serde_json::from_str(&json) {
Ok(l) => l,
Err(_) => vec!(),
}
} }
fn check_download_status(&self, profile: &ProfileIdentity, file_key: FileKey) { fn download_file_default_limit(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str, manifest_path: &str, file_key: &FileKey) {
self._download_file_default_limit(String::from(profile).as_str(), conversation_id.into(), file_path, manifest_path, String::from(file_key).as_str())
}
fn restart_fileshare(&self, profile: &ProfileIdentity, file_key: &FileKey) {
self._restart_fileshare(profile.as_str(), file_key.as_str())
}
fn stop_fileshare(&self, profile: &ProfileIdentity, file_key: &FileKey) {
self._stop_fileshare(profile.as_str(), file_key.as_str())
}
fn check_download_status(&self, profile: &ProfileIdentity, file_key: &FileKey) {
self._check_download_status(String::from(profile).as_str(), String::from(file_key).as_str()) self._check_download_status(String::from(profile).as_str(), String::from(file_key).as_str())
} }
fn verify_or_resume_download(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_key: FileKey) { fn verify_or_resume_download(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_key: &FileKey) {
self._verify_or_resume_download(String::from(profile).as_str(), conversation_id.into(), String::from(file_key).as_str()) self._verify_or_resume_download(String::from(profile).as_str(), conversation_id.into(), String::from(file_key).as_str())
} }
@ -179,8 +261,23 @@ impl CwtchLib for CwtchLibGo {
bindings::c_ResetTor(); bindings::c_ResetTor();
} }
} }
fn create_group(&self, profile: &ProfileIdentity, server: &str, name: &str) { fn start_group(&self, profile: &ProfileIdentity, server: &str, name: &str) {
self._create_group(String::from(profile).as_str(), server, name) self._start_group(String::from(profile).as_str(), server, name)
}
fn queue_join_server(&self, profile: &ProfileIdentity, server: &ServerIdentity) {
self._queue_join_server(profile.as_str(), server.as_str())
}
fn disconnect_from_server(&self, profile: &ProfileIdentity, server: &ServerIdentity) {
self._disconnect_from_server(profile.as_str(), server.as_str())
}
fn publish_server_update(&self, profile: &ProfileIdentity) {
self._publish_server_update(profile.as_str())
}
fn get_server_info_list(&self, profile: &ProfileIdentity) {
self._get_server_info_list(profile.as_str())
}
fn delete_server_info(&self, profile: &ProfileIdentity, server: &ServerIdentity) {
self._delete_server_info(profile.as_str(), server.as_str())
} }
fn delete_profile(&self, profile: &ProfileIdentity, pass: &str) { fn delete_profile(&self, profile: &ProfileIdentity, pass: &str) {
self._delete_profile(String::from(profile).as_str(), pass) self._delete_profile(String::from(profile).as_str(), pass)
@ -188,8 +285,8 @@ impl CwtchLib for CwtchLibGo {
fn archive_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) { fn archive_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._archive_conversation(String::from(profile).as_str(), conversation_id.into()) self._archive_conversation(String::from(profile).as_str(), conversation_id.into())
} }
fn delete_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID) { fn delete_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID) {
self._delete_contact(profile.as_str(), conversation_id.into()) self._delete_conversation(profile.as_str(), conversation_id.into())
} }
fn import_bundle(&self, profile: &ProfileIdentity, bundle: &str) { fn import_bundle(&self, profile: &ProfileIdentity, bundle: &str) {
self._import_bundle(String::from(profile).as_str(), bundle) self._import_bundle(String::from(profile).as_str(), bundle)
@ -223,8 +320,8 @@ impl CwtchLib for CwtchLibGo {
false => Ok(None), false => Ok(None),
} }
} }
fn set_message_attribute(&self, profile: &ProfileIdentity, conversation_id: ConversationID, channel_id: i32, message_id: i32, key: &str, val: &str) { fn update_message_attribute(&self, profile: &ProfileIdentity, conversation_id: ConversationID, channel_id: i32, message_id: i32, key: &str, val: &str) {
self._set_message_attribute(String::from(profile).as_str(), conversation_id.into(), channel_id, message_id, key, val) self._update_message_attribute(String::from(profile).as_str(), conversation_id.into(), channel_id, message_id, key, val)
} }
fn change_password(&self, profile: &ProfileIdentity, old_pass: &str, new_pass: &str, new_pass_again: &str) { fn change_password(&self, profile: &ProfileIdentity, old_pass: &str, new_pass: &str, new_pass_again: &str) {
self._change_password(String::from(profile).as_str(), old_pass, new_pass, new_pass_again) self._change_password(String::from(profile).as_str(), old_pass, new_pass, new_pass_again)
@ -243,7 +340,9 @@ impl CwtchLib for CwtchLibGo {
} }
c_bind!(load_servers(password: &str;;) c_LoadServers); c_bind!(load_servers(password: &str;;) c_LoadServers);
c_bind!(create_server(password: &str, description: &str; autostart: i8;) c_CreateServer); fn create_server(&self, password: &str, description: &str , autostart: bool) {
self._create_server(password, description, to_c_bool(autostart))
}
fn delete_server(&self, server: ServerIdentity, current_password: &str) { fn delete_server(&self, server: ServerIdentity, current_password: &str) {
self._delete_server(String::from(server).as_str(), current_password) self._delete_server(String::from(server).as_str(), current_password)
} }
@ -259,6 +358,7 @@ impl CwtchLib for CwtchLibGo {
fn set_server_attribute(&self, server: ServerIdentity, key: &str, val: &str) { fn set_server_attribute(&self, server: ServerIdentity, key: &str, val: &str) {
self._set_server_attribute(String::from(server).as_str(), key, val) self._set_server_attribute(String::from(server).as_str(), key, val)
} }
c_bind!(get_debug_info(;;) c_GetDebugInfo -> String); c_bind!(get_debug_info(;;) c_GetDebugInfo -> String);
fn get_appbus_event(&self) -> Event { fn get_appbus_event(&self) -> Event {

View File

@ -1,4 +1,4 @@
/* automatically generated by rust-bindgen 0.59.2 */ /* automatically generated by rust-bindgen 0.65.1 */
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
#[repr(C)] #[repr(C)]
@ -6,7 +6,6 @@ pub struct __BindgenComplex<T> {
pub re: T, pub re: T,
pub im: T, pub im: T,
} }
pub type size_t = ::std::os::raw::c_ulong;
pub type wchar_t = ::std::os::raw::c_int; pub type wchar_t = ::std::os::raw::c_int;
#[repr(C)] #[repr(C)]
#[repr(align(16))] #[repr(align(16))]
@ -18,6 +17,8 @@ pub struct max_align_t {
} }
#[test] #[test]
fn bindgen_test_layout_max_align_t() { fn bindgen_test_layout_max_align_t() {
const UNINIT: ::std::mem::MaybeUninit<max_align_t> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!( assert_eq!(
::std::mem::size_of::<max_align_t>(), ::std::mem::size_of::<max_align_t>(),
32usize, 32usize,
@ -29,9 +30,7 @@ fn bindgen_test_layout_max_align_t() {
concat!("Alignment of ", stringify!(max_align_t)) concat!("Alignment of ", stringify!(max_align_t))
); );
assert_eq!( assert_eq!(
unsafe { unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce1) as usize - ptr as usize },
&(*(::std::ptr::null::<max_align_t>())).__clang_max_align_nonce1 as *const _ as usize
},
0usize, 0usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -41,9 +40,7 @@ fn bindgen_test_layout_max_align_t() {
) )
); );
assert_eq!( assert_eq!(
unsafe { unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce2) as usize - ptr as usize },
&(*(::std::ptr::null::<max_align_t>())).__clang_max_align_nonce2 as *const _ as usize
},
16usize, 16usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -61,6 +58,8 @@ pub struct _GoString_ {
} }
#[test] #[test]
fn bindgen_test_layout__GoString_() { fn bindgen_test_layout__GoString_() {
const UNINIT: ::std::mem::MaybeUninit<_GoString_> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!( assert_eq!(
::std::mem::size_of::<_GoString_>(), ::std::mem::size_of::<_GoString_>(),
16usize, 16usize,
@ -72,7 +71,7 @@ fn bindgen_test_layout__GoString_() {
concat!("Alignment of ", stringify!(_GoString_)) concat!("Alignment of ", stringify!(_GoString_))
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<_GoString_>())).p as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).p) as usize - ptr as usize },
0usize, 0usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -82,7 +81,7 @@ fn bindgen_test_layout__GoString_() {
) )
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<_GoString_>())).n as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).n) as usize - ptr as usize },
8usize, 8usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -102,7 +101,7 @@ pub type GoInt64 = ::std::os::raw::c_longlong;
pub type GoUint64 = ::std::os::raw::c_ulonglong; pub type GoUint64 = ::std::os::raw::c_ulonglong;
pub type GoInt = GoInt64; pub type GoInt = GoInt64;
pub type GoUint = GoUint64; pub type GoUint = GoUint64;
pub type GoUintptr = ::std::os::raw::c_ulong; pub type GoUintptr = usize;
pub type GoFloat32 = f32; pub type GoFloat32 = f32;
pub type GoFloat64 = f64; pub type GoFloat64 = f64;
pub type GoComplex64 = __BindgenComplex<f32>; pub type GoComplex64 = __BindgenComplex<f32>;
@ -119,6 +118,8 @@ pub struct GoInterface {
} }
#[test] #[test]
fn bindgen_test_layout_GoInterface() { fn bindgen_test_layout_GoInterface() {
const UNINIT: ::std::mem::MaybeUninit<GoInterface> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!( assert_eq!(
::std::mem::size_of::<GoInterface>(), ::std::mem::size_of::<GoInterface>(),
16usize, 16usize,
@ -130,7 +131,7 @@ fn bindgen_test_layout_GoInterface() {
concat!("Alignment of ", stringify!(GoInterface)) concat!("Alignment of ", stringify!(GoInterface))
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<GoInterface>())).t as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).t) as usize - ptr as usize },
0usize, 0usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -140,7 +141,7 @@ fn bindgen_test_layout_GoInterface() {
) )
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<GoInterface>())).v as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize },
8usize, 8usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -159,6 +160,8 @@ pub struct GoSlice {
} }
#[test] #[test]
fn bindgen_test_layout_GoSlice() { fn bindgen_test_layout_GoSlice() {
const UNINIT: ::std::mem::MaybeUninit<GoSlice> = ::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!( assert_eq!(
::std::mem::size_of::<GoSlice>(), ::std::mem::size_of::<GoSlice>(),
24usize, 24usize,
@ -170,7 +173,7 @@ fn bindgen_test_layout_GoSlice() {
concat!("Alignment of ", stringify!(GoSlice)) concat!("Alignment of ", stringify!(GoSlice))
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<GoSlice>())).data as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize },
0usize, 0usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -180,7 +183,7 @@ fn bindgen_test_layout_GoSlice() {
) )
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<GoSlice>())).len as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize },
8usize, 8usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -190,7 +193,7 @@ fn bindgen_test_layout_GoSlice() {
) )
); );
assert_eq!( assert_eq!(
unsafe { &(*(::std::ptr::null::<GoSlice>())).cap as *const _ as usize }, unsafe { ::std::ptr::addr_of!((*ptr).cap) as usize - ptr as usize },
16usize, 16usize,
concat!( concat!(
"Offset of field: ", "Offset of field: ",
@ -200,6 +203,12 @@ fn bindgen_test_layout_GoSlice() {
) )
); );
} }
extern "C" {
pub fn c_FreePointer(ptr: *mut ::std::os::raw::c_char);
}
extern "C" {
pub fn c_Started() -> ::std::os::raw::c_int;
}
extern "C" { extern "C" {
pub fn c_StartCwtch( pub fn c_StartCwtch(
dir_c: *mut ::std::os::raw::c_char, dir_c: *mut ::std::os::raw::c_char,
@ -209,195 +218,13 @@ extern "C" {
) -> ::std::os::raw::c_int; ) -> ::std::os::raw::c_int;
} }
extern "C" { extern "C" {
pub fn c_Started() -> ::std::os::raw::c_int; pub fn c_GetAppBusEvent() -> *mut ::std::os::raw::c_char;
} }
extern "C" { extern "C" {
pub fn c_ReconnectCwtchForeground(); pub fn c_ReconnectCwtchForeground();
} }
extern "C" { extern "C" {
pub fn c_SendAppEvent(json_ptr: *mut ::std::os::raw::c_char, json_len: ::std::os::raw::c_int); pub fn c_ShutdownCwtch();
}
extern "C" {
pub fn c_SendProfileEvent(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
json_ptr: *mut ::std::os::raw::c_char,
json_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_GetAppBusEvent() -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_CreateProfile(
nick_ptr: *mut ::std::os::raw::c_char,
nick_len: ::std::os::raw::c_int,
pass_ptr: *mut ::std::os::raw::c_char,
pass_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_LoadProfiles(
passwordPtr: *mut ::std::os::raw::c_char,
passwordLen: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_AcceptConversation(
profilePtr: *mut ::std::os::raw::c_char,
profileLen: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_BlockContact(
profilePtr: *mut ::std::os::raw::c_char,
profileLen: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_UnblockContact(
profilePtr: *mut ::std::os::raw::c_char,
profileLen: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_GetMessage(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
message_index: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessageByID(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
message_index: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessagesByContentHash(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
contenthash_ptr: *mut ::std::os::raw::c_char,
contenthash_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessages(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
message_index: ::std::os::raw::c_int,
count: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_FreePointer(ptr: *mut ::std::os::raw::c_char);
}
extern "C" {
pub fn c_SendMessage(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
msg_ptr: *mut ::std::os::raw::c_char,
msg_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_SendInvitation(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
target_id: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_ShareFile(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
filepath_ptr: *mut ::std::os::raw::c_char,
filepath_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_DownloadFile(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
filepath_ptr: *mut ::std::os::raw::c_char,
filepath_len: ::std::os::raw::c_int,
manifestpath_ptr: *mut ::std::os::raw::c_char,
manifestpath_len: ::std::os::raw::c_int,
filekey_ptr: *mut ::std::os::raw::c_char,
filekey_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_CheckDownloadStatus(
profilePtr: *mut ::std::os::raw::c_char,
profileLen: ::std::os::raw::c_int,
fileKeyPtr: *mut ::std::os::raw::c_char,
fileKeyLen: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_VerifyOrResumeDownload(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
filekey_ptr: *mut ::std::os::raw::c_char,
filekey_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_ResetTor();
}
extern "C" {
pub fn c_CreateGroup(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
server_ptr: *mut ::std::os::raw::c_char,
server_len: ::std::os::raw::c_int,
name_ptr: *mut ::std::os::raw::c_char,
name_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DeleteProfile(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
password_ptr: *mut ::std::os::raw::c_char,
password_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_ArchiveConversation(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DeleteContact(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
conversation_id: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_ImportBundle(
profile_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int,
bundle_ptr: *mut ::std::os::raw::c_char,
bundle_len: ::std::os::raw::c_int,
);
} }
extern "C" { extern "C" {
pub fn c_SetProfileAttribute( pub fn c_SetProfileAttribute(
@ -438,80 +265,372 @@ extern "C" {
) -> *mut ::std::os::raw::c_char; ) -> *mut ::std::os::raw::c_char;
} }
extern "C" { extern "C" {
pub fn c_SetMessageAttribute( pub fn c_ResetTor();
profile_ptr: *mut ::std::os::raw::c_char, }
profile_len: ::std::os::raw::c_int, extern "C" {
conversation_id: ::std::os::raw::c_int, pub fn c_UpdateSettings(json_ptr: *mut ::std::os::raw::c_char, json_len: ::std::os::raw::c_int);
channel_id: ::std::os::raw::c_int, }
message_id: ::std::os::raw::c_int, extern "C" {
key_ptr: *mut ::std::os::raw::c_char, pub fn c_GetDebugInfo() -> *mut ::std::os::raw::c_char;
key_len: ::std::os::raw::c_int, }
val_ptr: *mut ::std::os::raw::c_char, extern "C" {
val_len: ::std::os::raw::c_int, pub fn c_ActivatePeerEngine(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
); );
} }
extern "C" { extern "C" {
pub fn c_ChangePassword( pub fn c_DeactivatePeerEngine(
profile_ptr: *mut ::std::os::raw::c_char, onion_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int, onion_len: ::std::os::raw::c_int,
oldpassword_ptr: *mut ::std::os::raw::c_char,
oldpassword_len: ::std::os::raw::c_int,
newpassword_ptr: *mut ::std::os::raw::c_char,
newpassword_len: ::std::os::raw::c_int,
newpassword_again_ptr: *mut ::std::os::raw::c_char,
newpassword_again_len: ::std::os::raw::c_int,
); );
} }
extern "C" { extern "C" {
pub fn c_ExportProfile( pub fn c_ConfigureConnections(
profile_ptr: *mut ::std::os::raw::c_char, onion_ptr: *mut ::std::os::raw::c_char,
profile_len: ::std::os::raw::c_int, onion_len: ::std::os::raw::c_int,
file_ptr: *mut ::std::os::raw::c_char, listen1: ::std::os::raw::c_char,
file_len: ::std::os::raw::c_int, peers2: ::std::os::raw::c_char,
servers3: ::std::os::raw::c_char,
);
}
extern "C" {
pub fn c_CreateProfile(
name_ptr: *mut ::std::os::raw::c_char,
name_len: ::std::os::raw::c_int,
password_ptr: *mut ::std::os::raw::c_char,
password_len: ::std::os::raw::c_int,
autostart4: ::std::os::raw::c_char,
);
}
extern "C" {
pub fn c_LoadProfiles(
password_ptr: *mut ::std::os::raw::c_char,
password_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DeleteProfile(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
password_ptr: *mut ::std::os::raw::c_char,
password_len: ::std::os::raw::c_int,
); );
} }
extern "C" { extern "C" {
pub fn c_ImportProfile( pub fn c_ImportProfile(
file_ptr: *mut ::std::os::raw::c_char, file5_ptr: *mut ::std::os::raw::c_char,
file_len: ::std::os::raw::c_int, file5_len: ::std::os::raw::c_int,
passwordPtr: *mut ::std::os::raw::c_char, password_ptr: *mut ::std::os::raw::c_char,
passwordLen: ::std::os::raw::c_int, password_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char; ) -> *mut ::std::os::raw::c_char;
} }
extern "C" { extern "C" {
pub fn c_ShutdownCwtch(); pub fn c_ChangePassword(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
current6_ptr: *mut ::std::os::raw::c_char,
current6_len: ::std::os::raw::c_int,
newPassword7_ptr: *mut ::std::os::raw::c_char,
newPassword7_len: ::std::os::raw::c_int,
newPasswordAgain8_ptr: *mut ::std::os::raw::c_char,
newPasswordAgain8_len: ::std::os::raw::c_int,
);
} }
extern "C" { extern "C" {
pub fn c_LoadServers( pub fn c_ExportProfile(
passwordPtr: *mut ::std::os::raw::c_char, onion_ptr: *mut ::std::os::raw::c_char,
passwordLen: ::std::os::raw::c_int, onion_len: ::std::os::raw::c_int,
file9_ptr: *mut ::std::os::raw::c_char,
file9_len: ::std::os::raw::c_int,
); );
} }
extern "C" {
pub fn c_ImportBundle(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
bundle10_ptr: *mut ::std::os::raw::c_char,
bundle10_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_ArchiveConversation(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_AcceptConversation(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_BlockConversation(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_UnblockConversation(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DeleteConversation(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_PeerWithOnion(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
handle11_ptr: *mut ::std::os::raw::c_char,
handle11_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DisconnectFromPeer(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
handle12_ptr: *mut ::std::os::raw::c_char,
handle12_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_GetConversationAccessControlList(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_UpdateConversationAccessControlList(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
json13_ptr: *mut ::std::os::raw::c_char,
json13_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_SearchConversations(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
pattern14_ptr: *mut ::std::os::raw::c_char,
pattern14_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_SendMessage(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
msg15_ptr: *mut ::std::os::raw::c_char,
msg15_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessageById(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
message_id: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessageByContentHash(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
contentHash16_ptr: *mut ::std::os::raw::c_char,
contentHash16_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetMessages(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
index: ::std::os::raw::c_int,
count: ::std::os::raw::c_uint,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_SendInviteMessage(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
target: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_UpdateMessageAttribute(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
channel_id: ::std::os::raw::c_int,
message_id: ::std::os::raw::c_int,
attributeKey17_ptr: *mut ::std::os::raw::c_char,
attributeKey17_len: ::std::os::raw::c_int,
attributeValue18_ptr: *mut ::std::os::raw::c_char,
attributeValue18_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_StartGroup(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
name19_ptr: *mut ::std::os::raw::c_char,
name19_len: ::std::os::raw::c_int,
server20_ptr: *mut ::std::os::raw::c_char,
server20_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_QueueJoinServer(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
handle21_ptr: *mut ::std::os::raw::c_char,
handle21_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DisconnectFromServer(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
handle22_ptr: *mut ::std::os::raw::c_char,
handle22_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_PublishServerUpdate(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_GetServerInfoList(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DeleteServerInfo(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
serverOnion23_ptr: *mut ::std::os::raw::c_char,
serverOnion23_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_DownloadFileDefaultLimit(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
filepath24_ptr: *mut ::std::os::raw::c_char,
filepath24_len: ::std::os::raw::c_int,
manifest25_ptr: *mut ::std::os::raw::c_char,
manifest25_len: ::std::os::raw::c_int,
filekey26_ptr: *mut ::std::os::raw::c_char,
filekey26_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_RestartFileShare(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
filekey27_ptr: *mut ::std::os::raw::c_char,
filekey27_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_StopFileShare(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
filekey28_ptr: *mut ::std::os::raw::c_char,
filekey28_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_CheckDownloadStatus(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
filekey29_ptr: *mut ::std::os::raw::c_char,
filekey29_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_VerifyOrResumeDownloadDefaultLimit(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
filekey30_ptr: *mut ::std::os::raw::c_char,
filekey30_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_ShareFile(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
filepath31_ptr: *mut ::std::os::raw::c_char,
filepath31_len: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn c_GetSharedFiles(
onion_ptr: *mut ::std::os::raw::c_char,
onion_len: ::std::os::raw::c_int,
conversation: ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char;
}
extern "C" { extern "C" {
pub fn c_CreateServer( pub fn c_CreateServer(
passwordPtr: *mut ::std::os::raw::c_char, password_ptr: *mut ::std::os::raw::c_char,
passwordLen: ::std::os::raw::c_int, password_len: ::std::os::raw::c_int,
descPtr: *mut ::std::os::raw::c_char, description32_ptr: *mut ::std::os::raw::c_char,
descLen: ::std::os::raw::c_int, description32_len: ::std::os::raw::c_int,
autostart: ::std::os::raw::c_char, autostart33: ::std::os::raw::c_char,
); );
} }
extern "C" { extern "C" {
pub fn c_DeleteServer( pub fn c_SetServerAttribute(
onionPtr: *mut ::std::os::raw::c_char, handle34_ptr: *mut ::std::os::raw::c_char,
onionLen: ::std::os::raw::c_int, handle34_len: ::std::os::raw::c_int,
currentPasswordPtr: *mut ::std::os::raw::c_char, key35_ptr: *mut ::std::os::raw::c_char,
currentPasswordLen: ::std::os::raw::c_int, key35_len: ::std::os::raw::c_int,
val36_ptr: *mut ::std::os::raw::c_char,
val36_len: ::std::os::raw::c_int,
);
}
extern "C" {
pub fn c_LoadServers(
password_ptr: *mut ::std::os::raw::c_char,
password_len: ::std::os::raw::c_int,
); );
} }
extern "C" { extern "C" {
pub fn c_LaunchServers(); pub fn c_LaunchServers();
} }
extern "C" { extern "C" {
pub fn c_LaunchServer(onionPtr: *mut ::std::os::raw::c_char, onionLen: ::std::os::raw::c_int); pub fn c_LaunchServer(
handle37_ptr: *mut ::std::os::raw::c_char,
handle37_len: ::std::os::raw::c_int,
);
} }
extern "C" { extern "C" {
pub fn c_StopServer(onionPtr: *mut ::std::os::raw::c_char, onionLen: ::std::os::raw::c_int); pub fn c_StopServer(
handle38_ptr: *mut ::std::os::raw::c_char,
handle38_len: ::std::os::raw::c_int,
);
} }
extern "C" { extern "C" {
pub fn c_StopServers(); pub fn c_StopServers();
@ -520,15 +639,10 @@ extern "C" {
pub fn c_DestroyServers(); pub fn c_DestroyServers();
} }
extern "C" { extern "C" {
pub fn c_SetServerAttribute( pub fn c_DeleteServer(
onionPtr: *mut ::std::os::raw::c_char, handle39_ptr: *mut ::std::os::raw::c_char,
onionLen: ::std::os::raw::c_int, handle39_len: ::std::os::raw::c_int,
keyPtr: *mut ::std::os::raw::c_char, password_ptr: *mut ::std::os::raw::c_char,
keyLen: ::std::os::raw::c_int, password_len: ::std::os::raw::c_int,
valPtr: *mut ::std::os::raw::c_char,
valLen: ::std::os::raw::c_int,
); );
} }
extern "C" {
pub fn c_GetDebugInfo() -> *mut ::std::os::raw::c_char;
}

View File

@ -5,7 +5,7 @@ use chrono::{DateTime, FixedOffset};
use chrono::prelude::*; use chrono::prelude::*;
use std::convert::From; use std::convert::From;
use crate::structs::{ACL, ConnectionState, CwtchEvent, Message, Profile, Settings}; use crate::structs::{ACL, ConnectionState, CwtchEvent, MessageWrapper, Profile, Settings};
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
@ -88,6 +88,12 @@ impl From<String> for GroupID {
} }
} }
impl GroupID {
/// Get &str of GroupID String
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
/// Server ID user to refer to a server in Cwtch /// Server ID user to refer to a server in Cwtch
@ -111,6 +117,13 @@ impl From<ServerIdentity> for String {
} }
} }
impl ServerIdentity {
/// Get &str of ServerIdentity String
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
/// FileKey ID user to refer to a file share in Cwtch /// FileKey ID user to refer to a file share in Cwtch
pub struct FileKey(String); pub struct FileKey(String);
@ -127,6 +140,19 @@ impl From<FileKey> for String {
} }
} }
impl From<&FileKey> for String {
fn from(x: &FileKey) -> Self {
x.into()
}
}
impl FileKey {
/// Get &str of FileKey String
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
/// Enum for type of notification a UI/client should emit for a new message /// Enum for type of notification a UI/client should emit for a new message
pub enum MessageNotification { pub enum MessageNotification {
@ -239,7 +265,9 @@ pub enum Event {
/// Cwtch had an error at the app level (not profile level), usually in response to an API call /// Cwtch had an error at the app level (not profile level), usually in response to an API call
AppError { AppError {
/// details of the app error that occured /// details of the app error that occured
error: String error: String,
/// possible data about the error
data: String
}, },
/// Global settings being emited from lcg, usually in response to them being sent to be saved by client /// Global settings being emited from lcg, usually in response to them being sent to be saved by client
UpdateGlobalSettings { UpdateGlobalSettings {
@ -333,7 +361,7 @@ pub enum Event {
/// time message was received /// time message was received
timestamp_received: DateTime<FixedOffset>, timestamp_received: DateTime<FixedOffset>,
/// the message /// the message
message: Message, message: MessageWrapper,
/// notification instructions (based on settings) /// notification instructions (based on settings)
notification: MessageNotification, notification: MessageNotification,
/// path to picture for the contact /// path to picture for the contact
@ -456,13 +484,11 @@ pub enum Event {
/// message index /// message index
index: i32, index: i32,
/// the message /// the message
message: Message, message: MessageWrapper,
/// hash of the message /// hash of the message
content_hash: String, content_hash: String,
/// path to picture for sender /// path to picture for sender
picture: String, picture: String,
/// name of sender
nick: String,
/// notification policy (based on settings) /// notification policy (based on settings)
notification: MessageNotification, notification: MessageNotification,
}, },
@ -489,18 +515,12 @@ pub enum Event {
profile_id: ProfileIdentity, profile_id: ProfileIdentity,
/// conversation id /// conversation id
conversation_id: ConversationID, conversation_id: ConversationID,
/// group id
group_id: GroupID,
/// server the group is on /// server the group is on
group_server: String, group_server: String,
/// invite string /// invite string
group_invite: String, group_invite: String,
/// group name /// group name
group_name: String, group_name: String,
/// path to group picture
picture: String,
/// Access Control List for group
access_control_list: ACL,
}, },
/// a server connection state has changed /// a server connection state has changed
ServerStateChange { ServerStateChange {
@ -636,13 +656,20 @@ impl From<&CwtchEvent> for Event {
contact_id: cwtch_event.data["RemotePeer"].clone().into(), contact_id: cwtch_event.data["RemotePeer"].clone().into(),
nick: cwtch_event.data["Nick"].clone(), nick: cwtch_event.data["Nick"].clone(),
timestamp_received: DateTime::parse_from_rfc3339(cwtch_event.data["TimestampReceived"].as_str()).unwrap_or( DateTime::from(Utc::now())), timestamp_received: DateTime::parse_from_rfc3339(cwtch_event.data["TimestampReceived"].as_str()).unwrap_or( DateTime::from(Utc::now())),
message: Message::from_json(&cwtch_event.data["Data"]), message: MessageWrapper::from_json(&cwtch_event.data["Data"]),
notification: MessageNotification::from(cwtch_event.data["notification"].clone()), notification: MessageNotification::from(cwtch_event.data["notification"].clone()),
picture: cwtch_event.data["picture"].clone(), picture: cwtch_event.data["picture"].clone(),
}, },
"PeerError" => Event::PeerError { error: cwtch_event.data["Error"].clone() }, "PeerError" => Event::PeerError { error: cwtch_event.data["Error"].clone() },
"AppError" => Event::AppError { "AppError" => Event::AppError {
error: cwtch_event.data["Error"].clone(), error: match cwtch_event.data.contains_key("Error") {
true => cwtch_event.data["Error"].clone(),
false => "".to_string()
},
data: match cwtch_event.data.contains_key("Data") {
true => cwtch_event.data["Data"].clone(),
false => "".to_string()
}
}, },
"ContactCreated" => Event::ContactCreated { "ContactCreated" => Event::ContactCreated {
profile_id: cwtch_event.data["ProfileOnion"].clone().into(), profile_id: cwtch_event.data["ProfileOnion"].clone().into(),
@ -771,8 +798,7 @@ impl From<&CwtchEvent> for Event {
content_hash: cwtch_event.data["ContentHash"].clone(), content_hash: cwtch_event.data["ContentHash"].clone(),
conversation_id: cwtch_event.data["ConversationID"].parse().unwrap_or(-2).into(), conversation_id: cwtch_event.data["ConversationID"].parse().unwrap_or(-2).into(),
contact_id: cwtch_event.data["RemotePeer"].clone().into(), contact_id: cwtch_event.data["RemotePeer"].clone().into(),
nick: cwtch_event.data["Nick"].clone(), message: MessageWrapper::from_json(&cwtch_event.data["Data"]),
message: Message::from_json(&cwtch_event.data["Data"]),
notification: MessageNotification::from(cwtch_event.data["notification"].clone()), notification: MessageNotification::from(cwtch_event.data["notification"].clone()),
picture: cwtch_event.data["picture"].clone(), picture: cwtch_event.data["picture"].clone(),
}, },
@ -788,12 +814,9 @@ impl From<&CwtchEvent> for Event {
"NewGroup" => Event::NewGroup { "NewGroup" => Event::NewGroup {
profile_id: cwtch_event.data["ProfileOnion"].clone().into(), profile_id: cwtch_event.data["ProfileOnion"].clone().into(),
conversation_id: cwtch_event.data["ConversationID"].parse().unwrap_or(-2).into(), conversation_id: cwtch_event.data["ConversationID"].parse().unwrap_or(-2).into(),
group_id: cwtch_event.data["GroupID"].clone().into(),
group_server: cwtch_event.data["GroupServer"].clone(), group_server: cwtch_event.data["GroupServer"].clone(),
group_invite: cwtch_event.data["GroupInvite"].clone(),
group_name: cwtch_event.data["GroupName"].clone(), group_name: cwtch_event.data["GroupName"].clone(),
picture: cwtch_event.data["picture"].clone(), group_invite: cwtch_event.data["GroupInvite"].clone(),
access_control_list: serde_json::from_str(cwtch_event.data["accessControlList"].as_str()).unwrap_or(ACL::new()),
}, },
"ServerStateChange" => Event::ServerStateChange { "ServerStateChange" => Event::ServerStateChange {
profile_id: cwtch_event.data["ProfileOnion"].clone().into(), profile_id: cwtch_event.data["ProfileOnion"].clone().into(),

View File

@ -4,7 +4,7 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use crate::event::{ConversationID, Event, FileKey, ProfileIdentity, ServerIdentity}; use crate::event::{ConversationID, Event, FileKey, ProfileIdentity, ServerIdentity};
use crate::structs::Message; use crate::structs::{ACL, MessageWrapper, Settings, SharedFile};
mod bindings_go; mod bindings_go;
mod cwtchlib_go; mod cwtchlib_go;
@ -25,17 +25,27 @@ pub trait CwtchLib {
/// Return 1 if cwtch has been started and 0 if not /// Return 1 if cwtch has been started and 0 if not
fn started(&self) -> i32; fn started(&self) -> i32;
/// Send json of a structs::CwtchEvent to the cwtch app bus /// Like StartCwtch, but StartCwtch has already been called so we don't need to restart Tor etc (probably)
fn send_app_event(&self, event_json: &str); /// Do need to re-send initial state tho, eg profiles that are already loaded (used by android when ui state is lost)
fn reconnect_cwtch_foreground(&self);
/// Send json of a structs::CwtchEvent to a cwtch profile /// Save and update the settings based on this settings
fn send_profile_event(&self, profile: &ProfileIdentity, event_json: &str); fn update_settings(&self, settings: &Settings);
/// Activate the networking engine of a profile so it can send and listen to/for messages
fn activate_peer_engine(&self, profile: &ProfileIdentity);
/// Deactivate the networking engine of a profile so it cannot send and listen to/for messages
fn deactivate_peer_engine(&self, profile: &ProfileIdentity);
/// Pull json of a structs::CwtchEvent off the appbus for responding to /// Pull json of a structs::CwtchEvent off the appbus for responding to
fn get_appbus_event(&self) -> Event; fn get_appbus_event(&self) -> Event;
/// configure a peer's connection settings, listen for incoming connections, connect to peers and connect to servers.
fn configure_connections(&self, profile: &ProfileIdentity, listen: bool, peers: bool, servers: bool);
/// Create a new profile encrypted with pass /// Create a new profile encrypted with pass
fn create_profile(&self, nick: &str, pass: &str); fn create_profile(&self, nick: &str, pass: &str, autostart: bool);
/// Load any profiles encrypted by pass /// Load any profiles encrypted by pass
fn load_profiles(&self, pass: &str); fn load_profiles(&self, pass: &str);
@ -44,13 +54,25 @@ pub trait CwtchLib {
fn accept_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID); fn accept_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID);
/// Cause profile to block conversation /// Cause profile to block conversation
fn block_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID); fn block_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID);
/// Cause profile to unblock contact /// Cause profile to unblock conversation
fn unblock_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID); fn unblock_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID);
/// Get a specific message for conversation of profile by index /// Attempt to peer with a a new peer
fn get_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32) -> String; fn peer_with(&self, profile: &ProfileIdentity, new_peer_address: &str);
/// manually disconnect from a conversation
fn disconnect_from_peer(&self, profile: &ProfileIdentity, peer_id: &str);
/// starts a search process on a profile for pattern. returns a searchID that resulting SearchResult messages will have
fn search_conversations(&self, profile: &ProfileIdentity, pattern: &str) -> String;
/// Get an ACL for a conversation
fn get_conversation_access_control_list(&self, profile: &ProfileIdentity, conversation_id: ConversationID) -> Result<ACL, CwtchError>;
/// Update a conversation's ACL
fn update_conversation_access_control_list(&self, profile: &ProfileIdentity, conversation_id: ConversationID, acl: ACL);
/// Get a specific message for a conversation by its id /// Get a specific message for a conversation by its id
fn get_message_by_id(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String; fn get_message_by_id(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String;
@ -64,41 +86,65 @@ pub trait CwtchLib {
) -> String; ) -> String;
/// Bulk get messages starting at message index and of count amoung /// Bulk get messages starting at message index and of count amoung
fn get_messages(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: i32) -> String; fn get_messages(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: u32) -> String;
/// Send json of a structs::Message from profile to contact. Returns computed sent message (including index and hash values) /// Send json of a structs::Message from profile to contact. Returns computed sent message (including index and hash values)
fn send_message_raw(&self, profile: &ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String; fn send_message_raw(&self, profile: &ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String;
/// Send structs::Message from profile to contact. Returns computed sent message (including index and hash values) or Error /// Send structs::Message from profile to contact. Returns computed sent message (including index and hash values) or Error
fn send_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message: &Message) -> Result<String, CwtchError>; fn send_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, message: &MessageWrapper) -> Result<String, CwtchError>;
/// Send profile's contact an invite for/to target. Returns computed sent message (including index and hash values) /// Send profile's contact an invite for/to target. Returns computed sent message (including index and hash values)
fn send_invitation(&self, profile: &ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String; fn send_invite_message(&self, profile: &ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String;
/// share a file file_path with a conersation. Returns computed sent message (including index and hash values) /// share a file file_path with a conersation. Returns computed sent message (including index and hash values)
fn share_file(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String; fn share_file(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String;
/// get list of SharedFile for a conversation
fn get_shared_files(&self, profile: &ProfileIdentity, conversaion_id: ConversationID) -> Vec<SharedFile>;
/// download a file from a conversation to the file_path /// download a file from a conversation to the file_path
fn download_file( fn download_file_default_limit(
&self, &self,
profile: &ProfileIdentity, profile: &ProfileIdentity,
conversation_id: ConversationID, conversation_id: ConversationID,
file_path: &str, file_path: &str,
manifest_path: &str, manifest_path: &str,
file_key: FileKey, file_key: &FileKey,
); );
/// Restart a fileshare (used when restarting app to reoffer a previously created fileshare)
fn restart_fileshare(&self, profile: &ProfileIdentity, file_key: &FileKey);
/// Stop offering a fileshare
fn stop_fileshare(&self, profile: &ProfileIdentity, file_key: &FileKey);
/// Query the status of a download /// Query the status of a download
fn check_download_status(&self, profile: &ProfileIdentity, file_key: FileKey); fn check_download_status(&self, profile: &ProfileIdentity, file_key: &FileKey);
/// Verufy a download is done, and if not, resume it /// Verufy a download is done, and if not, resume it
fn verify_or_resume_download(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_key: FileKey); fn verify_or_resume_download(&self, profile: &ProfileIdentity, conversation_id: ConversationID, file_key: &FileKey);
/// Ask the ACN inside the Cwtch app to restart the tor connection /// Ask the ACN inside the Cwtch app to restart the tor connection
fn reset_tor(&self); fn reset_tor(&self);
/// Cause profile to create a group on server with name /// Cause profile to create a group on server with name
fn create_group(&self, profile: &ProfileIdentity, server: &str, name: &str); fn start_group(&self, profile: &ProfileIdentity, name: &str, server: &str);
/// Queue joining a server in the out going connections queue
fn queue_join_server(&self, profile: &ProfileIdentity, server: &ServerIdentity);
/// Disconnect from a specific server
fn disconnect_from_server(&self, profile: &ProfileIdentity, server: &ServerIdentity);
/// Publish server status updates for a profile
fn publish_server_update(&self, profile: &ProfileIdentity);
/// Get list of known servers for a profile
fn get_server_info_list(&self, profile: &ProfileIdentity);
/// Delete server information from a profile, preventing future connections for all groups hosted on it
fn delete_server_info(&self, profile: &ProfileIdentity, server: &ServerIdentity);
/// Delete profile with encryption/password check of pass /// Delete profile with encryption/password check of pass
fn delete_profile(&self, profile: &ProfileIdentity, pass: &str); fn delete_profile(&self, profile: &ProfileIdentity, pass: &str);
@ -107,7 +153,7 @@ pub trait CwtchLib {
fn archive_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID); fn archive_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID);
/// Cause profile to delete contact/group identified by handle /// Cause profile to delete contact/group identified by handle
fn delete_contact(&self, profile: &ProfileIdentity, conversation_id: ConversationID); fn delete_conversation(&self, profile: &ProfileIdentity, conversation_id: ConversationID);
/// Cuase profile to attempt to import a contact/group/keybundle identified by bundle /// Cuase profile to attempt to import a contact/group/keybundle identified by bundle
fn import_bundle(&self, profile: &ProfileIdentity, bundle: &str); fn import_bundle(&self, profile: &ProfileIdentity, bundle: &str);
@ -121,8 +167,8 @@ pub trait CwtchLib {
/// Set a profile's contact's attribute of key to val /// Set a profile's contact's attribute of key to val
fn set_conversation_attribute(&self, profile: &ProfileIdentity, conversation_id: ConversationID, key: &str, val: &str); fn set_conversation_attribute(&self, profile: &ProfileIdentity, conversation_id: ConversationID, key: &str, val: &str);
/// Set an attribute on a message in a conversation /// Update an attribute on a message in a conversation
fn set_message_attribute( fn update_message_attribute(
&self, &self,
profile: &ProfileIdentity, profile: &ProfileIdentity,
conversation_id: ConversationID, conversation_id: ConversationID,
@ -152,8 +198,8 @@ pub trait CwtchLib {
/// Load all servers encrypted by password /// Load all servers encrypted by password
fn load_servers(&self, password: &str); fn load_servers(&self, password: &str);
/// Create a new server, encrypted with password, autostart i8 used as bool /// Create a new server, encrypted with password
fn create_server(&self, password: &str, description: &str, autostart: i8); fn create_server(&self, password: &str, description: &str, autostart: bool);
/// Delete the specified server (if password is correct) /// Delete the specified server (if password is correct)
fn delete_server(&self, server: ServerIdentity, current_password: &str); fn delete_server(&self, server: ServerIdentity, current_password: &str);

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DefaultOnError}; use serde_with::{serde_as, DefaultOnError};
use serde_repr::*; use serde_repr::*;
use std::collections::HashMap; use std::collections::HashMap;
use crate::event::ContactIdentity; use crate::event::{ContactIdentity, FileKey};
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
/// Defines the states a Cwtch connection can be in /// Defines the states a Cwtch connection can be in
@ -94,6 +94,18 @@ pub struct AccessControl {
pub read: bool, pub read: bool,
/// Allows a handle to append new messages to the conversation /// Allows a handle to append new messages to the conversation
pub append: bool, pub append: bool,
/// Profile should automatically try to connect with peer
pub auto_connect: bool,
/// Profile should automatically exchange attributes like Name, Profile Image, etc.
pub exchange_attributes: bool,
/// Allows a handle to share files to a conversation
pub share_files: bool,
/// Indicates that certain filetypes should be autodownloaded and rendered when shared by this contact
pub render_images: bool
} }
/// represents an access control list for a conversation. Mapping handles to conversation functions /// represents an access control list for a conversation. Mapping handles to conversation functions
@ -186,27 +198,119 @@ impl From<i32> for MessageType {
} }
} }
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
/// Struct to serialize/deserialize messages sent over Cwtch between profiles / conversation /// Struct to serialize/deserialize messages sent over Cwtch between profiles / conversation
pub struct Message { /// Overlay => data
/// 1 TextMessage: d = plain text message
/// 10 QuotedMessage: d = json of QuotedMessageStructure, body = plain text of message
pub struct MessageWrapper {
/// overlay id that the message is targeting as defined in cwtch/model/overlay.go /// overlay id that the message is targeting as defined in cwtch/model/overlay.go
/// [ OverlayChat = 1, OverlayInviteContact = 100, OverlayInviteGroup = 101, OverlayFileSharing = 200 ] /// [ OverlayChat = 1, OverlayInviteContact = 100, OverlayInviteGroup = 101, OverlayFileSharing = 200 ]
pub o: MessageType, pub o: MessageType,
/// data of the message /// data of the message, for OverlayChat, a
pub d: String, pub d: String,
} }
impl Message { impl MessageWrapper {
/// parse json into a Message /// parse json into a Message
pub fn from_json(json: &str) -> Self { pub fn from_json(json: &str) -> Self {
match serde_json::from_str(json) { match serde_json::from_str(json) {
Ok(m) => m, Ok(m) => m,
Err(e) => Message{o: MessageType::MalformedMessage, d: e.to_string()} Err(e) => MessageWrapper {o: MessageType::MalformedMessage, d: e.to_string()}
} }
} }
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
/// defined: cwtch-ui/lib/model/messages/quotedmessage.dart ~ln 15
#[allow(non_snake_case)]
pub struct QuotedMessageStructure {
/// hash message id of message being quoted
pub quotedHash: String,
/// plain text of the reply message
pub body: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
/// LocallyIndexedMessage is a type wrapper around a Message and a TimeLine Index that is local to this
/// instance of the timeline.
/// defined in: cwtch/model/message.go ~ln 31
#[allow(non_snake_case)]
pub struct LocallyIndexedMessage {
/// The message
pub Message: LocalMessage,
/// the local index in this timeline instance
pub LocalIndex: i32,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
/// Message is a local representation of a given message sent over a group chat channel.
/// defined in: cwtch/model/message.go ~ln 38
#[allow(non_snake_case)]
pub struct LocalMessage {
/// Timestamp of the message from sender
pub Timestamp: String, //time.Time
/// Timestamp message was received at
pub Received: String, //time.Time
/// ContactId of the sender
pub PeerID: String,
/// Message contents
pub Message: MessageWrapper,
/// author's signature verifying the message
pub Signature: String,
/// the signature of hte previous message in the sender's timeline
pub PreviousMessageSig: String,
/// was message confirmed by server
pub ReceivedByServer: bool,
/// was the message ack'ed by the recipient peer
pub Acknowledged: bool, // peer to peer
/// message if there was an error, empty if fine
pub Error: String,
/// Application specific flags, useful for storing small amounts of metadata
pub Flags: u64
}
// Only for internal use?
/*
#[derive(Debug, Serialize, Deserialize, Clone)]
/// FilesharingOverlayMessage presents the canonical format of the File Sharing functionality Overlay Message
/// This is the format that the UI will parse to display the message
/// defined: cwtch/functionality/filesharing/filesharing_functionality.go ~ln 156
pub struct FilesharingOverlayMessage {
#[serde(alias = "f")]
pub name: String,
#[serde(alias = "h")]
pub hash: String,
#[serde(alias = "n")]
pub nonce: String,
#[serde(alias = "s")]
pub size: u64,
}
*/
#[derive(Debug, Serialize, Deserialize, Clone)]
/// SharedFile struct from cwtch defined in cwtch/functionality/filesharing/filesharing_functionality.go ~ln 464
#[allow(non_snake_case)]
pub struct SharedFile {
/// The roothash.nonce identifier derived for this file share
pub FileKey: FileKey,
/// Path is the OS specific location of the file
pub Path: String,
/// DateShared is the original datetime the file was shared
/// go time.Time, => DateTime<FixedOffset>
/// DateTime::parse_from_rfc3339(cwtch_event.data["TimestampSent"].as_str()).unwrap_or( DateTime::from(Utc::now())),
pub DateShared: String,
/// Active is true if the file is currently being shared, false otherwise
pub Active: bool,
/// Expired is true if the file is not eligible to be shared (because e.g. it has been too long since the file was originally shared,
/// or the file no longer exists).
pub Expired: bool
}
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
/// Settings as defined in libcwtch-go/utils/settings.go and should be populated by handeling the UpdateGlobalSettings event emited during cwtch.start() /// Settings as defined in libcwtch-go/utils/settings.go and should be populated by handeling the UpdateGlobalSettings event emited during cwtch.start()
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -286,20 +390,7 @@ impl Experiments {
impl Settings { impl Settings {
/// Given a CwtchLib, handles sending an event to it with updated settings represented by this struct for saving /// Given a CwtchLib, handles sending an event to it with updated settings represented by this struct for saving
pub fn save(&self, cwtch: &dyn CwtchLib) -> Result<(), String> { pub fn save(&self, cwtch: &dyn CwtchLib) -> Result<(), String> {
let settings_json = match serde_json::to_string(&self) { cwtch.update_settings(&self);
Ok(s) => s,
Err(e) => return Err(e.to_string()),
};
let save_settings_event: CwtchEvent = CwtchEvent {
event_type: "UpdateGlobalSettings".to_string(),
event_ID: "0".to_string(),
data: HashMap::from([("Data".to_string(), settings_json)]),
};
let event_json = match serde_json::to_string(&save_settings_event) {
Ok(s) => s,
Err(e) => return Err(e.to_string()),
};
cwtch.send_app_event(&event_json);
return Ok(()); return Ok(());
} }
} }