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}