Files

402 lines
15 KiB
C
Raw Permalink Normal View History

2018-01-03 14:18:06 +01:00
/*
* This file is part of the MicroPython ESP32 project, https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo
2018-01-03 14:18:06 +01:00
*
* The MIT License (MIT)
*
* Copyright (c) 2018 LoBo (https://github.com/loboris)
2018-01-03 14:18:06 +01:00
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sdkconfig.h"
#ifdef CONFIG_MICROPY_USE_GSM
#include <stdio.h>
#include <stdint.h>
#include <string.h>
2018-12-04 14:06:15 +08:00
#include "tcpip_adapter.h"
2018-01-03 14:18:06 +01:00
#include "py/runtime.h"
2018-12-04 14:06:15 +08:00
#include "py/obj.h"
#include "netutils.h"
#include "mphalport.h"
2018-01-03 14:18:06 +01:00
#include "libs/libGSM.h"
//-------------------------------------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_startGSM(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
const mp_arg_t allowed_args[] = {
{ MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 115200} },
{ MP_QSTR_user, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_password, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_apn, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_connect, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_wait, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
2018-12-04 14:06:15 +08:00
{ MP_QSTR_roaming, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
2018-01-03 14:18:06 +01:00
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
char user[GSM_MAX_NAME_LEN] = {0};
char pass[GSM_MAX_NAME_LEN] = {0};
char apn[GSM_MAX_NAME_LEN] = {0};
int rx, tx, bdr, err = 0;
if (MP_OBJ_IS_STR(args[3].u_obj)) {
snprintf(user, GSM_MAX_NAME_LEN, mp_obj_str_get_str(args[3].u_obj));
}
if (MP_OBJ_IS_STR(args[4].u_obj)) {
snprintf(pass, GSM_MAX_NAME_LEN, mp_obj_str_get_str(args[4].u_obj));
}
if (MP_OBJ_IS_STR(args[5].u_obj)) {
snprintf(apn, GSM_MAX_NAME_LEN, mp_obj_str_get_str(args[5].u_obj));
}
else {
err = -10;
goto exit;
}
tx = args[0].u_int;
rx = args[1].u_int;
bdr = args[2].u_int;
if ((tx < 0) || (rx < 0)) {
err = -11;
goto exit;
}
2018-12-04 14:06:15 +08:00
int res = ppposInit(tx, rx, args[8].u_int, args[9].u_int, bdr, user, pass, apn, args[7].u_bool, args[6].u_bool, args[10].u_bool);
2018-01-03 14:18:06 +01:00
if (res == 0) return mp_const_true;
exit:
mp_printf(&mp_plat_print, "Error %d\n", err);
return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_gsm_startGSM_obj, 0, mod_gsm_startGSM);
//-------------------------------
STATIC mp_obj_t mod_gsm_stopGSM()
{
2018-12-04 14:06:15 +08:00
if (ppposDisconnect(1, 0) == 0) return mp_const_true;
return mp_const_false;
2018-01-03 14:18:06 +01:00
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_gsm_stopGSM_obj, mod_gsm_stopGSM);
//------------------------------------
STATIC mp_obj_t mod_gsm_stateGSM()
{
mp_obj_t tuple[2];
char state[20] = {'\0'};
2018-12-04 14:06:15 +08:00
int gsm_state = ppposStatus(NULL, NULL, NULL);
2018-01-03 14:18:06 +01:00
tuple[0] = mp_obj_new_int(gsm_state);
if (gsm_state == GSM_STATE_DISCONNECTED) sprintf(state, "Disconnected");
else if (gsm_state == GSM_STATE_CONNECTED) sprintf(state, "Connected");
else if (gsm_state == GSM_STATE_IDLE) sprintf(state, "Idle");
else if (gsm_state == GSM_STATE_FIRSTINIT) sprintf(state, "Not started");
else sprintf(state, "Unknown");
2018-12-04 14:06:15 +08:00
tuple[1] = mp_obj_new_str(state, strlen(state));
2018-01-03 14:18:06 +01:00
return mp_obj_new_tuple(2, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_gsm_stateGSM_obj, mod_gsm_stateGSM);
2018-12-04 14:06:15 +08:00
//--------------------------------
STATIC mp_obj_t mod_gsm_ifconfig()
{
uint32_t ip, netmask, gw;
ppposStatus(&ip, &netmask, &gw);
mp_obj_t tuple[3] = {
(mp_obj_t)netutils_format_ipv4_addr((uint8_t*)&ip, NETUTILS_BIG),
(mp_obj_t)netutils_format_ipv4_addr((uint8_t*)&netmask, NETUTILS_BIG),
(mp_obj_t)netutils_format_ipv4_addr((uint8_t*)&gw, NETUTILS_BIG)
};
// Return tuple: (ip, netmask, gateway)
return mp_obj_new_tuple(3, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_gsm_ifconfig_obj, mod_gsm_ifconfig);
2018-01-03 14:18:06 +01:00
//--------------------------------------
STATIC mp_obj_t mod_gsm_connectGSM()
{
2018-12-04 14:06:15 +08:00
mp_hal_reset_wdt();
2018-01-03 14:18:06 +01:00
int res = ppposConnect();
if (res == 0) return mp_const_true;
return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_gsm_connectGSM_obj, mod_gsm_connectGSM);
//------------------------------------------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_disconnectGSM(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
const mp_arg_t allowed_args[] = {
{ MP_QSTR_endtask, MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_rfoff, MP_ARG_BOOL, {.u_bool = false} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
2018-12-04 14:06:15 +08:00
if (ppposDisconnect(args[0].u_bool, args[1].u_bool) == 0) return mp_const_true;
return mp_const_false;
2018-01-03 14:18:06 +01:00
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_gsm_disconnectGSM_obj, 0, mod_gsm_disconnectGSM);
//------------------------------------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_sendSMS(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
const mp_arg_t allowed_args[] = {
{ MP_QSTR_gsmnum, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_msg, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
char *num = NULL;
char *msg = NULL;
int res = 0;
if (MP_OBJ_IS_STR(args[0].u_obj)) {
num = (char *)mp_obj_str_get_str(args[0].u_obj);
}
if (MP_OBJ_IS_STR(args[1].u_obj)) {
msg = (char *)mp_obj_str_get_str(args[1].u_obj);
}
if ((num) && (msg)) {
res = smsSend(num, msg);
}
if (res) return mp_const_true;
return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_gsm_sendSMS_obj, 2, mod_gsm_sendSMS);
//---------------------------------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_checkSMS(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
const mp_arg_t allowed_args[] = {
{ MP_QSTR_sort, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SMS_SORT_NONE} },
{ MP_QSTR_status, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SMS_LIST_ALL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int sort = SMS_SORT_NONE;
int rd_status = SMS_LIST_ALL;
if ((args[0].u_int == SMS_SORT_ASC) || (args[0].u_int == SMS_SORT_DESC)) sort = args[0].u_int;
if ((args[1].u_int == SMS_LIST_NEW) || (args[1].u_int == SMS_LIST_OLD)) rd_status = args[1].u_int;
mp_obj_t msg = mp_const_none;
SMS_indexes indexes;
int nmsg = getMessagesList(rd_status, 0, NULL, &indexes, sort);
if (nmsg > 0) {
mp_obj_t msgidx_tuple[nmsg];
for (int i=0; i<nmsg; i++) {
msgidx_tuple[i] = mp_obj_new_int(indexes.idx[i]);
}
msg = mp_obj_new_tuple(nmsg, msgidx_tuple);
}
return msg;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_gsm_checkSMS_obj, 0, mod_gsm_checkSMS);
//------------------------------------------------
STATIC mp_obj_t mod_gsm_deleteSMS(mp_obj_t idx_in)
{
if (smsDelete(mp_obj_get_int(idx_in))) return mp_const_true;
else return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_gsm_deleteSMS_obj, mod_gsm_deleteSMS);
//------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_readSMS(size_t n_args, const mp_obj_t *args)
{
mp_obj_t msg = mp_const_none;
SMS_Msg smsmsg;
int idx = mp_obj_get_int(args[0]);
int delsms = 0;
if (n_args > 1) delsms = mp_obj_get_int(args[1]);
int nmsg = getMessagesList(SMS_LIST_ALL, idx, &smsmsg, NULL, SMS_SORT_NONE);
if (nmsg > 0) {
mp_obj_t sms_tuple[7];
sms_tuple[0] = mp_obj_new_int(smsmsg.idx);
2018-12-04 14:06:15 +08:00
sms_tuple[1] = mp_obj_new_str(smsmsg.stat, strlen(smsmsg.stat));
sms_tuple[2] = mp_obj_new_str(smsmsg.from, strlen(smsmsg.from));
sms_tuple[3] = mp_obj_new_str(smsmsg.time, strlen(smsmsg.time));
2018-01-03 14:18:06 +01:00
sms_tuple[4] = mp_obj_new_int(smsmsg.time_value);
sms_tuple[5] = mp_obj_new_int(smsmsg.tz);
if (smsmsg.msg) {
2018-12-04 14:06:15 +08:00
sms_tuple[6] = mp_obj_new_str(smsmsg.msg, strlen(smsmsg.msg));
2018-01-03 14:18:06 +01:00
free(smsmsg.msg);
}
else sms_tuple[6] = mp_const_none;
msg = mp_obj_new_tuple(7, sms_tuple);
if (delsms) smsDelete(idx);
}
return msg;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_gsm_readSMS_obj, 1, 2, mod_gsm_readSMS);
//-----------------------------------------------------------------
STATIC mp_obj_t mod_gsm_SMS_cb(size_t n_args, const mp_obj_t *args)
{
2018-02-03 21:43:38 +01:00
if ((MP_OBJ_IS_FUN(args[0])) || (MP_OBJ_IS_METH(args[0]))) {
2018-01-03 14:18:06 +01:00
int interval = 60;
if (n_args > 1) interval = mp_obj_get_int(args[1]);
if ((interval < 5) || (interval > 86400)) return mp_const_false;
if (setSMS_cb((void *)args[0], interval*1000)) return mp_const_true;
else return mp_const_false;
}
else if (args[0] == mp_const_none) {
if (setSMS_cb(NULL, 0)) return mp_const_true;
else return mp_const_false;
}
else {
return mp_const_false;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_gsm_SMS_cb_obj, 1, 2, mod_gsm_SMS_cb);
//------------------------------------------------
STATIC mp_obj_t mod_gsm_GSM_debug(mp_obj_t dbg_in)
{
setDebug(mp_obj_get_int(dbg_in));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_gsm_GSM_debug_obj, mod_gsm_GSM_debug);
//------------------------------------------------------------------------------------------
STATIC mp_obj_t mod_gsm_atCmd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
const mp_arg_t allowed_args[] = {
{ MP_QSTR_cmd, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = 500} },
{ MP_QSTR_response, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_printable, MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_cmddata, MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
char *cmd = (char *)mp_obj_str_get_str(args[0].u_obj);
char *resp = NULL;
char *cmddata = NULL;
int tmo = args[1].u_int;
if (strlen(cmd) < 2) {
mp_raise_msg(&mp_type_ValueError, "Command too short");
}
if ((strstr(cmd, "AT") != cmd) && (strstr(cmd, "at") != cmd)) {
mp_raise_msg(&mp_type_ValueError, "Command must start with 'AT' or 'at'");
}
if (MP_OBJ_IS_STR(args[2].u_obj)) {
resp = (char *)mp_obj_str_get_str(args[2].u_obj);
}
if (resp) {
if (MP_OBJ_IS_STR(args[4].u_obj)) {
cmddata = (char *)mp_obj_str_get_str(args[4].u_obj);
}
}
char atcmd[strlen(cmd)+4];
if ((cmd[strlen(cmd)-2] != '\r') || (cmd[strlen(cmd)-2] != '\n')) {
strcpy(atcmd, cmd);
strcat(atcmd, "\r\n");
}
else strcpy(atcmd, cmd);
char *buffer = NULL;
buffer = malloc(1024);
if (buffer == NULL) {
mp_raise_msg(&mp_type_OSError, "Buffer allocation error");
}
char **pbuffer = &buffer;
int res = at_Cmd(atcmd, resp, pbuffer, 1024, tmo, cmddata);
if (res == 0) {
2018-12-04 14:06:15 +08:00
mp_obj_t response = mp_obj_new_str("", 0);
2018-01-03 14:18:06 +01:00
free(*pbuffer);
return response;
}
if (args[3].u_bool) {
for (int i=0; i<strlen(buffer); i++) {
if ((buffer[i] < 0x20) || (buffer[i] > 0x7F)) {
buffer[i] = '.';
}
}
}
2018-12-04 14:06:15 +08:00
mp_obj_t response = mp_obj_new_str(buffer, strlen(buffer));
2018-01-03 14:18:06 +01:00
free(*pbuffer);
return response;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_gsm_atCmd_obj, 1, mod_gsm_atCmd);
//===========================================================
STATIC const mp_rom_map_elem_t gsm_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&mod_gsm_startGSM_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&mod_gsm_stopGSM_obj) },
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&mod_gsm_stateGSM_obj) },
2018-12-04 14:06:15 +08:00
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&mod_gsm_ifconfig_obj) },
2018-01-03 14:18:06 +01:00
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&mod_gsm_disconnectGSM_obj) },
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&mod_gsm_connectGSM_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendSMS), MP_ROM_PTR(&mod_gsm_sendSMS_obj) },
{ MP_ROM_QSTR(MP_QSTR_checkSMS), MP_ROM_PTR(&mod_gsm_checkSMS_obj) },
{ MP_ROM_QSTR(MP_QSTR_readSMS), MP_ROM_PTR(&mod_gsm_readSMS_obj) },
{ MP_ROM_QSTR(MP_QSTR_deleteSMS), MP_ROM_PTR(&mod_gsm_deleteSMS_obj) },
{ MP_ROM_QSTR(MP_QSTR_sms_cb), MP_ROM_PTR(&mod_gsm_SMS_cb_obj) },
{ MP_ROM_QSTR(MP_QSTR_debug), MP_ROM_PTR(&mod_gsm_GSM_debug_obj) },
{ MP_ROM_QSTR(MP_QSTR_atcmd), MP_ROM_PTR(&mod_gsm_atCmd_obj) },
// Constants
{ MP_ROM_QSTR(MP_QSTR_SORT_NONE), MP_ROM_INT(SMS_SORT_NONE) },
{ MP_ROM_QSTR(MP_QSTR_SORT_ASC), MP_ROM_INT(SMS_SORT_ASC) },
{ MP_ROM_QSTR(MP_QSTR_SORT_DESC), MP_ROM_INT(SMS_SORT_DESC) },
{ MP_ROM_QSTR(MP_QSTR_SMS_READ), MP_ROM_INT(SMS_LIST_OLD) },
{ MP_ROM_QSTR(MP_QSTR_SMS_UNREAD), MP_ROM_INT(SMS_LIST_NEW) },
{ MP_ROM_QSTR(MP_QSTR_SMS_ALL), MP_ROM_INT(SMS_LIST_ALL) },
};
STATIC MP_DEFINE_CONST_DICT(gsm_module_globals, gsm_module_globals_table);
//======================================
const mp_obj_module_t mp_module_gsm = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&gsm_module_globals,
};
#endif