全部文档
OneOS简介 硬件支持 快速开发指南 编译构造工具 API参考文档 高级语言 用户编程手册 OnePos定位 应用笔记 FAQ

Socket套件

简介

OneOS socket组件为用户提供了一套兼容BSD的标准接口,用来实现网络连接及数据传输,下层涵盖了以太模块、蜂窝模组和wifi模组等不同制式的通信介质以及不同的通信协议栈。以太模块使用lwip协议栈,蜂窝模组和wifi模组使用at指令进行拨号连接和数据收发。

使用限制:标准socket组件使用时lwip和at只能二选一,在编译配置时决定。

配置指南

step 1. 使能BSD socket API
(Top) → Components→ Network→ Socket
                             OneOS Configuration
[*] Enable BSD socket API
        protocol stack implement (Support OneOS modules stack)  --->
step 2. 根据项目需求配置是否启用POSIX
(Top) → Osal→ POSIX compatibility layer
                            OneOS Configuration
[ ] Enable pthreads
[*] Enable POSIX layer for poll/select, stdin etc
[ ]     Enable mmap
[ ]     Enable termios feature
[ ]     Enable aio

Enable POSIX layer for poll/select, stdin etc配置项影响select函数的实现,如果启用POSIX,select实现基于vfs的poll机制;如果不启用POSIX,select由molink或者lwip单独实现。

step 3. molink配置

以ESP8266配置举例,Enable * BSD Socket Operates必须启用

(Top) → Components → Network → Molink → Enable IoT modules support → Modules → WiFi Modules Support → ESP8266 → ESP8266 Config
                                OneOS Configuration
[*] Enable ESP8266 Module Object Auto Create
(uart2) ESP8266 Interface Device Name
(115200) ESP8266 Interface Device Rate
(512)   The maximum length of AT command data accepted
[*]     Enable ESP8266 Module Auto Connect
(hw_hsj) ESP8266 Connect AP SSID
(Aa123456) ESP8266 Connect AP Password
[*] Enable ESP8266 Module General Operates
-*- Enable ESP8266 Module WiFi Operates
[*] Enable ESP8266 Module Network Service Operates
-*- Enable ESP8266 Module Network TCP/IP Operates
[*] Enable ESP8266 Module BSD Socket Operates
step 4. lwip配置
(Top) → Components → Networ→ LwIP                                               
                                         OneOS Configuration
[*] Enable lwIP stack                                                           
        lwIP version (lwIP v2.1.2)  --->                                       
[*]     IGMP protocol (NEW)                                                     
[*]     ICMP protocol (NEW)                                                     
[ ]     SNMP protocol (NEW)                                                     
[*]     Enble DNS for name resolution (NEW)                                     
[*]     Enable alloc ip address through DHCP (NEW)                             
(1)         SOF broadcast (NEW)                                                 
(1)         SOF broadcast recv (NEW)                                           
[ ]     Enable DHCP server (NEW)                                               
        Static IPv4 Address  --->                                               
-*-     UDP protocol (NEW)                                                     
[*]     TCP protocol (NEW)                                                     
[ ]     RAW protocol (NEW)                                                     
[ ]     PPP protocol (NEW)                                                                      ||||

示例

包含标准的socket头文件即可,如

#include <atest.h>
#include <shell.h>
#include <os_kernel.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/socket.h>
#ifdef OS_USING_POSIX
#include <sys/select.h>
#endif
#include <os_mutex.h>
#include <os_dbg_ext.h>

os_task_t *gs_socket_select_task = OS_NULL;
int gs_select_fd = -1;
os_mutex_t *gs_socket_mutex = OS_NULL;

static void socket_dump_hex(const os_uint8_t *ptr, os_size_t buflen)
{
    unsigned char *buf;
    int i;
    int j;

    buf = (unsigned char *)ptr;

    for (i = 0; i < buflen; i += 16)
    {
        os_kprintf("%08X: ", i);

        for (j = 0; j < 16; j++)
        {
            if (i + j < buflen)
            {
                os_kprintf("%02X ", buf[i + j]);
            }
            else
            {
                os_kprintf("   ");
            }
        }

        os_kprintf("\n");
    }
}

