差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
digi:cellular-router:central-management-demo [2024/11/20 19:57] – 移除 - 外部编辑 (未知日期) 127.0.0.1digi:cellular-router:central-management-demo [2024/11/21 11:34] (当前版本) robin
行 1: 行 1:
 +=====本地或远程管理和控制Digi联网设备=====
 +管理联网的设备,首先是用Digi Remote Manager,通过它也可以实现私网的路由器管理。许多用户仍执着于本地接口的监控和管理,这虽然有一定意义,但如果是SIM卡发卡方的原因或是物理因素,这最多也只是记录log的手段而已。
  
 +虽然Digi可以提供方式,让SIM卡未正常连上网络时有了调试手段,但在阅读本文之前,请先了解:
 +
 +1、Digi和北美欧洲运营商有全面的合作关系,您也可以通过Digi来获取北美或欧洲运营商的SIM卡,通过这种方式可避免因开卡问题引发的部署联网问题。
 +
 +2、Digi有集中管理平台包括Digi Remote Manager设备云和On-Prem Manager本地管理软件,它们都可以支持私网SIM卡的管理,并且对IT管理非常友好,同时,DRM还支持通过API查询运营商的SIM卡状态和消费的流量信息
 +
 +3、Digi路由器也支持SNMP软件来管理和配置SIM卡
 +
 +4、Digi路由器支持通过ssh连接和执行相关的命令行,查询和设置SIM卡的连网情况,本功能可通过python或Java来实现程序接口而非交互式访问。
 +
 +5、Digi的本地Web接口可对接口部分进行配置和查询 
 +
 +上面详述了Digi的路由器功能,通常出海企业最优的选择是通过Digi Remote Manager来远程管理设备,这也是最方便,最安全,功能最全的方式。
 +
 +====通过Digi Remote Manager的API获取LTE连网信息====
 +虽然可以通过平台可视化地获取或配置相关信息,但如果是程序或自建管理平台需要的话,可以用API方式来实现相关的功能。
 +
 +登陆到Digi Remote Manager后,点击右上角的配置齿轮图标,打开经典配置界面,然后点Documentation>API Explorer,在这里,您可以测试API功能,并导出相关例程,包括Java的支持。
 +点击SCI Target,从下拉窗口中添加您要测试的在线设备,然后在Example里选择v1/reports/devices/carrier,点击Send(首次使用会要求输入用户名和密码),就会向你的设备通过DRM发起一次Web请求,并返回相关的蜂窝网络连接信息。
 +{{:digi:cellular-router:pasted:20241120-165456.png}}
 +
 +点击Export,选择Java,就可以生成这个web service请求的例程,把它复制保存下来以备用:
 +<hidden 查询连接的APN的Java例程>
 +<code>
 +#其它API请修改id和insatll_code对应那两行
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.OutputStreamWriter;
 +import javax.net.ssl.HttpsURLConnection;
 +import java.net.URL;
 +import java.util.Scanner;
 +
 +/* Can replace this with any base 64 encoder for basic authentication. For java 6 
 + * installations on Sun's JRE you can use "sun.misc.BASE64Encoder" however this will 
 + * not work in some installations (using OpenJDK).  Java mail 
 + * (javax.mail.internet.MimeUtility) also contains a Base 64 encoder in Java 6.  A 
 + * public domain version exists at http://iharder.sourceforge.net/current/java/base64/
 + */
 +import org.apache.commons.codec.binary.Base64;
 +
 +/**
 + * This is a stub class with a main method to run a Remote Manager web service.
 + */
 +public class WebServiceRequest {
 +    private static final String username = "username"; // put your Remote Manager username here
 +    private static final String password = "password"; // put your Remote Manager password here
 +
 +    /**
 +     * Run the web service request
 +     */
 +    public static void main(String[] args) {
 +        HttpsURLConnection conn = null;
 +
 +        try {
 +            // Create url to the Remote Manager server for a given web service request
 +            URL url = new URL("https://remotemanager.digi.com/ws/v1/reports/devices/carrier");
 +            conn = (HttpsURLConnection) url.openConnection(); 
 +            conn.setDoOutput(true);
 +            conn.setDoInput(true);
 +            conn.setRequestMethod("GET"); 
 +            
 +            // Build authentication string
 +            String userpassword = username + ":" + password;
 +
 +            // can change this to use a different base64 encoder
 +            String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes()).trim();
 +
 +            // set request headers
 +            conn.setRequestProperty("Authorization", "Basic "
 +                    + encodedAuthorization);
 +// Get input stream from response and convert to String
 +            InputStream is = conn.getInputStream();
 +
 +            Scanner isScanner = new Scanner(is);
 +            StringBuffer buf = new StringBuffer();
 +            while (isScanner.hasNextLine()) {
 +                buf.append(isScanner.nextLine() + "\n");
 +            }
 +            String responseContent = buf.toString();
 +
 +            // add line returns between tags to make it a bit more readable
 +            responseContent = responseContent.replaceAll("><", ">\n<");
 +
 +            // Output response to standard out
 +            System.out.println(responseContent);
 +        } catch (Exception e) {
 +            // Print any exceptions that occur
 +            e.printStackTrace();
 +        } finally {
 +            if (conn != null)
 +                conn.disconnect();
 +        }
 +    }
 +}
 +</code>
 +</hidden>
 +注意,我们只需改变URL url = new URL("https://remotemanager.digi.com/ws/v1/reports/devices/carrier"); 中的URL地址,就可以实现任意的http的请求。
 +同样的道理,选择请求类型为POST时,我们就获取到了相关的例程。
 +<hidden  配置一个设备的post请求>
 +<code>
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.OutputStreamWriter;
 +import javax.net.ssl.HttpsURLConnection;
 +import java.net.URL;
 +import java.util.Scanner;
 +/* Can replace this with any base 64 encoder for basic authentication. For java 6 
 + * installations on Sun's JRE you can use "sun.misc.BASE64Encoder" however this will 
 + * not work in some installations (using OpenJDK).  Java mail 
 + * (javax.mail.internet.MimeUtility) also contains a Base 64 encoder in Java 6.  A 
 + * public domain version exists at http://iharder.sourceforge.net/current/java/base64/
 + */
 +import org.apache.commons.codec.binary.Base64;
 +
 +/**
 + * This is a stub class with a main method to run a Remote Manager web service.
 + */
 +public class WebServiceRequest {
 +    private static final String username = "username"; // put your Remote Manager username here
 +    private static final String password = "password"; // put your Remote Manager password here
 +
 +    /**
 +     * Run the web service request
 +     */
 +    public static void main(String[] args) {
 +        HttpsURLConnection conn = null;
 +        try {
 +            // Create url to the Remote Manager server for a given web service request
 +            URL url = new URL("https://remotemanager.digi.com/ws/v1/devices/inventory");
 +            conn = (HttpsURLConnection) url.openConnection(); 
 +            conn.setDoOutput(true);
 +            conn.setDoInput(true);
 +            conn.setRequestMethod("POST"); 
 +            
 +            // Build authentication string
 +            String userpassword = username + ":" + password;
 +
 +            // can change this to use a different base64 encoder
 +            String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes()).trim();
 +
 +            // set request headers
 +            conn.setRequestProperty("Authorization", "Basic "
 +                    + encodedAuthorization);
 +            conn.setRequestProperty("Content-Type", "application/json");
 +            conn.setRequestProperty("Accept", "application/json");
 +            
 +            // Send data to server
 +            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
 +            out.write("{\r\n");
 +            out.write("  \"id\": \"00000000-00000000-00000000-00000000\",\r\n");
 +            out.write("  \"install_code\": \"myInstallCode\"\r\n");
 +            out.write("}\r\n");
 +            out.close();
 +            // Get input stream from response and convert to String
 +            InputStream is = conn.getInputStream();
 +
 +            Scanner isScanner = new Scanner(is);
 +            StringBuffer buf = new StringBuffer();
 +            while (isScanner.hasNextLine()) {
 +                buf.append(isScanner.nextLine() + "\n");
 +            }
 +            String responseContent = buf.toString();
 +
 +            // add line returns between tags to make it a bit more readable
 +            responseContent = responseContent.replaceAll("><", ">\n<");
 +
 +            // Output response to standard out
 +            System.out.println(responseContent);
 +        } catch (Exception e) {
 +            // Print any exceptions that occur
 +            e.printStackTrace();
 +        } finally {
 +            if (conn != null)
 +                conn.disconnect();
 +        }
 +    }
 +}
 +</code>
 +</hidden>
 +由于经典界面的例程不够多,下面我们回到当前DRM界面,在Example里选择V1/network_interfaces,发起post请求,便可以获取相关的SIM卡信息。
 +{{:digi:cellular-router:pasted:20241120-171641.png}}
 +
 +此外,在经典界面下,执行SCI>RCI的例程,也可从Query Device Setting或Status命令中获取更多有用的状态或配置信息。
 +
 +用这种办法几乎可以获取路由器的任意信息,包括log的调试信息,因此非常方便。
 +
 +<hidden 进阶功能-执行CLI命令并读取返回值>
 +高阶的功能包括执行设备所支持的CLI命令,甚至也可以是一个自定义python脚本命令和返值值,通过云端触发后,在本地执行,并按需返回相关参数。
 +
 +比如像SIM卡DHCP自动获取的IP地址等信息,通常没必要在本地接口获取,但也是可以实现的,它可以通过SCI>CLI>Send a single Command获取,也就是发送show network命令并返回相关结果。
 +Java 例程代码:
 +<code>
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.OutputStreamWriter;
 +import javax.net.ssl.HttpsURLConnection;
 +import java.net.URL;
 +import java.util.Scanner;
 +
 +/* Can replace this with any base 64 encoder for basic authentication. For java 6 
 + * installations on Sun's JRE you can use "sun.misc.BASE64Encoder" however this will 
 + * not work in some installations (using OpenJDK).  Java mail 
 + * (javax.mail.internet.MimeUtility) also contains a Base 64 encoder in Java 6.  A 
 + * public domain version exists at http://iharder.sourceforge.net/current/java/base64/
 + */
 +import org.apache.commons.codec.binary.Base64;
 +
 +/**
 + * This is a stub class with a main method to run a Remote Manager web service.
 + */
 +public class WebServiceRequest {
 +    private static final String username = "username"; // put your Remote Manager username here
 +    private static final String password = "password"; // put your Remote Manager password here
 +
 +    /**
 +     * Run the web service request
 +     */
 +    public static void main(String[] args) {
 +        HttpsURLConnection conn = null;
 +
 +        try {
 +            // Create url to the Remote Manager server for a given web service request
 +            URL url = new URL("https://remotemanager.digi.com/ws/sci");
 +            conn = (HttpsURLConnection) url.openConnection(); 
 +            conn.setDoOutput(true);
 +            conn.setDoInput(true);
 +            conn.setRequestMethod("POST"); 
 +            
 +            // Build authentication string
 +            String userpassword = username + ":" + password;
 +
 +            // can change this to use a different base64 encoder
 +            String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes()).trim();
 +
 +            // set request headers
 +            conn.setRequestProperty("Authorization", "Basic "
 +                    + encodedAuthorization);
 +            conn.setRequestProperty("Content-Type", "text/xml");
 +            conn.setRequestProperty("Accept", "text/xml");
 +            
 +            // Send data to server
 +            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
 +            out.write("<sci_request version=\"1.0\"> \r\n");
 +            out.write("  <cli> \r\n");
 +            out.write("    <targets> \r\n");
 +            out.write("      <device id=\"00000000-00000000-0004F3FF-FF4F95C0\"/> \r\n");
 +            out.write("    </targets>\r\n");
 +            out.write("    <execute timeout=\"10\">show network</execute>\r\n");
 +            out.write("    <!-- <execute format=\"base64\">ZGV2aWNlIGNsaSBjb21tYW5k</execute> -->\r\n");
 +            out.write("  </cli>\r\n");
 +            out.write("</sci_request>\r\n");
 +            out.close();
 +            // Get input stream from response and convert to String
 +            InputStream is = conn.getInputStream();
 +
 +            Scanner isScanner = new Scanner(is);
 +            StringBuffer buf = new StringBuffer();
 +            while (isScanner.hasNextLine()) {
 +                buf.append(isScanner.nextLine() + "\n");
 +            }
 +            String responseContent = buf.toString();
 +
 +            // add line returns between tags to make it a bit more readable
 +            responseContent = responseContent.replaceAll("><", ">\n<");
 +
 +            // Output response to standard out
 +            System.out.println(responseContent);
 +        } catch (Exception e) {
 +            // Print any exceptions that occur
 +            e.printStackTrace();
 +        } finally {
 +            if (conn != null)
 +                conn.disconnect();
 +        }
 +    }
 +}
 +</code>
 +
 +{{:digi:cellular-router:pasted:20241120-175451.png}}
 +
 +注意,获取到的值为BASE64,需转码为ASCII即可,如本例转码后:
 +
 +{{:digi:cellular-router:pasted:20241120-180308.png}}
 +
 +</hidden>
 +
 +====通过本地REST接口或SNMP接口设置和获取相关信息====
 +SNMP能实现大部分功能,包括读取SIM卡信息等,SNMP协议比较复杂,一般专业的网络管理软件支持SNMP协议来管理网络设备。详情请[[https://www.digi.com/resources/documentation/digidocs/90002537/#os/services-snmp-c.htm|参考文档]]
 +
 +REST API可以用于读取和设置部分信息,但并不支持读取Modem的相关配置,它的用法详见:[[digi:cellular-router:dal-restful|使用本地基于Web的REST API 来配置DAL设备]]
 +
 +要在本地使用完整功能,一般是可通过Python和Java来ssh到路由器设备并获取相关的CLI信息,这个方法和同DRM的API相比较为不方便,因为它不像DRM可以精细化的直接得到Json键值对,而是需要通过对seesion中命令的输出来提取相关信息。这里是一些示例,比如使用python或java来获取CLI的输出:
 +{{:digi:cellular-router:pasted:20241120-185116.png}}
 +
 +
 +一、python的方式
 +
 +确保你安装了paramiko库。如果你还没有安装,可以使用以下命令安装:
 +<code>
 +pip install paramiko
 +</code>
 +
 +以下是<hidden Java示例代码>:
 +<code>
 +import paramiko
 +import time
 +
 +# 连接参数
 +hostname = 'your.server.com'
 +username = 'your_username'
 +password = 'your_password'
 +
 +# 创建SSH对象
 +ssh = paramiko.SSHClient()
 +
 +# 自动添加策略,保存服务器的主机名和密钥信息
 +ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 +
 +# 连接服务器
 +ssh.connect(hostname, username=username, password=password)
 +
 +# 打开一个Channel并获取一个交互式shell
 +channel = ssh.invoke_shell()
 +
 +# 等待shell初始化
 +time.sleep(1)
 +
 +# 发送交互字符并回车
 +channel.send('a\n')
 +
 +# 等待交互字符被处理
 +time.sleep(1)
 +
 +# 发送命令并回车
 +channel.send('show network\n')
 +
 +# 获取命令输出
 +time.sleep(1)  # 等待命令执行完成
 +output = channel.recv(65535).decode('utf-8')
 +
 +# 打印输出
 +print(output)
 +
 +# 关闭连接
 +channel.close()
 +ssh.close()
 +
 +</code>
 +</hidden>
 +
 +二、Java的实现方式
 +
 +在Java中,你可以使用JSch库来实现SSH连接并执行命令,然后获取命令的执行结果。以下是一个简单的示例,演示如何使用JSch库来实现这一功能。
 +<hidden Java 例程代码>
 +<code>
 +import com.jcraft.jsch.*;
 +
 +import java.io.InputStream;
 +
 +public class JSchExample {
 +    public static void main(String[] args) {
 +        String host = "your.server.com";
 +        String user = "your_username";
 +        String password = "your_password";
 +
 +        try {
 +            JSch jsch = new JSch();
 +            Session session = jsch.getSession(user, host, 22);
 +            session.setPassword(password);
 +            java.util.Properties config = new java.util.Properties();
 +            config.put("StrictHostKeyChecking", "no");
 +            session.setConfig(config);
 +            session.connect();
 +
 +            Channel channel = session.openChannel("shell");
 +            ((ChannelShell) channel).setPty(true);
 +
 +            InputStream in = channel.getInputStream();
 +            channel.connect();
 +
 +            // Wait for the initial prompt (adjust the sleep time as necessary)
 +            Thread.sleep(2000);
 +
 +            // Send the interactive character followed by a newline
 +            String interactiveChar = "a\n";
 +            sendCommand(channel, interactiveChar);
 +
 +            // Wait for the server to process the interactive character
 +            Thread.sleep(1000);
 +
 +            // Send the 'show network' command followed by a newline
 +            String command = "show network\n";
 +            sendCommand(channel, command);
 +
 +            // Read the output of the 'show network' command
 +            String output = readOutput(in);
 +
 +            System.out.println("Command output:\n" + output);
 +
 +            channel.disconnect();
 +            session.disconnect();
 +        } catch (Exception e) {
 +            e.printStackTrace();
 +        }
 +    }
 +
 +    private static void sendCommand(Channel channel, String command) throws Exception {
 +        OutputStream out = channel.getOutputStream();
 +        out.write(command.getBytes());
 +        out.flush();
 +    }
 +
 +    private static String readOutput(InputStream in) throws Exception {
 +        byte[] buffer = new byte[1024];
 +        StringBuilder output = new StringBuilder();
 +        int readCount;
 +        while ((readCount = in.read(buffer)) != -1) {
 +            output.append(new String(buffer, 0, readCount));
 +            if (output.toString().contains("username@hostname:~$")) { // Adjust the end of output marker as necessary
 +                break;
 +            }
 +        }
 +        return output.toString();
 +    }
 +}
 +
 +
 +</code>
 +</hidden>
 +在这个代码示例中,sendCommand 方法用于发送命令到服务器,而 readOutput 方法用于读取命令的输出。请注意,你可能需要根据服务器的实际响应来调整 readOutput 方法中的结束标记,以便正确地捕获命令的输出。