1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
package com.iailab.netsdk.demo.module;
 
import java.awt.Panel;
 
import com.iailab.netsdk.lib.NetSDKLib.CFG_DVRIP_INFO;
import com.iailab.netsdk.lib.NetSDKLib.LLong;
import com.iailab.netsdk.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.iailab.netsdk.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.iailab.netsdk.lib.NetSDKLib.fServiceCallBack;
import com.iailab.netsdk.lib.NetSDKLib;
import com.iailab.netsdk.lib.ToolKits;
 
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public class AutoRegisterModule {
    // 监听服务句柄
    public static LLong mServerHandler = new LLong(0);    
    
    // 设备信息
    public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
    
    // 语音对讲句柄
    public static LLong m_hTalkHandle = new LLong(0);
    private static boolean m_bRecordStatus    = false;
    
    /**
     * 开启服务
     * @param address 本地IP地址
     * @param port 本地端口, 可以任意
     * @param callback 回调函数
     */
    public static boolean startServer(String address, int port, fServiceCallBack callback) {
        
        mServerHandler = LoginModule.netsdk.CLIENT_ListenServer(address, port, 1000, callback, null);
        if (0 == mServerHandler.longValue()) {
            System.err.println("Failed to start server." + ToolKits.getErrorCodePrint());
        } else {
            System.out.printf("Start server, [Server address %s][Server port %d]\n", address, port);
        }
        return mServerHandler.longValue() != 0;
    }
    
    /**
     * 结束服务
     */
    public static boolean stopServer() {
        boolean bRet = false;
        
        if(mServerHandler.longValue() != 0) {
            bRet = LoginModule.netsdk.CLIENT_StopListenServer(mServerHandler);    
            mServerHandler.setValue(0);
            System.out.println("Stop server!");
        }
        
        return bRet;
    }
    
    /**
     * 登录设备(主动注册登陆接口)
     * @param m_strIp  设备IP
     * @param m_nPort  设备端口号
     * @param m_strUser  设备用户名
     * @param m_strPassword  设备密码
     * @param deviceId  设备ID
     * @return
     */
    public static LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword, String deviceIds) {    
        Pointer deviceId = ToolKits.GetGBKStringToPointer(deviceIds);        
        //IntByReference nError = new IntByReference(0);
        //入参
        NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam=new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort=m_nPort;
        pstInParam.szIP=m_strIp.getBytes();
        pstInParam.szPassword=m_strPassword.getBytes();
        pstInParam.szUserName=m_strUser.getBytes();
        pstInParam.emSpecCap = 2;// 主动注册方式
        pstInParam.pCapParam=deviceId;
        //出参
        NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam=new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo=m_stDeviceInfo;
        /*LLong m_hLoginHandle = LoginModule.netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 
                                    tcpSpecCap, deviceId, m_stDeviceInfo, nError);*/
        LLong m_hLoginHandle=LoginModule.netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        return m_hLoginHandle;
    }
    
    /**
     * 登出设备
     * @param m_hLoginHandle  登陆句柄
     * @return
     */
    public static boolean logout(LLong m_hLoginHandle) {
        boolean bRet = false;
        if(m_hLoginHandle.longValue() != 0) {
            bRet = LoginModule.netsdk.CLIENT_Logout(m_hLoginHandle);
            m_hLoginHandle.setValue(0);    
        }
 
        return bRet;
    }
    
    /**
     * 开始预览
     * @param m_hLoginHandle 登陆句柄
     * @param channel  通道号
     * @param stream  码流类型
     * @param realPlayWindow  拉流窗口
     * @return
     */
    public static LLong startRealPlay(LLong m_hLoginHandle, int channel, int stream, Panel realPlayWindow) {
        LLong m_hPlayHandle = LoginModule.netsdk.CLIENT_RealPlayEx(m_hLoginHandle, channel, Native.getComponentPointer(realPlayWindow), stream);
    
        if(m_hPlayHandle.longValue() == 0) {
              System.err.println("Failed to start realplay." + ToolKits.getErrorCodePrint());
        } else {
              System.out.println("Success to start realplay"); 
        }
        
        return m_hPlayHandle;
    } 
    
    /**
     * 停止预览
     * @param m_hPlayHandle 实时预览句柄
     * @return
     */
    public static boolean stopRealPlay(LLong m_hPlayHandle) {
        boolean bRet = false;
        if(m_hPlayHandle.longValue() != 0) {
            bRet = LoginModule.netsdk.CLIENT_StopRealPlayEx(m_hPlayHandle);
            m_hPlayHandle.setValue(0);
        }
        
        return bRet;
    }
    
    /**
     * 远程抓图
     * @param m_hLoginHandle 登陆句柄
     * @param chn  通道号
     * @return
     */
    public static boolean snapPicture(LLong m_hLoginHandle, int chn) {
        // 发送抓图命令给前端设备,抓图的信息
        NetSDKLib.SNAP_PARAMS msg = new NetSDKLib.SNAP_PARAMS(); 
        msg.Channel = chn;              // 抓图通道
        msg.mode = 0;                    // 抓图模式
        msg.Quality = 3;                // 画质
        msg.InterSnap = 0;                 // 定时抓图时间间隔
        msg.CmdSerial = 0;              // 请求序列号,有效值范围 0~65535,超过范围会被截断为  
        
        IntByReference reserved = new IntByReference(0);
        
        if (!LoginModule.netsdk.CLIENT_SnapPictureEx(m_hLoginHandle, msg, reserved)) { 
            System.err.printf("SnapPictureEx Failed!" + ToolKits.getErrorCodePrint());
            return false;
        } else { 
            System.out.println("SnapPictureEx success"); 
        }
        return true;
    }
    
    /**
     *设置抓图回调函数, 图片主要在m_SnapReceiveCB中返回
     * @param m_SnapReceiveCB
     */
    public static void setSnapRevCallBack(NetSDKLib.fSnapRev m_SnapReceiveCB){     
        LoginModule.netsdk.CLIENT_SetSnapRevCallBack(m_SnapReceiveCB, null);
    }
    
    /**
     * 获取网络协议
     * @param m_hLoginHandle 登录句柄
     * @return
     */
    public static CFG_DVRIP_INFO getDVRIPConfig(LLong m_hLoginHandle) {
        CFG_DVRIP_INFO msg = new CFG_DVRIP_INFO();
        
        if(!ToolKits.GetDevConfig(m_hLoginHandle, -1, NetSDKLib.CFG_CMD_DVRIP, msg)) {
            return null;
        }
        
        return msg;
    }
    
    /**
     * 网络协议配置
     * @param m_hLoginHandle 登陆句柄
     * @param enable  使能
     * @param address 服务器地址
     * @param nPort  服务器端口号
     * @param deviceId  设备ID
     * @param info 获取到的网络协议配置
     * @return
     */
    public static boolean setDVRIPConfig(LLong m_hLoginHandle, boolean enable, String address, int nPort, byte[] deviceId, CFG_DVRIP_INFO info) {
        CFG_DVRIP_INFO msg = info;
        // 主动注册配置个数
        msg.nRegistersNum = 1;  
        
         // 主动注册使能
        msg.stuRegisters[0].bEnable = enable? 1:0; 
    
        // 服务器个数
        msg.stuRegisters[0].nServersNum = 1;
        
        // 服务器地址
        ToolKits.StringToByteArray(address, msg.stuRegisters[0].stuServers[0].szAddress);
        
        // 服务器端口号
        msg.stuRegisters[0].stuServers[0].nPort = nPort;
        
        // 设备ID
        ToolKits.ByteArrayToByteArray(deviceId, msg.stuRegisters[0].szDeviceID);
        
        return ToolKits.SetDevConfig(m_hLoginHandle, -1, NetSDKLib.CFG_CMD_DVRIP, msg);
    }
    
    /**
     * \if ENGLISH_LANG
     * Start Talk
     * \else
     * 开始通话
     * \endif
     */
    public static boolean startTalk(LLong m_hLoginHandle) {
    
        // 设置语音对讲编码格式
        NetSDKLib.NETDEV_TALKDECODE_INFO talkEncode = new NetSDKLib.NETDEV_TALKDECODE_INFO();
        talkEncode.encodeType = NetSDKLib.NET_TALK_CODING_TYPE.NET_TALK_PCM;
        talkEncode.dwSampleRate = 8000;
        talkEncode.nAudioBit = 16;
        talkEncode.nPacketPeriod = 25;
        talkEncode.write();
        if(LoginModule.netsdk.CLIENT_SetDeviceMode(m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_ENCODE_TYPE, talkEncode.getPointer())) {
            System.out.println("Set Talk Encode Type Succeed!");
        } else {
            System.err.println("Set Talk Encode Type Failed!" + ToolKits.getErrorCodePrint());
            return false;
        }
        
        // 设置对讲模式
        NetSDKLib.NET_SPEAK_PARAM speak = new NetSDKLib.NET_SPEAK_PARAM();
        speak.nMode = 0;
        speak.bEnableWait = false;
        speak.nSpeakerChannel = 0;
        speak.write();
        
        if (LoginModule.netsdk.CLIENT_SetDeviceMode(m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_SPEAK_PARAM, speak.getPointer())) {
            System.out.println("Set Talk Speak Mode Succeed!");
        } else {
            System.err.println("Set Talk Speak Mode Failed!" + ToolKits.getErrorCodePrint());
            return false;
        }
        
        // 设置语音对讲是否为转发模式
        NetSDKLib.NET_TALK_TRANSFER_PARAM talkTransfer = new NetSDKLib.NET_TALK_TRANSFER_PARAM();
        talkTransfer.bTransfer = 0;   // 是否开启语音对讲转发模式, 1-true; 0-false
        talkTransfer.write();
        if(LoginModule.netsdk.CLIENT_SetDeviceMode(m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_TRANSFER_MODE, talkTransfer.getPointer())) {
            System.out.println("Set Talk Transfer Mode Succeed!");
        } else {
            System.err.println("Set Talk Transfer Mode Failed!" + ToolKits.getErrorCodePrint());
            return false;
        }
        
        m_hTalkHandle = LoginModule.netsdk.CLIENT_StartTalkEx(m_hLoginHandle, AudioDataCB.getInstance(), null);
        
        if(m_hTalkHandle.longValue() == 0) {
              System.err.println("Start Talk Failed!" + ToolKits.getErrorCodePrint());      
              return false;
        } else {
              System.out.println("Start Talk Success");
            if(LoginModule.netsdk.CLIENT_RecordStart()){
                System.out.println("Start Record Success");
                m_bRecordStatus = true;
            } else {
                System.err.println("Start Local Record Failed!" + ToolKits.getErrorCodePrint());
                stopTalk(m_hTalkHandle);                
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * \if ENGLISH_LANG
     * Stop Talk
     * \else
     * 结束通话
     * \endif
     */
    public static void stopTalk(LLong m_hTalkHandle) {
        if(m_hTalkHandle.longValue() == 0) {
            return;
        }
        
        if (m_bRecordStatus){
            LoginModule.netsdk.CLIENT_RecordStop();
            m_bRecordStatus = false;
        }
        
        if(!LoginModule.netsdk.CLIENT_StopTalkEx(m_hTalkHandle)) {            
            System.err.println("Stop Talk Failed!" + ToolKits.getErrorCodePrint());
        } else {
            m_hTalkHandle.setValue(0);
        }
    }
    
    /**
     * \if ENGLISH_LANG
     * Audio Data Callback
     * \else
     * 语音对讲的数据回调
     * \endif
     */
    private static class AudioDataCB implements NetSDKLib.pfAudioDataCallBack {
        
        private AudioDataCB() {}
        private static AudioDataCB audioCallBack = new AudioDataCB();
        
        public static AudioDataCB getInstance() {
            return audioCallBack;
        }
        
        public void invoke(LLong lTalkHandle, Pointer pDataBuf, int dwBufSize, byte byAudioFlag, Pointer dwUser){
            
            if(lTalkHandle.longValue() != m_hTalkHandle.longValue()) {
                return;
            }
            
            if (byAudioFlag == 0) { // 将收到的本地PC端检测到的声卡数据发送给设备端
                
                LLong lSendSize = LoginModule.netsdk.CLIENT_TalkSendData(m_hTalkHandle, pDataBuf, dwBufSize);
                if(lSendSize.longValue() != (long)dwBufSize) {
                    System.err.println("send incomplete" + lSendSize.longValue() + ":" + dwBufSize);
                } 
            }else if (byAudioFlag == 1) { // 将收到的设备端发送过来的语音数据传给SDK解码播放
                LoginModule.netsdk.CLIENT_AudioDecEx(m_hTalkHandle, pDataBuf, dwBufSize);
            }
        }
    }
}