【问题标题】:Getting Callerid from serial port with Conexant USB CX93010 modem?使用 Conexant USB CX93010 调制解调器从串口获取 Callerid?
【发布时间】:2014-06-17 17:00:20
【问题描述】:

我有一个 C# 代码,但是当我将线路连接到电话时,它不需要从连接到 USB 端口的拨号调制解调器获取来电显示。它获得了 CallerID,但在程序运行和阅读行中,我只是 RING 没有别的。

这是我的代码:

public partial class Form1 : XtraForm
{
    public Form1()
    {
        InitializeComponent();            
    }

    SerialPort sp ;
    private void simpleButton1_Click(object sender, EventArgs e)
    {            
        sp = new SerialPort(textEdit1.Text);
        sp.NewLine = "\r\n";
        sp.Parity = Parity.None;
        sp.DataBits = 8;
        sp.StopBits = StopBits.One;
        sp.DtrEnable = true;
        sp.WriteBufferSize = 1024;

        sp.Open();
        sp.WriteLine("AT+VCID=1");
        sp.RtsEnable = true;
        timer1.Start();
    }

    void sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {

    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        sp.Close();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        memoEdit1.Text += "\n" + sp.ReadExisting();
    }

    private void simpleButton2_Click(object sender, EventArgs e)
    {
        sp.Close();
    }

【问题讨论】:

  • 您的调制解调器是否支持接收来电显示(FSK 解码)?
  • 我们希望用户发布有效的代码,演示问题并且没有绒毛。您的代码充满了注释的代码片段。先把它清理干净。
  • 是的,手册中写道它支持来电显示检测科胜讯 USB CX93010 ACF 调制解调器
  • @Manish - AT+VCID=? 返回(0-2),所以调制解调器支持来电显示。
  • 这个调制解调器是有线的,我只是运行 AT+VCID=1 并且调制解调器完美地报告了 callerId,但几天后它停止工作。一个法国人对这个调制解调器做了一些调查,但他们没有解决我的问题。 domoticz.com/forum/viewtopic.php?t=33161

标签: c# serial-port modem


【解决方案1】:

当您的调制解调器支持来电显示时,请使用 AT+CLIP=1。这将导致在调用调制解调器时显示未经请求的 +CLIP 消息。

+CLIP 主动消息通常表述如下:

+CLIP: <number>,<type>,,,,<cli validity>

其中&lt;number&gt; 是一个字符串,其中包含由&lt;type&gt; 定义的格式的数字。 &lt;type&gt; 地址八位字节,例如国际号码是 145。&lt;cli validity&gt; 确定号码是否被扣留等。

【讨论】:

  • +VCID=1 可能会解决您的问题。查找调制解调器模块的 AT 参考指南总是好的。它们通常对学习模块专业非常有用。
【解决方案2】:

Conexant USB CX93010 ACF 调制解调器没有 FSK 协议

【讨论】:

  • 它确实支持FSK(实际上大多数拨号数据调制解调器都是基于FSK工作的)。如果您有任何参考,请提及!我觉得应该和时序或者数据长度有关
【解决方案3】:

我根据我对科胜讯 USB CX93010 所做的一些测试发布了下面的代码。下面的代码是用 C(而不是 C#)编写的,并且在 Linux(而不是 Windows)上运行。但它应该为 C# 程序提供良好的基线。

代码是基于另一个由Sawdust编写的Stack Overflow answer,并有程序测试结果。

您还可以在http://www.arcelect.com 找到适用于科胜讯调制解调器的综合 AT 命令集。它的日期是 2001 年,但它为调制解调器提供的 AT 命令比我在网上其他地方找到的要多。


这是代码。

#include <errno.h>
#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define DISPLAY_STRING 1

int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfmakeraw (&tty);
    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

void write_command(int fd, const void* cmd, size_t len)
{
    if (len == ~(size_t)0)
        len = strlen((const char*)cmd);

    printf("Send %d: %s\n", (int)len, (const char*)cmd);

    int wlen = write(fd, cmd, len);

    if (wlen != len) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);    /* delay for output */
}

void read_response(int fd)
{
    char buf[256];
    int rlen = read(fd, buf, sizeof(buf) - 1);

    if (rlen > 0) {
#ifdef DISPLAY_STRING
        buf[rlen] = 0;
        printf("Read %d: \"%s\"\n", rlen, buf);
#else /* display hex */
        unsigned char *p;
        printf("Read %d:", rlen);
        for (p = buf; rlen-- > 0; p++)
            printf(" 0x%x", *p);
        printf("\n");
#endif
    } else if (rlen < 0) {
        printf("Error from read: %d: %s\n", rlen, strerror(errno));
    } else {  /* rlen == 0 */
        printf("Timeout from read\n");
    }
}

int main(int argc, char* argv[])
{
    int fd;
    const char portname[] = "/dev/ttyACM0";

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }

