rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,7 @@
NAME := sal_modulue_gt202
#$(NAME)_COMPONENTS += atparser
$(NAME)_SOURCES += gt202_sal.c
GLOBAL_DEFINES += DEV_SAL_GT202

View file

@ -0,0 +1,405 @@
#include <stdio.h>
#include <stddef.h>
#include <aos/kernel.h>
#include "qcom_api.h"
#include "sal.h"
#define CONN_LIST_MAX (10)
#define QCOM_SELECT_TIMEOUT (10)
// Convert IP address in uint32_t to comma separated bytes
#define UINT32_IPADDR_TO_CSV_BYTES(a) (((a) >> 24) & 0xFF), (((a) >> 16) & 0xFF), (((a) >> 8) & 0xFF), ((a)&0xFF)
// Convert comma separated bytes to a uint32_t IP address
#define CSV_BYTES_TO_UINT32_IPADDR(a0, a1, a2, a3) (((uint32_t)(a0)&0xFF) << 24) | (((uint32_t)(a1)&0xFF) << 16) | (((uint32_t)(a2)&0xFF) << 8) | ((uint32_t)(a3)&0xFF)
typedef struct {
int fd;
int qcom_socket;
}SocketFDMap;
static SocketFDMap sock_list[CONN_LIST_MAX];
static netconn_data_input_cb_t g_netconn_data_input_cb;
static int sal_qcom_init(void)
{
return 0;
}
static int remove_sock_form_list_by_fd(int fd)
{
int i;
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].fd == fd)
{
sock_list[i].fd = -1;
sock_list[i].qcom_socket = -1;
}
}
return 0;
}
static int remove_sock_form_list_by_qsock(int socket)
{
int i;
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].qcom_socket == socket)
{
sock_list[i].fd = -1;
sock_list[i].qcom_socket = -1;
}
}
return 0;
}
static int add_sock_to_list(int fd, int sock)
{
int i;
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].qcom_socket < 0)
{
sock_list[i].fd = fd;
sock_list[i].qcom_socket = sock;
return 0;
}
}
return 1;
}
static int fd_to_socket(int fd)
{
int i;
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].fd == fd)
{
return sock_list[i].qcom_socket;
}
}
return -1;
}
static int socket_to_fd(int socket)
{
int i;
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].qcom_socket == socket)
{
return sock_list[i].fd;
}
}
return -1;
}
static int sal_qcom_domain_to_ip(char *domain, char ip[16])
{
uint32_t addr = 0;
A_STATUS status;
PRINTF("DNS Request %s\r\n", domain);
if (strcmp(domain, "public.iot-as-mqtt.cn-shanghai.aliyuncs.com") == 0) {
/* Workaround DNS */
PRINTF("Work around DNS\r\n");
strcpy(ip, "139.196.135.135");
return 0;
}
if (strcmp(domain, "iotx-ota.oss-cn-shanghai.aliyuncs.com") == 0) {
PRINTF("Work around DNS\r\n");
strcpy(ip, "106.14.228.182");
return 0;
}
// NOTE: This function returns the address in reverse byte order
status = qcom_dnsc_get_host_by_name((char *)domain, &addr);
PRINTF("DNS Resolve %d, status = %d\r\n", addr, status);
if (status == 0)
{
int len = snprintf(ip, 16, "%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(addr));
ip[len] = 0;
PRINTF("Looked up %s as %d.%d.%d.%d\r\n", domain, UINT32_IPADDR_TO_CSV_BYTES(addr));
}
return status;
}
int sal_qcom_start(sal_conn_t *c)
{
int sock, ret;
SOCKADDR_T l_addr, r_addr;
memset(&l_addr, 0, sizeof(l_addr));
memset(&r_addr, 0, sizeof(r_addr));
A_STATUS status;
if(!c || !c->addr)
{
PRINTF("sal_qcom_start paramter error\r\n");
return 1;
}
PRINTF("sal_qcom_start %s\r\n", c->addr);
// NOTE: This function returns the address in reverse byte order
status = qcom_dnsc_get_host_by_name(c->addr, (uint32_t*)&r_addr.sin_addr.s_addr);
if(status != A_OK)
{
/*domain resolve failed, try to use IP directly */
int a0, a1, a2, a3;
ret = sscanf(c->addr, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
if(ret == 4)
{
r_addr.sin_addr.s_addr = CSV_BYTES_TO_UINT32_IPADDR(a0, a1, a2, a3);
}
else
{
return 1;
}
}
switch(c->type)
{
case TCP_CLIENT:
case TCP_SERVER:
sock = qcom_socket(ATH_AF_INET, SOCK_STREAM_TYPE, 0);
PRINTF("QCOM TCP SOCKET = %d\r\n", sock);
break;
case UDP_UNICAST:
case UDP_BROADCAST:
sock = qcom_socket(ATH_AF_INET, SOCK_DGRAM_TYPE, 0);
PRINTF("QCOM UDP SOCKET = %d\r\n", sock);
break;
default:
return 1;
break;
}
if(sock < 0)
{
return 1;
}
if(c->type == TCP_CLIENT || c->type == SSL_CLIENT)
{
r_addr.sin_port = c->r_port;
r_addr.sin_family = ATH_AF_INET;
status = (A_STATUS)qcom_connect(sock, (struct sockaddr *)&r_addr, sizeof(r_addr));
if(status != A_OK)
{
return 1;
}
}
if(c->type == TCP_SERVER)
{
l_addr.sin_port = c->l_port;
l_addr.sin_family = ATH_AF_INET;
l_addr.sin_addr.s_addr = CSV_BYTES_TO_UINT32_IPADDR(0, 0, 0, 0);
status = (A_STATUS)qcom_bind(sock, (struct sockaddr *)(&l_addr), sizeof(l_addr));
if(status != A_OK)
{
qcom_socket_close(sock);
return 1;
}
status = qcom_listen(sock, 1);
if(status != A_OK)
{
qcom_socket_close(sock);
return 1;
}
}
if(c->type == UDP_UNICAST || c->type == UDP_BROADCAST)
{
l_addr.sin_port = c->l_port;
l_addr.sin_family = ATH_AF_INET;
l_addr.sin_addr.s_addr = CSV_BYTES_TO_UINT32_IPADDR(0, 0, 0, 0);
status = (A_STATUS)qcom_bind(sock, (struct sockaddr *)(&l_addr), sizeof(l_addr));
if(status != A_OK)
{
qcom_socket_close(sock);
return 1;
}
}
PRINTF("sal_qcom_start c->fd = %d, socket = %d\r\n", c->fd, sock);
add_sock_to_list(c->fd, sock);
return 0;
}
static int sal_qcom_send(int fd, uint8_t *data, uint32_t len, char remote_ip[16], int32_t remote_port, int32_t timeout)
{
volatile int sent;
int qcom_socket = 0;
/* qcom driver enable ZERO_COPY, then must use custom_alloc */
uint8_t *send_buf = custom_alloc(len);
PRINTF("sal_qcom_send fd = %d, size = %d\r\n",fd, len);
qcom_socket = fd_to_socket(fd);
if(send_buf == NULL)
{
PRINTF("sal_qcom_send allocation failed\r\n");
return 1;
}
memcpy(send_buf, data, len);
/* if remote_ip, regard it as TCP send */
if(remote_ip == NULL)
{
sent = qcom_send(qcom_socket, (char*)send_buf, len, 0);
PRINTF("TCP Send return %d\r\n", sent);
}
else /* UDP send */
{
int a0, a1, a2, a3;
sscanf(remote_ip, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
SOCKADDR_T r_addr;
r_addr.sin_family = ATH_AF_INET;
r_addr.sin_port = remote_port;
r_addr.sin_addr.s_addr = CSV_BYTES_TO_UINT32_IPADDR(a0, a1, a2, a3);
PRINTF("UDP Send, %d-%d-%d-%d:%d\r\n", a0,a1,a2,a3,remote_port);
sent = qcom_sendto(qcom_socket, (char*)send_buf, len, 0, (struct sockaddr *)&r_addr, sizeof(SOCKADDR_T));
PRINTF("UDP Send return %d\r\n", sent);
}
custom_free(send_buf);
return 0;
}
static int sal_qcom_close(int fd, int32_t remote_port)
{
int sock;
sock = fd_to_socket(fd);
if (sock == -1) {
/* SOCKET close by remote */
return 0;
}
PRINTF("sal_qcom_close fd = %d, socket =%d\r\n", fd, sock);
qcom_socket_close(sock);
remove_sock_form_list_by_fd(fd);
return 0;
}
static int sal_qcom_register_netconn_data_input_cb(netconn_data_input_cb_t cb)
{
PRINTF("sal_qcom_register_netconn_data_input_cb\r\n");
if (cb)
g_netconn_data_input_cb = cb;
return 0;
}
static int sal_qcom_deinit(void)
{
return 0;
}
void sal_recv_task(void *param)
{
int i, rev_len, timeout, sock, fd;
char *recv_buf;
SOCKADDR_T r_addr;
socklen_t r_addr_len;
PRINTF("sal_recv_task starting... \r\n");
while(1)
{
for(i=0; i<CONN_LIST_MAX; i++)
{
if(sock_list[i].qcom_socket > 0)
{
sock = sock_list[i].qcom_socket;
QCA_CONTEXT_STRUCT *enetCtx = wlan_get_context();
switch(t_select(enetCtx, sock, QCOM_SELECT_TIMEOUT))
{
case A_SOCK_INVALID: /* socket err */
PRINTF("CLOSE BY REMOTE\r\n");
remove_sock_form_list_by_qsock(sock);
continue;
case A_OK:
recv_buf = NULL;
rev_len = qcom_recvfrom(sock, &recv_buf, 1400, 0, (struct sockaddr *)&r_addr, &r_addr_len);
if(rev_len >= 0)
{
fd = socket_to_fd(sock);
PRINTF("qcom_recvfrom get data %d, fd = %d, sock = %d\r\n", rev_len, fd, sock);
g_netconn_data_input_cb(fd, recv_buf, rev_len, NULL, 0);
zero_copy_free(recv_buf);
continue;
}
break;
case A_ERROR: /* timeout */
continue;
default:
break;
}
}
}
A_MDELAY(1);
}
}
static ktask_t *g_sal_task = NULL;
sal_op_t gt202_sal_op;
#define WIFI_SAL_STACK_SIZE 256
int gt202_sal_init()
{
kstat_t status;
int i = 0;
gt202_sal_op.version = "1.0.0";
gt202_sal_op.init = sal_qcom_init;
gt202_sal_op.start = sal_qcom_start;
gt202_sal_op.send = sal_qcom_send;
gt202_sal_op.deinit = sal_qcom_deinit;
gt202_sal_op.close = sal_qcom_close;
gt202_sal_op.domain_to_ip = sal_qcom_domain_to_ip;
gt202_sal_op.register_netconn_data_input_cb = sal_qcom_register_netconn_data_input_cb;
PRINTF("gt202_sal_init\r\n");
while (i < CONN_LIST_MAX) {
sock_list[i].fd = -1;
sock_list[i].qcom_socket = -1;
i++;
}
status = krhino_task_dyn_create(&g_sal_task, "WIFI SAL", 0, (AOS_DEFAULT_APP_PRI - 9), 0,
WIFI_SAL_STACK_SIZE, (task_entry_t)sal_recv_task, 1);
if(status != RHINO_SUCCESS)
{
PRINTF("WIFI SAL Task creation failed %d\r\n", status);
return 1;
}
sal_module_register(&gt202_sal_op);
return 0;
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _ATCMD_CONFIG_MODULE
#define _ATCMD_CONFIG_MODULE
#include <hal/soc/soc.h>
/**
* AT related platform-dependent things are here, including:
* 1. AT command;
* 2. AT response code;
* 3. AT delimiter;
* 4. AT event;
* 5. Uart port used by AT;
* 6. ...
*/
// AT command
#define AT_CMD_ENET_SEND "AT+ENETRAWSEND"
#define AT_CMD_ENTER_ENET_MODE "AT+ENETRAWMODE=ON"
#define AT_CMD_EHCO_OFF "AT+UARTE=OFF"
#define AT_CMD_TEST "AT"
// Delimiter
#define AT_RECV_PREFIX "\r\n"
#define AT_RECV_SUCCESS_POSTFIX "OK\r\n"
#define AT_RECV_FAIL_POSTFIX "ERROR\r\n"
#define AT_SEND_DELIMITER "\r"
// AT event
#define AT_EVENT_ENET_DATA "+ENETEVENT:"
// uart config
#define AT_UART_BAUDRATE 115200
#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT
#define AT_UART_PARITY NO_PARITY
#define AT_UART_STOP_BITS STOP_BITS_1
#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED
#define AT_UART_MODE MODE_TX_RX
#endif

View file

@ -0,0 +1,786 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <aos/aos.h>
#include <hal/hal.h>
#include <atparser.h>
#include <sal.h>
#define TAG "sal_wifi"
#define CMD_SUCCESS_RSP "OK"
#define CMD_FAIL_RSP "ERROR"
#define MAX_DATA_LEN 4096
#define MAX_DOMAIN_LEN 256
#define DATA_LEN_MAX 10
#define LINK_ID_MAX 5
#define STOP_CMD "AT+CIPSTOP"
#define STOP_CMD_LEN (sizeof(STOP_CMD)+1+1+5+1)
#define STOP_AUTOCONN_CMD "AT+CIPAUTOCONN"
#define STOP_AUTOCONN_CMD_LEN (sizeof(STOP_AUTOCONN_CMD)+1+1+5+1)
#define AT_RESET_CMD "AT"
typedef int (*at_data_check_cb_t)(char data);
/* Change to include data slink for each link id respectively. <TODO> */
typedef struct link_s {
int fd;
aos_sem_t sem_start;
aos_sem_t sem_close;
} link_t;
static link_t g_link[LINK_ID_MAX];
static aos_mutex_t g_link_mutex;
static netconn_data_input_cb_t g_netconn_data_input_cb;
static char localipaddr[16];
static void handle_tcp_udp_client_conn_state(uint8_t link_id)
{
char s[32] = {0};
at.read(s, 6);
if (strstr(s, "CLOSED") != NULL) {
LOGI(TAG, "Server closed event.");
if (aos_sem_is_valid(&g_link[link_id].sem_close)) {
LOGD(TAG, "sem is going to be waked up: 0x%x", &g_link[link_id].sem_close);
aos_sem_signal(&g_link[link_id].sem_close); // wakeup send task
}
LOGI(TAG, "Server conn (%d) closed.", link_id);
} else if (strstr(s, "CONNEC") != NULL){
LOGI(TAG, "Server conn (%d) successful.", link_id);
at.read(s, 3);
if (aos_sem_is_valid(&g_link[link_id].sem_start)) {
LOGD(TAG, "sem is going to be waked up: 0x%x", &g_link[link_id].sem_start);
aos_sem_signal(&g_link[link_id].sem_start); // wakeup send task
}
} else if (strstr(s, "DISCON") != NULL) {
LOGI(TAG, "Server conn (%d) disconnected.", link_id);
at.read(s, 6);
} else {
LOGW(TAG, "No one handle this unkown event!!!");
}
}
static void handle_client_conn_state()
{
}
static int socket_data_len_check(char data)
{
if (data > '9' || data < '0') {
return -1;
}
return 0;
}
static int socket_ip_info_check(char data)
{
if ((data > '9' || data < '0') && data != '.') {
return -1;
}
return 0;
}
static int socket_data_info_get(char *buf, uint32_t buflen, at_data_check_cb_t valuecheck)
{
uint32_t i = 0;
if (NULL == buf || 0 ==buflen){
return -1;
}
do {
at.read(&buf[i], 1);
if (buf[i] == ',') {
buf[i] = 0;
break;
}
if (i >= buflen) {
LOGE(TAG, "Too long length of data.reader is %s \r\n", buf);
return -1;
}
if (NULL != valuecheck){
if (valuecheck(buf[i])){
LOGE(TAG, "Invalid string!!!, reader is %s \r\n", buf);
return -1;
}
}
i++;
} while (1);
return 0;
}
static void handle_socket_data()
{
int link_id = 0;
int ret = 0;
uint32_t len = 0;
char reader[16] = {0};
char *recvdata = NULL;
/* Eat the "OCKET," */
at.read(reader, 6);
if (memcmp(reader, "OCKET,", strlen("OCKET,")) != 0) {
LOGE(TAG, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x invalid event format!!!\r\n",
reader[0], reader[1], reader[2], reader[3], reader[4], reader[5]);
return;
}
memset(reader, 0, sizeof(reader));
ret = socket_data_info_get(reader, 1, &socket_data_len_check);
if (ret){
LOGE(TAG, "Invalid link id 0x%02x !!!\r\n", reader[0]);
return;
}
link_id = reader[0] - '0';
memset(reader, 0, sizeof(reader));
/* len */
ret = socket_data_info_get(reader, sizeof(reader), &socket_data_len_check);
if (ret){
LOGE(TAG, "Invalid datalen %s !!!\r\n", reader);
return;
}
len = atoi(reader);
if (len > MAX_DATA_LEN){
LOGE(TAG, "invalid input socket data len %d \r\n", len);
return;
}
/* Prepare socket data */
recvdata = (char *)aos_malloc(len + 1);
if (!recvdata) {
LOGE(TAG, "Error: %s %d out of memory, len is %d. \r\n", __func__, __LINE__, len);
return;
}
at.read(recvdata, len);
recvdata[len] = '\0';
LOGD(TAG, "The socket data is %s", recvdata);
if (g_netconn_data_input_cb && (g_link[link_id].fd >= 0)){
/* TODO get recv data src ip and port*/
if (g_netconn_data_input_cb(g_link[link_id].fd, recvdata, len, NULL, 0)){
LOGE(TAG, " %s socket %d get data len %d fail to post to sal, drop it\n",
__func__, g_link[link_id].fd, len);
}
}
LOGD(TAG, "%s socket data on link %d with length %d posted to sal\n",
__func__, link_id, len);
aos_free(recvdata);
}
static void handle_udp_broadcast_data()
{
uint32_t len = 0;
uint32_t remoteport = 0;
int32_t linkid = 0;
int32_t ret = 0;
char reader[16] = {0};
char ipaddr[16] = {0};
char *recvdata = NULL;
/* Eat the "DP_BROADCAST," */
at.read(reader, 13);
if (memcmp(reader, "DP_BROADCAST,", strlen("DP_BROADCAST,")) != 0) {
LOGE(TAG, "%s invalid event format!!!\r\n",
reader[0], reader[1], reader[2], reader[3], reader[4], reader[5]);
return;
}
/* get ip addr */
ret = socket_data_info_get(ipaddr, sizeof(ipaddr), &socket_ip_info_check);
if (ret){
LOGE(TAG, "Invalid ip addr %s !!!\r\n", ipaddr);
return;
}
LOGD(TAG, "get broadcast form ip addr %s \r\n", ipaddr);
/* get ip port */
memset(reader, 0, sizeof(reader));
ret = socket_data_info_get(reader, sizeof(reader), &socket_data_len_check);
if (ret){
LOGE(TAG, "Invalid ip addr %s !!!\r\n", reader);
return;
}
LOGD(TAG, "get broadcast form ip port %s \r\n", reader);
remoteport = atoi(reader);
memset(reader, 0, sizeof(reader));
ret = socket_data_info_get(reader, 1, &socket_data_len_check);
if (ret){
LOGE(TAG, "Invalid link id 0x%02x !!!\r\n", reader[0]);
return;
}
linkid = reader[0] - '0';
LOGD(TAG, "get udp broadcast linkid %d \r\n", linkid);
/* len */
memset(reader, 0, sizeof(reader));
ret = socket_data_info_get(reader, sizeof(reader), &socket_data_len_check);
if (ret){
LOGE(TAG, "Invalid datalen %s !!!\r\n", reader);
return;
}
len = atoi(reader);
if (len > MAX_DATA_LEN){
LOGE(TAG, "invalid input socket data len %d \r\n", len);
return;
}
/* Prepare socket data */
recvdata = (char *)aos_malloc(len + 1);
if (!recvdata) {
LOGE(TAG, "Error: %s %d out of memory, len is %d. \r\n", __func__, __LINE__, len);
return;
}
at.read(recvdata, len);
recvdata[len] = '\0';
if (strcmp(ipaddr, localipaddr) != 0) {
if (g_netconn_data_input_cb && (g_link[linkid].fd >= 0)){
if (g_netconn_data_input_cb(g_link[linkid].fd, recvdata, len, ipaddr, remoteport)){
LOGE(TAG, " %s socket %d get data len %d fail to post to sal, drop it\n",
__func__, g_link[linkid].fd, len);
}
}
} else {
LOGD(TAG, "drop broadcast packet len %d \r\n", len);
}
aos_free(recvdata);
}
static void mk3060_get_local_ip_addr()
{
int ret = 0;
hal_wifi_ip_stat_t ip_stat = {0};
at_wevent_handler(NULL, NULL, 0);
ret = hal_wifi_get_ip_stat(NULL, &ip_stat, STATION);
if (ret){
printf("fail to get local ip addr \r\n");
return ;
}
LOGD(TAG, "local ip is %s \r\n", ip_stat.ip);
strcpy(localipaddr, ip_stat.ip);
}
/*
* Wifi station event handler. include:
* +WEVENT:AP_UP
* +WEVENT:AP_DOWN
* +WEVENT:STATION_UP
* +WEVENT:STATION_DOWN
*/
static void mk3060wifi_event_handler(void *arg, char *buf, int buflen)
{
char eventhead[4] = {0};
char eventotal[16] = {0};
at.read(eventhead, 3);
if (strcmp(eventhead, "AP_") == 0) {
at.read(eventotal, 2);
if (strcmp(eventotal, "UP") == 0){
} else if (strcmp(eventotal, "DO") == 0){
/*eat WN*/
at.read(eventotal, 2);
} else {
LOGE(TAG, "!!!Error: wrong WEVENT AP string received. %s\r\n", eventotal);
return;
}
}else if (strcmp(eventhead, "STA") == 0){
at.read(eventotal, 7);
if (strcmp(eventotal, "TION_UP") == 0){
aos_loop_schedule_work(0, mk3060_get_local_ip_addr, NULL, NULL, NULL);
} else if (strcmp(eventotal, "TION_DO") == 0){
/*eat WN*/
at.read(eventotal, 2);
memset(localipaddr, 0, sizeof(localipaddr));
} else {
LOGE(TAG, "!!!Error: wrong WEVENT STATION string received. %s\r\n", eventotal);
return;
}
}else {
LOGE(TAG, "!!!Error: wrong WEVENT string received. %s\r\n", eventhead);
return;
}
return;
}
/**
* Network connection state event handler. Events includes:
* 1. +CIPEVENT:id,SERVER,CONNECTED
* 2. +CIPEVENT:id,SERVER,CLOSED
* 3. +CIPEVENT:CLIENT,CONNECTED,ip,port
* 4. +CIPEVENT:CLIENT,CLOSED,ip,port
* 5. +CIPEVENT:id,UDP,CONNECTED
* 6. +CIPEVENT:id,UDP,CLOSED
* 7. +CIPEVENT:SOCKET,id,len,data
* 8. +CIPEVENT:UDP_BROADCAST,ip,port,id,len,data
*/
static void net_event_handler(void *arg, char *buf, int buflen)
{
char c;
char s[32] = {0};
LOGD(TAG, "%s entry.", __func__);
at.read(&c, 1);
if (c >= '0' && c < ('0' + LINK_ID_MAX)) {
int link_id = c - '0';
at.read(&c, 1);
if (c != ',') {
LOGE(TAG, "!!!Error: wrong CIPEVENT string. 0x%02x\r\n", c);
return;
}
at.read(&c, 1);
if (c == 'S') {
LOGD(TAG, "%s server conn state event, linkid: %d.", __func__, link_id);
/* Eat the "ERVER," */
at.read(s, 6);
if (memcmp(s, "ERVER,", strlen("ERVER,")) != 0) {
LOGE(TAG, "invalid event format 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
s[0], s[1], s[2], s[3], s[4], s[5]);
return;
}
handle_tcp_udp_client_conn_state(link_id);
} else if (c == 'U') {
LOGD(TAG, "%s UDP conn state event.", __func__);
/* Eat the "DP," */
at.read(s, 3);
if (memcmp(s, "DP,", strlen("DP,")) != 0) {
LOGE(TAG, "%s invalid event format 0x%02x 0x%02x 0x%02x \r\n", __FUNCTION__, s[0], s[1], s[2]);
return;
}
handle_tcp_udp_client_conn_state(link_id);
} else {
LOGE(TAG, "!!!Error: wrong CIPEVENT string 0x%02x at line %d\r\n", c, __LINE__);
return ;
}
} else if (c == 'S') {
LOGD(TAG, "%s socket data event.", __func__);
handle_socket_data();
} else if (c == 'C') {
LOGD(TAG, "%s client conn state event.", __func__);
handle_client_conn_state();
} else if (c == 'U') {
LOGD(TAG, "%s udp broadcast data event.", __func__);
handle_udp_broadcast_data();
}
else {
LOGE(TAG, "!!!Error: wrong CIPEVENT string received. 0x%02x\r\n", c);
return;
}
LOGD(TAG, "%s exit.", __func__);
}
// turn off AT echo
static void mk3060_uart_echo_off()
{
char out[64] = {0};
at.send_raw(AT_CMD_EHCO_OFF, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGE(TAG, "%s %d failed", __func__, __LINE__);
}
return;
}
static uint8_t inited = 0;
#define NET_OOB_PREFIX "+CIPEVENT:"
#define WIFIEVENT_OOB_PREFIX "+WEVENT:"
static int sal_wifi_init(void)
{
int link;
char cmd[STOP_AUTOCONN_CMD_LEN] = {0};
char out[64] = {0};
if (inited) {
LOGW(TAG, "sal component is already initialized");
return 0;
}
if (0 != aos_mutex_new(&g_link_mutex)) {
LOGE(TAG, "Creating link mutex failed (%s %d).", __func__, __LINE__);
return -1;
}
mk3060_uart_echo_off();
memset(g_link, 0, sizeof(g_link));
for (link = 0; link < LINK_ID_MAX; link++) {
g_link[link].fd = -1;
/*close all link */
snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link);
LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
at.send_raw(cmd, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGD(TAG, "%s %d failed", __func__, __LINE__);
//return -1;
}
memset(cmd, 0, sizeof(cmd));
/*close all link auto reconnect */
snprintf(cmd, STOP_AUTOCONN_CMD_LEN - 1, "%s=%d,0", STOP_AUTOCONN_CMD, link);
LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
at.send_raw(cmd, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGE(TAG, "%s %d failed", __func__, __LINE__);
//return -1;
}
memset(cmd, 0, sizeof(cmd));
}
at.oob(NET_OOB_PREFIX, NULL, 0, net_event_handler, NULL);
at.oob(WIFIEVENT_OOB_PREFIX, NULL, 0, mk3060wifi_event_handler, NULL);
inited = 1;
return 0;
}
static int sal_wifi_deinit(void)
{
if (!inited) return 0;
// at.exitoob(NET_OOB_PREFIX); // <TODO>
aos_mutex_free(&g_link_mutex);
return 0;
}
#define START_CMD "AT+CIPSTART"
#define START_CMD_LEN (sizeof(START_CMD)+1+1+13+1+MAX_DOMAIN_LEN+1+5+1+5+1)
static char *start_cmd_type_str[] = {"tcp_server", "tcp_client", \
"ssl_client", "udp_broadcast", "udp_unicast"};
int sal_wifi_start(sal_conn_t *c)
{
int link_id;
char cmd[START_CMD_LEN] = {0};
char out[256] = {0};
if (!c || !c->addr) {
LOGE(TAG, "%s %d - invalid argument", __func__, __LINE__);
return -1;
}
if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "Failed to lock mutex (%s).", __func__);
return -1;
}
for (link_id = 0; link_id < LINK_ID_MAX; link_id++) {
if (g_link[link_id].fd >= 0)
continue;
else {
g_link[link_id].fd = c->fd;
if (aos_sem_new(&g_link[link_id].sem_start, 0) != 0){
LOGE(TAG, "failed to allocate semaphore %s", __func__);
g_link[link_id].fd = -1;
return -1;
}
if (aos_sem_new(&g_link[link_id].sem_close, 0) != 0){
LOGE(TAG, "failed to allocate semaphore %s", __func__);
aos_sem_free(&g_link[link_id].sem_start);
g_link[link_id].fd = -1;
return -1;
}
break;
}
}
aos_mutex_unlock(&g_link_mutex);
// The caller should deal with this failure
if (link_id >= LINK_ID_MAX) {
LOGI(TAG, "No link available for now, %s failed.", __func__);
return -1;
}
LOGD(TAG, "Creating %s connection ...", start_cmd_type_str[c->type]);
switch (c->type) {
case TCP_SERVER:
snprintf(cmd, START_CMD_LEN - 1, "%s=%d,%s,%d,",
START_CMD, link_id, start_cmd_type_str[c->type], c->l_port);
break;
case TCP_CLIENT:
case SSL_CLIENT:
snprintf(cmd, START_CMD_LEN - 5 - 1, "%s=%d,%s,%s,%d",
START_CMD, link_id, start_cmd_type_str[c->type],
c->addr, c->r_port);
if (c->l_port >= 0)
snprintf(cmd + strlen(cmd), 7, ",%d", c->l_port);
break;
case UDP_BROADCAST:
case UDP_UNICAST:
snprintf(cmd, START_CMD_LEN - 1, "%s=%d,%s,%s,%d,%d",
START_CMD, link_id, start_cmd_type_str[c->type],
c->addr, c->r_port, c->l_port);
break;
default:
LOGE(TAG, "Invalid connection type.");
goto err;
}
LOGD(TAG, "\r\n%s %d - AT cmd to run: %s \r\n", __func__, __LINE__, cmd);
at.send_raw(cmd, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGE(TAG, "%s %d failed", __func__, __LINE__);
goto err;
}
if (aos_sem_wait(&g_link[link_id].sem_start, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "%s sem_wait failed", __func__);
goto err;
}
LOGD(TAG, "%s sem_wait succeed.", __func__);
return 0;
err:
if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "Failed to lock mutex (%s).", __func__);
return -1;
}
if (aos_sem_is_valid(&g_link[link_id].sem_start)){
aos_sem_free(&g_link[link_id].sem_start);
}
if (aos_sem_is_valid(&g_link[link_id].sem_close)){
aos_sem_free(&g_link[link_id].sem_close);
}
g_link[link_id].fd = -1;
aos_mutex_unlock(&g_link_mutex);
return -1;
}
static int fd_to_linkid(int fd)
{
int link_id;
if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "Failed to lock mutex (%s).", __func__);
return -1;
}
for (link_id = 0; link_id < LINK_ID_MAX; link_id++) {
if (g_link[link_id].fd == fd)
break;
}
aos_mutex_unlock(&g_link_mutex);
return link_id;
}
#define SEND_CMD "AT+CIPSEND"
#define SEND_CMD_LEN (sizeof(SEND_CMD)+1+1+5+1+DATA_LEN_MAX+1)
static int sal_wifi_send(int fd,
uint8_t *data,
uint32_t len,
char remote_ip[16],
int32_t remote_port,
int32_t timeout)
{
int link_id;
char cmd[SEND_CMD_LEN] = {0}, out[128] = {0};
if (!data) return -1;
LOGD(TAG, "%s on fd %d", __func__, fd);
link_id = fd_to_linkid(fd);
if (link_id >= LINK_ID_MAX) {
LOGE(TAG, "No connection found for fd (%d) in %s", fd, __func__);
return -1;
}
/* AT+CIPSEND=id, */
snprintf(cmd, SEND_CMD_LEN - 1, "%s=%d,", SEND_CMD, link_id);
/* [remote_port,] */
if (remote_port >= 0)
snprintf(cmd + strlen(cmd), 7, "%d,", remote_port);
/* data_length */
snprintf(cmd + strlen(cmd), DATA_LEN_MAX + 1, "%d", len);
LOGD(TAG, "\r\n%s %d - AT cmd to run: %s\r\n", __func__, __LINE__, cmd);
at.send_data_2stage((const char *)cmd, (const char *)data, len, out, sizeof(out));
LOGD(TAG, "\r\nThe AT response is: %s\r\n", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGD(TAG, "%s %d failed", __func__, __LINE__);
return -1;
}
return 0;
}
#define DOMAIN_RSP "+CIPDOMAIN:"
#define DOMAIN_CMD "AT+CIPDOMAIN"
#define DOMAIN_CMD_LEN (sizeof(DOMAIN_CMD)+MAX_DOMAIN_LEN+1)
/* Return the first IP if multiple found. */
static int sal_wifi_domain_to_ip(char *domain,
char ip[16])
{
char cmd[DOMAIN_CMD_LEN] = {0}, out[256] = {0}, *head, *end;
snprintf(cmd, DOMAIN_CMD_LEN - 1, "%s=%s", DOMAIN_CMD, domain);
LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
at.send_raw(cmd, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, at._default_recv_success_postfix) == NULL) {
LOGE(TAG, "%s %d failed", __func__, __LINE__);
return -1;
}
/**
* +CIPDOMAIN:1\r\n
* 180.97.33.108\r\n
*
* OK\r\n
*/
if ((head = strstr(out, DOMAIN_RSP)) == NULL) {
LOGE(TAG, "No IP info found in result string %s \r\n.", out);
return -1;
}
/* Check the format */
head += strlen(DOMAIN_RSP);
if (head[0] < '0' && head[0] >= ('0' + LINK_ID_MAX)){
LOGE(TAG, "%s %d failed", __func__, __LINE__);
goto err;
}
head++;
if (memcmp(head, at._default_recv_prefix, at._recv_prefix_len) != 0){
LOGE(TAG, "%s %d failed", __func__, __LINE__);
goto err;
}
/* We find the IP head */
head += at._recv_prefix_len;
end = head;
while (((end - head) < 15) && (*end != at._default_recv_prefix[0])) end++;
if (((end - head) < 6) || ((end -head) > 15)) goto err;
/* We find a good IP, save it. */
memcpy(ip, head, end - head);
ip[end-head] = '\0';
LOGD(TAG, "get domain %s ip %s \r\n", domain, ip);
return 0;
err:
LOGE(TAG, "Failed to get IP due to unexpected result string %s \r\n.", out);
return -1;
}
static int sal_wifi_close(int fd,
int32_t remote_port)
{
int link_id;
char cmd[STOP_CMD_LEN] = {0}, out[64];
link_id = fd_to_linkid(fd);
if (link_id >= LINK_ID_MAX) {
LOGE(TAG, "No connection found for fd (%d) in %s", fd, __func__);
return -1;
}
snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link_id);
LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd);
at.send_raw(cmd, out, sizeof(out));
LOGD(TAG, "The AT response is: %s", out);
if (strstr(out, CMD_FAIL_RSP) != NULL) {
LOGE(TAG, "%s %d failed", __func__, __LINE__);
goto err;
}
if (aos_sem_wait(&g_link[link_id].sem_close, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "%s sem_wait failed", __func__);
goto err;
}
LOGD(TAG, "%s sem_wait succeed.", __func__);
err:
if (aos_mutex_lock(&g_link_mutex, AOS_WAIT_FOREVER) != 0) {
LOGE(TAG, "Failed to lock mutex (%s).", __func__);
return -1;
}
if (aos_sem_is_valid(&g_link[link_id].sem_start)){
aos_sem_free(&g_link[link_id].sem_start);
}
if (aos_sem_is_valid(&g_link[link_id].sem_close)){
aos_sem_free(&g_link[link_id].sem_close);
}
g_link[link_id].fd = -1;
aos_mutex_unlock(&g_link_mutex);
return -1;
}
static int mk3060_wifi_packet_input_cb_register(netconn_data_input_cb_t cb)
{
if (cb)
g_netconn_data_input_cb = cb;
return 0;
}
sal_op_t sal_op = {
.version = "1.0.0",
.init = sal_wifi_init,
.start = sal_wifi_start,
.send = sal_wifi_send,
.domain_to_ip = sal_wifi_domain_to_ip,
.close = sal_wifi_close,
.deinit = sal_wifi_deinit,
.register_netconn_data_input_cb = mk3060_wifi_packet_input_cb_register,
};
int mk3060_sal_init(void)
{
return sal_module_register(&sal_op);
}

