744 lines
22 KiB
C
744 lines
22 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
|
||
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
|
be copied by any method or incorporated into another program without
|
||
|
the express written consent of Aerospace C.Power. This Information or any portion
|
||
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
|
liability for its use in any way and conveys no license or title under
|
||
|
any patent or copyright and makes no representation or warranty that this
|
||
|
Information is free from patent or copyright infringement.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "os_task_api.h"
|
||
|
#include "iot_gpio_api.h"
|
||
|
#include "iot_uart_api.h"
|
||
|
#include "os_timer_api.h"
|
||
|
#include "os_utils_api.h"
|
||
|
#include "iot_task_api.h"
|
||
|
#include "iot_module_api.h"
|
||
|
#include "iot_errno_api.h"
|
||
|
#include "iot_io_api.h"
|
||
|
#include "iot_utils_api.h"
|
||
|
#include "iot_board_api.h"
|
||
|
#include "os_lock_api.h"
|
||
|
#include "iot_string_api.h"
|
||
|
#include "n11_gprs.h"
|
||
|
|
||
|
#define N11_MID 0
|
||
|
|
||
|
#define N11_GPIO_RESET 32
|
||
|
#define N11_GPIO_ST_ON 0
|
||
|
#define N11_GPIO_ST_OFF 1
|
||
|
|
||
|
#define N11_UART_BUFFER_LEN 500
|
||
|
#define N11_UART_DEF_BRATE 115200
|
||
|
#define N11_UART_DEF_PRT IOT_UART_PARITY_NONE
|
||
|
#define N11_UART_DEF_DLEN IOT_UART_DLEN_8_BITS
|
||
|
#define N11_UART_DEF_STOP IOT_UART_STOP_1_BITS
|
||
|
|
||
|
#define N11_UART_DEF_BRATE_STR "115200"
|
||
|
|
||
|
#define N11_TASK_PRIO 7
|
||
|
#define N11_TASK_STACK_SIZE 1024
|
||
|
#define N11_TASK_MSG_COUNT 32
|
||
|
|
||
|
#define N11_RESP_TIMEOUT 1000 /* 1 seconds to wait response from N11. */
|
||
|
#define N11_RESP_RETRY_TIME 30
|
||
|
|
||
|
#define N11_TCP 1 /*establish a tcp connection. */
|
||
|
#define N11_UDP 0 /*establish a udp connection. */
|
||
|
|
||
|
#define DST_SERVER_ADDR (uint8_t *)("60.205.179.198")
|
||
|
#define DST_SERVER_PORT 11111
|
||
|
#define UART_PORT_TO_BIND 0
|
||
|
|
||
|
typedef struct _iot_n11_state_t {
|
||
|
uint8_t power_on; /* if power on for n11 chip. */
|
||
|
uint8_t gprs_att; /* if GPRS attached. */
|
||
|
uint8_t pin_ready; /* if PIN code if ready. */
|
||
|
uint8_t network_r; /* if network registered. */
|
||
|
uint8_t connect_ok; /* if connection established. */
|
||
|
uint8_t in_datatrans; /* if data transmission started. */
|
||
|
} iot_n11_state_t;
|
||
|
|
||
|
typedef struct _iot_n11_pick_str_t {
|
||
|
uint8_t *wonder; /* The string wanted. */
|
||
|
uint32_t found; /* Set if string found in responsed message. */
|
||
|
iot_pkt_t *pkt; /* The pkt_t of responsed string. */
|
||
|
} iot_n11_pick_t;
|
||
|
|
||
|
typedef struct _iot_n11_object_t {
|
||
|
iot_uart_h uart_h;
|
||
|
iot_task_h task_h;
|
||
|
iot_n11_state_t state; /* State of N11 chip. */
|
||
|
iot_n11_pick_t pick; /* For picking responsed message on initializing. */
|
||
|
iot_n11_fn_rcv fn_rcv; /* Callback API, uplayer registered. */
|
||
|
} iot_n11_obj_t;
|
||
|
|
||
|
typedef struct _iot_n11_msg_type_t {
|
||
|
iot_task_msg_t msg; /* The main entity of message. */
|
||
|
void *data; /* The user data inside this message. */
|
||
|
} n11_msg_t;
|
||
|
|
||
|
/* message to rise init action. */
|
||
|
#define N11_MSG_TYPE_DO_INIT 0
|
||
|
/* message to indicate data from N11 */
|
||
|
#define N11_MSG_TYPE_N11_RESP 1
|
||
|
/* message to indicate set transparent process */
|
||
|
#define N11_MSG_TYPE_N11_SET_TRANSPARENT 2
|
||
|
|
||
|
static iot_n11_obj_t n11 = {0};
|
||
|
|
||
|
#define n11_gprs_set_unready() \
|
||
|
do { \
|
||
|
n11.state.power_on = n11.state.pin_ready = n11.state.gprs_att = n11.state.network_r = \
|
||
|
n11.state.connect_ok = 0; \
|
||
|
} while (0)
|
||
|
|
||
|
#define n11_gprs_ready() \
|
||
|
(n11.state.power_on && n11.state.pin_ready && n11.state.gprs_att && n11.state.network_r)
|
||
|
|
||
|
#define n11_gprs_connect_ok() \
|
||
|
(n11.state.power_on && n11.state.pin_ready && n11.state.gprs_att && n11.state.network_r && \
|
||
|
n11.state.connect_ok)
|
||
|
|
||
|
uint8_t *n11_gprs_strstr(uint8_t *src, uint8_t *sub, uint32_t len)
|
||
|
{
|
||
|
const uint8_t *bp = src, *sp = sub;
|
||
|
uint32_t count = len;
|
||
|
|
||
|
if (NULL == src || NULL == sub) {
|
||
|
return src;
|
||
|
}
|
||
|
|
||
|
while ((*src) && (count--)) {
|
||
|
bp = src;
|
||
|
sp = sub;
|
||
|
do {
|
||
|
if (!*sp)
|
||
|
return src;
|
||
|
} while (*bp++ == *sp++);
|
||
|
src++;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void n11_gprs_data_dump(void *buf, uint32_t len, uint32_t line)
|
||
|
{
|
||
|
static char dump_buf[1024];
|
||
|
char *p = buf, *q = dump_buf;
|
||
|
uint32_t i, buf_len;
|
||
|
|
||
|
buf_len = iot_sprintf(q, "DUMP(%03d):", len);
|
||
|
|
||
|
// Buf len should not exceed 1024 - 3, as added len is 1 space and 2 hex, or index will overflow
|
||
|
for (i = 0; (i < len) && (buf_len < 1021); i++, p++) {
|
||
|
buf_len += iot_sprintf(q + buf_len, " %02x", ((int)*p) & 0xFF);
|
||
|
}
|
||
|
|
||
|
iot_cus_printf("\n[N11@%04d]:%s\n", line, dump_buf);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* post message to task */
|
||
|
static uint32_t n11_gprs_post_msg(uint16_t msg_type, uint16_t msg_id, void *data)
|
||
|
{
|
||
|
iot_task_msg_t *msg;
|
||
|
n11_msg_t *task_msg;
|
||
|
|
||
|
msg = iot_task_alloc_msg_with_reserved(n11.task_h, 0);
|
||
|
|
||
|
if (NULL == msg) {
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
task_msg = (n11_msg_t *)msg;
|
||
|
|
||
|
task_msg->msg.type = msg_type;
|
||
|
task_msg->msg.id = msg_id;
|
||
|
task_msg->data = data;
|
||
|
|
||
|
iot_task_queue_msg(n11.task_h, &task_msg->msg, 0);
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
/*Check whether tcp connection has broken*/
|
||
|
static void n11_gprs_check_interrupt_command(uint8_t *data, uint32_t dlen)
|
||
|
{
|
||
|
char *check_str = "+TRANSCLOSE: 0,OK";
|
||
|
if (NULL != n11_gprs_strstr(data, (uint8_t *)check_str, dlen)) {
|
||
|
// TCP TRANS CLOSED
|
||
|
n11.state.connect_ok = false;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* API for uart driver to receive data from N11 */
|
||
|
static uint32_t n11_gprs_receive_from_n11(uint8_t *data, uint32_t dlen, bool_t full,
|
||
|
uint32_t i_dlen)
|
||
|
{
|
||
|
iot_pkt_t *pkt;
|
||
|
|
||
|
(void)full;
|
||
|
(void)i_dlen;
|
||
|
|
||
|
iot_cus_printf("[N11@%d]received from n11:\n", __LINE__);
|
||
|
n11_gprs_data_dump(data, dlen, __LINE__);
|
||
|
|
||
|
if (n11.state.in_datatrans) {
|
||
|
// TODO: support protocol other than GE
|
||
|
if (dlen < 2 || 0xAA != data[0] || 0xAA != data[1]) {
|
||
|
iot_cus_printf("[N11]Got invalid ge command, need set back to transparent mode!");
|
||
|
n11.state.in_datatrans = false;
|
||
|
n11_gprs_check_interrupt_command(data, dlen);
|
||
|
|
||
|
/*Will be caught by msg handle for the first msg, then response will be clean in cancel
|
||
|
* handler*/
|
||
|
n11_gprs_post_msg(N11_MSG_TYPE_N11_SET_TRANSPARENT, 0, NULL);
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (NULL == (pkt = iot_pkt_alloc(dlen, N11_MID))) {
|
||
|
iot_cus_printf("[N11@%d]alloc pkt failed, len %d!\n", __LINE__, dlen);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
os_mem_cpy(iot_pkt_put(pkt, dlen), data, dlen);
|
||
|
n11_gprs_post_msg(N11_MSG_TYPE_N11_RESP, 0, (void *)pkt);
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
static void n11_gprs_display_send_data(uint8_t *data, uint32_t dlen, uint32_t line_no)
|
||
|
{
|
||
|
iot_cus_printf("[N11]send to n11 %p, uart: %p :\n", (void *)&n11, n11.uart_h);
|
||
|
n11_gprs_data_dump(data, dlen, line_no);
|
||
|
}
|
||
|
|
||
|
/* Send data to N11 */
|
||
|
static uint32_t n11_gprs_send_binary_data(uint8_t *data, uint32_t dlen)
|
||
|
{
|
||
|
iot_pkt_t *pkt;
|
||
|
|
||
|
if (NULL == (pkt = iot_pkt_alloc(dlen, N11_MID))) {
|
||
|
iot_cus_printf("[N11@%d]alloc pkt failed, len %d!\n", __LINE__, dlen);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
os_mem_cpy(iot_pkt_put(pkt, dlen), data, dlen);
|
||
|
|
||
|
n11_gprs_display_send_data(data, dlen, __LINE__);
|
||
|
return iot_uart_send(n11.uart_h, pkt, NULL);
|
||
|
}
|
||
|
|
||
|
/* find message with type & id, in message queue, with msg_clean API */
|
||
|
static uint32_t n11_gprs_start_pick_init_resp_msg_inner(char *command_str, char *wonder_str,
|
||
|
uint32_t command_time, uint32_t retry)
|
||
|
{
|
||
|
uint32_t times, ret = ERR_FAIL;
|
||
|
|
||
|
n11.pick.found = false;
|
||
|
n11.pick.wonder = (uint8_t *)wonder_str;
|
||
|
if (wonder_str == NULL) {
|
||
|
n11.pick.found = true;
|
||
|
}
|
||
|
|
||
|
times = retry;
|
||
|
|
||
|
do {
|
||
|
n11_gprs_send_binary_data((uint8_t *)command_str, iot_strlen((char *)command_str));
|
||
|
|
||
|
// process no response command
|
||
|
if (n11.pick.found) {
|
||
|
// Empty response, no response msg need to be wait and release
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
os_delay(command_time);
|
||
|
|
||
|
iot_task_clean_msg(n11.task_h, N11_MSG_TYPE_N11_RESP, 0);
|
||
|
|
||
|
if (n11.pick.found) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} while (times--);
|
||
|
|
||
|
if (n11.pick.found) {
|
||
|
iot_cus_printf("[N11]\nCommand:%s Response:%s\n", command_str, iot_pkt_data(n11.pick.pkt));
|
||
|
iot_pkt_free(n11.pick.pkt);
|
||
|
n11.pick.pkt = NULL;
|
||
|
ret = ERR_OK;
|
||
|
} else {
|
||
|
iot_cus_printf("[N11]\nCommand:%s Response:(NULL)\n", command_str);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
#define n11_gprs_start_pick_init_resp_msg(cmd, wdr) \
|
||
|
n11_gprs_start_pick_init_resp_msg_inner(cmd, wdr, N11_RESP_TIMEOUT, N11_RESP_RETRY_TIME)
|
||
|
|
||
|
static void n11_gprs_pick_init_resp_msg_handle(iot_pkt_t *pkt)
|
||
|
{
|
||
|
uint8_t *p_str, *p_sub_str = n11.pick.wonder;
|
||
|
uint32_t len;
|
||
|
|
||
|
if (n11_gprs_connect_ok() && n11.state.in_datatrans) {
|
||
|
iot_cus_printf("[N11] in data transmission, should not be processed as AT resp!\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((NULL == pkt) || (NULL == p_sub_str)) {
|
||
|
iot_cus_printf("[N11]%s somthing error!\n", __FUNCTION__);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
p_str = iot_pkt_data(pkt);
|
||
|
|
||
|
len = iot_pkt_data_len(pkt);
|
||
|
|
||
|
if (NULL != n11_gprs_strstr(p_str, p_sub_str, len)) {
|
||
|
n11.pick.found = true;
|
||
|
if (NULL != n11.pick.pkt) {
|
||
|
iot_pkt_free(n11.pick.pkt);
|
||
|
}
|
||
|
n11.pick.pkt = pkt;
|
||
|
} else {
|
||
|
iot_pkt_free(pkt);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Config N11 with AT command in list */
|
||
|
static uint32_t n11_gprs_config_with_at(void)
|
||
|
{
|
||
|
/* Config uart. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+IPR=" N11_UART_DEF_BRATE_STR "\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Config bandrate OK!\n", __LINE__);
|
||
|
|
||
|
/* Query module vendor information. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("ATI\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query module vendor information OK!\n", __LINE__);
|
||
|
|
||
|
/* Query module software version. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+GMR\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query module software version OK!\n", __LINE__);
|
||
|
|
||
|
/* Query module signal information. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CGMM\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query module signal information OK!\n", __LINE__);
|
||
|
|
||
|
/* Query sim card CCID information. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CCID\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
|
||
|
iot_cus_printf("[N11@%d]Query module signal information OK!\n", __LINE__);
|
||
|
|
||
|
/* Check PIN code. TODO input PIN & PUK code. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CPIN?\n", "CPIN: READY")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]PIN code ready!\n", __LINE__);
|
||
|
n11.state.pin_ready = true;
|
||
|
|
||
|
/* Query the registered GSM network. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+COPS?\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query the registered GSM network ok.\n", __LINE__);
|
||
|
|
||
|
/* Check if network registered. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CREG?\n", "+CREG: 0,1")) {
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CREG?\n", "+CREG: 0,5")) {
|
||
|
goto err_out;
|
||
|
} else {
|
||
|
iot_cus_printf("[N11@%d]Registered roaming network!\n", __LINE__);
|
||
|
}
|
||
|
} else {
|
||
|
iot_cus_printf("[N11@%d]Registered local network!\n", __LINE__);
|
||
|
}
|
||
|
n11.state.network_r = true;
|
||
|
|
||
|
/* Check if GPRS attached. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+CGATT?\n", "CGATT: 1")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]GPRS attached!\n", __LINE__);
|
||
|
n11.state.gprs_att = true;
|
||
|
return ERR_OK;
|
||
|
|
||
|
err_out:
|
||
|
/* reset N11 chip && try again. */
|
||
|
iot_n11_gprs_reset();
|
||
|
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
/*Setup transport layer data communication*/
|
||
|
static uint32_t iot_n11_gprs_setup_data_trans(uint8_t conn_type, uint8_t *dst_ipaddr, uint32_t port)
|
||
|
{
|
||
|
|
||
|
char cmd_buffer[128] = {0};
|
||
|
if (N11_CONN_TCP == conn_type) {
|
||
|
|
||
|
/* TCP passthrough test server. */
|
||
|
iot_sprintf(cmd_buffer, "AT+TCPTRANS=%s,%d\n", dst_ipaddr, port);
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg(cmd_buffer, "+TCPTRANS: OK")) {
|
||
|
|
||
|
iot_cus_printf("[N11@%d]%s failed\n", __LINE__, __FUNCTION__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
n11.state.connect_ok = true;
|
||
|
n11.state.in_datatrans = true;
|
||
|
iot_cus_printf("[N11@%d]TCP passthrough test server OK!\n", __LINE__);
|
||
|
|
||
|
} else if (N11_CONN_UDP == conn_type) {
|
||
|
|
||
|
/* UDP passthrough test server. */
|
||
|
iot_sprintf(cmd_buffer, "AT+UDPTRANS=%s,%d\n", dst_ipaddr, port);
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg(cmd_buffer, "+UDPRANS: OK")) {
|
||
|
|
||
|
iot_cus_printf("[N11@%d]%s failed\n", __LINE__, __FUNCTION__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
n11.state.connect_ok = true;
|
||
|
n11.state.in_datatrans = true;
|
||
|
iot_cus_printf("[N11@%d]UDP passthrough test server OK!\n", __LINE__);
|
||
|
|
||
|
} else {
|
||
|
iot_printf("[N11@%d]invalid connection type. connection type = %d\n", __LINE__, conn_type);
|
||
|
iot_cus_printf("%s failed\n", __FUNCTION__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
/*Setup transparent data transmission back to normal*/
|
||
|
static uint32_t iot_n11_gprs_set_transparent(void)
|
||
|
{
|
||
|
if (!n11.state.network_r) {
|
||
|
iot_cus_printf("[N11]Invalid n11 state!\n");
|
||
|
return ERR_FAIL;
|
||
|
} else if (!n11.state.connect_ok) {
|
||
|
return iot_n11_gprs_setup_data_trans(N11_TCP, DST_SERVER_ADDR, DST_SERVER_PORT);
|
||
|
}
|
||
|
|
||
|
/*Set transparent data transmission*/
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("ATO\n", "CONNECT")) {
|
||
|
iot_cus_printf("[N11@%d]Set transparent process Fail!\n", __LINE__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
n11.state.in_datatrans = true;
|
||
|
iot_cus_printf("[N11@%d]Set transparent process OK!\n", __LINE__);
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
uint32_t iot_n11_gprs_establish_network_connection(uint8_t conn_type, uint8_t *dst_ipaddr,
|
||
|
uint32_t port)
|
||
|
{
|
||
|
if (!n11_gprs_ready()) {
|
||
|
iot_cus_printf("[N11@%d]n11 not ready!\n", __LINE__);
|
||
|
goto err_out;
|
||
|
}
|
||
|
|
||
|
if (NULL == dst_ipaddr || 0 == port) {
|
||
|
iot_cus_printf("[N11]please input the destination ipaddr and port number!!\n");
|
||
|
goto err_out;
|
||
|
}
|
||
|
|
||
|
iot_cus_printf("\n[N11]Establish a TCP passthrough connection...\n");
|
||
|
|
||
|
/* Query the current TCP/UDP receive data mode. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+TRANMODE?\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query the current TCP/UDP receive data mode OK!\n", __LINE__);
|
||
|
|
||
|
/* Query APN information. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+NETAPN?\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query APN information OK!\n", __LINE__);
|
||
|
|
||
|
/* Set APN information. */
|
||
|
if (ERR_OK !=
|
||
|
n11_gprs_start_pick_init_resp_msg("AT+NETAPN=\"CMNET\",\"GSM\",\"1234\"\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Set APN information OK!\n", __LINE__);
|
||
|
|
||
|
/* Query PPP connect status. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+XIIC?\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query PPP connect status OK!\n", __LINE__);
|
||
|
|
||
|
/* Establish ppp connection. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+XIIC=1\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Establish ppp connection OK!\n", __LINE__);
|
||
|
|
||
|
/* Query PPP connection status. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg("AT+XIIC?\n", "OK")) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Query PPP connection status OK!\n", __LINE__);
|
||
|
|
||
|
if (ERR_OK != iot_n11_gprs_setup_data_trans(conn_type, dst_ipaddr, port)) {
|
||
|
goto err_out;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
/* Close the TCP connection. */
|
||
|
if (ERR_OK != n11_gprs_start_pick_init_resp_msg(
|
||
|
"AT+TRANSCLOSE\n",
|
||
|
"OK"
|
||
|
)) {
|
||
|
//goto err_out;
|
||
|
}
|
||
|
iot_cus_printf("[N11@%d]Close the TCP connection OK!\n", __LINE__);
|
||
|
#endif
|
||
|
return ERR_OK;
|
||
|
|
||
|
err_out:
|
||
|
iot_cus_printf("[N11@%d]%s failed\n", __LINE__, __FUNCTION__);
|
||
|
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
static uint32_t n11_gprs_auto_connect(void)
|
||
|
{
|
||
|
if (n11.state.connect_ok) {
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
if (ERR_OK !=
|
||
|
iot_n11_gprs_establish_network_connection(N11_TCP, DST_SERVER_ADDR, DST_SERVER_PORT)) {
|
||
|
iot_cus_printf("[N11][gprs]Failed to connect to server!");
|
||
|
iot_n11_gprs_reset();
|
||
|
return ERR_FAIL;
|
||
|
} else {
|
||
|
iot_cus_printf("[N11]Connected to remote server!");
|
||
|
}
|
||
|
|
||
|
iot_cus_printf("[N11@%d]N11 chip init successfully!\n", __LINE__);
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
/* init N11 chip */
|
||
|
static uint32_t n11_gprs_init_n11_chip(void)
|
||
|
{
|
||
|
uint32_t ret;
|
||
|
|
||
|
n11_gprs_set_unready();
|
||
|
|
||
|
ret = iot_gpio_value_set(N11_GPIO_RESET, N11_GPIO_ST_OFF);
|
||
|
|
||
|
os_delay(1500);
|
||
|
|
||
|
ret |= iot_gpio_value_set(N11_GPIO_RESET, N11_GPIO_ST_ON);
|
||
|
if (ERR_OK != ret) {
|
||
|
iot_cus_printf("[N11@%d]Can't set reset pin %d!\n", __LINE__, N11_GPIO_RESET);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
ret = n11_gprs_config_with_at();
|
||
|
if (ERR_OK != ret) {
|
||
|
iot_cus_printf("[N11@%d]Config N11 with AT failed!\n", __LINE__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
n11.state.power_on = true;
|
||
|
|
||
|
return n11_gprs_auto_connect();
|
||
|
}
|
||
|
|
||
|
static uint32_t n11_gprs_handle_received_data(iot_pkt_t *p_pkt)
|
||
|
{
|
||
|
uint32_t ret = ERR_FAIL;
|
||
|
uint8_t *p_str = NULL;
|
||
|
uint32_t len;
|
||
|
|
||
|
if (NULL == p_pkt) {
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
if (!n11_gprs_connect_ok()) {
|
||
|
iot_cus_printf("[N11@%d]N11 connection not ok!\n", __LINE__);
|
||
|
goto out;
|
||
|
}
|
||
|
p_str = iot_pkt_data(p_pkt);
|
||
|
|
||
|
len = iot_pkt_data_len(p_pkt);
|
||
|
|
||
|
if (NULL != n11.fn_rcv) {
|
||
|
// iot_cus_printf("%s send data to app, len = %d\n", __FUNCTION__, len);
|
||
|
// n11_gprs_data_dump(p_str, len, __LINE__);
|
||
|
n11.fn_rcv(p_str, len);
|
||
|
} else {
|
||
|
iot_cus_printf("[n11 err], need to register received function!!\n");
|
||
|
}
|
||
|
|
||
|
ret = ERR_OK;
|
||
|
out:
|
||
|
iot_pkt_free(p_pkt);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static void n11_gprs_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
|
||
|
{
|
||
|
n11_msg_t *n11_msg = (n11_msg_t *)msg;
|
||
|
|
||
|
if (N11_MSG_TYPE_DO_INIT == n11_msg->msg.type) {
|
||
|
/* do nothing */
|
||
|
} else if (N11_MSG_TYPE_N11_RESP == n11_msg->msg.type) {
|
||
|
n11_gprs_pick_init_resp_msg_handle((iot_pkt_t *)n11_msg->data);
|
||
|
} else {
|
||
|
iot_cus_printf("[N11@%d]Unknown MSG-TYPE %d!\n", __LINE__, n11_msg->msg.type);
|
||
|
}
|
||
|
|
||
|
iot_task_free_msg(task_h, &(n11_msg->msg));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
static void n11_gprs_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
|
||
|
{
|
||
|
n11_msg_t *n11_msg = (n11_msg_t *)msg;
|
||
|
|
||
|
(void)task_h;
|
||
|
|
||
|
if (N11_MSG_TYPE_DO_INIT == n11_msg->msg.type) {
|
||
|
n11_gprs_init_n11_chip();
|
||
|
} else if (N11_MSG_TYPE_N11_RESP == n11_msg->msg.type) {
|
||
|
n11_gprs_handle_received_data((iot_pkt_t *)n11_msg->data);
|
||
|
} else if (N11_MSG_TYPE_N11_SET_TRANSPARENT == n11_msg->msg.type) {
|
||
|
iot_n11_gprs_set_transparent();
|
||
|
} else {
|
||
|
iot_cus_printf("[N11@%d]Unknown MSG-TYPE %d!\n", __LINE__, n11_msg->msg.type);
|
||
|
}
|
||
|
|
||
|
iot_task_free_msg(task_h, &(n11_msg->msg));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uint32_t iot_n11_gprs_send(void *data, uint32_t dlen)
|
||
|
{
|
||
|
iot_pkt_t *pkt = (iot_pkt_t *)data;
|
||
|
if (NULL == data) {
|
||
|
iot_cus_printf("[N11]param err, data =%p, dlen = %d\n", data, dlen);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
if (!n11_gprs_connect_ok()) {
|
||
|
iot_cus_printf("[N11@%d]N11 not ready!\n", __LINE__);
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
n11_gprs_display_send_data(iot_pkt_data(pkt), iot_pkt_data_len(pkt), __LINE__);
|
||
|
return iot_uart_send(n11.uart_h, pkt, NULL);
|
||
|
}
|
||
|
|
||
|
uint32_t iot_n11_gprs_register_call_back(iot_n11_fn_rcv fn)
|
||
|
{
|
||
|
if ((NULL == fn) || (NULL != n11.fn_rcv)) {
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
n11.fn_rcv = fn;
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
void iot_n11_gprs_reset(void)
|
||
|
{
|
||
|
/* Just post msg to reset n11 chip */
|
||
|
n11_gprs_post_msg(N11_MSG_TYPE_DO_INIT, 0, 0);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uint32_t iot_n11_gprs_init(void)
|
||
|
{
|
||
|
uint8_t uartport;
|
||
|
iot_task_config_t t_cfg;
|
||
|
|
||
|
uartport = iot_board_get_uart(UART_EXT_CHIP);
|
||
|
|
||
|
if (IOT_UART_PORT_SUPP_MAX <= uartport) {
|
||
|
iot_cus_printf("[N11@%d]No uart for communication!\n", __LINE__);
|
||
|
goto error_0;
|
||
|
}
|
||
|
|
||
|
n11.uart_h =
|
||
|
iot_uart_open(uartport, (void *)n11_gprs_receive_from_n11, N11_UART_BUFFER_LEN, NULL);
|
||
|
|
||
|
if (NULL == n11.uart_h) {
|
||
|
iot_cus_printf("[N11@%d]Open uart failed!\n", __LINE__);
|
||
|
goto error_0;
|
||
|
} else {
|
||
|
iot_cus_printf("[N11@%d]Open uart %d success.\n", __LINE__, uartport);
|
||
|
}
|
||
|
|
||
|
if (!iot_uart_set_config(n11.uart_h, N11_UART_DEF_BRATE, N11_UART_DEF_PRT, N11_UART_DEF_DLEN,
|
||
|
N11_UART_DEF_STOP)) {
|
||
|
iot_cus_printf("[N11@%d]Config uart failed!\n", __LINE__);
|
||
|
goto error_1;
|
||
|
}
|
||
|
|
||
|
if (ERR_OK != iot_gpio_open_as_output(N11_GPIO_RESET)) {
|
||
|
iot_cus_printf("[N11@%d]Can't open reset pin %d!\n", __LINE__, N11_GPIO_RESET);
|
||
|
goto error_1;
|
||
|
}
|
||
|
|
||
|
t_cfg.stack_size = N11_TASK_STACK_SIZE;
|
||
|
t_cfg.task_prio = N11_TASK_PRIO;
|
||
|
t_cfg.msg_size = sizeof(n11_msg_t);
|
||
|
t_cfg.msg_cnt = N11_TASK_MSG_COUNT;
|
||
|
t_cfg.queue_cnt = 1;
|
||
|
t_cfg.queue_cfg[0].quota = 0;
|
||
|
t_cfg.task_event_func = NULL;
|
||
|
t_cfg.msg_exe_func = n11_gprs_msg_handle;
|
||
|
t_cfg.msg_cancel_func = n11_gprs_msg_cancel;
|
||
|
|
||
|
n11.task_h = iot_task_create(N11_MID, &t_cfg);
|
||
|
|
||
|
if (NULL == n11.task_h) {
|
||
|
iot_cus_printf("[N11@%d]Init task failed!\n", __LINE__);
|
||
|
goto error_1;
|
||
|
}
|
||
|
|
||
|
/* start init N11. */
|
||
|
iot_n11_gprs_reset();
|
||
|
|
||
|
iot_cus_printf("[N11@%d]Init task successfully!\n", __LINE__);
|
||
|
goto out;
|
||
|
|
||
|
error_1:
|
||
|
iot_uart_close(n11.uart_h);
|
||
|
error_0:
|
||
|
return ERR_FAIL;
|
||
|
|
||
|
out:
|
||
|
return ERR_OK;
|
||
|
}
|