페이지 선택

MXOS HTTP APIs

 

MXOS provides a set of API functional interfaces for HTTP communication.

 

§ MXCHIP MXOS API Site 참조한다.

⊕ mxos-demos SDK를 참조한다.

 

 

 

 

1. HTTP API List

 

HTTP API Description
PrintHTTPHeader  
findHeader  
HTTPScanFHeaderValue  
findCRLF  
findChunkedDataLength  
SocketReadHTTPHeader  
SocketReadHTTPBody  
SocketReadHTTPSHeader  
SocketReadHTTPSBody  
HTTPHeaderParse  
HTTPHeaderMatchMethod  
HTTPHeaderMatchURL  
HTTPHeaderMatchPartialURL  
HTTPHeaderCreate  
HTTPHeaderCreateWithCallback  
HTTPHeaderClear  
HTTPHeaderDestory  
CreateSimpleHTTPOKMessage  
CreateSimpleHTTPMessage  
CreateSimpleHTTPMessageNoCopy  
CreateHTTPRespondMessageNoCopy  
CreateHTTPMessage  
CreateHTTPMessageWithHost  

 

 

 

 

 

2. Example

 

 

 

http_client.c

 

Implementation: After the device is equipped with the network, you can access Baidu’s web page information. code show as below:

 

#include "mxos.h"
#include "HTTPUtils.h"
#include "SocketUtils.h"
#include "StringUtils.h"

#define http_client_log(M, ...) custom_log("HTTP", M, ##__VA_ARGS__)

static OSStatus onReceivedData( struct _HTTPHeader_t * httpHeader,
                                uint32_t pos,
                                uint8_t *data,
                                size_t len,
                                void * userContext );
static void onClearData( struct _HTTPHeader_t * inHeader, void * inUserContext );

static mxos_semaphore_t wait_sem = NULL;

typedef struct _http_context_t
{
    char *content;
    uint64_t content_length;
} http_context_t;

void simple_http_get( char* host, char* query );
void simple_https_get( char* host, char* query );

#define SIMPLE_GET_REQUEST \
    "GET / HTTP/1.1\r\n" \
    "Host: www.baidu.com\r\n" \
    "Connection: close\r\n" \
    "\r\n"

static void mxosNotify_WifiStatusHandler( WiFiEvent status, void* const inContext )
{
    UNUSED_PARAMETER( inContext );
    switch ( status )
    {
        case NOTIFY_STATION_UP:
            mxos_rtos_set_semaphore( &wait_sem );
            break;
        case NOTIFY_STATION_DOWN:
            case NOTIFY_AP_UP:
            case NOTIFY_AP_DOWN:
            break;
    }
}

int application_start( void )
{
    OSStatus err = kNoErr;

    mxos_rtos_init_semaphore( &wait_sem, 1 );

    /*Register user function for mxos nitification: WiFi status changed */
    err = mxos_system_notify_register( mxos_notify_WIFI_STATUS_CHANGED,
                                       (void *) mxosNotify_WifiStatusHandler, NULL );
    require_noerr( err, exit );

    /* Start mxos system functions according to mxos_config.h */
    err = mxos_system_init( mxos_system_context_init( 0 ) );
    require_noerr( err, exit );

    /* Wait for wlan connection*/
    mxos_rtos_get_semaphore( &wait_sem, mxos_WAIT_FOREVER );
    http_client_log( "wifi connected successful" );

    /* Read http data from server */
    simple_http_get( "www.baidu.com", SIMPLE_GET_REQUEST );
    simple_https_get( "www.baidu.com", SIMPLE_GET_REQUEST );

    exit:
    mxos_rtos_delete_thread( NULL );
    return err;
}

void simple_http_get( char* host, char* query )
{
    OSStatus err;
    int client_fd = -1;
    fd_set readfds;
    char ipstr[16];
    struct sockaddr_in addr;
    HTTPHeader_t *httpHeader = NULL;
    http_context_t context = { NULL, 0 };
    struct hostent* hostent_content = NULL;
    char **pptr = NULL;
    struct in_addr in_addr;

    hostent_content = gethostbyname( host );
    require_action_quiet( hostent_content != NULL, exit, err = kNotFoundErr);
    pptr=hostent_content->h_addr_list;
    in_addr.s_addr = *(uint32_t *)(*pptr);
    strcpy( ipstr, inet_ntoa(in_addr));
    http_client_log("HTTP server address: %s, host ip: %s", host, ipstr);

    /*HTTPHeaderCreateWithCallback set some callback functions */
    httpHeader = HTTPHeaderCreateWithCallback( 1024, onReceivedData, onClearData, &context );
    require_action( httpHeader, exit, err = kNoMemoryErr );

    client_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    addr.sin_family = AF_INET;
    addr.sin_addr = in_addr;
    addr.sin_port = htons(80);
    err = connect( client_fd, (struct sockaddr *)&addr, sizeof(addr) );
    require_noerr_string( err, exit, "connect http server failed" );

    /* Send HTTP Request */
    send( client_fd, query, strlen( query ), 0 );

    FD_ZERO( &readfds );
    FD_SET( client_fd, &readfds );

    select( client_fd + 1, &readfds, NULL, NULL, NULL );
    if ( FD_ISSET( client_fd, &readfds ) )
    {
        /*parse header*/
        err = SocketReadHTTPHeader( client_fd, httpHeader );
        switch ( err )
        {
            case kNoErr:
                PrintHTTPHeader( httpHeader );
                err = SocketReadHTTPBody( client_fd, httpHeader );/*get body data*/
                require_noerr( err, exit );
                /*get data and print*/
                http_client_log( "Content Data: %s", context.content );
                break;
            case EWOULDBLOCK:
                case kNoSpaceErr:
                case kConnectionErr:
                default:
                http_client_log("ERROR: HTTP Header parse error: %d", err);
                break;
        }
    }

    exit:
    http_client_log( "Exit: Client exit with err = %d, fd: %d", err, client_fd );
    SocketClose( &client_fd );
    HTTPHeaderDestory( &httpHeader );
}

