nym_cpp_ffi/
lib.rs

1// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3// TODO REMOVE when you're working on new CPP branch
4#![allow(clippy::all)]
5// use nym_ffi_shared;
6use std::ffi::{c_char, c_int, CStr, CString};
7
8use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag;
9use std::mem::forget;
10mod types;
11use crate::types::types::{CMessageCallback, CStringCallback, ReceivedMessage, StatusCode};
12
13#[no_mangle]
14pub extern "C" fn init_logging() {
15    nym_bin_common::logging::setup_tracing_logger();
16}
17
18#[no_mangle]
19pub extern "C" fn init_ephemeral() -> c_int {
20    match nym_ffi_shared::init_ephemeral_internal() {
21        Ok(_) => StatusCode::NoError as c_int,
22        Err(_) => StatusCode::ClientInitError as c_int,
23    }
24}
25
26#[no_mangle]
27pub extern "C" fn get_self_address(callback: CStringCallback) -> c_int {
28    match nym_ffi_shared::get_self_address_internal(/*callback*/) {
29        Ok(addr) => {
30            let c_ptr = CString::new(addr).expect("could not convert Nym address to CString");
31            let call = CStringCallback::new(callback.callback);
32            // as_ptr() keeps ownership in rust unlike into_raw() so no need to free it
33            call.trigger(c_ptr.as_ptr());
34            StatusCode::NoError as c_int
35        }
36        Err(_) => StatusCode::SelfAddrError as c_int,
37    }
38}
39
40#[no_mangle]
41pub extern "C" fn send_message(recipient: *const c_char, message: *const c_char) -> c_int {
42    let c_str = unsafe {
43        if recipient.is_null() {
44            return StatusCode::RecipientNullError as c_int;
45        }
46        let c_str = CStr::from_ptr(recipient);
47        c_str
48    };
49    let r_str = c_str.to_str().unwrap();
50    let recipient = r_str.parse().unwrap();
51    let c_str = unsafe {
52        if message.is_null() {
53            return StatusCode::MessageNullError as c_int;
54        }
55        let c_str = CStr::from_ptr(message);
56        c_str
57    };
58    let message = c_str.to_str().unwrap();
59
60    match nym_ffi_shared::send_message_internal(recipient, message) {
61        Ok(_) => StatusCode::NoError as c_int,
62        Err(_) => StatusCode::SendMsgError as c_int,
63    }
64}
65
66#[no_mangle]
67pub extern "C" fn reply(recipient: *const c_char, message: *const c_char) -> c_int {
68    let recipient = unsafe {
69        if recipient.is_null() {
70            return StatusCode::RecipientNullError as c_int;
71        }
72        let r_str = CStr::from_ptr(recipient).to_string_lossy().into_owned();
73        AnonymousSenderTag::try_from_base58_string(r_str)
74            .expect("could not construct AnonymousSenderTag from supplied value")
75    };
76    let message = unsafe {
77        if message.is_null() {
78            return StatusCode::MessageNullError as c_int;
79        }
80        let c_str = CStr::from_ptr(message);
81        let r_str = c_str.to_str().unwrap();
82        r_str
83    };
84
85    match nym_ffi_shared::reply_internal(recipient, message) {
86        Ok(_) => StatusCode::NoError as c_int,
87        Err(_) => StatusCode::ReplyError as c_int,
88    }
89}
90
91#[no_mangle]
92pub extern "C" fn listen_for_incoming(callback: CMessageCallback) -> c_int {
93    match nym_ffi_shared::listen_for_incoming_internal() {
94        Ok(received) => {
95            let message_ptr = received.message.as_ptr();
96            let message_length = received.message.len();
97            let c_string = CString::new(received.sender_tag.unwrap().to_string()).unwrap();
98            let sender_ptr = c_string.as_ptr();
99            // stop deallocation when out of scope as passing raw ptr to it elsewhere
100            forget(received);
101            let rec_for_c = ReceivedMessage {
102                message: message_ptr,
103                size: message_length,
104                sender_tag: sender_ptr,
105            };
106            let call = CMessageCallback::new(callback.callback);
107            call.trigger(rec_for_c);
108
109            StatusCode::NoError as c_int
110        }
111        Err(_) => StatusCode::ListenError as c_int,
112    }
113}