Example #1
0
static wiced_result_t receive_data(wiced_tcp_socket_t *sock, uint32_t timeout, char **p_buf, uint32_t *len) {
    wiced_packet_t *packet;
    uint16_t data_offset;
    uint16_t data_len;
    uint16_t total_data_len;
    uint8_t *data;
    char *curr;

    WICED_VERIFY(wiced_tcp_receive(sock, &packet, timeout));

    data_offset = 0;
    wiced_packet_get_data(packet, data_offset, &data, &data_len, &total_data_len);

    *p_buf = (char *)malloc(sizeof(char) * ((size_t)total_data_len + 1));
    curr = *p_buf;
    memcpy(*p_buf, data, data_len);
    data_offset = (uint16_t)(data_offset + data_len);
    curr += data_len;

    while (data_len < total_data_len) {
        wiced_packet_get_data(packet, data_offset, &data, &data_len, &total_data_len);
        memcpy(curr, data, data_len);
        data_offset = (uint16_t)(data_offset + data_len);
        curr += data_len;
    }

    *curr = '\0';
    *len = total_data_len;

    wiced_packet_delete(packet);
    return WICED_SUCCESS;
}
Example #2
0
wiced_result_t wiced_tls_encrypt_packet( wiced_tls_context_t* context, wiced_packet_t* packet )
{
    uint8_t* data;
    uint16_t length;
    uint16_t available;
    wiced_result_t result;
    tls_record_t* record;

    wiced_packet_get_data(packet, 0, &data, &length, &available);
    data -= sizeof(tls_record_header_t);
    result = (wiced_result_t) tls_host_set_packet_start((tls_packet_t*)packet, data);
    if ( result != WICED_SUCCESS)
    {
        return result;
    }

    record                = (tls_record_t*) data;
    record->type          = SSL_MSG_APPLICATION_DATA;
    record->major_version = (uint8_t)context->major_ver;
    record->minor_version = (uint8_t)context->minor_ver;
    record->length        = htobe16( length );

    result = (wiced_result_t) tls_encrypt_record( context, record, length );
    if ( result != WICED_SUCCESS )
    {
        return result;
    }

    wiced_packet_set_data_end(packet, data + htobe16(record->length) + sizeof(tls_record_header_t));
    return WICED_SUCCESS;
}
Example #3
0
wiced_result_t process_received_udp_packet()
{
    wiced_packet_t*           packet;
    char*                     rx_data;
    static uint16_t           rx_data_length;
    uint16_t                  available_data_length;
    static wiced_ip_address_t udp_src_ip_addr;
    static uint16_t           udp_src_port;

    wiced_result_t result = wiced_udp_receive( &udp_socket, &packet, RX_WAIT_TIMEOUT );
    if ( ( result == WICED_ERROR ) || ( result == WICED_TIMEOUT ) ) {
        return result;
    }
    wiced_udp_packet_get_info( packet, &udp_src_ip_addr, &udp_src_port );
    wiced_packet_get_data( packet, 0, (uint8_t**) &rx_data, &rx_data_length, &available_data_length );
	uint32_t data_len = MIN(rx_data_length, BUFFER_SIZE-(48));
	write_ws2812(0, data_len, rx_data);
//    WPRINT_APP_INFO ( ("UDP Rx: \"%.2x\" from IP %u.%u.%u.%u:%d\n", *rx_data,
//                                                                  (unsigned char) ( ( GET_IPV4_ADDRESS(udp_src_ip_addr) >> 24 ) & 0xff ),
//                                                                  (unsigned char) ( ( GET_IPV4_ADDRESS(udp_src_ip_addr) >> 16 ) & 0xff ),
//                                                                  (unsigned char) ( ( GET_IPV4_ADDRESS(udp_src_ip_addr) >>  8 ) & 0xff ),
//                                                                  (unsigned char) ( ( GET_IPV4_ADDRESS(udp_src_ip_addr) >>  0 ) & 0xff ),
//                                                                  udp_src_port ) );
    wiced_packet_delete( packet );

    return WICED_SUCCESS;
}
Example #4
0
wiced_result_t wiced_tls_receive_packet( wiced_tcp_socket_t* socket, wiced_packet_t** packet, uint32_t timeout )
{
    wiced_result_t result;
    wiced_tls_context_t* context = &socket->tls_context->context;


    /* Check if we already have a record which should only happen if it was larger than a packet which means it's stored in the defragmentation buffer */
    if ( context->current_record != NULL )
    {
        wiced_assert( "Something wrong", (void*)context->current_record == context->defragmentation_buffer );
        return tls_packetize_buffered_data( context, packet );
    }
    else
    {
        tls_record_t* record;
        result = tls_get_next_record( context, &record, timeout, TLS_RECEIVE_PACKET_IF_NEEDED );
        if ( result != WICED_SUCCESS )
        {
            return result;
        }
        /* Check if this record has been defragmented */
        if ( (void*)record == context->defragmentation_buffer )
        {
            return tls_packetize_buffered_data( context, packet );
        }
        else
        {
            tls_record_t* temp_record;
            uint8_t* packet_data;
            uint16_t length;
            uint16_t available;
            uint8_t* end_of_data;

            /* We have a pointer to the current record so we can move on */
            tls_skip_current_record(context);

            /* Make sure we process every record in this packet */
            end_of_data = record->message + htobe16( record->length );
            while ( tls_get_next_record( context, &temp_record, timeout, TLS_AVOID_NEW_RECORD_PACKET_RECEIVE ) == TLS_SUCCESS )
            {
                /* Make the record data contiguous with the previous record */
                uint16_t temp_record_length = htobe16( temp_record->length );
                end_of_data = MEMCAT( end_of_data, temp_record->message, temp_record_length );
                record->length = htobe16( htobe16(record->length) + temp_record_length );
                tls_skip_current_record( context );
            }

            /* Set the packet start and end */
            wiced_packet_get_data( (wiced_packet_t*)context->received_packet, 0, &packet_data, &length, &available );
            tls_host_set_packet_start( context->received_packet, record->message );
            wiced_packet_set_data_end( (wiced_packet_t*)context->received_packet, end_of_data );

            *packet = (wiced_packet_t*)context->received_packet;
            context->received_packet        = NULL;
            context->received_packet_length = 0;
        }
    }

    return WICED_SUCCESS;
}
Example #5
0
tls_result_t tls_host_get_packet_data( ssl_context* ssl, tls_packet_t* packet, uint32_t offset, uint8_t** data, uint16_t* data_length, uint16_t* available_data_length )
{
    uint16_t temp_length;
    uint16_t temp_available_length;

    if ( ssl->transport_protocol == TLS_TCP_TRANSPORT )
    {
        wiced_result_t result = wiced_packet_get_data((wiced_packet_t*)packet, (uint16_t)offset, data, &temp_length, &temp_available_length);
        if ( result != WICED_SUCCESS)
        {
            return (tls_result_t) result;
        }
        *data_length = temp_length;
        *available_data_length = temp_available_length;
        return TLS_SUCCESS;
    }
#ifndef DISABLE_EAP_TLS
    else if ( ssl->transport_protocol == TLS_EAP_TRANSPORT )
    {
        besl_result_t result = supplicant_host_get_tls_data( (besl_packet_t) packet, (uint16_t)offset, data, &temp_length, &temp_available_length );
        if ( result != BESL_SUCCESS )
        {
            return (tls_result_t) result;
        }

        *data_length = temp_length;
        *available_data_length = temp_available_length;
        return TLS_SUCCESS;
    }
#endif /* DISABLE_EAP_TLS */
    return TLS_ERROR_BAD_INPUT_DATA;
}
Example #6
0
int read_packet_and_dispose(tcp_packet_t& packet, void* buffer, int len, wiced_tcp_socket_t* tcp_socket, int _timeout)
{
    int bytes_read = 0;
    if (!packet.packet) {
        packet.offset = 0;
        wiced_result_t result = wiced_tcp_receive(tcp_socket, &packet.packet, _timeout);
        if (result!=WICED_SUCCESS && result!=WICED_TIMEOUT) {
            DEBUG("Socket %d receive fail %d", (int)(int)tcp_socket->socket, int(result));
            return -result;
        }
    }
    uint8_t* data;
    uint16_t available;
    uint16_t total;
    bool dispose = true;
    if (packet.packet && (wiced_packet_get_data(packet.packet, packet.offset, &data, &available, &total)==WICED_SUCCESS)) {
        int read = std::min(uint16_t(len), available);
        packet.offset += read;
        memcpy(buffer, data, read);
        dispose = (total==read);
        bytes_read = read;
        DEBUG("Socket %d receive bytes %d of %d", (int)(int)tcp_socket->socket, int(bytes_read), int(available));
    }
    if (dispose) {
        packet.dispose_packet();
    }
    return bytes_read;
}
wiced_result_t wiced_tcp_stream_read_with_count( wiced_tcp_stream_t* tcp_stream, void* buffer, uint16_t buffer_length, uint32_t timeout, uint32_t* read_count )
{
    WICED_LINK_CHECK_TCP_SOCKET( tcp_stream->socket );

    if ( read_count != NULL )
    {
        *read_count = 0;
    }

    while ( buffer_length != 0 )
    {
        uint16_t amount_to_read;
        uint16_t total_available;
        uint8_t* packet_data     = NULL;
        uint16_t space_available = 0;

        /* Check if we don't have a packet */
        if (tcp_stream->rx_packet == NULL)
        {
            wiced_result_t result;
            result = wiced_tcp_receive(tcp_stream->socket, &tcp_stream->rx_packet, timeout );
            if ( result != WICED_TCPIP_SUCCESS)
            {
                if ( ( read_count != NULL ) && ( *read_count != 0 ) )
                {
                    result = WICED_TCPIP_SUCCESS;
                }
                return result;
            }
        }

        wiced_packet_get_data(tcp_stream->rx_packet, 0, &packet_data, &space_available, &total_available);

        /* Read data */
        amount_to_read = MIN(buffer_length, space_available);
        buffer         = MEMCAT((uint8_t*)buffer, packet_data, amount_to_read);

        if ( read_count != NULL )
        {
            *read_count += amount_to_read;
        }

        /* Update buffer length */
        buffer_length = (uint16_t)(buffer_length - amount_to_read);

        /* Check if we need a new packet */
        if ( amount_to_read == space_available )
        {
            wiced_packet_delete( tcp_stream->rx_packet );
            tcp_stream->rx_packet = NULL;
        }
        else
        {
            /* Otherwise update the start of the data for the next read request */
            wiced_packet_set_data_start(tcp_stream->rx_packet, packet_data + amount_to_read);
        }
    }
    return WICED_TCPIP_SUCCESS;
}
Example #8
0
tls_result_t tls_host_get_packet_data( tls_packet_t* packet, uint32_t offset, uint8_t** data, uint16_t* data_length, uint16_t* available_data_length )
{
    uint16_t temp_length;
    uint16_t temp_available_length;
    if ( wiced_packet_get_data((wiced_packet_t*)packet, (uint16_t)offset, data, &temp_length, &temp_available_length) == WICED_SUCCESS)
    {
        *data_length = temp_length;
        *available_data_length = temp_available_length;
        return WICED_SUCCESS;
    }
    else
    {
        return TLS_ERROR_BAD_INPUT_DATA;
    }
}
Example #9
0
static wiced_result_t tcp_server_process(  tcp_server_handle_t* server, wiced_packet_t* rx_packet )
{
    char*           request;
    uint16_t        request_length;
    uint16_t        available_data_length;
    wiced_packet_t* tx_packet;
    char*           tx_data;

    wiced_packet_get_data( rx_packet, 0, (uint8_t**) &request, &request_length, &available_data_length );

    /* Null terminate the received string */
    request[request_length] = '\x0';
    WPRINT_APP_INFO(("Received data: %s \n", request));

    /* Send echo back */
    if (wiced_packet_create_tcp(&server->socket, TCP_PACKET_MAX_DATA_LENGTH, &tx_packet, (uint8_t**)&tx_data, &available_data_length) != WICED_SUCCESS)
    {
        WPRINT_APP_INFO(("TCP packet creation failed\n"));
        return WICED_ERROR;
    }

    /* Write the message into tx_data"  */
    tx_data[request_length] = '\x0';
    memcpy(tx_data, request, request_length);

    /* Set the end of the data portion */
    wiced_packet_set_data_end(tx_packet, (uint8_t*)tx_data + request_length);

    /* Send the TCP packet */
    if (wiced_tcp_send_packet(&server->socket, tx_packet) != WICED_SUCCESS)
    {
        WPRINT_APP_INFO(("TCP packet send failed\n"));

        /* Delete packet, since the send failed */
        wiced_packet_delete(tx_packet);

        server->quit=WICED_TRUE;
        return WICED_ERROR;
    }
    WPRINT_APP_INFO(("Echo data: %s\n", tx_data));

    return WICED_SUCCESS;
}
Example #10
0
wiced_result_t read_packet(wiced_packet_t* packet, uint8_t* target, uint16_t target_len, uint16_t* read_len)
{
    uint16_t read = 0;
    wiced_result_t result = WICED_SUCCESS;
    uint16_t fragment;
    uint16_t available;
    uint8_t* data;

    while (target_len!=0 && (result = wiced_packet_get_data(packet, read, &data, &fragment, &available))==WICED_SUCCESS && available!=0) {
        uint16_t to_read = std::min(fragment, target_len);
        memcpy(target+read, data, to_read);
        read += to_read;
        target_len -= to_read;
        available -= to_read;
        if (!available)
            break;
    }
    if (read_len!=NULL)
        *read_len = read;
    return result;
}
Example #11
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;
}
Example #12
0
int
rwl_read_eth_port(void* hndle, char* read_buf, unsigned int data_size, unsigned int *numread)
{
    wiced_result_t  result = WICED_SUCCESS;
    char*           request;
    uint16_t        request_length;
    uint16_t        available_data_length;
    wiced_packet_t* temp_packet = NULL;

    *numread = 0;

    if ( data_size == 0 )
     {
         return SUCCESS;
     }

    if (wiced_tcp_receive( &tcp_client_socket, &temp_packet, WICED_WAIT_FOREVER ) == WICED_SUCCESS)
    {
        result = result;

        if (temp_packet)
        {
            /* Process the client request */
            wiced_packet_get_data( temp_packet, 0, (uint8_t **)&request, &request_length, &available_data_length );
        }

        memcpy(read_buf,request,data_size);

        // read_buf = request;
        *numread = request_length;

        wiced_packet_delete( temp_packet );
    }

    return SUCCESS;
}
static wiced_result_t received_data_callback( wiced_tcp_socket_t* socket, void* arg )
{

	uint16_t        request_length;
	uint16_t        available_data_length;
	wiced_packet_t* temp_packet = NULL;

	if(wiced_tcp_receive( socket, &temp_packet, 500 ) == WICED_SUCCESS) // get the data from the client
	{
		char *rbuffer;
		dbEntry_t receive;
		char commandId;
		int err=1;
		char returnMessage[15];

		// get the pointer to the packet sent by the client and the data
		wiced_packet_get_data( temp_packet, 0, (uint8_t**) &rbuffer, &request_length, &available_data_length );
		sscanf(rbuffer,"%c%4x%2x%4x",&commandId,(unsigned int *)&receive.deviceId,(unsigned int *)&receive.regId,(unsigned int *)&receive.value);
		wiced_packet_delete( temp_packet ); // free the packet

		if(request_length >= 11 && request_length <= 13  ) //11 if no end 12 if CR 13 if CRLF
		{
			dbEntry_t *newDbEntry;
			switch(commandId)
			{
			case 'R': // they sent a Read command
				newDbEntry = dbFind(&receive); // look through the database to find a previous write of the deviceId/regId
				if(newDbEntry)
				{
					err=0;
					sprintf(returnMessage,"A%04X%02X%04X",(unsigned int)newDbEntry->deviceId,(unsigned int)newDbEntry->regId,(unsigned int)newDbEntry->value);
				}
				else
					err = 1;
				break;
			case 'W': // they sent a Write command
				sprintf(returnMessage,"A%04X%02X%04X",(unsigned int)receive.deviceId,(unsigned int)receive.regId,(unsigned int)receive.value);
				dbEntry_t *newDB;
				newDB = malloc(sizeof(dbEntry_t)); // make a new entry to put in the database
				memcpy(newDB,&receive,sizeof(dbEntry_t)); // copy the received data into the new entry
				dbSetValue(newDB); // save it.
				err = 0;
				break;
			default: // if they don't send a legal command then it is an error
				err = 1;
				break;
			}
		}

		// Print IP address of the client (peer) that sent the data and print to terminal
		uint32_t 		peerAddressV4;
		peerAddressV4 = (*socket).socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4;
		WPRINT_APP_INFO(("%u.%u.%u.%u\t",
				(uint8_t)(peerAddressV4 >> 24),
				(uint8_t)(peerAddressV4 >> 16),
				(uint8_t)(peerAddressV4 >> 8),
				(uint8_t)(peerAddressV4 >> 0)));

		// Print the port that the peer connected from
		uint16_t	    peerPort;
		peerPort = (*socket).socket.nx_tcp_socket_connect_port;
		WPRINT_APP_INFO(("%d\t",peerPort));

		// Print the data that was sent by the client (peer)
		if(err)
		{
			strcpy(returnMessage,"X");
			WPRINT_APP_INFO(("X length=%d\n",available_data_length));
		}
		else
		{
			uint32_t count;
			linked_list_get_count(&db,&count);
			WPRINT_APP_INFO(("%c\t%4X\t%2X\t%4X\t%d\n",commandId,(unsigned int)receive.deviceId,(unsigned int)receive.regId,(unsigned int)receive.value,(int)count));
		}

		// send response packet
		wiced_packet_t* tx_packet;
		uint8_t *tx_data;
		wiced_packet_create_tcp(socket, strlen(returnMessage), &tx_packet, (uint8_t**)&tx_data, &available_data_length);
		memcpy(tx_data, returnMessage, strlen(returnMessage));
		wiced_packet_set_data_end(tx_packet, (uint8_t*)&tx_data[strlen(returnMessage)]);
		wiced_tcp_send_packet(socket, tx_packet);
		wiced_packet_delete(tx_packet);

		wiced_tcp_server_disconnect_socket(&tcp_server,socket);

	}
/**
 *  Implements a very simple DHCP server.
 *
 *  Server will always offer next available address to a DISCOVER command
 *  Server will NAK any REQUEST command which is not requesting the next available address
 *  Server will ACK any REQUEST command which is for the next available address, and then increment the next available address
 *
 * @param my_addr : local IP address for binding of server port.
 */
static void dhcp_thread( uint32_t thread_input )
{
    wiced_packet_t*      received_packet;
    wiced_packet_t*      transmit_packet;
    wiced_ip_address_t   local_ip_address;
    wiced_ip_address_t   netmask;
    uint32_t             next_available_ip_addr;
    uint32_t             ip_mask;
    uint32_t             subnet;
    uint32_t             netmask_htobe;
    char*                option_ptr;
    wiced_dhcp_server_t* server                       = (wiced_dhcp_server_t*)thread_input;
    uint8_t              subnet_mask_option_buff[]    = { 1, 4, 0, 0, 0, 0 };
    uint8_t              server_ip_addr_option_buff[] = { 54, 4, 0, 0, 0, 0 };
    uint32_t*            server_ip_addr_ptr           = (uint32_t*)&server_ip_addr_option_buff[2];
    uint8_t              wpad_option_buff[ 2 + sizeof(WPAD_SAMPLE_URL)-1 ] = { 252, sizeof(WPAD_SAMPLE_URL)-1 };

    /* Save local IP address to be sent in DHCP packets */
    wiced_ip_get_ipv4_address(server->interface, &local_ip_address);
    *server_ip_addr_ptr = htobe32( GET_IPV4_ADDRESS( local_ip_address ) );

    /* Save the current netmask to be sent in DHCP packets as the 'subnet mask option' */
    wiced_ip_get_netmask(server->interface, &netmask);
    netmask_htobe = htobe32( GET_IPV4_ADDRESS(netmask) );
    memcpy(&subnet_mask_option_buff[2], &netmask_htobe, 4);

    /* Calculate the first available IP address which will be served - based on the netmask and the local IP */
    ip_mask = ~( GET_IPV4_ADDRESS( netmask ) );
    subnet = GET_IPV4_ADDRESS( local_ip_address ) & GET_IPV4_ADDRESS( netmask );
    next_available_ip_addr = subnet | ( ( GET_IPV4_ADDRESS( local_ip_address ) + 1 ) & ip_mask );

    /* Prepare the Web proxy auto discovery URL */
    memcpy(&wpad_option_buff[2], WPAD_SAMPLE_URL, sizeof(WPAD_SAMPLE_URL)-1);
    ipv4_to_string( (char*)&wpad_option_buff[2 + 7], *server_ip_addr_ptr);

    /* Initialise the server quit flag */
    server->quit = WICED_FALSE;

    /* Loop endlessly */
    while ( server->quit == WICED_FALSE )
    {
        uint16_t       data_length;
        uint16_t       available_data_length;
        dhcp_header_t* request_header;

        /* Sleep until data is received from socket. */
        if ( wiced_udp_receive( &server->socket, &received_packet, WICED_WAIT_FOREVER ) != WICED_SUCCESS )
        {
            continue;
        }

        /* Get a pointer to the data in the packet */
        wiced_packet_get_data( received_packet, 0, (uint8_t**) &request_header, &data_length, &available_data_length );

        /* Check DHCP command */
        switch ( request_header->options[2] )
        {
            case DHCPDISCOVER:
            {
                dhcp_header_t*     reply_header;
                uint16_t           available_space;
                wiced_mac_t        client_mac_address;
                wiced_ip_address_t client_ip_address;
                uint32_t           temp;

                /* Create reply packet */
                if ( wiced_packet_create_udp( &server->socket, sizeof(dhcp_header_t), &transmit_packet, (uint8_t**) &reply_header, &available_space ) != WICED_SUCCESS )
                {
                    /* Cannot reply - release incoming packet */
                    wiced_packet_delete( received_packet );
                    break;
                }

                /* Copy in the DHCP header content from the received discover packet into the reply packet */
                memcpy( reply_header, request_header, sizeof(dhcp_header_t) - sizeof(reply_header->options) );

                /* Finished with the received discover packet - release it */
                wiced_packet_delete( received_packet );

                /* Now construct the OFFER response */
                reply_header->opcode = BOOTP_OP_REPLY;

                /* Clear the DHCP options list */
                memset( &reply_header->options, 0, sizeof( reply_header->options ) );

                /* Record client MAC address */
                memcpy( &client_mac_address, request_header->client_hardware_addr, sizeof( client_mac_address ) );

                /* Check whether device is already cached */
                if ( get_client_ip_address_from_cache( &client_mac_address, &client_ip_address ) != WICED_SUCCESS )
                {
                    /* Address not found in cache. Use next available IP address */
                    client_ip_address.version = WICED_IPV4;
                    client_ip_address.ip.v4   = next_available_ip_addr;
                }

                /* Create the IP address for the Offer */
                temp = htonl(client_ip_address.ip.v4);
                memcpy( reply_header->your_ip_addr, &temp, sizeof( temp ) );

                /* Copy the magic DHCP number */
                memcpy( reply_header->magic, dhcp_magic_cookie, 4 );

                /* Add options */
                option_ptr     = (char *) &reply_header->options;
                option_ptr     = MEMCAT( option_ptr, dhcp_offer_option_buff, 3 );                                   /* DHCP message type            */
                option_ptr     = MEMCAT( option_ptr, server_ip_addr_option_buff, 6 );                               /* Server identifier            */
                option_ptr     = MEMCAT( option_ptr, lease_time_option_buff, 6 );                                   /* Lease Time                   */
                option_ptr     = MEMCAT( option_ptr, subnet_mask_option_buff, 6 );                                  /* Subnet Mask                  */
                option_ptr     = (char*)MEMCAT( option_ptr, wpad_option_buff, sizeof(wpad_option_buff) );           /* Web proxy auto discovery URL */
                /* Copy the local IP into the Router & DNS server Options */
                memcpy( option_ptr, server_ip_addr_option_buff, 6 );                                                /* Router (gateway)             */
                option_ptr[0]  = 3;                                                                                 /* Router id                    */
                option_ptr    += 6;
                memcpy( option_ptr, server_ip_addr_option_buff, 6 );                                                /* DNS server                   */
                option_ptr[0]  = 6;                                                                                 /* DNS server id                */
                option_ptr    += 6;
                option_ptr     = MEMCAT( option_ptr, mtu_option_buff, 4 );                                          /* Interface MTU                */
                option_ptr[0]  = (char) 0xff;                                                                       /* end options                  */
                option_ptr++;

                /* Send OFFER reply packet */
                wiced_packet_set_data_end( transmit_packet, (uint8_t*) option_ptr );
                if ( wiced_udp_send( &server->socket, WICED_IP_BROADCAST, IPPORT_DHCPC, transmit_packet ) != WICED_SUCCESS )
                {
                    wiced_packet_delete( transmit_packet );
                }
            }
                break;

            case DHCPREQUEST:
            {
                /* REQUEST command - send back ACK or NAK */
                uint32_t           temp;
                uint32_t*          server_id_req;
                dhcp_header_t*     reply_header;
                uint16_t           available_space;
                wiced_mac_t        client_mac_address;
                wiced_ip_address_t given_ip_address;
                wiced_ip_address_t requested_ip_address;
                wiced_bool_t       next_avail_ip_address_used = WICED_FALSE;

                /* Check that the REQUEST is for this server */
                server_id_req = (uint32_t*) find_option( request_header, 54 );
                if ( ( server_id_req != NULL ) && ( GET_IPV4_ADDRESS( local_ip_address ) != htobe32(*server_id_req) ) )
                {
                    break; /* Server ID does not match local IP address */
                }

                /* Create reply packet */
                if ( wiced_packet_create_udp( &server->socket, sizeof(dhcp_header_t), &transmit_packet, (uint8_t**) &reply_header, &available_space ) != WICED_SUCCESS )
                {
                    /* Cannot reply - release incoming packet */
                    wiced_packet_delete( received_packet );
                    break;
                }

                /* Copy in the DHCP header content from the received request packet into the reply packet */
                memcpy( reply_header, request_header, sizeof(dhcp_header_t) - sizeof(reply_header->options) );

                /* Record client MAC address */
                memcpy( &client_mac_address, request_header->client_hardware_addr, sizeof( client_mac_address ) );

                /* Locate the requested address in the options and keep requested address */
                requested_ip_address.version = WICED_IPV4;
                requested_ip_address.ip.v4   = ntohl(*(uint32_t*)find_option( request_header, 50 ));

                /* Delete received packet. We don't need it anymore */
                wiced_packet_delete( received_packet );

                reply_header->opcode = BOOTP_OP_REPLY;

                /* Blank options list */
                memset( &reply_header->options, 0, sizeof( reply_header->options ) );

                /* Copy DHCP magic number into packet */
                memcpy( reply_header->magic, dhcp_magic_cookie, 4 );

                option_ptr = (char *) &reply_header->options;

                /* Check if device is cache. If it is, give the previous IP address. Otherwise give the next available IP address */
                if ( get_client_ip_address_from_cache( &client_mac_address, &given_ip_address ) != WICED_SUCCESS )
                {
                    /* Address not found in cache. Use next available IP address */
                    next_avail_ip_address_used = WICED_TRUE;
                    given_ip_address.version   = WICED_IPV4;
                    given_ip_address.ip.v4     = next_available_ip_addr;
                }

                /* Check if the requested IP address matches one we have assigned */
                if ( memcmp( &requested_ip_address.ip.v4, &given_ip_address.ip.v4, sizeof( requested_ip_address.ip.v4 ) ) != 0 )
                {
                    /* Request is not for the assigned IP - force client to take next available IP by sending NAK */
                    /* Add appropriate options */
                    option_ptr = (char*)MEMCAT( option_ptr, dhcp_nak_option_buff, 3 );             /* DHCP message type */
                    option_ptr = (char*)MEMCAT( option_ptr, server_ip_addr_option_buff, 6 );       /* Server identifier */
                    memset( reply_header->your_ip_addr, 0, sizeof( reply_header->your_ip_addr ) ); /* Clear IP addr     */
                }
                else
                {
                    /* Request is for next available IP */
                    /* Add appropriate options */
                    option_ptr     = (char*)MEMCAT( option_ptr, dhcp_ack_option_buff, 3 );                              /* DHCP message type            */
                    option_ptr     = (char*)MEMCAT( option_ptr, server_ip_addr_option_buff, 6 );                        /* Server identifier            */
                    option_ptr     = (char*)MEMCAT( option_ptr, lease_time_option_buff, 6 );                            /* Lease Time                   */
                    option_ptr     = (char*)MEMCAT( option_ptr, subnet_mask_option_buff, 6 );                           /* Subnet Mask                  */
                    option_ptr     = (char*)MEMCAT( option_ptr, wpad_option_buff, sizeof(wpad_option_buff) );           /* Web proxy auto discovery URL */
                    /* Copy the local IP into the Router & DNS server Options */
                    memcpy( option_ptr, server_ip_addr_option_buff, 6 );                                                /* Router (gateway)             */
                    option_ptr[0]  = 3;                                                                                 /* Router id                    */
                    option_ptr    += 6;
                    memcpy( option_ptr, server_ip_addr_option_buff, 6 );                                                /* DNS server                   */
                    option_ptr[0]  = 6;                                                                                 /* DNS server id                */
                    option_ptr    += 6;
                    option_ptr     = (char*)MEMCAT( option_ptr, mtu_option_buff, 4 );                                   /* Interface MTU                */

                    /* Create the IP address for the Offer */
                    temp = htonl(given_ip_address.ip.v4);
                    memcpy( reply_header->your_ip_addr, &temp, sizeof( temp ) );

                    /* Increment next available IP address only if not found in cache */
                    if ( next_avail_ip_address_used == WICED_TRUE )
                    {
                        do
                        {
                            next_available_ip_addr = subnet | ( ( next_available_ip_addr + 1 ) & ip_mask );
                        } while ( next_available_ip_addr == GET_IPV4_ADDRESS(local_ip_address) );
                    }

                    /* Cache client */
                    add_client_to_cache( &client_mac_address, &given_ip_address );

                }

                option_ptr[0] = (char) 0xff; /* end options */
                option_ptr++;

                /* Send reply packet */
                wiced_packet_set_data_end( transmit_packet, (uint8_t*) option_ptr );
                if ( wiced_udp_send( &server->socket, WICED_IP_BROADCAST, IPPORT_DHCPC, transmit_packet ) != WICED_SUCCESS )
                {
                    wiced_packet_delete( transmit_packet );
                }

            }
                break;

            default:
                /* Unknown packet type - release received packet */
                wiced_packet_delete( received_packet );
                break;
        }
    }

    /* Server loop has exited due to quit flag */

    /* Delete DHCP socket */
    wiced_udp_delete_socket( &server->socket );
    WICED_END_OF_CURRENT_THREAD( );
}
Example #15
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;
}
/*
 * Function:    wilddog_receive
 * Description: wilddog receive function, it use the interface in wiced platform.
 * Input:        socketId: The socket id.
 *                  addr:  The pointer of Wilddog_Address_T
 *                  buf: The pointer of the send buffer
 *                  bufLen: The length of the send buffer.
 *                  timeout: The max timeout in recv process.
 * Output:      N/A
 * Return:      If success, return the number of bytes received; else return -1.
*/
int wilddog_receive
    ( 
    int socketId, 
    Wilddog_Address_T* addr_in, 
    void* buf, 
    s32 bufLen, 
    s32 timeout
    )
{
    wiced_udp_socket_t* socket = (wiced_udp_socket_t*) socketId;

    wiced_packet_t* receive = NULL;
    u16 totalLeft = 0;
    u16 total = 0;
    uint16_t pos = 0;
    uint8_t* rxData;
    uint16_t fragLeft = 0;
    wiced_ip_address_t recieve_ip_addr;
    uint16_t receive_port;
    wiced_result_t result;
    result = wiced_udp_receive( socket, &receive, timeout );
    if ( result == WICED_SUCCESS )
    {
        if(NULL == receive)
        {
            wilddog_debug_level(WD_DEBUG_ERROR, "receive is NULL!");
            return -1;
        }
        wiced_udp_packet_get_info( receive, &recieve_ip_addr, &receive_port );

        if ( !recieve_ip_addr.ip.v4 == MAKE_IPV4_ADDRESS(addr_in->ip[0], \
            addr_in->ip[1], addr_in->ip[2], addr_in->ip[3]) )
        {
            wilddog_debug_level(WD_DEBUG_ERROR, "addr error!\n" );
            wiced_packet_delete( receive );
            return -1;
        }
        do
        {
            if ( wiced_packet_get_data( receive, 0, (uint8_t**) &rxData, \
                &fragLeft, &totalLeft ) != WICED_SUCCESS )
            {
                wilddog_debug_level(WD_DEBUG_ERROR, \
                    "get data from packet error \r\n" );
                wiced_packet_delete( receive );
                return -1;
            }
            else
            {
                if ( pos + fragLeft > bufLen )
                {
                    /* too large, drop*/
                    wiced_packet_delete( receive );
                    wilddog_debug_level(WD_DEBUG_ERROR, \
                        "too large receive end , get %d bytes\n", pos );
                    return 0;
                }
                if ( total == 0 )
                {
                    /*only get first data, next fragment's total is wrong*/
                    total = totalLeft;
                }

                memcpy( (uint8_t *) ( buf + pos ), rxData, fragLeft );
                pos += fragLeft;

                fragLeft = 0;
            }
            if ( pos == total )
            {
                /*end*/
#if WILDDOG_SELFTEST
                {
                    performtest_getWaitSessionQueryTime();
                    performtest_getWaitRecvTime();
                }
#endif
                wilddog_debug_level(WD_DEBUG_LOG, "received %d data!", pos);
                wiced_packet_delete( receive );
                return pos;
            }
            else if ( pos < total )
            {
                /*get next fragment*/
                wilddog_debug_level(WD_DEBUG_LOG, "more than one packet!");
                if ( WICED_SUCCESS != _packet_get_next_fragment( receive, \
                    &receive ) )
                {
                    wilddog_debug_level(WD_DEBUG_ERROR, \
                        "get next fragment err! %d lost!", total);
					if(receive)
	                    wiced_packet_delete( receive );
                    return -1;
                }
                if ( NULL == receive )
                {
                    wilddog_debug_level(WD_DEBUG_ERROR, \
                        "get next fragment err! %d lost!", total);
                    return -1;
                }

            }
            else
            {
                wiced_packet_delete( receive );
                return -1;
            }
        } while ( pos < total );
    }
    else
    {
        wilddog_debug_level(WD_DEBUG_LOG, "result = %d",result);
    }
    /*if(receive)
        wiced_packet_delete( receive );*/
    return 0;
}
Example #17
0
static void ota_server_thread_main(uint32_t arg)
{
    ota_server_t*          server          = (ota_server_t*) arg;
    uint32_t               total_body_size = 0;
    int                    i               = 0;

    server->reboot_required = WICED_FALSE;
    while ( server->quit != WICED_TRUE )
    {
        wiced_packet_t* temp_packet = NULL;

        /* Wait for a connection */
        wiced_result_t result = wiced_tcp_accept( &server->socket );
        if ( result == WICED_SUCCESS )
        {
            for(;;)
            {
                if ( wiced_tcp_receive( &server->socket, &temp_packet, WICED_WAIT_FOREVER ) == WICED_SUCCESS )
                {
                    char* request_string;
                    uint16_t request_length;
                    uint16_t available_data_length;

                    if( server->state == READING_HEADER )
                    {
                        uint8_t         temp   = 0;
                        wiced_result_t  result = WICED_ERROR;

                        if ( temp_packet == NULL )
                        {
                            goto disconnect;
                        }
                        init_request(server);

                        server->request.request_packets[server->request.current_packet_index] = temp_packet;


                        wiced_packet_get_data(temp_packet, 0, (uint8_t**)&request_string, &request_length, &available_data_length);

                        /* Check that this is a GET or POST request, abort everything else */
                        if ( ( strstr( request_string, "GET" ) == 0 ) && ( strstr( request_string, "POST") == 0 ) )
                        {
                            result = WICED_ERROR;
                            wiced_packet_delete(temp_packet);
                            goto disconnect;
                        }

                        /* Get header pointer and header size */
                        server->request.header_ptr = (uint8_t*)request_string;
                        server->request.header_size = ( (char*)strstr( (char*)request_string, crlfcrlf ) + strlen( crlfcrlf ) ) - (char*)request_string;
                        if( server->request.header_size == strlen( crlfcrlf ) )
                        {
                            goto disconnect;
                        }

                        /* Get content length */
                        server->request.content_length = 0;
                        if( strstr( request_string, "Content-Length") != NULL )
                        {
                            uint8_t* content_length_value = (uint8_t*)strstr( request_string, "Content-Length") + strlen("Content-Length:");
                            server->request.content_length = atoi((const char*)content_length_value);
                        }

                        temp = request_string[ server->request.header_size ];
                        request_string[ server->request.header_size ] ='\0';
                        request_string[ server->request.header_size ] = temp;

                        /* Get request type and the url */
                        result = get_http_request_type_and_url( (uint8_t*)request_string, request_length, &server->request);
                        if ( result == WICED_ERROR )
                        {
                           goto disconnect;
                        }

                        server->state = READING_BODY;
                    }

                    if( server->state == READING_BODY )
                    {
                        http_body_chunk_t*          current_body_chunk = &server->request.body_chunks[server->request.current_packet_index];

                        if( server->request.current_packet_index != 0 )
                        {
                            server->request.request_packets[server->request.current_packet_index] = temp_packet;
                        }

                        wiced_packet_get_data(temp_packet, 0, (uint8_t**)&request_string, &request_length, &available_data_length);

                        if( server->request.current_packet_index == 0 )
                        {
                            current_body_chunk->data = server->request.header_ptr + server->request.header_size;
                            current_body_chunk->size = ( request_string + request_length ) - (char*)current_body_chunk->data;
                        }
                        else
                        {
                            current_body_chunk->data = (uint8_t*)request_string;
                            current_body_chunk->size = request_length;
                        }
                        /* calculate total combined size of all body chunks which belongs to this message */
                        total_body_size = 0;

                        for( i = 0; i < ( server->request.current_packet_index + 1 ) ; i++ )
                        {
                            total_body_size+= server->request.body_chunks[i].size;
                        }

                        server->request.current_packet_index++;

                        /* Check whether the combined size of the previous chunks and the current one is equal to the content length received in the first packet */
                        if( total_body_size == server->request.content_length )
                        {
                            ota_server_process_request( server, &server->socket );
                            /* Delete all packets belonging to the message */
                            for( i = 0; i < server->request.current_packet_index; i++ )
                            {
                                wiced_packet_delete(server->request.request_packets[i]);
                            }
                            server->state = READING_HEADER;
                            break;
                        }
                    }
                }
                else
                {
                    goto disconnect;
                }
            }
        }
disconnect:
        wiced_tcp_disconnect( &server->socket );
    }

    wiced_tcp_delete_socket( &server->socket );
    if( server->reboot_required == WICED_TRUE )
    {
        /* Give some for the response to be sent properly */
        wiced_rtos_delay_milliseconds(2000);

        /* Perform a reboot!!! */
        wiced_framework_reboot();
    }
    WICED_END_OF_CURRENT_THREAD( );
}