View file

@ -0,0 +1,13 @@
NAME := device_sal_mk3060
$(NAME)_SOURCES += wifi_atcmd.c
GLOBAL_DEFINES += DEV_SAL_MK3060
$(NAME)_COMPONENTS += yloop
ifneq (1, $(at_adapter))
$(NAME)_COMPONENTS += sal atparser
$(NAME)_SOURCES += mk3060.c
endif
GLOBAL_INCLUDES += ./

View file

@ -0,0 +1,13 @@
src = Split('''
wifi_atcmd.c
mk3060.c
''')
component = aos_component('device_sal_mk3060', src)
component.add_comp_deps('framework/atparser')
component.add_comp_deps('kernel/yloop')
component.add_global_includes('.')
component.add_global_macros('DEV_SAL_MK3060')

View file

@ -0,0 +1,302 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hal/base.h>
#include <hal/wifi.h>
#include "atparser.h"
#define TAG "wifi_port"
#define AT_RSP_SUCCESS "OK"
#define AT_RSP_FAIL "ERROR"
static int get_mac_helper(char *mac);
static int get_ip_stat_helper(hal_wifi_ip_stat_t *result);
static void fetch_ip_stat(void *arg)
{
hal_wifi_ip_stat_t ip_stat = {0};
hal_wifi_module_t *m;
if (!arg) {
LOGE(TAG, "%s failed, invalid argument\r\n", __func__);
return;
}
m = (hal_wifi_module_t *)arg;
get_ip_stat_helper(&ip_stat);
if (m->ev_cb->ip_got != NULL) {
m->ev_cb->ip_got(m, &ip_stat, NULL);
}
}
void at_wevent_handler(void *arg, char *buf, int buflen)
{
hal_wifi_module_t *m;
if (NULL == arg){
m = hal_wifi_get_default_module();
} else {
m = (hal_wifi_module_t *)arg;
}
if (NULL == m) {
return;
}
if (m->ev_cb->stat_chg != NULL) {
m->ev_cb->stat_chg(m, NOTIFY_STATION_UP, NULL);
}
fetch_ip_stat(m);
}
static int wifi_init(hal_wifi_module_t *m)
{
LOGI(TAG, "wifi init success!!\n");
return 0;
};
#define MAC_STR_LEN 12
// str: char[12], mac: hex[6]
static void mac_str_to_hex(char *str, uint8_t *mac)
{
int i;
char c;
uint8_t j;
if (!str || !mac) return;
memset(mac, 0, MAC_STR_LEN >> 1);
for (i = 0; i < MAC_STR_LEN; i++) {
c = str[i];
if (c >= '0' && c <= '9') j = c - '0';
else if (c >= 'A' && c <= 'F') j = c - 'A' + 0xa;
else if (c >= 'a' && c <= 'f') j = c - 'a' + 0xa;
else j = c % 0xf;
j <<= i & 1 ? 0 : 4;
mac[i>>1] |= j;
}
}
// mac - hex[6]
static void wifi_get_mac_addr(hal_wifi_module_t *m, uint8_t *mac)
{
char mac_str[MAC_STR_LEN+1] = {0};
if (!mac) return;
(void)m;
LOGD(TAG, "wifi_get_mac_addr!!\n");
get_mac_helper(mac_str);
mac_str_to_hex(mac_str, mac);
LOGI(TAG, "mac in hex: %02x%02x%02x%02x%02x%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
};
#define AT_CMD_CONNECT_AP "AT+WJAP"
static int wifi_start(hal_wifi_module_t *m, hal_wifi_init_type_t *init_para)
{
char in[128] = {0};
char out[128] = {0};
(void)init_para;
if (strcmp(init_para->wifi_key, "open") == 0) {
snprintf(in, sizeof(in), AT_CMD_CONNECT_AP"=%s",
init_para->wifi_ssid);
} else {
snprintf(in, sizeof(in), AT_CMD_CONNECT_AP"=%s,%s",
init_para->wifi_ssid, init_para->wifi_key);
}
LOGI(TAG, "Will connect via at cmd: %s\r\n", in);
if (at.send_raw(in, out, sizeof(out)) == 0)
LOGI(TAG, "AT command %s succeed, rsp: %s\r\n", in, out);
else
LOGE(TAG, "AT command %s failed\r\n", in);
if (strstr(out, AT_RSP_FAIL)) {
LOGE(TAG, "Connect wifi failed\r\n");
return -1;
}
return 0;
}
static int wifi_start_adv(hal_wifi_module_t *m, hal_wifi_init_type_adv_t *init_para_adv)
{
(void)init_para_adv;
return 0;
}
#define AT_CMD_OBTAIN_MAC "AT+WMAC?"
// mac string, e.g. "BF01ADE2F5CE"
static int get_mac_helper(char *mac)
{
char out[128] = {0};
if (!mac) return -1;
if (at.send_raw(AT_CMD_OBTAIN_MAC, out, sizeof(out)) == 0) {
LOGI(TAG, "AT command %s succeed, rsp: %s", AT_CMD_OBTAIN_MAC, out);
} else {
LOGE(TAG, "AT command %s failed\r\n", AT_CMD_OBTAIN_MAC);
return -1;
}
if (strstr(out, AT_RSP_FAIL)) {
LOGE(TAG, "Command %s executed with ERROR.", AT_CMD_OBTAIN_MAC);
return -1;
}
sscanf(out, "%*[^:]:%[^\r]", mac);
LOGI(TAG, "mac result: %s\r\n", mac);
return 0;
}
#define AT_CMD_OBTAIN_IP "AT+WJAPIP?"
static int get_ip_stat_helper(hal_wifi_ip_stat_t *result)
{
char out[128] = {0};
int ret = 0;
if (!result) return -1;
if (at.send_raw(AT_CMD_OBTAIN_IP, out, sizeof(out)) == 0) {
LOGI(TAG, "AT command %s succeed, rsp: %s", AT_CMD_OBTAIN_IP, out);
} else {
LOGE(TAG, "AT command %s failed\r\n", AT_CMD_OBTAIN_IP);
return -1;
}
if (strstr(out, AT_RSP_FAIL)) {
LOGE(TAG, "Command %s executed with ERROR", AT_CMD_OBTAIN_IP);
return -1;
}
sscanf(out, "%*[^:]:%[^,],%[^,],%[^,],%[^\r]",
result->ip, result->mask, result->gate, result->dns);
LOGD(TAG, "result: %s %s %s %s\r\n",
result->ip, result->mask, result->gate, result->dns);
ret = get_mac_helper(result->mac);
return ret;
}
static int get_ip_stat(hal_wifi_module_t *m, hal_wifi_ip_stat_t *out_net_para, hal_wifi_type_t wifi_type)
{
(void)wifi_type;
(void)m;
get_ip_stat_helper(out_net_para);
return 0;
}
static int get_link_stat(hal_wifi_module_t *m, hal_wifi_link_stat_t *out_stat)
{
return 0;
}
static void start_scan(hal_wifi_module_t *m)
{
}
static void start_scan_adv(hal_wifi_module_t *m)
{
}
static int power_off(hal_wifi_module_t *m)
{
return 0;
}
static int power_on(hal_wifi_module_t *m)
{
return 0;
}
static int suspend(hal_wifi_module_t *m)
{
return 0;
}
static int suspend_station(hal_wifi_module_t *m)
{
return 0;
}
static int suspend_soft_ap(hal_wifi_module_t *m)
{
return 0;
}
static int set_channel(hal_wifi_module_t *m, int ch)
{
return 0;
}
static void start_monitor(hal_wifi_module_t *m)
{
}
static void stop_monitor(hal_wifi_module_t *m)
{
}
static void register_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn)
{
}
static void register_wlan_mgnt_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn)
{
}
static int wlan_send_80211_raw_frame(hal_wifi_module_t *m, uint8_t *buf, int len)
{
return 0;
}
hal_wifi_module_t aos_wifi_module_mk3060 = {
.base.name = "aos_wifi_module_mk3060",
.init = wifi_init,
.get_mac_addr = wifi_get_mac_addr,
.start = wifi_start,
.start_adv = wifi_start_adv,
.get_ip_stat = get_ip_stat,
.get_link_stat = get_link_stat,
.start_scan = start_scan,
.start_scan_adv = start_scan_adv,
.power_off = power_off,
.power_on = power_on,
.suspend = suspend,
.suspend_station = suspend_station,
.suspend_soft_ap = suspend_soft_ap,
.set_channel = set_channel,
.start_monitor = start_monitor,
.stop_monitor = stop_monitor,
.register_monitor_cb = register_monitor_cb,
.register_wlan_mgnt_monitor_cb = register_wlan_mgnt_monitor_cb,
.wlan_send_80211_raw_frame = wlan_send_80211_raw_frame
};