static void socket_do_select_task(void *parm)
{
    os_uint8_t recv_buf[128];
    fd_set readfds;    
    fd_set exfds;
    int maxfd;
    int err;
    int fd;

    while (1)
    {
        os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
        if (gs_select_fd < 0)
        {
            os_mutex_unlock(gs_socket_mutex);
            os_task_sleep(100);

            continue;
        }

        fd = gs_select_fd;
        maxfd = fd + 1; 
        os_mutex_unlock(gs_socket_mutex);

        do
        {    
            FD_ZERO(&readfds);
            FD_SET(fd, &readfds);
            FD_ZERO(&exfds);
            FD_SET(fd, &exfds);

            err = select(maxfd, &readfds, OS_NULL, OS_NULL, OS_NULL);
            if (err > 0)
            {
                if (FD_ISSET(fd, &readfds))
                {
                    err = recv(fd, recv_buf, sizeof(recv_buf), 0);

                    os_kprintf("recv len[%d]\n", err);
                    if (err > 0)
                    {
                        socket_dump_hex(recv_buf, err);
                    }
                    else
                    {                        
                        os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
                        if(gs_select_fd >= 0)
                        {
                            closesocket(gs_select_fd);
                            gs_select_fd = -1;
                        }
                        os_mutex_unlock(gs_socket_mutex);
                        break;
                    }
                }
            }

            os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
            if (gs_select_fd != fd)
            {
                os_mutex_unlock(gs_socket_mutex);
                break;
            }
            os_mutex_unlock(gs_socket_mutex);
        } while (err >= 0);
        os_task_sleep(5);
    }
}

static int socket_cmd_select_init(void)
{
    if (OS_NULL == gs_socket_mutex)
    {
        gs_socket_mutex = os_mutex_create("slt_mtx", OS_IPC_FLAG_FIFO, OS_FALSE);
    }

    if (OS_NULL == gs_socket_mutex)
    {
        os_kprintf("mutex failed\n");
        return OS_ERROR;
    }

    if (OS_NULL == gs_socket_select_task)
    {
        gs_socket_select_task = os_task_create("slt_task", socket_do_select_task, 
                                OS_NULL, 1024, OS_TASK_PRIORITY_MAX - 5, 5);
        if (OS_NULL != gs_socket_select_task)
        {
            (void)os_task_startup(gs_socket_select_task);
        }
        else
        {
            os_kprintf("select task create failed\n");
            return OS_ERROR;
        }
    }

    return OS_EOK;
}

static int socket_cmd_socket_select(int argc, char **argv)
{
    struct sockaddr_in server_addr;
    char send_buf[] = "hello world";
    int type;
    int flag;
    int port;
    int err;

    if (argc != 5)
    {
        os_kprintf("Input errror, please input: socket_select flag ip port type\n");
        return OS_ERROR;
    }

    err = socket_cmd_select_init();
    if (OS_EOK != err)
    {
        os_kprintf("Do socket select init failed\n");
        return OS_ERROR;
    }

    flag = atoi(argv[1]);
    port = atoi(argv[3]);

    if (!strcmp(argv[4], "udp"))
    {
        type = SOCK_DGRAM;
    }
    else if (!strcmp(argv[4], "tcp"))
    {
        type = SOCK_STREAM;
    }
    else
    {
        type = SOCK_RAW;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = inet_addr(argv[2]); 

    if (!flag)
    {        
        os_kprintf("stop socket select fd = %d\n", gs_select_fd);
        os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
        if (gs_select_fd >= 0)
        {
            closesocket(gs_select_fd);
            gs_select_fd = -1;
        }        
        os_mutex_unlock(gs_socket_mutex);        
    }
    else
    { 
        os_mutex_lock(gs_socket_mutex, OS_IPC_WAITING_FOREVER);
        if (gs_select_fd >= 0)
        {
            os_mutex_unlock(gs_socket_mutex);
            os_kprintf("socket select fd = %d is already exist\n", gs_select_fd);
            return OS_EOK;
        }

        gs_select_fd = socket(AF_INET, type, 0);
        if (gs_select_fd < 0)
        {            
            os_mutex_unlock(gs_socket_mutex);
            os_kprintf("why socket failed = %d\n", gs_select_fd);
            return OS_ERROR;
        }

        err = connect(gs_select_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
        if (err < 0)
        {
            os_kprintf("connect socket =%d failed\n", gs_select_fd);
            closesocket(gs_select_fd);
            gs_select_fd = -1;         
            os_mutex_unlock(gs_socket_mutex);

            return OS_ERROR;
        }

        if (SOCK_DGRAM == type)
        {
            err = sendto(gs_select_fd, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));           
            os_kprintf("udp[fd = %d] send = %d\n", gs_select_fd, err);
        }        
        os_mutex_unlock(gs_socket_mutex);
    }

    return OS_EOK;
}

SH_CMD_EXPORT(socket_select, socket_cmd_socket_select, "socket_select 1/0 ipaddr port tcp/udp");

results matching ""

    No results matching ""

    返回顶部