예제 #1
0
wiced_result_t wiced_tcp_stream_deinit( wiced_tcp_stream_t* tcp_stream )
{
    /* Flush the TX */
    wiced_tcp_stream_flush( tcp_stream );

    /* Flush the RX */
    if ( tcp_stream->rx_packet != NULL )
    {
        wiced_packet_delete( tcp_stream->rx_packet );
        tcp_stream->rx_packet = NULL;
    }
    tcp_stream->tx_packet = NULL;
    tcp_stream->rx_packet = NULL;
    tcp_stream->socket    = NULL;

    return WICED_TCPIP_SUCCESS;
}
예제 #2
0
int platform_network_write(Network* n, unsigned char* buffer, int length, int timeout)
{
    wiced_result_t rc = wiced_tcp_stream_write(&n->stream, buffer, length);
    if (rc != WICED_SUCCESS)
    {
        platform_printf("unable to write data to tcp stream, rc = %d\n", rc);
        return -1;
    }

    rc = wiced_tcp_stream_flush(&n->stream);
    if (rc != WICED_SUCCESS)
    {
        platform_printf("unable to flush tcp stream, rc = %d\n", rc);
        return -1;
    }

    //platform_printf("%s: successfully sent %d bytes to tcp stream\n", __func__, length);

    return length;
}
예제 #3
0
wiced_result_t xively_flush_datastream( xively_datastream_t* stream )
{
    wiced_packet_t* response_packet;

    WICED_VERIFY( wiced_tcp_stream_flush( &stream->tcp_stream ) );

    /* Receive and free response packet */
    if ( wiced_tcp_receive( stream->tcp_stream.socket, &response_packet, 3000 ) == WICED_SUCCESS )
    {
        uint8_t* data;
        uint16_t data_length;
        uint16_t available_data_length;
        char* is_ok_found;

        /* Parse HTTP response.  */
        wiced_packet_get_data( response_packet, 0, &data, &data_length, &available_data_length );

        /* Ensure that packet payload is NUL-terminated */
        *( data + data_length - 1 ) = 0;

        /* Find OK. Returns NULL of not found */
        is_ok_found = strstr( (char*) data, (char*) "OK" );

        wiced_packet_delete( response_packet );

        /* OK found. */
        if ( is_ok_found != NULL )
        {
            return WICED_SUCCESS;
        }

        /* If Not OK, assert flag to perform DNS query in the next data sending */
        is_ip_address_resolved = WICED_FALSE;
    }

    return WICED_ERROR;
}
// The nonsecure server thread
static void tcp_server_nonsecure_thread_main(wiced_thread_arg_t arg)
{
    wiced_result_t result;
    wiced_tcp_stream_t stream;                      // The TCP stream
    wiced_tcp_socket_t socket;
    uint8_t rbuffer[MAX_LEGAL_MSG];

    char returnMessage[128]; // better use less than 128 bytes
    // setup the server by creating the socket and hooking it to the correct TCP Port
    result = wiced_tcp_create_socket(&socket, INTERFACE);
    if(WICED_SUCCESS != result)
    {
        WPRINT_APP_INFO(("Create socket failed\n"));
        return; // this is a bad outcome
    }

    wiced_tcp_stream_init(&stream,&socket);
    if(WICED_SUCCESS != result)
    {
        WPRINT_APP_INFO(("Init stream failed\n"));
        return; // this is a bad outcome
    }

    result = wiced_tcp_listen( &socket, TCP_SERVER_NONSECURE_LISTEN_PORT );
    if(WICED_SUCCESS != result)
    {
        WPRINT_APP_INFO(("Listen socket failed\n"));
        return;
    }


    while (1 )
    {

        result = wiced_tcp_accept( &socket ); // this halts the thread until there is a connection

        if(result != WICED_SUCCESS) // this occurs if the accept times out
            continue;

        nonsecureConnectionCount += 1;

        /// Figure out which client is talking to us... and on which port
        wiced_ip_address_t peerAddress;
        uint16_t	peerPort;
        wiced_tcp_server_peer(&socket,&peerAddress,&peerPort);

        uint32_t dataReadCount;
        wiced_tcp_stream_read_with_count(&stream,&rbuffer,MAX_LEGAL_MSG,100,&dataReadCount); // timeout in 100 ms

        processClientCommand(rbuffer, dataReadCount ,returnMessage);

        displayResult(peerAddress,peerPort,returnMessage);


        // send response and close things up
        wiced_tcp_stream_write(&stream,returnMessage,strlen(returnMessage));
        wiced_tcp_stream_flush(&stream);
        wiced_tcp_disconnect(&socket); // disconnect the connection

        wiced_tcp_stream_deinit(&stream); // clear the stream if any crap left
        wiced_tcp_stream_init(&stream,&socket); // setup for next connection

    }
}
예제 #5
0
wiced_result_t open_websocket(websocket_handshake_t *hs, websocket_msg_handler_t binary_msg_handler, websocket_msg_handler_t text_msg_handler, void *ctx) {
    wiced_result_t ret;
    wiced_ip_address_t host_ip;
    wiced_tls_context_t tls_ctx;
    wiced_tcp_socket_t sock;
    wiced_tcp_stream_t stream;
    char *buf = NULL;
    uint32_t i;
    https_header_t *header;

    WPRINT_LIB_INFO( ("Starting WebSocket handshake to https://%s%s\n", hs->hostname, hs->path) );

    ret = wiced_hostname_lookup(hs->hostname, &host_ip, DNS_TIMEOUT);
    if (ret != WICED_SUCCESS) {
        WPRINT_LIB_INFO( ("DNS lookup failed for %s (err=%u)\n", hs->hostname, ret) );
        return ret;
    }

    wiced_tls_init_context(&tls_ctx, NULL, NULL);
    wiced_tcp_create_socket(&sock, WICED_STA_INTERFACE);
    wiced_tcp_enable_tls(&sock, &tls_ctx);

    {
        char ip_str[48];
        ip_to_str(&host_ip, ip_str);
        WPRINT_LIB_INFO( ("Establishing TLS connection to %s port %d\n", ip_str, HTTPS_PORT) );
    }

    ret = wiced_tcp_connect(&sock, &host_ip, HTTPS_PORT, HTTPS_CONNECT_TIMEOUT);
    if (ret != WICED_SUCCESS) {
        WPRINT_LIB_INFO( ("Failed to create TCP connection (err=%u)\n", ret) );
        wiced_tcp_delete_socket(&sock);
        return ret;
    }

    do {
        ret = wiced_tcp_stream_init(&stream, &sock);
        if (ret != WICED_SUCCESS) {
            WPRINT_LIB_INFO( ("Failed to initialize TCP stream (err=%u)\n", ret) );
            break;
        }

        buf = (char *)malloc(STREAM_BUF_SIZE);

        snprintf(buf, STREAM_BUF_SIZE, "GET %s HTTP/1.1\r\n", hs->path);
        WRITE_STREAM(stream, buf, ret);

        // Required headers.
        snprintf(buf, STREAM_BUF_SIZE,
                 "Host: %s\r\n" \
                 "Connection: upgrade\r\n" \
                 "Upgrade: websocket\r\n" \
                 "Sec-WebSocket-Key: %s\r\n" \
                 "Sec-WebSocket-Version: 13\r\n",
                 hs->hostname, hs->key);
        WRITE_STREAM(stream, buf, ret);

        // Additional headers.
        for (i = 0; i < hs->num_headers; i++) {
            header = &(hs->headers[i]);
            snprintf(buf, STREAM_BUF_SIZE, "%s: %s\r\n", header->name, header->value);
            WRITE_STREAM(stream, buf, ret);
        }

        if (i < hs->num_headers) {
            break;
        }

        strcpy(buf, "\r\n");
        WRITE_STREAM(stream, buf, ret);

        ret = wiced_tcp_stream_flush(&stream);
        if (ret != WICED_SUCCESS) {
            break;
        }

        ret = process_handshake_response(hs, &sock);

    } while (WICED_FALSE);

    if (buf) {
        free(buf);
    }

    wiced_tcp_stream_deinit(&stream);

    if (ret == WICED_SUCCESS) {
        WPRINT_LIB_INFO( ("WebSocket handshake OK\n") );
        process_frames(&sock, binary_msg_handler, text_msg_handler, ctx);
        WPRINT_LIB_INFO( ("Closing WebSocket.\n") );
    }
    else {
        WPRINT_LIB_INFO( ("WebSocket handshake failed (err=%u)\n", ret) );
    }

    wiced_tcp_disconnect(&sock);
    wiced_tcp_delete_socket(&sock);

    return ret;
}
예제 #6
0
wiced_result_t wiced_establish_websocket_handshake( wiced_websocket_t* websocket, wiced_websocket_handshake_fields_t* websocket_header_fields )
{
    wiced_tcp_stream_t stream;
    wiced_packet_t*                     tcp_reply_packet;
    uint16_t                            tcp_data_available;
    uint16_t                            total_received_bytes;
    uint8_t*                            received_handshake;

    /*Initialise the tcp stream*/
    wiced_tcp_stream_init(&stream, &websocket->socket);

    /*Initialise key array*/
    memset(websocket_key_base64,0x0,CLIENT_WEBSOCKET_BASE64_KEY_LENGTH);

    /*generate a unique websocket key to send to server as part of initial handshake*/
    WICED_VERIFY( wiced_generate_client_websocket_key( websocket_key_base64 ) );

    /*build the handshaking headers*/

    /*< GET /uri HTTP/1.1 >*/
    wiced_tcp_stream_write( &stream, "GET ",( uint16_t )strlen("GET ") );
    wiced_tcp_stream_write(&stream, websocket_header_fields->request_uri, ( uint16_t )strlen(websocket_header_fields->request_uri) );
    wiced_tcp_stream_write( &stream, " HTTP/1.1\r\n",( uint16_t )strlen(" HTTP/1.1\r\n") );

    /*< Host: ip1.ip2.ip3.ip4 >*/
    wiced_tcp_stream_write( &stream, "Host: ",( uint16_t )strlen("Host: ") );
    wiced_tcp_stream_write(&stream, websocket_header_fields->host, ( uint16_t )strlen(websocket_header_fields->host) );
    wiced_tcp_stream_write( &stream, "\r\n",( uint16_t )strlen("\r\n") );

    /*< Upgrade: websocket>*/
    wiced_tcp_stream_write(&stream, "Upgrade: websocket\r\n",( uint16_t )strlen("Upgrade: websocket\r\n") );

    /*< Connection: Upgrade >*/
    wiced_tcp_stream_write(&stream, "Connection: Upgrade\r\n",( uint16_t )strlen("Connection: Upgrade\r\n") );

    /*< Sec-WebSocket-Key: random_base4_value >*/
    wiced_tcp_stream_write(&stream, "Sec-WebSocket-Key: ",( uint16_t )strlen("Sec-WebSocket-Key: ") );
    wiced_tcp_stream_write(&stream, websocket_key_base64, ( uint16_t )strlen((char*)websocket_key_base64) );
    wiced_tcp_stream_write(&stream, "\r\n", ( uint16_t )strlen("\r\n") );

    /*< Origin: ip1.ip2.ip3.ip4 >*/
    wiced_tcp_stream_write(&stream, "Origin: ", ( uint16_t )strlen("Origin: ") );
    wiced_tcp_stream_write(&stream, websocket_header_fields->origin, ( uint16_t )strlen( websocket_header_fields->origin ) );
    wiced_tcp_stream_write(&stream, "\r\n",( uint16_t )strlen("\r\n") );

    /*The sec_websocket_protocol is optional, so check if it has been added, include in header if required*/
    if ( websocket_header_fields->sec_websocket_protocol != NULL)
    {
        /*< Sec-WebSocket-Protocol: server_understood_protocol >*/
        wiced_tcp_stream_write(&stream, "Sec-WebSocket-Protocol: ",( uint16_t )strlen("Sec-WebSocket-Protocol: ") );
        wiced_tcp_stream_write(&stream, websocket_header_fields->sec_websocket_protocol, ( uint16_t )strlen( websocket_header_fields->sec_websocket_protocol ) );
        wiced_tcp_stream_write(&stream, "\r\n",( uint16_t )strlen("\r\n") );
    }

    /*< Sec-WebSocket-Version: 13 >*/
    wiced_tcp_stream_write(&stream, "Sec-WebSocket-Version: 13\r\n\r\n",strlen("Sec-WebSocket-Version: 13\r\n\r\n") );

     /*send the handshake to server*/
    wiced_tcp_stream_flush( &stream );
    wiced_tcp_stream_deinit( &stream );

    WICED_VERIFY( wiced_tcp_receive( &websocket->socket, &tcp_reply_packet, WICED_WAIT_FOREVER ) );
    wiced_packet_get_data( tcp_reply_packet, 0, (uint8_t**)&received_handshake, &total_received_bytes, &tcp_data_available );

    WICED_VERIFY( wiced_verify_server_handshake( (char*)received_handshake ) );

    return WICED_SUCCESS;
}
예제 #7
0
static wiced_result_t process_request( ota_http_request_message_t* request, wiced_tcp_socket_t* socket, const ota_http_page_t* server_url_list )
{
    /* Search the url to find the question mark if there is one */
    int i = 0;
    wiced_tcp_stream_t stream;
    wiced_bool_t found = WICED_FALSE;

    /* Init the tcp stream */
    wiced_tcp_stream_init(&stream, socket);

    /* Search URL list to determine if request matches one of our pages */
    while ( server_url_list[i].ota_url != NULL )
    {
        /* Compare request to a path */
        if ( 0 == strncmp( server_url_list[i].ota_url, (const char*)request->url_ptr, request->url_length ) )
        {
            /* Matching path found */
            found = WICED_TRUE;
            /* Call the content handler function to write the page content into the packet and adjust the write pointers */
            switch (server_url_list[i].ota_url_content_type)
            {
                case OTA_DYNAMIC_URL_CONTENT:
                    write_reply_header(&stream, server_url_list[i].ota_mime_type, WICED_TRUE);
                    /* Fall through */
                case OTA_RAW_DYNAMIC_URL_CONTENT:
                    server_url_list[i].ota_url_content.ota_dynamic_data.generator( request, &stream, server_url_list[i].ota_url_content.ota_dynamic_data.arg );
                    wiced_tcp_stream_flush(&stream);
                    break;

                case OTA_STATIC_URL_CONTENT:
                    write_reply_header(&stream, server_url_list[i].ota_mime_type, WICED_FALSE);
                    /* Fall through */
                case OTA_RAW_STATIC_URL_CONTENT:
                    wiced_tcp_stream_write(&stream, server_url_list[i].ota_url_content.ota_static_data.ptr, server_url_list[i].ota_url_content.ota_static_data.length);
                    wiced_tcp_stream_flush(&stream);
                    break;
                case OTA_RESOURCE_URL_CONTENT:
                    write_reply_header(&stream, server_url_list[i].ota_mime_type, WICED_FALSE);
                    /* Fall through */
                case OTA_RAW_RESOURCE_URL_CONTENT:
                    wiced_tcp_stream_write_resource( &stream, server_url_list[i].ota_url_content.ota_resource_data );
                    wiced_tcp_stream_flush( &stream );
                    break;
                default:
                    wiced_assert("Unknown entry in URL list", 0 != 0 );
                    break;

            }
            break;
        }
        i++;
    }

    /* Check if page was not found */
    if ( found == WICED_FALSE )
    {
        /* Send back 404 */
        wiced_tcp_stream_write(&stream, not_found_header, sizeof(not_found_header)-1);
        wiced_tcp_stream_flush(&stream);
    }

    wiced_assert( "Page Serve finished with data still in stream", stream.tx_packet == NULL );

    return WICED_SUCCESS;
}
static void tcp_server_thread_main(wiced_thread_arg_t arg)
{
    wiced_bool_t wwepSecurity = (wiced_bool_t)arg;

    wiced_result_t result;
    wiced_tcp_stream_t stream;                      // The TCP stream
    wiced_tcp_socket_t socket;
    platform_dct_security_t *dct_security;
    wiced_tls_identity_t tls_identity;
    wiced_tls_context_t tls_context;
    uint8_t rbuffer[MAX_LEGAL_MSG];

    char returnMessage[128]; // better use less than 128 bytes
    // setup the server by creating the socket and hooking it to the correct TCP Port
    result = wiced_tcp_create_socket(&socket, INTERFACE);
    if(WICED_SUCCESS != result)
    {
        WPRINT_APP_INFO(("Create socket failed\n"));
        return; // this is a bad outcome
    }

    if(wwepSecurity == WICED_TRUE)
    {
        WPRINT_APP_INFO(("Starting secure\n"));

    }
    else
    {
        WPRINT_APP_INFO(("Starting non-secure\n"));
    }

    result = wiced_tcp_listen( &socket, (wwepSecurity == WICED_TRUE)?TCP_SERVER_SECURE_LISTEN_PORT:TCP_SERVER_NONSECURE_LISTEN_PORT );
    if(WICED_SUCCESS != result)
    {
        WPRINT_APP_INFO(("Listen socket failed\n"));
        return;
    }

    if(wwepSecurity == WICED_TRUE)
    {
        /* Lock the DCT to allow us to access the certificate and key */
        WPRINT_APP_INFO(( "Read the certificate Key from DCT\n" ));
        result = wiced_dct_read_lock( (void**) &dct_security, WICED_FALSE, DCT_SECURITY_SECTION, 0, sizeof( *dct_security ) );
        if ( result != WICED_SUCCESS )
        {
            WPRINT_APP_INFO(("Unable to lock DCT to read certificate\n"));
            return;
        }

        /* Setup TLS identity */
        result = wiced_tls_init_identity( &tls_identity, dct_security->private_key, strlen( dct_security->private_key ), (uint8_t*) dct_security->certificate, strlen( dct_security->certificate ) );
        if ( result != WICED_SUCCESS )
        {
            WPRINT_APP_INFO(( "Unable to initialize TLS identity. Error = [%d]\n", result ));
            return;
        }

    }
    else
    {
        wiced_tcp_stream_init(&stream,&socket);
        if(WICED_SUCCESS != result)
        {
            WPRINT_APP_INFO(("Init stream failed\n"));
            return; // this is a bad outcome
        }
    }

    while (1 )
    {
        if(wwepSecurity == WICED_TRUE)
        {
            result = wiced_tls_init_context( &tls_context, &tls_identity, NULL );
            if(result != WICED_SUCCESS)
            {
                WPRINT_APP_INFO(("Init context failed %d",result));
                return;
            }

            result = wiced_tcp_enable_tls(&socket,&tls_context);

            if(result != WICED_SUCCESS)
            {
                WPRINT_APP_INFO(("Enabling TLS failed %d",result));
                return;
            }

            wiced_tcp_stream_init(&stream,&socket);
            if(WICED_SUCCESS != result)
            {
                WPRINT_APP_INFO(("Init stream failed\n"));
                return; // this is a bad outcome
            }
        }

        result = wiced_tcp_accept( &socket ); // this halts the thread until there is a connection

        if(result != WICED_SUCCESS) // this occurs if the accept times out
            continue;

        if(wwepSecurity == WICED_TRUE)
            secureConnectionCount += 1;
        else
            nonsecureConnectionCount += 1;

        /// Figure out which client is talking to us... and on which port
        wiced_ip_address_t peerAddress;
        uint16_t	peerPort;
        wiced_tcp_server_peer(&socket,&peerAddress,&peerPort);

        uint32_t dataReadCount;
        wiced_tcp_stream_read_with_count(&stream,&rbuffer,MAX_LEGAL_MSG,100,&dataReadCount); // timeout in 100 ms
        processClientCommand(rbuffer, dataReadCount ,returnMessage);

        displayResult(peerAddress,peerPort,returnMessage);


        // send response and close things up
        wiced_tcp_stream_write(&stream,returnMessage,strlen(returnMessage));
        wiced_tcp_stream_flush(&stream);
        wiced_tcp_disconnect(&socket); // disconnect the connection

        if(wwepSecurity == WICED_TRUE)
        {
            wiced_tls_deinit_context(&tls_context);
        }

        wiced_tcp_stream_deinit(&stream); // clear the stream if any crap left
        wiced_tcp_stream_init(&stream,&socket); // setup for next connection

    }
}