65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Telit 蜂窝模块进行 GPRS 和 Telnet

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (6投票s)

2010 年 11 月 10 日

CPOL

4分钟阅读

viewsIcon

38251

本文将介绍如何打开一个监听套接字,以及在套接字连接后如何将数据传递到串行端口。

引言

Telit提供了示例代码和文档,支持打开一个连接到服务器的套接字并来回传递数据。如果您希望部署大量的数据收集点,这很好,但如果您需要它连接到具有Telnet会话的模块怎么办?本文将介绍如何打开一个监听套接字,以及在套接字连接后如何将数据传递到串行端口。

安装

GPRS连接是模块与互联网对话的方式。根据运营商和您的个人套餐,该模块可能具有也可能没有动态IP地址。在继续之前,您需要从您的运营商处获得一些信息。

  1. APN名称
  2. 用户ID
  3. 密码

大多数手机使用通用的APN来访问互联网。AT&T可以为您的使用设置自定义APN,以满足大型项目所需的任何特殊要求和数据计划。他们可以提供诸如静态IP或网关连接到内部局域网之类的东西。其他运营商也有类似的选择,但我只对AT&T有经验。

def make_connection():
    "Establishes connection over internet."
    MDM.send('AT#GPRS=0\r', 2)
    MDM.receive(5)
    MDM.send('AT+CGDCONT=1,"IP","INTERNETTRIAL"\r', 2)
    MDM.receive(5)
    MDM.send('AT#USERID="trial488@INTERNETTRIAL"\r', 2)
    MDM.receive(5)
    MDM.send('AT#PASSW="trialpass488"\r', 2)
    MDM.receive(5)
    MDM.send('AT#FRWL=1,"192.168.1.1","255.255.255.0"\r', 5)
    MDM.receive(5)

AT#GPRS=0 断开任何现有连接。然后可以将先前从您的提供商处获得的信息保存到设备中。此信息未存储在NVM中,因此您需要在代码中包含它,并在每次重启后提供它。

#FRWL命令很重要。该设备将只允许来自防火墙中条目的传入数据。如果您只有一个服务器,则可以将其硬编码到程序中,就像此示例一样,或者我所做的是将列表写入NVM,并在每次重启设备时读取它。我使用短信来更改该列表。

########################################################################

# Firewall Service Processor & Subroutines

def process_FIREWALL(number, SMSmessage):
    "Modifies the firewall settings from command."
    settings = load_firewall()
    if contains(SMSmessage, 'add'):
        reply = add_to_firewall(SMSmessage, settings)
    elif contains(SMSmessage, 'list'):
        reply = list_firewall_settings(settings)
    elif contains(SMSmessage, 'rem'):
        reply = remove_from_firewall(SMSmessage, settings)
    else:
        reply = 'Invalid Command'
    save_firewall(settings)
    sendSMS(number, reply)
    MDM.send('AT#SL=1,1,1700\r', 5)

def load_firewall():
    "Retrieves the firewall settings."
    try:
        file = open('FRWL', 'rb')
    except IOError:
        return []
    else:
        file_contents = file.read()
        file.close()
        non_microsoft = file_contents.replace('\r\n', '\n')
        non_macintosh = non_microsoft.replace('\r', '\n')
        settings = filter(None, non_macintosh.split('\n'))
        return settings

def add_to_firewall(SMSmessage, settings):
    "Adds IP address to the firewall settings."
    start = SMSmessage.index('add')
    address = SMSmessage[start+4:start+19].strip()
    settings.append(address)
    return address + ' added to firewall'

def list_firewall_settings(settings):
    "Concatenates the settings for a reply."
    reply = ';'.join(settings)
    MOD.sleep(15)
    return reply

def remove_from_firewall(SMSmessage, settings):
    "Removes IP address from the firewall settings."
    start = SMSmessage.index('rem')
    address = SMSmessage[start+4:start+19].strip()
    while address in settings:
        settings.remove(address)
    return address + ' removed from firewall'

