/* * Function: wilddog_send * Description: wilddog send function, it use the interface in wiced platform. * Input: socketId: The socket id. * addr_in: The pointer of Wilddog_Address_T * tosend: The pointer of the send buffer * tosendLength: The length of the send buffer. * Output: N/A * Return: If success, return the number of characters sent.; else return -1. */ int wilddog_send ( int socketId, Wilddog_Address_T* addr_in, void* tosend, s32 tosendLength ) { wiced_udp_socket_t* socket = (wiced_udp_socket_t*) socketId; wiced_ip_address_t ipaddr; ipaddr.version = WICED_IPV4; ipaddr.ip.v4 = WILDDOG_MAKE_IPV4(addr_in->ip[0], addr_in->ip[1], \ addr_in->ip[2], addr_in->ip[3]); wiced_packet_t* packet; uint8_t* data; uint16_t aval; if ( wiced_packet_create_udp( socket, 0, &packet, &data, &aval ) != \ WICED_SUCCESS ) { wilddog_debug_level(WD_DEBUG_ERROR, "error create packet ...\r\n"); return -1; } if ( aval < tosendLength ) { /* Delete packet, since the send failed */ wiced_packet_delete( packet ); wilddog_debug_level(WD_DEBUG_ERROR, \ "too large length to translate! should be %d, want send %ld\n", \ aval, tosendLength); return -1; } memcpy( data, tosend, tosendLength ); #if WILDDOG_SELFTEST performtest_getDtlsSendTime(); #endif wiced_packet_set_data_end( packet, (uint8_t*) ( data + tosendLength ) ); wilddog_debug_level(WD_DEBUG_LOG, "socketId = %d, port = %d\n", \ socketId, addr_in->port); if ( wiced_udp_send( socket, &ipaddr, addr_in->port, packet ) != \ WICED_SUCCESS ) { wilddog_debug_level(WD_DEBUG_ERROR, "UDP packet send failed\r\n"); wiced_packet_delete( packet ); } else { wilddog_debug_level(WD_DEBUG_LOG, "send packet success!\n"); return tosendLength; } return -1; }
int rwl_write_eth_port(void* hndle, char* write_buf, unsigned long size, unsigned long *numwritten) { uint16_t available_data_length; wiced_packet_t* tx_packet; char* tx_data; unsigned long temp_size = 0; unsigned long temp=0; if ( size == 0 ) { return SUCCESS; } while (size > 0) { if (wiced_packet_create_tcp(&tcp_client_socket, 128, &tx_packet, (uint8_t **)&tx_data, &available_data_length) != WICED_SUCCESS) { WPRINT_APP_INFO(("TCP packet creation failed\n")); return WICED_ERROR; } if (size > available_data_length) { temp_size = available_data_length; } else { temp_size =size; } /* Write the message into tx_data"*/ memcpy(tx_data, (write_buf + temp), temp_size); wiced_packet_set_data_end( tx_packet, (uint8_t*)tx_data + temp_size ); /* Send the TCP packet*/ if ( wiced_tcp_send_packet( &tcp_client_socket, tx_packet ) != WICED_SUCCESS ) { WPRINT_APP_INFO(("TCP packet send failed \n")); /*Delete packet, since the send failed*/ wiced_packet_delete(tx_packet); return WICED_ERROR; } wiced_packet_delete(tx_packet); size = size - temp_size; temp = temp+temp_size; } return available_data_length; }
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; }
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; }
void dispose_packet() { if (packet) { wiced_packet_delete(packet); packet = NULL; offset = 0; } }
wiced_result_t wiced_tcp_stream_flush( wiced_tcp_stream_t* tcp_stream ) { wiced_result_t result = WICED_TCPIP_SUCCESS; wiced_assert("Bad args", tcp_stream != NULL); WICED_LINK_CHECK_TCP_SOCKET( tcp_stream->socket ); /* Check if there is a packet to send */ if ( tcp_stream->tx_packet != NULL ) { wiced_packet_set_data_end(tcp_stream->tx_packet, tcp_stream->tx_packet_data); result = wiced_tcp_send_packet( tcp_stream->socket, tcp_stream->tx_packet ); tcp_stream->tx_packet_data = NULL; tcp_stream->tx_packet_space_available = 0; if ( result != WICED_TCPIP_SUCCESS ) { wiced_packet_delete( tcp_stream->tx_packet ); } tcp_stream->tx_packet = NULL; } return result; }
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; }
tls_result_t tls_host_send_tcp_packet( void* context, tls_packet_t* packet ) { if ( network_tcp_send_packet( (wiced_tcp_socket_t*)context, (wiced_packet_t*)packet) != WICED_SUCCESS ) { wiced_packet_delete((wiced_packet_t*)packet); } return TLS_SUCCESS; }
wiced_result_t wiced_tcp_stream_write( wiced_tcp_stream_t* tcp_stream, const void* data, uint32_t data_length ) { wiced_assert("Bad args", tcp_stream != NULL); WICED_LINK_CHECK_TCP_SOCKET( tcp_stream->socket ); while ( data_length != 0 ) { uint16_t amount_to_write; /* Check if we don't have a packet */ if ( tcp_stream->tx_packet == NULL ) { wiced_result_t result; result = wiced_packet_create_tcp( tcp_stream->socket, (uint16_t) MIN( data_length, 0xffff ), &tcp_stream->tx_packet, &tcp_stream->tx_packet_data , &tcp_stream->tx_packet_space_available ); if ( result != WICED_TCPIP_SUCCESS ) { return result; } } /* Write data */ amount_to_write = (uint16_t) MIN( data_length, tcp_stream->tx_packet_space_available ); tcp_stream->tx_packet_data = MEMCAT( tcp_stream->tx_packet_data, data, amount_to_write ); /* Update variables */ data_length = (uint16_t)(data_length - amount_to_write); tcp_stream->tx_packet_space_available = (uint16_t) ( tcp_stream->tx_packet_space_available - amount_to_write ); data = (void*)((uint32_t)data + amount_to_write); /* Check if the packet is full */ if ( tcp_stream->tx_packet_space_available == 0 ) { wiced_result_t result; /* Send the packet */ wiced_packet_set_data_end( tcp_stream->tx_packet, (uint8_t*)tcp_stream->tx_packet_data ); result = wiced_tcp_send_packet( tcp_stream->socket, tcp_stream->tx_packet ); tcp_stream->tx_packet_data = NULL; tcp_stream->tx_packet_space_available = 0; if ( result != WICED_TCPIP_SUCCESS ) { wiced_packet_delete( tcp_stream->tx_packet ); tcp_stream->tx_packet = NULL; return result; } tcp_stream->tx_packet = NULL; } } return WICED_TCPIP_SUCCESS; }
/* * Function: _packet_get_next_fragment * Description: Get next fragment packet, it use the interface in wiced platform. * Input: packet: The pointer of packet. * Output: next_packet_fragment: The second rank pointer of the next packet. * Return: If success, return 0 */ wiced_result_t _packet_get_next_fragment ( wiced_packet_t* packet, wiced_packet_t** next_packet_fragment ) { wiced_packet_t* p_tmp = NULL; if ( packet->nx_packet_fragment_next ) { p_tmp = packet->nx_packet_fragment_next; } wiced_packet_delete( packet ); *next_packet_fragment = p_tmp; return 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; }
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; }
wiced_result_t wiced_tcp_send_buffer( wiced_tcp_socket_t* socket, const void* buffer, uint16_t buffer_length ) { wiced_packet_t* packet = NULL; uint8_t* data_ptr = (uint8_t*)buffer; uint8_t* packet_data_ptr; uint16_t available_space; wiced_assert("Bad args", socket != NULL); WICED_LINK_CHECK_TCP_SOCKET( socket ); /* Create a packet, copy the data and send it off */ while ( buffer_length != 0 ) { uint16_t data_to_write; wiced_result_t result = wiced_packet_create_tcp( socket, buffer_length, &packet, &packet_data_ptr, &available_space ); if ( result != WICED_TCPIP_SUCCESS ) { return result; } /* Write data */ data_to_write = MIN(buffer_length, available_space); packet_data_ptr = MEMCAT(packet_data_ptr, data_ptr, data_to_write); wiced_packet_set_data_end( packet, packet_data_ptr ); /* Update variables */ data_ptr += data_to_write; buffer_length = (uint16_t) ( buffer_length - data_to_write ); available_space = (uint16_t) ( available_space - data_to_write ); result = wiced_tcp_send_packet( socket, packet ); if ( result != WICED_TCPIP_SUCCESS ) { wiced_packet_delete( packet ); return result; } } return WICED_TCPIP_SUCCESS; }
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; }
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 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( ); }
/* * TLS support functions */ tls_result_t tls_host_free_packet( tls_packet_t* packet ) { wiced_packet_delete((wiced_packet_t*)packet); return TLS_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); }
/* * 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; }
/** * 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( ); }
static void tcp_server_thread_main(uint32_t arg) { tcp_server_handle_t* server = (tcp_server_handle_t*) arg; while ( quit != WICED_TRUE ) { wiced_packet_t* temp_packet = NULL; /* Wait for a connection */ wiced_result_t result = wiced_tcp_accept( &server->socket ); #ifdef TCP_KEEPALIVE_ENABLED result = wiced_tcp_enable_keepalive(&server->socket, TCP_SERVER_KEEP_ALIVE_INTERVAL, TCP_SERVER_KEEP_ALIVE_PROBES, TCP_SERVER_KEEP_ALIVE_TIME ); if( result != WICED_SUCCESS ) { WPRINT_APP_INFO(("Keep alive initialization failed \n")); } #endif /* TCP_KEEPALIVE_ENABLED */ if ( result == WICED_SUCCESS ) { /* Receive the query from the TCP client */ if (wiced_tcp_receive( &server->socket, &temp_packet, WICED_WAIT_FOREVER ) == WICED_SUCCESS) { /* Process the client request */ tcp_server_process( server, temp_packet ); /* Delete the packet, we're done with it */ wiced_packet_delete( temp_packet ); #ifdef TCP_KEEPALIVE_ENABLED WPRINT_APP_INFO(("Waiting for data on a socket\n")); /* Check keepalive: wait to see whether the keepalive protocol has commenced */ /* This is achieved by waiting forever for a packet to be received on the TCP connection*/ if (wiced_tcp_receive( &server->socket, &temp_packet, WICED_WAIT_FOREVER ) == WICED_SUCCESS) { tcp_server_process( server, temp_packet ); /* Release the packet, we don't need it any more */ wiced_packet_delete( temp_packet ); } else { WPRINT_APP_INFO(("Connection has been dropped by networking stack\n\n")); } #endif /* TCP_KEEPALIVE_ENABLED */ } else { /* Send failed or connection has been lost, close the existing connection and */ /* get ready to accept the next one */ wiced_tcp_disconnect( &server->socket ); } } } WPRINT_APP_INFO(("Disconnect\n")); wiced_tcp_disconnect( &server->socket ); WICED_END_OF_CURRENT_THREAD( ); }