rust_snap7/
server.rs

1//
2// server.rs
3// Copyright (C) 2021 gmg137 <gmg137 AT live.com>
4// snap7-rs is licensed under Mulan PSL v2.
5// You can use this software according to the terms and conditions of the Mulan PSL v2.
6// You may obtain a copy of Mulan PSL v2 at:
7//          http://license.coscl.org.cn/MulanPSL2
8// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11// See the Mulan PSL v2 for more details.
12//
13use crate::{ffi::*, model::*};
14use anyhow::*;
15use std::{
16    ffi::{CStr, CString},
17    os::raw::*,
18};
19
20/// S7 服务端
21///
22/// # Examples
23/// ```
24/// use snap7_rs::{AreaCode, InternalParam, InternalParamValue, S7Server, MaskKind};
25/// use std::ffi::*;
26/// use std::os::raw::*;
27///
28/// // 创建 S7 服务端
29/// let server = S7Server::create();
30///
31/// // 创建共享内存区
32/// let mut db_buff = [0u8; 1024];
33///
34/// // 添加共享区块
35/// assert!(server
36///     .register_area(AreaCode::S7AreaDB, 1, &mut db_buff)
37///     .is_ok());
38///
39/// // 过滤读和写
40/// assert!(server
41///     .set_mask(MaskKind::Event, 0x00020000 | 0x00040000)
42///     .is_ok());
43///
44/// // 设置事件回调
45/// assert!(server
46///     .set_events_callback(Some(move |_, p_event, _| {
47///         if let Ok(text) = S7Server::event_text(p_event) {
48///             println!("{:?}", text);
49///         }
50///     }))
51///     .is_ok());
52///
53/// // 启动服务
54/// if let Err(e) = server.start() {
55///     dbg!(e);
56/// }
57///
58/// // 处理逻辑
59/// //loop {
60///    // ......
61/// //}
62///
63/// // 关闭服务
64/// assert!(server.stop().is_ok());
65/// ```
66pub struct S7Server {
67    handle: usize,
68}
69
70impl Drop for S7Server {
71    fn drop(&mut self) {
72        unsafe {
73            Srv_Destroy(&mut self.handle as *mut S7Object);
74        }
75    }
76}
77
78impl Default for S7Server {
79    fn default() -> Self {
80        Self::create()
81    }
82}
83
84impl S7Server {
85    /// 创建一个 S7 服务端
86    pub fn create() -> Self {
87        S7Server {
88            handle: unsafe { Srv_Create() },
89        }
90    }
91
92    ///
93    /// 读取一个服务端对象的内部参数。
94    ///
95    /// **输入参数:**
96    ///
97    ///  - param: 内部参数类型
98    ///  - value: 内部参数值
99    ///
100    /// **返回值:**
101    ///
102    ///  - Ok: 设置成功
103    ///  - Err: 设置失败
104    ///
105    pub fn get_param(&self, param: InternalParam, value: &mut InternalParamValue) -> Result<()> {
106        match param {
107            InternalParam::KeepAliveTime | InternalParam::RecoveryTime => unsafe {
108                let mut buff = [0u8; 4];
109                let res = Srv_GetParam(
110                    self.handle,
111                    param as c_int,
112                    &mut buff as *mut [u8] as *mut c_void,
113                );
114                if res == 0 {
115                    *value = InternalParamValue::U32(u32::from_le_bytes(buff));
116                    return Ok(());
117                }
118                bail!("{}", Self::error_text(res))
119            },
120            InternalParam::LocalPort
121            | InternalParam::RemotePort
122            | InternalParam::DstRef
123            | InternalParam::SrcTSap
124            | InternalParam::SrcRef => unsafe {
125                let mut buff = [0u8; 2];
126                let res = Srv_GetParam(
127                    self.handle,
128                    param as c_int,
129                    &mut buff as *mut [u8] as *mut c_void,
130                );
131                if res == 0 {
132                    *value = InternalParamValue::U16(u16::from_le_bytes(buff));
133                    return Ok(());
134                }
135                bail!("{}", Self::error_text(res))
136            },
137            _ => unsafe {
138                let mut buff = [0u8; 4];
139                let res = Srv_GetParam(
140                    self.handle,
141                    param as c_int,
142                    &mut buff as *mut [u8] as *mut c_void,
143                );
144                if res == 0 {
145                    *value = InternalParamValue::I32(i32::from_le_bytes(buff));
146                    return Ok(());
147                }
148                bail!("{}", Self::error_text(res))
149            },
150        }
151    }
152
153    ///
154    /// 设置服务端的内部参数。
155    ///
156    /// **输入参数:**
157    ///
158    ///  - param: 内部参数类型
159    ///  - value: 内部参数值
160    ///
161    /// **返回值:**
162    ///
163    ///  - Ok: 设置成功
164    ///  - Err: 设置失败
165    ///
166    pub fn set_param(&self, param: InternalParam, value: InternalParamValue) -> Result<()> {
167        match param {
168            InternalParam::KeepAliveTime | InternalParam::RecoveryTime => unsafe {
169                if let InternalParamValue::U32(v) = value {
170                    let mut buff = v.to_le_bytes();
171                    let res = Srv_SetParam(
172                        self.handle,
173                        param as c_int,
174                        &mut buff as *mut [u8] as *mut c_void,
175                    );
176                    if res == 0 {
177                        return Ok(());
178                    }
179                    bail!("{}", Self::error_text(res))
180                } else {
181                    bail!("{}", Self::error_text(-1))
182                }
183            },
184            InternalParam::LocalPort
185            | InternalParam::RemotePort
186            | InternalParam::DstRef
187            | InternalParam::SrcTSap
188            | InternalParam::SrcRef => unsafe {
189                if let InternalParamValue::U16(v) = value {
190                    let mut buff = v.to_le_bytes();
191                    let res = Srv_SetParam(
192                        self.handle,
193                        param as c_int,
194                        &mut buff as *mut [u8] as *mut c_void,
195                    );
196                    if res == 0 {
197                        return Ok(());
198                    }
199                    bail!("{}", Self::error_text(res))
200                } else {
201                    bail!("{}", Self::error_text(-1))
202                }
203            },
204            _ => unsafe {
205                if let InternalParamValue::I32(v) = value {
206                    let mut buff = v.to_le_bytes();
207                    let res = Srv_SetParam(
208                        self.handle,
209                        param as c_int,
210                        &mut buff as *mut [u8] as *mut c_void,
211                    );
212                    if res == 0 {
213                        return Ok(());
214                    }
215                    bail!("{}", Self::error_text(res))
216                } else {
217                    bail!("{}", Self::error_text(-1))
218                }
219            },
220        }
221    }
222
223    ///
224    /// 启动服务端并将其绑定到指定的 IP 地址和 TCP 端口。
225    ///
226    /// **输入参数:**
227    ///
228    ///  - address: 服务器地址
229    ///
230    /// **返回值:**
231    ///  - Ok: 操作成功
232    ///  - Err: 操作失败
233    ///
234    pub fn start_to(&self, address: &str) -> Result<()> {
235        let address = CString::new(address).unwrap();
236        unsafe {
237            let res = Srv_StartTo(self.handle, address.as_ptr());
238            if res == 0 {
239                return Ok(());
240            }
241            bail!("{}", Self::error_text(res))
242        }
243    }
244
245    ///
246    /// 启动服务端并将其绑定到 start_to() 中指定的 IP 地址。
247    ///
248    /// **返回值:**
249    ///  - Ok: 操作成功
250    ///  - Err: 操作失败
251    ///
252    /// `注:如果 start_to() 之前未被调用,则绑定 IP 到 0.0.0.0。`
253    ///
254    pub fn start(&self) -> Result<()> {
255        unsafe {
256            let res = Srv_Start(self.handle);
257            if res == 0 {
258                return Ok(());
259            }
260            bail!("{}", Self::error_text(res))
261        }
262    }
263
264    ///
265    /// 停止服务端,优雅地断开所有客户端的连接,销毁所有的 S7 作业,并解除监听器套接字与地址的绑定。
266    ///
267    /// **返回值:**
268    ///  - Ok: 操作成功
269    ///  - Err: 操作失败
270    ///
271    pub fn stop(&self) -> Result<()> {
272        unsafe {
273            let res = Srv_Stop(self.handle);
274            if res == 0 {
275                return Ok(());
276            }
277            bail!("{}", Self::error_text(res))
278        }
279    }
280
281    ///
282    /// 共享一个内存区域,该内存块将被客户端看到。
283    ///
284    /// **输入参数:**
285    ///
286    ///  - area_code: 区块类型
287    ///  - index: 要分享的数据块(DB)编号。如果 area_code != S7AreaDB 则被忽略,值为 0。
288    ///  - buff: 要分享的内存缓冲区
289    ///
290    /// **返回值:**
291    ///  - Ok: 操作成功
292    ///  - Err: 操作失败
293    ///
294    pub fn register_area(&self, area_code: AreaCode, index: u16, buff: &mut [u8]) -> Result<()> {
295        unsafe {
296            let res = Srv_RegisterArea(
297                self.handle,
298                area_code as c_int,
299                index,
300                buff as *mut [u8] as *mut c_void,
301                buff.len() as c_int,
302            );
303            if res == 0 {
304                return Ok(());
305            }
306            bail!("{}", Self::error_text(res))
307        }
308    }
309
310    ///
311    /// 解除先前 register_area() 共享的内存区域,该内存块将不再被客户端看到。
312    ///
313    /// **输入参数:**
314    ///
315    ///  - area_code: 区块类型
316    ///  - index: 要解除的数据块(DB)编号。如果 area_code != S7AreaDB 则被忽略,值为 0。
317    ///
318    /// **返回值:**
319    ///  - Ok: 操作成功
320    ///  - Err: 操作失败
321    ///
322    pub fn unregister_area(&self, area_code: AreaCode, index: u16) -> Result<()> {
323        unsafe {
324            let res = Srv_UnregisterArea(self.handle, area_code as c_int, index);
325            if res == 0 {
326                return Ok(());
327            }
328            bail!("{}", Self::error_text(res))
329        }
330    }
331
332    ///
333    /// 锁定一个共享内存区域。
334    ///
335    /// **输入参数:**
336    ///
337    ///  - area_code: 区块类型
338    ///  - index: 要解除的数据块(DB)编号。如果 area_code != S7AreaDB 则被忽略,值为 0。
339    ///
340    /// **返回值:**
341    ///  - Ok: 操作成功
342    ///  - Err: 操作失败
343    ///
344    pub fn lock_area(&self, area_code: AreaCode, index: u16) -> Result<()> {
345        unsafe {
346            let res = Srv_LockArea(self.handle, area_code as c_int, index);
347            if res == 0 {
348                return Ok(());
349            }
350            bail!("{}", Self::error_text(res))
351        }
352    }
353
354    ///
355    /// 解锁先前锁定的共享内存区域。
356    ///
357    /// **输入参数:**
358    ///
359    ///  - area_code: 区块类型
360    ///  - index: 要解除的数据块(DB)编号。如果 area_code != S7AreaDB 则被忽略,值为 0。
361    ///
362    /// **返回值:**
363    ///  - Ok: 操作成功
364    ///  - Err: 操作失败
365    ///
366    pub fn unlock_area(&self, area_code: AreaCode, index: u16) -> Result<()> {
367        unsafe {
368            let res = Srv_UnlockArea(self.handle, area_code as c_int, index);
369            if res == 0 {
370                return Ok(());
371            }
372            bail!("{}", Self::error_text(res))
373        }
374    }
375
376    ///
377    /// 设置服务器对象在创建事件时要调用的用户回调。
378    ///
379    /// **输入参数:**
380    ///
381    ///  - callback: 回调函数
382    ///
383    /// **返回值:**
384    ///  - Ok: 操作成功
385    ///  - Err: 操作失败
386    ///
387    /// # Examples
388    /// ```ignore
389    /// use std::sync::{Arc,Mutex};
390    ///
391    /// let num = Arc::new(Mutex::new(32));
392    /// let num_clone = te.clone();
393    /// server.set_events_callback(Some(move |_, p_event, _| {
394    ///     let mut num = num_clone.lock().unwrap();
395    ///     *num += 100;
396    ///     println!("num: {}", num);
397    ///     if let Some(text) = S7Server::event_text(p_event) {
398    ///         println!("{:?}", text);
399    ///     }
400    /// })).unwrap();
401    /// println!("num:{}", num.lock().unwrap());
402    /// ```
403    pub fn set_events_callback<F>(&self, callback: Option<F>) -> Result<()>
404    where
405        F: FnMut(*mut c_void, PSrvEvent, c_int) + 'static,
406    {
407        if callback.is_some() {
408            unsafe {
409                let data = Box::into_raw(Box::new(callback));
410                let res = Srv_SetEventsCallback(
411                    self.handle,
412                    Some(call_events_closure::<F>),
413                    data as *mut c_void,
414                );
415                if res == 0 {
416                    return Ok(());
417                }
418                bail!("{}", Self::error_text(res))
419            }
420        } else {
421            unsafe {
422                let res =
423                    Srv_SetEventsCallback(self.handle, None, std::ptr::null_mut() as *mut c_void);
424                if res == 0 {
425                    return Ok(());
426                }
427                bail!("{}", Self::error_text(res))
428            }
429        }
430    }
431
432    ///
433    /// 设置服务端对象在客户请求读/写时要调用的用户回调。。
434    ///
435    /// **输入参数:**
436    ///
437    ///  - callback: 回调函数
438    ///
439    /// **返回值:**
440    ///  - Ok: 操作成功
441    ///  - Err: 操作失败
442    ///
443    /// # Examples
444    /// ```ignore
445    /// use std::os::raw::*;
446    ///
447    /// server.set_rw_area_callback(Some(
448    ///     move |usr_ptr, sender, operation, ps7tag: PS7Tag, p_usr_data: *mut c_void| {
449    ///         unsafe {
450    ///             let pbuff = p_usr_data as *mut u8;
451    ///             if operation == 0 {
452    ///                 println!("读请求!");
453    ///             } else {
454    ///                 println!("写请求!");
455    ///             }
456    ///             let p7 = *ps7tag;
457    ///             match p7.Area {
458    ///                 0x81 => println!("Area: PE"),
459    ///                 0x82 => println!("Area: PA"),
460    ///                 0x83 => println!("Area: MK"),
461    ///                 0x1c => println!("Area: CT"),
462    ///                 0x1d => println!("Area: TM"),
463    ///                 0x84 => println!("Area: DB{}", p7.DBNumber as i32),
464    ///                 _ => println!("未定义的 Area"),
465    ///             }
466    ///             println!("Strat: {}", p7.Start as i32);
467    ///             println!("Size: {}", p7.Size as i32);
468    ///             if operation == 1 {
469    ///                 let buff = std::slice::from_raw_parts(pbuff, p7.Size as usize);
470    ///                 println!("pUsrData: {:#x?}", buff);
471    ///             } else {
472    ///                 //
473    ///             }
474    ///         }
475    ///     }
476    /// )).unwrap();
477    /// ```
478    pub fn set_rw_area_callback<F>(&self, callback: Option<F>) -> Result<()>
479    where
480        F: FnMut(*mut c_void, c_int, c_int, PS7Tag, *mut c_void),
481    {
482        if callback.is_some() {
483            unsafe {
484                let data = Box::into_raw(Box::new(callback));
485                let res = Srv_SetRWAreaCallback(
486                    self.handle,
487                    Some(call_rw_area_closure::<F>),
488                    data as *mut c_void,
489                );
490                if res == 0 {
491                    return Ok(());
492                }
493                bail!("{}", Self::error_text(res))
494            }
495        } else {
496            unsafe {
497                let res =
498                    Srv_SetRWAreaCallback(self.handle, None, std::ptr::null_mut() as *mut c_void);
499                if res == 0 {
500                    return Ok(());
501                }
502                bail!("{}", Self::error_text(res))
503            }
504        }
505    }
506
507    ///
508    /// 设置服务端对象在创建读取事件时要调用的用户回调。
509    ///
510    /// **输入参数:**
511    ///
512    ///  - callback: 回调函数
513    ///
514    /// **返回值:**
515    ///  - Ok: 操作成功
516    ///  - Err: 操作失败
517    ///
518    /// # Examples
519    /// ```ignore
520    /// server.set_read_events_callback(Some(|ptr, p_event, size| {
521    ///     println!("ptr: {:?}, size: {}", ptr, size);
522    ///     if let Some(text) = S7Server::event_text(p_event) {
523    ///         println!("{:?}", text);
524    ///     }
525    /// })).unwrap();
526    /// ```
527    pub fn set_read_events_callback<F>(&self, callback: Option<F>) -> Result<()>
528    where
529        F: FnMut(*mut c_void, PSrvEvent, c_int) + 'static,
530    {
531        if callback.is_some() {
532            unsafe {
533                let data = Box::into_raw(Box::new(callback));
534                let res = Srv_SetReadEventsCallback(
535                    self.handle,
536                    Some(call_events_closure::<F>),
537                    data as *mut c_void,
538                );
539                if res == 0 {
540                    return Ok(());
541                }
542                bail!("{}", Self::error_text(res))
543            }
544        } else {
545            unsafe {
546                let res =
547                    Srv_SetEventsCallback(self.handle, None, std::ptr::null_mut() as *mut c_void);
548                if res == 0 {
549                    return Ok(());
550                }
551                bail!("{}", Self::error_text(res))
552            }
553        }
554    }
555
556    ///
557    /// 读取指定的过滤器掩码。
558    ///
559    /// **输入参数:**
560    ///
561    ///  - mask_kind: 掩码类型
562    ///  - mask: 掩码值
563    ///
564    /// **返回值:**
565    ///  - Ok: 操作成功
566    ///  - Err: 操作失败
567    ///
568    pub fn get_mask(&self, mask_kind: MaskKind, mask: &mut u32) -> Result<()> {
569        unsafe {
570            let res = Srv_GetMask(self.handle, mask_kind as c_int, mask as *mut c_uint);
571            if res == 0 {
572                return Ok(());
573            }
574            bail!("{}", Self::error_text(res))
575        }
576    }
577
578    ///
579    /// 写入指定的过滤掩码。
580    ///
581    /// **输入参数:**
582    ///
583    ///  - mask_kind: 掩码类型
584    ///  - mask: 掩码值
585    ///
586    /// **返回值:**
587    ///  - Ok: 操作成功
588    ///  - Err: 操作失败
589    ///
590    pub fn set_mask(&self, mask_kind: MaskKind, mask: u32) -> Result<()> {
591        unsafe {
592            let res = Srv_SetMask(self.handle, mask_kind as c_int, mask);
593            if res == 0 {
594                return Ok(());
595            }
596            bail!("{}", Self::error_text(res))
597        }
598    }
599
600    ///
601    /// 从事件队列中提取一个事件(如果有的话)。
602    ///
603    /// **输入参数:**
604    ///
605    ///  - event: 事件变量
606    ///  - evt_ready: 提取是否成功,返回 1 代表提取成功,0 代表无事件。
607    ///
608    /// **返回值:**
609    ///  - Ok: 操作成功
610    ///  - Err: 操作失败
611    ///
612    pub fn pick_event(&self, event: &mut TSrvEvent, evt_ready: &mut i32) -> Result<()> {
613        unsafe {
614            let res = Srv_PickEvent(
615                self.handle,
616                event as *mut TSrvEvent,
617                evt_ready as *mut c_int,
618            );
619            if res == 0 {
620                return Ok(());
621            }
622            bail!("{}", Self::error_text(res))
623        }
624    }
625
626    ///
627    /// 清空事件队列。
628    ///
629    /// **返回值:**
630    ///  - true: 操作成功
631    ///  - false: 操作失败
632    ///
633    pub fn clear_events(&self) -> bool {
634        unsafe { Srv_ClearEvents(self.handle) == 0 }
635    }
636
637    ///
638    /// 读取服务器状态、虚拟 CPU 状态和连接的客户端数量。
639    ///
640    /// **输入参数:**
641    ///
642    ///  - server_status: 服务端状态
643    ///     - 0: 服务停止
644    ///     - 1: 服务运行
645    ///     - 2: 服务错误
646    ///  - cpu_status: CPU 状态
647    ///     - 0x00: 状态未知
648    ///     - 0x08: CPU Run
649    ///     - 0x04: CPU Stop
650    ///  - client_count: 客户端连接数
651    ///
652    /// **返回值:**
653    ///  - Ok: 操作成功
654    ///  - Err: 操作失败
655    ///
656    ///  `注:CPU 的状态可以由客户端调用相关的 S7 控制功能(冷启动/热启动/停止)或以编程方式,在服务器端调用函数 set_cpu_status() 来改变。`
657    ///
658    pub fn get_status(
659        &self,
660        server_status: &mut i32,
661        cpu_status: &mut i32,
662        client_count: &mut i32,
663    ) -> Result<()> {
664        unsafe {
665            let res = Srv_GetStatus(
666                self.handle,
667                server_status as *mut c_int,
668                cpu_status as *mut c_int,
669                client_count as *mut c_int,
670            );
671            if res == 0 {
672                return Ok(());
673            }
674            bail!("{}", Self::error_text(res))
675        }
676    }
677
678    ///
679    /// 设置虚拟 CPU 状态。
680    ///
681    /// **输入参数:**
682    ///
683    ///  - cpu_status: CPU 状态
684    ///     - 0x00: 状态未知
685    ///     - 0x08: CPU Run
686    ///     - 0x04: CPU Stop
687    ///
688    /// **返回值:**
689    ///  - Ok: 操作成功
690    ///  - Err: 操作失败
691    ///
692    pub fn set_cpu_status(&self, cpu_status: i32) -> Result<()> {
693        unsafe {
694            let res = Srv_SetCpuStatus(self.handle, cpu_status as c_int);
695            if res == 0 {
696                return Ok(());
697            }
698            bail!("{}", Self::error_text(res))
699        }
700    }
701
702    ///
703    /// 返回一个给定错误的文本解释。
704    ///
705    /// **输入参数:**
706    ///
707    ///  - error: 错误代码
708    ///
709    pub fn error_text(error: i32) -> String {
710        let mut chars = [0i8; 1024];
711        unsafe {
712            Srv_ErrorText(error, chars.as_mut_ptr() as *mut c_char, 1024);
713            CStr::from_ptr(chars.as_ptr() as *const c_char)
714                .to_string_lossy()
715                .into_owned()
716        }
717    }
718
719    ///
720    /// 返回一个给定事件的文本解释。
721    ///
722    /// **输入参数:**
723    ///
724    ///  - event: 事件
725    ///
726    /// **返回值:**
727    ///  - Ok: 操作成功
728    ///  - Err: 操作失败
729    ///
730    #[allow(clippy::not_unsafe_ptr_arg_deref)]
731    pub fn event_text(event: *mut TSrvEvent) -> Result<String> {
732        let mut chars = [0i8; 1024];
733        unsafe {
734            let res = Srv_EventText(event, chars.as_mut_ptr() as *mut c_char, 1024);
735            if res == 0 {
736                Ok(CStr::from_ptr(chars.as_ptr() as *const c_char)
737                    .to_string_lossy()
738                    .into_owned())
739            } else {
740                Ok("".to_owned())
741            }
742        }
743    }
744}
745
746unsafe extern "C" fn call_events_closure<F>(usr_ptr: *mut c_void, p_event: PSrvEvent, size: c_int)
747where
748    F: FnMut(*mut c_void, PSrvEvent, c_int),
749{
750    let callback_ptr = usr_ptr as *mut F;
751    let callback = &mut *callback_ptr;
752    callback(usr_ptr, p_event, size);
753}
754
755unsafe extern "C" fn call_rw_area_closure<F>(
756    usr_ptr: *mut c_void,
757    sender: c_int,
758    operation: c_int,
759    p_tag: PS7Tag,
760    p_usr_data: *mut c_void,
761) where
762    F: FnMut(*mut c_void, c_int, c_int, PS7Tag, *mut c_void),
763{
764    let callback_ptr = usr_ptr as *mut F;
765    let callback = &mut *callback_ptr;
766    callback(usr_ptr, sender, operation, p_tag, p_usr_data)
767}
768
769#[cfg(test)]
770mod tests {
771    use super::*;
772    use std::result::Result::Ok;
773    use std::sync::{Arc, Mutex};
774
775    #[test]
776    fn test_server() {
777        let server = S7Server::create();
778        let mut db_buff = [0u8; 1024];
779        let mut ab_buff = [0u8; 1024];
780        let mut eb_buff = [0u8; 1024];
781        let mut mb_buff = [0u8; 1024];
782
783        assert!(server
784            .register_area(AreaCode::S7AreaDB, 1, &mut db_buff)
785            .is_ok());
786        assert!(server
787            .register_area(AreaCode::S7AreaPA, 1, &mut ab_buff)
788            .is_ok());
789        assert!(server
790            .register_area(AreaCode::S7AreaPE, 1, &mut eb_buff)
791            .is_ok());
792        assert!(server
793            .register_area(AreaCode::S7AreaMK, 1, &mut mb_buff)
794            .is_ok());
795        // 过滤读和写
796        assert!(server
797            .set_mask(MaskKind::Event, 0x00020000 | 0x00040000)
798            .is_ok());
799
800        // assert!(server.set_rw_area_callback(Some(
801        //     move |usr_ptr, sender, operation, ps7tag: PS7Tag, p_usr_data: *mut c_void| {
802        //         unsafe {
803        //             let pbuff = p_usr_data as *mut u8;
804        //             if operation == 0 {
805        //                 println!("读请求!");
806        //             } else {
807        //                 println!("写请求!");
808        //             }
809        //             let p7 = *ps7tag;
810        //             match p7.Area {
811        //                 0x81 => println!("Area: PE"),
812        //                 0x82 => println!("Area: PA"),
813        //                 0x83 => println!("Area: MK"),
814        //                 0x1c => println!("Area: CT"),
815        //                 0x1d => println!("Area: TM"),
816        //                 0x84 => println!("Area: DB{}", p7.DBNumber as i32),
817        //                 _ => println!("未定义的 Area"),
818        //             }
819        //             println!("Strat: {}", p7.Start as i32);
820        //             println!("Size: {}", p7.Size as i32);
821        //             if operation == 1 {
822        //                 let buff = std::slice::from_raw_parts(p_usr_data, p7.Size as usize);
823        //                 println!("pUsrData: {:#x?}", buff);
824        //             } else {
825        //                 *pbuff = 0x08;
826        //             }
827        //         }
828        //     }
829        // )).is_ok());
830        let te = Arc::new(Mutex::new(32));
831        let tee = te.clone();
832        assert!(server
833            .set_events_callback(Some(move |_, p_event, _| {
834                let mut data = tee.lock().unwrap();
835                *data += 100;
836                println!("te: {}", data);
837                if let Ok(text) = S7Server::event_text(p_event) {
838                    println!("{:?}", text);
839                }
840            }))
841            .is_ok());
842        println!("te1:{}", te.lock().unwrap());
843
844        assert!(server
845            .set_read_events_callback(Some(|_ptr, p_event, _size| {
846                if let Ok(text) = S7Server::event_text(p_event) {
847                    println!("{:?}", text);
848                }
849            }))
850            .is_ok());
851
852        server
853            .set_param(InternalParam::LocalPort, InternalParamValue::U16(7878))
854            .unwrap();
855        assert!(server.start().is_ok());
856
857        let mut value = InternalParamValue::U16(0);
858        assert!(server
859            .get_param(InternalParam::WorkInterval, &mut value)
860            .is_ok());
861        println!("WorkInterval: {:?}", value);
862        let mut value = InternalParamValue::I32(0);
863        assert!(server
864            .get_param(InternalParam::MaxClients, &mut value)
865            .is_ok());
866        println!("MaxClients: {:?}", value);
867
868        let mut event = TSrvEvent::default();
869        let mut ready = 0;
870        assert!(server.pick_event(&mut event, &mut ready).is_ok());
871        if let Ok(text) = S7Server::event_text(&mut event as *mut TSrvEvent) {
872            println!("{:?}", text);
873        }
874        println!("{:?}", event);
875        println!("{:?}", ready);
876        println!("{:?}", &db_buff[0..24]);
877        std::thread::sleep(std::time::Duration::from_secs(3));
878        println!("{:?}", &db_buff[0..24]);
879
880        let (mut server_status, mut cpu_status, mut client_count) = (0, 0, 0);
881        assert!(server
882            .get_status(&mut server_status, &mut cpu_status, &mut client_count)
883            .is_ok());
884        println!(
885            "server_status:{}, cpu_status:{},client_count:{}",
886            server_status, cpu_status, client_count
887        );
888        server.stop().unwrap();
889    }
890}