    /*baudrate 115200, 8 bits, no parity, 1 stop bit */
    set_interface_attribs(fd, B115200);

    write_command(fd, "ATZ\r", 4); /* Reset */

    read_response(fd);

    write_command(fd, "ATE0\r", -1);  /* Echo off */

    read_response(fd);

    write_command(fd, "AT+VCID=?\r", -1);  /* Query CallerID caps */

    read_response(fd);

    write_command(fd, "AT+CLIP=?\r", -1);  /* Query CallerID caps */

    read_response(fd);

    write_command(fd, "AT+VCID=1\r", -1);  /* Set CallerID */

    read_response(fd);

    printf("Entering loop, CTRL+C to break...\n\n");

    while (1)
    {
        read_response(fd);
    }

    return 0;
}

以下是使用手机的测试结果。我更改了姓名和电话号码;否则它就是程序的确切输出。

$ sudo ./modem.exe
Send 4: ATZ
Read 6: "
OK
"
Send 5: ATE0
Read 11: "ATE0
OK
"
Send 10: AT+VCID=?
Read 15: "
(0-2)

OK
"
Send 10: AT+CLIP=?
Read 9: "
ERROR
"
Send 10: AT+VCID=1
Read 6: "
OK
"

Entering loop, CTRL+C to break...

Read 8: "
RING
"
Read 67: "
DATE = 0214
TIME = 2116
NMBR = 2025551212
NAME = JANE DOE
"
Read 8: "
RING
"
Read 67: "
DATE = 0214
TIME = 2116
NMBR = 2025551212
NAME = JANE DOE
"
Read 8: "
RING
"
Read 8: "
RING
"
Read 8: "
RING
"

此外,您可以发送AT+GSR 以获取真正的调制解调器版本,而不是 Windows 提供的版本(这似乎有点不准确):

Send 7: AT+GMR
Read 44: "AT+GMR
+GMR: CX93001-EIS_V0.2013-V92

OK"

【讨论】:

    【解决方案4】:
    1. 您必须将Country of Installation 设置为B5 AT+GCI=B5 经过三周的调查后我得到了它(在您的国家可能推迟它可以是 00 或 B4 或 B5,但 B5 用于大多数固定线路的工程):

    2. 然后通过AT+VCID=1 或AT+VCID=2 启用CID 报告,如manual 所述:

    3. 然后它完美地工作:

    这是我基于你的工作代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO.Ports;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace CIDResolver
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            SerialPort sp;
            private void Connect_click(object sender, EventArgs e)
            {
                sp = new SerialPort(textEdit1.Text);
                sp.BaudRate = 11500;
                sp.NewLine = "\r\n";
    
                sp.Open();
    
                sp.WriteLine("AT+GCI=B5"); // can be 00 or B4 or B5
                sp.WriteLine("AT+VCID=1");
    
                sp.DataReceived += new SerialDataReceivedEventHandler((object _s, SerialDataReceivedEventArgs _e) =>
                {
                    string newData = sp.ReadExisting();
                    consoleOut.Invoke((MethodInvoker)delegate {
                        // Running on the UI thread
                        consoleOut.Text += newData+ "\r\n";
                    });
                });
            }
    
    
            private void disConnectBtn_Click(object sender, EventArgs e)
            {
                sp.Close();
            }
    
            private void Form1_FormClosed_1(object sender, FormClosedEventArgs e)
            {
                sp.Close();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-25
      • 2019-08-08
      • 2015-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      相关资源
      最近更新 更多