ae6c80f0cd
* fixed rebase conflict with cargo.lock * shared cleanup * moved returncode to shared * first pass at Go binding structure * minor cleanup * working on custom type udl * trying to get LDFLAG script working * commit before changing alias -> proper types * converted CCallbacks from aliases to Struct * cleanup comments * temp * push to share * cleanup * trait Lift not implemented for *const i8 issue * test of refactor: * move c-specific var casting out of shared/ into cpp/ * error returning in go/ over ffi boundary with uniffi * _internal functions ffi wrapper agnostic * moved lang-specific type conversions to cpp / go bindings and out of shared * got send_message working in c/c++ & go * split out c/c++-specific types to mod * cont. with making _internal fns lang agnostic * working on final fn for C and shared (listening for incoming messages) * fixed return err on listen_for_incoming * got full example run running again after shared/ refactor * removed unused struct * code comments * got first runthrough of go example code * script cleanup * clean up readme instructions * clippy * removed unused imports * rustfmt * Update sdk/ffi/go/README.md with link to example file Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> * updated readme with extra build and usage info * renamed binding outer directory for nicer path * moved example file from ffi/main.go -> ./example.go * updated README with new example file name --------- Co-authored-by: mfahampshire <mfahampshire@pm.me> Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
113 lines
3.8 KiB
Rust
113 lines
3.8 KiB
Rust
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use nym_ffi_shared;
|
|
use std::ffi::{c_char, c_int, CStr, CString};
|
|
|
|
use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag;
|
|
use std::mem::forget;
|
|
mod types;
|
|
use crate::types::types::{CMessageCallback, CStringCallback, ReceivedMessage, StatusCode};
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn init_logging() {
|
|
nym_bin_common::logging::setup_logging();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn init_ephemeral() -> c_int {
|
|
match nym_ffi_shared::init_ephemeral_internal() {
|
|
Ok(_) => StatusCode::NoError as c_int,
|
|
Err(_) => StatusCode::ClientInitError as c_int,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn get_self_address(callback: CStringCallback) -> c_int {
|
|
match nym_ffi_shared::get_self_address_internal(/*callback*/) {
|
|
Ok(addr) => {
|
|
let c_ptr = CString::new(addr).expect("could not convert Nym address to CString");
|
|
let call = CStringCallback::new(callback.callback);
|
|
// as_ptr() keeps ownership in rust unlike into_raw() so no need to free it
|
|
call.trigger(c_ptr.as_ptr());
|
|
StatusCode::NoError as c_int
|
|
}
|
|
Err(_) => StatusCode::SelfAddrError as c_int,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn send_message(recipient: *const c_char, message: *const c_char) -> c_int {
|
|
let c_str = unsafe {
|
|
if recipient.is_null() {
|
|
return StatusCode::RecipientNullError as c_int;
|
|
}
|
|
let c_str = CStr::from_ptr(recipient);
|
|
c_str
|
|
};
|
|
let r_str = c_str.to_str().unwrap();
|
|
let recipient = r_str.parse().unwrap();
|
|
let c_str = unsafe {
|
|
if message.is_null() {
|
|
return StatusCode::MessageNullError as c_int;
|
|
}
|
|
let c_str = CStr::from_ptr(message);
|
|
c_str
|
|
};
|
|
let message = c_str.to_str().unwrap();
|
|
|
|
match nym_ffi_shared::send_message_internal(recipient, message) {
|
|
Ok(_) => StatusCode::NoError as c_int,
|
|
Err(_) => StatusCode::SendMsgError as c_int,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn reply(recipient: *const c_char, message: *const c_char) -> c_int {
|
|
let recipient = unsafe {
|
|
if recipient.is_null() {
|
|
return StatusCode::RecipientNullError as c_int;
|
|
}
|
|
let r_str = CStr::from_ptr(recipient).to_string_lossy().into_owned();
|
|
AnonymousSenderTag::try_from_base58_string(r_str)
|
|
.expect("could not construct AnonymousSenderTag from supplied value")
|
|
};
|
|
let message = unsafe {
|
|
if message.is_null() {
|
|
return StatusCode::MessageNullError as c_int;
|
|
}
|
|
let c_str = CStr::from_ptr(message);
|
|
let r_str = c_str.to_str().unwrap();
|
|
r_str
|
|
};
|
|
|
|
match nym_ffi_shared::reply_internal(recipient, message) {
|
|
Ok(_) => StatusCode::NoError as c_int,
|
|
Err(_) => StatusCode::ReplyError as c_int,
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn listen_for_incoming(callback: CMessageCallback) -> c_int {
|
|
match nym_ffi_shared::listen_for_incoming_internal() {
|
|
Ok(received) => {
|
|
let message_ptr = received.message.as_ptr();
|
|
let message_length = received.message.len();
|
|
let c_string = CString::new(received.sender_tag.unwrap().to_string()).unwrap();
|
|
let sender_ptr = c_string.as_ptr();
|
|
// stop deallocation when out of scope as passing raw ptr to it elsewhere
|
|
forget(received);
|
|
let rec_for_c = ReceivedMessage {
|
|
message: message_ptr,
|
|
size: message_length,
|
|
sender_tag: sender_ptr,
|
|
};
|
|
let call = CMessageCallback::new(callback.callback);
|
|
call.trigger(rec_for_c);
|
|
|
|
StatusCode::NoError as c_int
|
|
}
|
|
Err(_) => StatusCode::ListenError as c_int,
|
|
}
|
|
}
|