def save_firewall(settings):
    "Stores the IP addresses in a file."
    MDM.send('AT#FRWL=2,"192.168.4.1","225.255.255.0"\r', 5)
    MDM.receive(5)
    file = open('FRWL', 'wb')
    for address in settings:
        MDM.send('AT#FRWL=1,"%s","255.255.255.0"\r' % address, 5)
        MDM.receive(5)
        file.write(address + '\r\n')
        MOD.sleep(5)
    file.close()

########################################################################

这里我不会深入讨论,因为这只是Python中的简单文件访问,短信处理已经在这里介绍过。在我的情况下,我想使用我们的外部静态地址将其硬编码到模块中。其他临时IP根据需要添加和删除。文件FRWL存储在模块上并保留在NVM中,因此即使在重新启动后,列表也保持活动状态。

GPRS连接

在连接设置和防火墙到位后,创建连接只需要命令AT#GPRS=1。

def request_GPRS_context():
    "Activates the GPRS context for internet."
    while True:
        MDM.send('AT#GPRS=1\r', 5)
        MOD.sleep(20)
        if MDM.receive(5).find('IP') != -1:
            return

该模块并非总是在第一次尝试创建GPRS连接时成功。除非建立连接,否则它将返回错误。如果成功,该模块将显示IP地址。这可以被捕获并存储,以用于动态IP情况。我正在使用静态IP,因此这里不需要这样做。

现在您已连接到互联网。这允许您访问FTP站点或您需要通过互联网连接执行的任何其他操作。我需要设备等待我的Telnet会话,然后将该信息传递到串行端口。为此,我们首先需要打开监听套接字。

def open_listening_socket():
    "Opens server socket for connections."
    while True:
        MDM.send('AT#SL=1,1,23\r', 2)
        MOD.sleep(20)
        if MDM.receive(5).find('OK') != -1:
            return

AT#SL 打开或关闭套接字。1,1,23 在端口23上开始监听,套接字ID为1。也可以定义套接字关闭类型,有关更多信息,请参阅Telit的AT命令参考。我将其保留为默认值,即当主机断开连接时关闭连接。需要注意的是,只要没有发生任何事情,套接字将保持打开状态。在收到短信后,我遇到了它消失的问题。因此,在处理完每条短信后,我使用AT#SL=1,1,23重新初始化监听端口。

应答套接字很容易。AT#SA 应答连接。当尝试连接时,MDM接口将显示“SRING”。

########################################################################

# Socket Connection Handlers

def handle_socket_call():
    "Forwards socket data over MDM and SER."
    MDM.send('AT#SA=1,0\r', 2)
    forward = True
    while forward:
        forward_messages()
        MDM2.send('AT#SS\r', 5)
        forward_messages()
        print forward
        forward = MDM2.receive(5).find('#SS: 1,0') == -1
        print forward
        forward_messages()
    MDM.send('AT#SL=1,1,23\r', 5)

def forward_messages(timeout=2):
    "Transfers data two ways across MDM and SER."
    SER.send(MDM.receive(timeout))
    MDM.send(SER.read(), timeout)

########################################################################

在我的应用程序中,我不想与模块对话,我需要与外部设备对话,并将其用作WAN到串行网关。使用AT#SS检查连接状态,这是在MDM2接口上完成的,因为在模块和WAN连接之间来回传输的数据位于MDM接口上。AT#SS返回所有已打开的套接字的列表,并且关闭的套接字由“ID”,0表示。因此,扫描“1,0”可以告诉我连接的计算机何时断开连接,我可以将模块返回到监听模式。传递数据只是将传入的MDM数据传递给SER实例,反之亦然。

结论

GRPS连接是Telit模块系列的一个强大工具。它们可以用于轮询远程位置的数据或控制一个设施,或者只是检查您是否忘记关掉熨斗。此代码是为GC864-PY模块编写的,并且仅在此模块上进行了测试。其他模块和固件版本可能会有所不同。有关所有AT命令的更多信息,请参阅您的特定模块的Telit AT命令参考。请参阅我之前的文章,以获取有关使用python和处理短信的更多信息。

历史

  • 2010年11月8日:初始版本
© . All rights reserved.