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
12static WMCA_LIB_CELL: OnceCell<WmcaLib> = OnceCell::new();
14
15pub 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 _ => 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}