void simple_https_get( char* host, char* query )
{
    OSStatus err;
    int client_fd = -1;
    int ssl_errno = 0;
    mxos_ssl_t client_ssl = NULL;
    fd_set readfds;
    char ipstr[16];
    struct sockaddr_in addr;
    HTTPHeader_t *httpHeader = NULL;
    http_context_t context = { NULL, 0 };
    struct hostent* hostent_content = NULL;
    char **pptr = NULL;
    struct in_addr in_addr;

    hostent_content = gethostbyname( host );
    require_action_quiet( hostent_content != NULL, exit, err = kNotFoundErr);
    pptr = hostent_content->h_addr_list;
    in_addr.s_addr = *(uint32_t *)(*pptr);
    strcpy( ipstr, inet_ntoa(in_addr));
    http_client_log("HTTP server address: host:%s, ip: %s", host, ipstr);

    /*HTTPHeaderCreateWithCallback set some callback functions */
    httpHeader = HTTPHeaderCreateWithCallback( 1024, onReceivedData, onClearData, &context );
    require_action( httpHeader, exit, err = kNoMemoryErr );

    client_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    addr.sin_family = AF_INET;
    addr.sin_addr = in_addr;
    addr.sin_port = htons(443);
    err = connect( client_fd, ( struct sockaddr * )&addr, sizeof(addr) );
    require_noerr_string( err, exit, "connect http server failed" );

    ssl_set_client_version(TLS_V1_2_MODE);
    client_ssl = ssl_connect( client_fd, 0, NULL, &ssl_errno );
    require_string( client_ssl != NULL, exit, "ERROR: ssl disconnect" );

    /* Send HTTP Request */
    ssl_send( client_ssl, query, strlen( query ) );

    FD_ZERO( &readfds );
    FD_SET( client_fd, &readfds );

    select( client_fd + 1, &readfds, NULL, NULL, NULL );
    if ( FD_ISSET( client_fd, &readfds ) )
    {
        /*parse header*/
        err = SocketReadHTTPSHeader( client_ssl, httpHeader );
        switch ( err )
        {
            case kNoErr:
                PrintHTTPHeader( httpHeader );
                err = SocketReadHTTPSBody( client_ssl, httpHeader );/*get body data*/
                require_noerr( err, exit );
                /*get data and print*/
                http_client_log( "Content Data: %s", context.content );
                break;
            case EWOULDBLOCK:
                case kNoSpaceErr:
                case kConnectionErr:
                default:
                http_client_log("ERROR: HTTP Header parse error: %d", err);
                break;
        }
    }

    exit:
    http_client_log( "Exit: Client exit with err = %d, fd: %d", err, client_fd );
    if ( client_ssl ) ssl_close( client_ssl );
    SocketClose( &client_fd );
    HTTPHeaderDestory( &httpHeader );
}

/*one request may receive multi reply*/
static OSStatus onReceivedData( struct _HTTPHeader_t * inHeader, uint32_t inPos, uint8_t * inData,
                                size_t inLen, void * inUserContext )
{
    OSStatus err = kNoErr;
    http_context_t *context = inUserContext;
    if ( inHeader->chunkedData == false )
    { //Extra data with a content length value
        if ( inPos == 0 && context->content == NULL )
        {
            context->content = calloc( inHeader->contentLength + 1, sizeof(uint8_t) );
            require_action( context->content, exit, err = kNoMemoryErr );
            context->content_length = inHeader->contentLength;

        }
        memcpy( context->content + inPos, inData, inLen );
    } else
    { //extra data use a chunked data protocol
        http_client_log("This is a chunked data, %d", inLen);
        if ( inPos == 0 )
        {
            context->content = calloc( inHeader->contentLength + 1, sizeof(uint8_t) );
            require_action( context->content, exit, err = kNoMemoryErr );
            context->content_length = inHeader->contentLength;
        } else
        {
            context->content_length += inLen;
            context->content = realloc( context->content, context->content_length + 1 );
            require_action( context->content, exit, err = kNoMemoryErr );
        }
        memcpy( context->content + inPos, inData, inLen );
    }

    exit:
    return err;
}

/* Called when HTTPHeaderClear is called */
static void onClearData( struct _HTTPHeader_t * inHeader, void * inUserContext )
{
    UNUSED_PARAMETER( inHeader );
    http_context_t *context = inUserContext;
    if ( context->content )
    {
        free( context->content );
        context->content = NULL;
    }
}

 

 

 

 

이상 끝 —

Viewed Page List