#![allow(
clippy::unreadable_literal,
clippy::upper_case_acronyms,
dead_code,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
overflowing_literals,
unused_variables,
unused_assignments
)]
use crate::bcossdk::bcos_ssl_native::BcosNativeTlsClient;
use crate::bcossdk::bcos_ssl_normal::BcosSSLClient;
use crate::bcossdk::bcosclientconfig::{BcosCryptoKind, ChannelConfig};
use crate::bcossdk::bufferqueue::BufferQueue;
use crate::bcossdk::channelpack::{make_channel_pack, ChannelPack};
use crate::bcossdk::kisserror::{KissErrKind, KissError};
use std::time::Duration;
pub trait IBcosChannel {
fn connect(&mut self) -> Result<i32, KissError>;
fn send(&mut self, sendbuff: &Vec<u8>) -> Result<i32, KissError>;
fn recv(&mut self) -> Result<Vec<u8>, KissError>;
fn finish(&mut self);
}
pub struct BcosChannelClient {
pub channelimpl: Box<dyn IBcosChannel>,
pub config: ChannelConfig,
pub bufferqueue: BufferQueue,
pub channelpackpool: Vec<ChannelPack>, }
impl IBcosChannel for BcosChannelClient {
fn connect(&mut self) -> Result<i32, KissError> {
self.channelimpl.connect()
}
fn send(&mut self, sendbuff: &Vec<u8>) -> Result<i32, KissError> {
self.channelimpl.send(sendbuff)
}
fn recv(&mut self) -> Result<Vec<u8>, KissError> {
self.channelimpl.recv()
}
fn finish(&mut self) {
self.channelimpl.finish()
}
}
impl BcosChannelClient {
pub fn default(config:&ChannelConfig)->BcosChannelClient{
let channelimpl: Box<dyn IBcosChannel>;
let ssl_client = BcosSSLClient::default(&config);
let channelimpl: Box<dyn IBcosChannel> = Box::from(ssl_client);
BcosChannelClient{
config: config.clone(),
bufferqueue: Default::default(),
channelimpl: channelimpl,
channelpackpool: vec![],
}
}
pub fn new(config: &ChannelConfig) -> Result<BcosChannelClient, KissError> {
let channelimpl: Box<dyn IBcosChannel>;
match config.tlskind {
BcosCryptoKind::ECDSA => {
let mut ssl_client = BcosSSLClient::default(&config);
ssl_client.build()?;
channelimpl = Box::from(ssl_client)
}
BcosCryptoKind::GM => {
let mut tls_client = BcosNativeTlsClient::default(&config);
tls_client.build()?;
channelimpl = Box::from(tls_client);
}
}
let wraper = BcosChannelClient {
config: config.clone(),
bufferqueue: Default::default(),
channelimpl: channelimpl,
channelpackpool: vec![],
};
Ok(wraper)
}
pub fn try_send(&mut self, outbuffer: &Vec<u8>) -> Result<i32, KissError> {
let mut i:u32 = 0;
while i < 5 {
let res = self.send(outbuffer)?;
if res > 0 {
return Ok(res);
}
std::thread::sleep(Duration::from_millis(50));
i += 1;
}
kisserr!(KissErrKind::ENetwork, "send none bytes after try")
}
pub fn try_recv(&mut self) -> Result<Vec<u8>, KissError> {
let mut i = 0;
let start = time::now();
while time::now() - start < chrono::Duration::seconds(self.config.timeout as i64) {
let res = self.recv()?;
if res.len() > 0 {
return Ok(res);
}
i += 1;
std::thread::sleep(Duration::from_millis(100));
}
kisserr!(KissErrKind::ENetwork, "recv time out")
}
pub fn request_sync(&mut self, reqtext: &str) -> Result<String, KissError> {
let outpack = make_channel_pack(reqtext).unwrap();
let returnpack = self.request_channelpack_sync(&outpack)?;
let res = String::from_utf8(returnpack.data);
match res {
Ok(s) => {
return Ok(s);
}
Err(e) => {
return kisserr!(KissErrKind::ENetwork, "pack data is not string {:?}", e);
}
}
}
pub fn try_match_channelpack(
&mut self,
outpack: &ChannelPack,
) -> Result<ChannelPack, KissError> {
let mut i = 0;
let mut thepack: Option<ChannelPack> = Option::None;
while i < 50 {
if self.bufferqueue.queue.len() <= 42 {
break;
}
let packres = ChannelPack::unpack(&self.bufferqueue.queue);
match packres {
Ok(pack) => {
self.bufferqueue.cut(pack.length);
if pack.packtype == outpack.packtype && pack.seq == outpack.seq {
thepack = Option::from(pack);
} else {
self.channelpackpool.push(pack);
}
}
Err(e) => {
break;
}
}
i += 1;
}
match thepack {
Some(pack) => Ok(pack),
_ => {
kisserr!(KissErrKind::EAgain, "no pack found")
}
}
}
pub fn request_channelpack_sync(
&mut self,
outpack: &ChannelPack,
) -> Result<ChannelPack, KissError> {
let outbuffer = outpack.pack();
printlnex!("chanel buffer length {} ", outbuffer.len());
self.try_send(&outbuffer)?;
let mut i = 0;
while i < 50 {
let mut res = self.try_recv()?;
if res.len() == 0 {
continue;
}
self.bufferqueue.append(&mut res);
let matchres = self.try_match_channelpack(outpack);
match matchres {
Ok(pack) => {
return Ok(pack);
}
_ => { }
}
i += 1;
}
return kisserr!(KissErrKind::EAgain, "no data return");
}
}