qvopenapi/
wmca_lib.rs

1use crate::{error::*, models::*, *};
2
3use log::*;
4use once_cell::sync::OnceCell;
5use qvopenapi_sys::WmcaLib;
6use std::{
7    ffi::{c_int, CString},
8    mem::size_of,
9    os::raw::c_char,
10};
11
12// Static mutables need wrappers like OnceCell to prevent concurrency problem
13static WMCA_LIB_CELL: OnceCell<WmcaLib> = OnceCell::new();
14
15/**
16 * DLL을 미리 로드
17 */
18pub fn init() -> Result<(), QvOpenApiError> {
19    get_lib()?;
20    Ok(())
21}
22
23pub fn assert_connected() -> Result<(), QvOpenApiError> {
24    match is_connected()? {
25        true => Ok(()),
26        false => Err(QvOpenApiError::NotConnectedError),
27    }
28}
29
30pub fn is_connected() -> Result<bool, QvOpenApiError> {
31    let ret = (get_lib()?.is_connected)();
32    Ok(ret != 0)
33}
34
35pub fn set_server(server: &str) -> Result<(), QvOpenApiError> {
36    let server_cstr = make_c_string(server);
37    c_bool_to_result((get_lib()?.set_server)(server_cstr.as_ptr()))
38}
39
40pub fn set_port(port: i32) -> Result<(), QvOpenApiError> {
41    c_bool_to_result((get_lib()?.set_port)(port))
42}
43
44pub fn connect(
45    hwnd: isize,
46    account_type: AccountType,
47    id: &str,
48    password: &str,
49    cert_password: &str,
50) -> Result<(), QvOpenApiError> {
51    let msg = crate::window_mgr::message_const::WM_WMCAEVENT;
52    let media_type = match account_type {
53        AccountType::QV => 'P',
54        AccountType::NAMUH => 'T',
55    } as c_char;
56    let user_type = match account_type {
57        AccountType::QV => '1',
58        AccountType::NAMUH => 'W',
59    } as c_char;
60
61    debug!(
62        "connect ({}, {}, {}, {}, \"{}\", **, **)",
63        hwnd, msg, media_type, user_type, id
64    );
65
66    let id_cstr = make_c_string(id);
67    let password_cstr = make_c_string(password);
68    let cert_password_cstr = make_c_string(cert_password);
69
70    c_bool_to_result((get_lib()?.connect)(
71        hwnd,
72        msg,
73        media_type,
74        user_type,
75        id_cstr.as_ptr(),
76        password_cstr.as_ptr(),
77        cert_password_cstr.as_ptr(),
78    ))
79}
80
81pub fn query<T>(
82    hwnd: isize,
83    tr_index: i32,
84    tr_code: &str,
85    input: &T,
86    account_index: i32,
87) -> Result<(), QvOpenApiError> {
88    let tr_code_cstr = make_c_string(tr_code);
89
90    debug!("query ({})", tr_code);
91
92    c_bool_to_result((get_lib()?.query)(
93        hwnd,
94        tr_index,
95        tr_code_cstr.as_ptr(),
96        input as *const T as *const c_char,
97        size_of::<T>() as c_int,
98        account_index,
99    ))
100}
101
102pub fn disconnect() -> Result<(), QvOpenApiError> {
103    debug!("disconnect");
104
105    c_bool_to_result((get_lib()?.disconnect)())
106}
107
108#[allow(dead_code)]
109pub fn set_account_index_pwd<T>(
110    input: &mut T,
111    account_index: i32,
112    password: &str,
113) -> Result<(), QvOpenApiError> {
114    let password_cstr = make_c_string(password);
115    c_bool_to_result((get_lib()?.set_account_index_pwd)(
116        input as *const T as *const c_char,
117        account_index,
118        password_cstr.as_ptr(),
119    ))
120}
121
122fn c_bool_to_result(val: i32) -> Result<(), QvOpenApiError> {
123    debug!("c_bool_to_result {}", val);
124    match val {
125        // FIXME
126        //0 => Err(QvOpenApiError::ReturnCodeError{code: val}),
127        _ => Ok(()),
128    }
129}
130
131fn make_c_string(original: &str) -> CString {
132    CString::new(original).unwrap()
133}
134
135fn get_lib() -> Result<&'static WmcaLib, QvOpenApiError> {
136    WMCA_LIB_CELL.get_or_try_init(bind_lib)
137}
138
139fn bind_lib() -> Result<WmcaLib, QvOpenApiError> {
140    info!("Loading wmca.dll");
141    let lib = qvopenapi_sys::bind_lib()?;
142    info!("Loaded wmca.dll");
143    Ok(lib)
144}