Last active
November 19, 2023 11:31
-
-
Save weimzh/66fb93b8aac11690ec2ab59f99d9b50a to your computer and use it in GitHub Desktop.
Quick and dirty code to read and send SMS messages for Huawei EC122 CDMA Modem. Might be buggy, use with caution.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# Copyright (c) 2022, Wei Mingzhi <[email protected]>. | |
# SPDX-License-Identifier: BSD-3-Clause | |
# https://spdx.org/licenses/BSD-3-Clause.html | |
# | |
# Quick and dirty code to read and send SMS messages for Huawei EC122 CDMA Modem. | |
# | |
# Most likely this will NOT work with any other GSM/CDMA phones/modems, as the AT | |
# commands of Huawei EC122 seem different from Nokia's or any other GSM modems. | |
# | |
# Please use a better solution like Gammu for supported modems: | |
# https://wammu.eu/ | |
import serial | |
import sys | |
import re | |
import logging | |
logging.basicConfig(level=logging.INFO, format='%(levelname)-8s %(message)s') | |
def _write_cmd(ser, cmd): | |
logging.debug('writing command: ' + cmd) | |
cmd = ('AT' + cmd).encode('ascii') + serial.CR + serial.LF | |
ser.write(cmd) | |
def _get_line(ser): | |
line = b'' | |
line_began = False | |
while True: | |
ch = ser.read(size=1) | |
if not line_began: | |
if ch == serial.CR or ch == serial.LF: | |
continue | |
line_began = True | |
if ch == serial.CR: | |
ser.read(size=1) # skip LF | |
return line.decode('ascii') | |
line += ch | |
return line | |
def _unlock_pin(ser, pin): | |
_write_cmd(ser, '^CPIN="' + pin + '"') | |
while True: | |
line = _get_line(ser) | |
if line.startswith('OK'): | |
logging.debug('PIN unlocked') | |
break | |
elif line.startswith('+CMS ERROR'): | |
logging.error('PIN unlock error, exiting immediately to avoid SIM locking!!! ' + line) | |
sys.exit(255) | |
def read_all_sms_ec122(port, delete_sms=False, pin=None): | |
ser = serial.Serial(port=port, baudrate=19200) | |
try: | |
if pin is not None: | |
_unlock_pin(ser, pin) | |
sms_list = [] | |
sms_text_list = [] | |
logging.debug('getting sms list...') | |
_write_cmd(ser, '^HCMGL') | |
while True: | |
line = _get_line(ser) | |
if line.startswith('^HCMGL'): | |
line_split = re.split('[:,]', line) | |
index = int(line_split[1]) | |
sms_list.append(index) | |
elif line.startswith('+CMS ERROR'): | |
logging.error('get sms list error: ' + line) | |
return None | |
elif line.startswith('OK'): | |
break | |
for index in sms_list: | |
_write_cmd(ser, '^HCMGR=' + str(index)) | |
while True: | |
line = _get_line(ser) | |
if line.startswith('^HCMGR'): | |
line_split = re.split('[:,]', line) | |
(dummy, caller_id, year, month, day, hour, minute, second, lang, fmt, length, v3, v4, v5, v6) = line_split | |
sms_data = ser.read(size=int(length)) | |
ser.read(size=3) # skip ^Z CR LF | |
fmt = int(fmt) | |
if fmt == 1: | |
sms_text = sms_data.decode('ascii') | |
elif fmt == 6: | |
sms_text = sms_data.decode('utf-16be') | |
else: | |
logging.info('unsupported sms format, skipping: ' + str(fmt)) | |
break | |
stat_line = _get_line(ser) | |
if stat_line != 'OK': | |
logging.error('ending line is not OK: ' + stat_line) | |
else: | |
s = {} | |
s['Number'] = caller_id | |
s['Text'] = sms_text | |
s['DateTime'] = (int(year), int(month), int(day), int(hour), int(minute), int(second)) | |
sms_text_list.append(s) | |
break | |
if delete_sms: | |
for index in sms_list: | |
_write_cmd(ser, '+CMGD=' + str(index)) | |
while True: | |
line = _get_line(ser) | |
if line.startswith('OK'): | |
logging.debug('SMS deleted: ' + str(index)) | |
break | |
elif line.startswith('+CMS ERROR'): | |
logging.error('SMS delete error: ' + str(index)) | |
break | |
return sms_text_list | |
finally: | |
ser.close() | |
def send_sms_ec122(port, dest, text, pin=None): | |
ser = serial.Serial(port=port, baudrate=19200) | |
try: | |
if pin is not None: | |
_unlock_pin(ser, pin) | |
_write_cmd(ser, '^HCMGS="' + dest + '"') | |
ser.write(text.encode('utf-8')) | |
ser.write(int(26).to_bytes(1, 'big')) | |
while True: | |
line = _get_line(ser) | |
if line.startswith('+CMS ERROR'): | |
logging.error('send sms error: ' + line) | |
break | |
elif line.startswith('OK'): | |
logging.info('send sms ok') | |
break | |
finally: | |
ser.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment