forked from xuos/xiuos
274 lines
7.8 KiB
C
274 lines
7.8 KiB
C
/*
|
|
* Copyright (c) 2020 AIIT XUOS Lab
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
|
|
/**
|
|
* @file ec200t.c
|
|
* @brief Implement the connection 4G adapter function, using EC200T device
|
|
* @version 1.1
|
|
* @author AIIT XUOS Lab
|
|
* @date 2021.07.08
|
|
*/
|
|
|
|
#include <adapter.h>
|
|
|
|
static void Ec200tPowerSet(void)
|
|
{
|
|
int pin_fd;
|
|
pin_fd = PrivOpen(ADAPTER_EC200T_PIN_DRIVER, O_RDWR);
|
|
|
|
struct PinParam pin_param;
|
|
pin_param.cmd = GPIO_CONFIG_MODE;
|
|
pin_param.mode = GPIO_CFG_INPUT_PULLUP;
|
|
pin_param.pin = ADAPTER_EC200T_PWRKEY;
|
|
|
|
struct PrivIoctlCfg ioctl_cfg;
|
|
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
|
ioctl_cfg.args = &pin_param;
|
|
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
|
|
|
|
struct PinStat pin_stat;
|
|
pin_stat.pin = ADAPTER_EC200T_PWRKEY;
|
|
pin_stat.val = GPIO_HIGH;
|
|
PrivWrite(pin_fd, &pin_stat, 1);
|
|
|
|
PrivTaskDelay(600);//at least 500ms
|
|
|
|
pin_stat.val = GPIO_LOW;
|
|
PrivWrite(pin_fd, &pin_stat, 1);
|
|
|
|
PrivClose(pin_fd);
|
|
}
|
|
|
|
static int Ec200tOpen(struct Adapter *adapter)
|
|
{
|
|
uint8_t ec200t_cmd[64];
|
|
|
|
/*step1: open ec200t serial port*/
|
|
adapter->fd = PrivOpen(ADAPTER_EC200T_DRIVER, O_RDWR);
|
|
if (adapter->fd < 0) {
|
|
printf("Ec200tOpen get serial %s fd error\n", ADAPTER_EC200T_DRIVER);
|
|
return -1;
|
|
}
|
|
|
|
/*step2: serial write "+++", quit transparent mode*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "+++");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
/*step3: serial write "AT+CCID", get SIM ID*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+CCID\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step4: serial write "AT+CPIN?", check SIM status*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+CPIN?\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step5: serial write "AT+CREG?", check whether registered to GSM net*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+CREG?\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step6: serial write "AT+QICLOSE", close socket connect before open socket*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step7: serial write "AT+QIDEACT", close TCP net before open socket*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QIDEACT=1\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
ADAPTER_DEBUG("Ec200t open done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tClose(struct Adapter *adapter)
|
|
{
|
|
uint8_t ec200t_cmd[64];
|
|
|
|
/*step1: serial write "+++", quit transparent mode*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "+++");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
/*step2: serial write "AT+QICLOSE", close socket connect before open socket*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step3: serial write "AT+QIDEACT", close TCP net before open socket*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QIDEACT=1\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step4: close ec200t serial port*/
|
|
PrivClose(adapter->fd);
|
|
|
|
/*step5: power down ec200t*/
|
|
Ec200tPowerSet();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
|
|
{
|
|
if (OPE_INT != cmd) {
|
|
printf("Ec200tIoctl only support OPE_INT, do not support %d\n", cmd);
|
|
return -1;
|
|
}
|
|
|
|
uint32_t baud_rate = *((uint32_t *)args);
|
|
|
|
struct SerialDataCfg serial_cfg;
|
|
memset(&serial_cfg, 0 ,sizeof(struct SerialDataCfg));
|
|
serial_cfg.serial_baud_rate = baud_rate;
|
|
serial_cfg.serial_data_bits = DATA_BITS_8;
|
|
serial_cfg.serial_stop_bits = STOP_BITS_1;
|
|
serial_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
|
|
serial_cfg.serial_parity_mode = PARITY_NONE;
|
|
serial_cfg.serial_bit_order = STOP_BITS_1;
|
|
serial_cfg.serial_invert_mode = NRZ_NORMAL;
|
|
#ifdef ADAPTER_EC200T_DRIVER_EXT_PORT
|
|
serial_cfg.ext_uart_no = ADAPTER_EC200T_DRIVER_EXT_PORT;
|
|
serial_cfg.port_configure = PORT_CFG_INIT;
|
|
#endif
|
|
|
|
struct PrivIoctlCfg ioctl_cfg;
|
|
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
|
ioctl_cfg.args = &serial_cfg;
|
|
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tConnect(struct Adapter *adapter, const char *ip, const char *port, enum IpType ip_type)
|
|
{
|
|
uint8_t ec200t_cmd[64];
|
|
|
|
/*step1: serial write "AT+QICSGP", connect to China Mobile using ipv4 or ipv6*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
|
|
if (IPV4 == ip_type) {
|
|
strcpy(ec200t_cmd, "AT+QICSGP=1,1,\"CMNET\",\"\",\"\",1\r\n");
|
|
} else if (IPV6 == ip_type) {
|
|
strcpy(ec200t_cmd, "AT+QICSGP=1,2,\"CMNET\",\"\",\"\",1\r\n");
|
|
}
|
|
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step2: serial write "AT+QIACT", open TCP net*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QIACT=1\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
/*step3: serial write "AT+QIOPEN", connect socket using TCP*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QIOPEN=1,0,\"TCP\",\"");
|
|
strcat(ec200t_cmd, ip);
|
|
strcat(ec200t_cmd, "\",");
|
|
strcat(ec200t_cmd, port);
|
|
strcat(ec200t_cmd, ",0,2\r\n");
|
|
|
|
ADAPTER_DEBUG("Ec200t connect AT CMD :%s\n", ec200t_cmd);
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
ADAPTER_DEBUG("Ec200t connect TCP done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tSend(struct Adapter *adapter, const void *buf, size_t len)
|
|
{
|
|
PrivWrite(adapter->fd, buf, len);
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tRecv(struct Adapter *adapter, void *buf, size_t len)
|
|
{
|
|
PrivRead(adapter->fd, buf, len);
|
|
return 0;
|
|
}
|
|
|
|
static int Ec200tDisconnect(struct Adapter *adapter)
|
|
{
|
|
uint8_t ec200t_cmd[64];
|
|
|
|
/*step1: serial write "+++", quit transparent mode*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "+++");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
/*step2: serial write "AT+QICLOSE", close socket connect before open socket*/
|
|
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
|
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
|
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
|
|
|
PrivTaskDelay(2500);
|
|
|
|
ADAPTER_DEBUG("Ec200t disconnect TCP done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct IpProtocolDone ec200t_done =
|
|
{
|
|
.open = Ec200tOpen,
|
|
.close = Ec200tClose,
|
|
.ioctl = Ec200tIoctl,
|
|
.connect = Ec200tConnect,
|
|
.send = Ec200tSend,
|
|
.recv = Ec200tRecv,
|
|
.disconnect = Ec200tDisconnect,
|
|
};
|
|
|
|
AdapterProductInfoType Ec200tAttach(struct Adapter *adapter)
|
|
{
|
|
struct AdapterProductInfo *product_info = malloc(sizeof(struct AdapterProductInfo));
|
|
if (!product_info) {
|
|
printf("Ec200tAttach malloc product_info error\n");
|
|
free(product_info);
|
|
return NULL;
|
|
}
|
|
|
|
product_info->model_name = ADAPTER_4G_EC200T;
|
|
|
|
product_info->model_done = (void *)&ec200t_done;
|
|
|
|
Ec200tPowerSet();
|
|
|
|
return product_info;
|
|
}
|
|
|
|
|
|
|