API  2.2
TSmarT Software Library
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
wifi_tcp_client_server.c

This is an example of how to manage a TCP client and a TCP server at the same time using BSD socket API with the wifi device.

/* @file wifi_tcp_client_server.c
* @author TST
* @version 0.1
* @date 14/06/2012
* @brief This is an example of how to manage a TCP client and server at the same
* time using the wifi device.
*
* The wifi device in use is a CC3000 from Texas Instrument.
* This example shows the user how to manage the TCP connections using the wifi
* interface. This examples manage in two different task a TCP server and a TCP client.
*
* The TCP client will perform a download from "google" website. To achieve it, this
* application uses the HTTP protocol(HEAD method).
* The TCP server is checking if there is a new incoming data. If a new data is
* received, they will be processed by a task.
*
* The interface selection is really done during compiling process. So you shall select
* the adequate interface for the application(WIFI for this example) enabling or
* disabling the following definitions located in the App.defs file in the application
* folder:
*
* MIDDELWARE_INTERFACE = ETHERNET
* MIDDELWARE_INTERFACE = WIFI
* MIDDELWARE_INTERFACE = CELLULAR_2G
*
* After selecting one of them, users only have to use the functions of the interface selected
* besides of the common API functions to program their applications.
*
* To run this application is necessary a TCP client. User can use a Telnet
* protocol for this application, mainly because it's very easy to find one
* Telnet Client.
* Telnet is a network protocol used on the Internet or local area networks
* to provide a bidirectional interactive text-oriented communications facility
* using a virtual terminal connection. Telnet runs over the Transmission
* Control Protocol (TCP) then user can send TCP data to a TSgaTe/TSmoTe in an
* easy way. The TCP port used is 1237.
* Example:
* telnet <your IP board> 1237
*
* @note To run this application it's necessary to set some wireless network parameters:
* - SSID ------------------> Service Set IDentifier. It is also the network name.
* - BSSID -----------------> Basic Service Set Identifier.
* - Network key -----------> Wifi network key.
* - Type of network key ---> type of the network key: open, WEP, WPA, WPA2.
* - Local IP --------------> Set 0.0.0.0 for dynamic IP address.
* - Subnet mask -----------> Set 0.0.0.0 for dynamic IP address.
* - IP gateway ------------> Set 0.0.0.0 for dynamic IP address.
* - DNS -------------------> Set 0.0.0.0 for dynamic IP address.
* User shall set them in the definitions below.
*
* @note This application uses the debug UART to display debug information like ip address asigned.
* According to use it, users should set the next configuration in their serial communication program:
* - Baud rate -----> 115200
* - Word length ---> 8 bits
* - Parity --------> none
* - Stop bit ------> 1
* - Flow control --> none
*
*/
/*-------------------------------------------------------- System headers -------------------------------------------------*/
#include "tsmart.h"
/* Wifi headers */
#include "tsmart_wifi_headers.h"
/*-------------------------------------------------------- UART Debug -----------------------------------------------------*/
#define DEBUG_UART tsmart_uart2
#define APP_RX_BUFFER_SZ 10
static uint8_t app_rx_buf[APP_RX_BUFFER_SZ];
/*-------------------------------------------------------- Global variables -----------------------------------------------*/
volatile unsigned long ulSmartConfigFinished;
volatile unsigned long ulCC3000Connected;
volatile unsigned long ulCC3000DHCP;
volatile unsigned long OkToDoShutDown;
/* Multitask protection */
static xSemaphoreHandle application_mutex;
/*-------------------------------------------------------- Wireless network parameters ------------------------------------*/
/* IP address (0.0.0.0 for dynamic IP address) */
#define TSMART_IP0 0x00
#define TSMART_IP1 0x00
#define TSMART_IP2 0x00
#define TSMART_IP3 0x00
/* Subnet mask (0.0.0.0 for dynamic IP address) */
#define TSMART_MASK0 0x00
#define TSMART_MASK1 0x00
#define TSMART_MASK2 0x00
#define TSMART_MASK3 0x00
/* Gateway address (0.0.0.0 for dynamic IP address) */
#define TSMART_IP_GW0 0x00
#define TSMART_IP_GW1 0x00
#define TSMART_IP_GW2 0x00
#define TSMART_IP_GW3 0x00
/* DNS (0.0.0.0 for dynamic IP address) */
#define TSMART_DNS0 0x00
#define TSMART_DNS1 0x00
#define TSMART_DNS2 0x00
#define TSMART_DNS3 0x00
/* SSID */
#define TSMART_SSID "TSMART_TST"//"<SET YOUR SSID>"
/* Network key */
#define TSMART_KEY "tsmart78"//"<SET YOUR KEY>"
/* Type network key: select one of them */
//#define TSMART_KEY_TYPE WLAN_SEC_UNSEC
//#define TSMART_KEY_TYPE WLAN_SEC_WEP
//#define TSMART_KEY_TYPE WLAN_SEC_WPA
#define TSMART_KEY_TYPE WLAN_SEC_WPA2
/* TCP server port */
#define SERVER_PORT 1237
/*-------------------------------------------------------- Handlers -------------------------------------------------------*/
/* sendDriverPatch
*
*\param pointer to the length
*
*\return none
*
*\brief The function returns a pointer to the driver patch: since there is no patch yet -
* it returns 0
*/
char *sendDriverPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
/*
*sendBootLoaderPatch
*
*\param pointer to the length
*
*\return none
*
*\brief The function returns a pointer to the boot loader patch: since there is no patch yet -
* it returns 0
*/
char *sendBootLoaderPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
/*
* sendWLFWPatch
*
* \param pointer to the length
*
* \return none
*
* \brief The function returns a pointer to the FW patch: since there is no patch yet - it returns 0
*/
char *sendWLFWPatch(unsigned long *Length)
{
*Length = 0;
return NULL;
}
/*
*CC3000_UsynchCallback
*
* \param Event type
*
*\return none
*
*\brief The function handles asynchronous events that come from CC3000 device
*
*/
void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
{
if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
{
/* Create handler */
ulSmartConfigFinished = 1;
}
if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
{
/* Create handler */
ulCC3000Connected = 1;
}
if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
{
/* Create handler */
}
if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
{
/* Create handler */
ulCC3000DHCP = 1;
}
if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
{
/* Create handler */
OkToDoShutDown = 1;
}
}
/*-------------------------------------------------------- Applictions Test -----------------------------------------------*/
/* @brief WIFI task. This task configures and opens a TCP client
* using the BSD sockets API.
* This client uses a HTTP protocol to request the header of the
* google website using a HEAD HTTP method.
*
* In addition it manages a debug UART. Users can display debug
* information using the UART2 using a serial communication
* program in a PC.
*
* @param pvParameters
*/
void vWIFI_CLIENT(void *pvParameters){
/* Variables */
unsigned char pucip_addr[4];
unsigned char pucip_defaultgwaddr[4];
unsigned char pucsubnetmask[4];
unsigned char pucdns[4];
unsigned long ip;
long network_status;
long answer;
static uint8_t debug_buffer1[1000];
sockaddr tremoteaddr;
int ret;
tNetappIpconfigRetArgs ipconfig;
uint8_t google_ip[sizeof(ip)];
int ulsocket;
uint8_t http_head[]="HEAD / HTTP/1.1\r\nHost: www.google.es\r\nAccept: */*\r\n\r\n";
TSMART_UART_Send(&DEBUG_UART, "----------- CT - init -----------\r\n", strlen("----------- CT - init -----------\r\n"), 1000/portTICK_RATE_MS);
/* WLAN On API Implementation */
TSMART_UART_Send(&DEBUG_UART, "CT - wlan init ", strlen("CT - wlan init "), 1000/portTICK_RATE_MS);
TSMART_UART_Send(&DEBUG_UART, "ok\r\n", strlen("ok\r\n"), 1000/portTICK_RATE_MS);
/* Trigger a WLAN device */
TSMART_UART_Send(&DEBUG_UART, "CT - wlan start ", strlen("CT - wlan start "), 1000/portTICK_RATE_MS);
TSMART_UART_Send(&DEBUG_UART, "ok\r\n", strlen("ok\r\n"), 1000/portTICK_RATE_MS);
TSMART_UART_Send(&DEBUG_UART, "CT - wlan set event mask ", strlen("CT - wlan set event mask "), 1000/portTICK_RATE_MS);
/* Mask out all non-required events from CC3000 */
answer = wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
if(answer != 0){
TSMART_UART_Send(&DEBUG_UART, "fail\r\n", strlen("fail\r\n"), 1000/portTICK_RATE_MS);
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, "ok\r\n", strlen("ok\r\n"), 1000/portTICK_RATE_MS);
/* IP configuration */
/* Local IP */
pucip_addr[0] = TSMART_IP0;
pucip_addr[1] = TSMART_IP1;
pucip_addr[2] = TSMART_IP2;
pucip_addr[3] = TSMART_IP3;
/* Network mask */
pucsubnetmask[0] = TSMART_MASK0;
pucsubnetmask[1] = TSMART_MASK1;
pucsubnetmask[2] = TSMART_MASK2;
pucsubnetmask[3] = TSMART_MASK3;
/* Gateway IP */
pucip_defaultgwaddr[0] = TSMART_IP_GW0;
pucip_defaultgwaddr[1] = TSMART_IP_GW1;
pucip_defaultgwaddr[2] = TSMART_IP_GW2;
pucip_defaultgwaddr[3] = TSMART_IP_GW3;
/* DNS */
pucdns[0] = TSMART_DNS0;
pucdns[1] = TSMART_DNS1;
pucdns[2] = TSMART_DNS2;
pucdns[3] = TSMART_DNS3;
answer = netapp_dhcp((unsigned long *)pucip_addr, (unsigned long *)pucsubnetmask, (unsigned long *)pucip_defaultgwaddr, (unsigned long *)pucdns);
if(answer != 0){
TSMART_UART_Send(&DEBUG_UART, "--> FAIL\r\n", strlen("--> FAIL\r\n"), 1000/portTICK_RATE_MS);
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, "CT - IP configuration set\r\n", strlen("CT - IP configuration set\r\n"), 1000/portTICK_RATE_MS);
/* Start a WLAN Connect process */
TSMART_UART_Send(&DEBUG_UART, "CT - Connecting to AP", strlen("CT - Connecting to AP"), 1000/portTICK_RATE_MS);
answer = wlan_connect(TSMART_KEY_TYPE, TSMART_SSID, strlen(TSMART_SSID), 0, TSMART_KEY, strlen(TSMART_KEY));
if(answer != 0){
TSMART_UART_Send(&DEBUG_UART, "--> FAIL\r\n", strlen("--> FAIL\r\n"), 1000/portTICK_RATE_MS);
for(;;);
}
/* Wait for connecting is OK */
do{
network_status = wlan_ioctl_statusget();
TSMART_UART_Send(&DEBUG_UART, ".", strlen("."), 1000/portTICK_RATE_MS);
vTaskDelay(80/portTICK_RATE_MS);
}while(network_status != 3);
TSMART_UART_Send(&DEBUG_UART, "OK\r\n", strlen("OK\r\n"), 1000/portTICK_RATE_MS);
/* Wait for DHCP process to finish (if you are using a static IP address please delete the wait for DHCP event - ulCC3000DHCP */
while ((ulCC3000DHCP == 0) || (ulCC3000Connected == 0)){
hci_unsolicited_event_handler();
vTaskDelay(1000/portTICK_RATE_MS);
}
/* Get Ip configuration */
netapp_ipconfig(&ipconfig);
sprintf(debug_buffer1, "CT - Local IP: %d.%d.%d.%d\r\n", ipconfig.aucIP[3], ipconfig.aucIP[2],ipconfig.aucIP[1], ipconfig.aucIP[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
sprintf(debug_buffer1, "CT - Local MASK: %d.%d.%d.%d\r\n", ipconfig.aucSubnetMask[3], ipconfig.aucSubnetMask[2], ipconfig.aucSubnetMask[1], ipconfig.aucSubnetMask[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
sprintf(debug_buffer1, "CT - GW IP : %d.%d.%d.%d\r\n", ipconfig.aucDefaultGateway[3], ipconfig.aucDefaultGateway[2], ipconfig.aucDefaultGateway[1], ipconfig.aucDefaultGateway[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
sprintf(debug_buffer1, "CT - DNS : %d.%d.%d.%d\r\n", ipconfig.aucDNSServer[3], ipconfig.aucDNSServer[2], ipconfig.aucDNSServer[1], ipconfig.aucDNSServer[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
sprintf(debug_buffer1, "CT - DHCP : %d.%d.%d.%d\r\n", ipconfig.aucDHCPServer[3], ipconfig.aucDHCPServer[2], ipconfig.aucDHCPServer[1], ipconfig.aucDHCPServer[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
sprintf(debug_buffer1, "CT - SSID: %s\r\n", ipconfig.uaSSID);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
/* Get google IP address format */
ret = gethostbyname("www.google.es", strlen("www.google.es"), &ip);
if(ret <0 ){
for(;;);
}
memcpy(google_ip, &ip, sizeof(ip));
sprintf(debug_buffer1, "CT - Google IP: %d.%d.%d.%d\r\n", google_ip[3], google_ip[2], google_ip[1], google_ip[0]);
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
/* Give mutex */
xSemaphoreGive(application_mutex);
/* ------------------------------------------------ CLIENT MODE ----------------------------------------------------------- */
for(;;){
/* Multi-task protection */
xSemaphoreTake(application_mutex, portMAX_DELAY);
/* Get client socket */
TSMART_UART_Send(&DEBUG_UART, "CT - Get client socket\r\n", strlen("CT - Get client socket\r\n"), 1000/portTICK_RATE_MS);
ulsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ulsocket < 0){
for(;;);
}
/* Connect socket */
tremoteaddr.sa_family = AF_INET;
tremoteaddr.sa_data[0] = 0x00;
tremoteaddr.sa_data[1] = 0x50;
tremoteaddr.sa_data[2] = google_ip[3];
tremoteaddr.sa_data[3] = google_ip[2];
tremoteaddr.sa_data[4] = google_ip[1];
tremoteaddr.sa_data[5] = google_ip[0];
TSMART_UART_Send(&DEBUG_UART, "CT - Connecting client socket\r\n", strlen("CT - Connecting client socket\r\n"), 1000/portTICK_RATE_MS);
ret = connect(ulsocket, &tremoteaddr, sizeof(tremoteaddr));
if (ret == -1) {
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, "CT - Sending: Google Header...", strlen("CT - Sending: Google Header..."), 1000/portTICK_RATE_MS);
/* Request HTTP: HEAD */
ret = send(ulsocket, http_head, strlen(http_head), 0);
if (ret != strlen(http_head)){
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, "\r\n\r\n\r\n", strlen("\r\n\r\n\r\n"), 1000/portTICK_RATE_MS);
/* Reset buffer */
memset(debug_buffer1, 0x00, sizeof(debug_buffer1));
/* Read socket */
ret = recv(ulsocket, debug_buffer1, sizeof(debug_buffer1) - 1, 0);
if(ret < 0){
TSMART_UART_Send(&DEBUG_UART, "fail\r\n", strlen("fail\r\n"), 1000/portTICK_RATE_MS);
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, debug_buffer1, strlen(debug_buffer1), 1000/portTICK_RATE_MS);
/* Close socket */
TSMART_UART_Send(&DEBUG_UART, "\r\n\r\n\r\nCT - Closing client socket\r\n", strlen("\r\n\r\n\r\nCT - Closing client socket\r\n"), 1000/portTICK_RATE_MS);
if(closesocket(ulsocket) < 0){
for(;;);
}
/* Give mutex */
xSemaphoreGive(application_mutex);
vTaskDelay(1000/portTICK_RATE_MS);
}
/* Wait forever */
for(;;);
}/* End task */
/* @brief SERVER task
*
* This task opens a TCP server using the BSD sockets API.
* After that, the program is waiting for incomming data.
*
* In addition it manages a debug UART. Users can display debug
* information using the UART2 using a serial communication
* program in a PC.
*/
void vWIFI_SERVER(void *pvParameters){
/* Variables */
long answer;
static uint8_t debug_buffer2[500];
int ret;
int clientfd;
int ulsocket;
socklen_t tsoclength ;
sockaddr saddrclient;
sockaddr saddrserver;
TSMART_UART_Send(&DEBUG_UART, "----------- ST - init -----------\r\n", strlen("----------- ST - init -----------\r\n"), 1000/portTICK_RATE_MS);
/* Multi-task protection */
xSemaphoreTake(application_mutex, portMAX_DELAY);
/* ------------------------------------------------ SERVER MODE ----------------------------------------------------------- */
/* Get server socket */
TSMART_UART_Send(&DEBUG_UART, "ST - Get socket\r\n", strlen("ST - Get socket\r\n"), 1000/portTICK_RATE_MS);
ulsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ulsocket < 0){
for(;;);
}
/* Bind a socket */
saddrserver.sa_family = AF_INET;
saddrserver.sa_data[0] = (SERVER_PORT & 0xFF00) >> 8;
saddrserver.sa_data[1] = (SERVER_PORT & 0x00FF) >> 0;
saddrserver.sa_data[2] = 0x00;
saddrserver.sa_data[3] = 0x00;
saddrserver.sa_data[4] = 0x00;
saddrserver.sa_data[5] = 0x00;
TSMART_UART_Send(&DEBUG_UART, "ST - Blind socket\r\n", strlen(" ST - Blind socket\r\n"), 1000/portTICK_RATE_MS);
ret = bind(ulsocket, &saddrserver, sizeof(saddrserver));
if (ret < 0) {
for(;;);
}
/* Listen */
TSMART_UART_Send(&DEBUG_UART, "ST - Listen socket\r\n", strlen("ST -Listen socket\r\n"), 1000/portTICK_RATE_MS);
ret = listen(ulsocket, 1);
if ( ret != 0 ){
for(;;);
}
/* Give mutex */
xSemaphoreGive(application_mutex);
tsoclength = sizeof(saddrclient);
for(;;){
TSMART_UART_Send(&DEBUG_UART, "ST - Wait for incoming client...\r\n", strlen("ST - Wait for incoming client...\r\n"), 1000/portTICK_RATE_MS);
/* Multi-task protection */
xSemaphoreTake(application_mutex, portMAX_DELAY);
/* Wait for accepting new connection */
clientfd = accept(ulsocket, &saddrclient, &tsoclength);
if (clientfd > 0){
TSMART_UART_Send(&DEBUG_UART, "ST - Client accepted\r\n", strlen("ST - Client accepted\r\n"), 1000/portTICK_RATE_MS);
/* Send to the remote TCP client the exit condition */
ret = send(clientfd, "Press '*' to exit\r\n", sizeof("Press '*' to exit\r\n"), 0);
/* Wait for a moment */
vTaskDelay(500/portTICK_RATE_MS);
/* Received information */
do{
TSMART_UART_Send(&DEBUG_UART, "ST - received-> ", strlen("ST - received-> "), 1000/portTICK_RATE_MS);
memset(debug_buffer2, 0x00, sizeof(debug_buffer2));
ret = recv(clientfd, debug_buffer2, sizeof(debug_buffer2)-1, 0);
if(ret <= 0){
TSMART_UART_Send(&DEBUG_UART, "ST - Timeout to recieve\r\n", strlen("ST - Timeout to recieve\r\n"), 1000/portTICK_RATE_MS);
for(;;);
}
TSMART_UART_Send(&DEBUG_UART, debug_buffer2, strlen(debug_buffer2), 1000/portTICK_RATE_MS);
}while(debug_buffer2[0] != '*');
/* Close socket */
TSMART_UART_Send(&DEBUG_UART, "ST - Closing socket", strlen("ST - Closing socket"), 1000/portTICK_RATE_MS);
if(closesocket(clientfd) < 0){
for(;;);
}
/* Give mutex */
xSemaphoreGive(application_mutex);
}else{
/* Give mutex */
xSemaphoreGive(application_mutex);
vTaskDelay(1000/portTICK_RATE_MS);
TSMART_UART_Send(&DEBUG_UART, "ST - Expired timeout to accept\r\n", strlen("ST - Expired timeout to accept\r\n"), 1000/portTICK_RATE_MS);
}
}
/* Wait forever */
for(;;);
}/* End task */
/*
* @brief init() function
*
* This is the first thing that the user must do for using TSmarT.
* It initializes the specific hardware resources (CELLULAR, GPS, AI, DIO, MODBUS, MSA...)
* and software resources (queues, mutex, tasks...) for the user application.
*
* The way to fill in this function properly is to initialize first
* hardware resources and after that software resources.
*
* This function must return: TSMART_PASS when every thing is OK or
* TSMART_FAIL when a failure happened.
*
* @return
* @arg TSMART_PASS
* @arg TSMART_FAIL
*/
int32_t init() {
/* Variables */
tsmart_uart_config_t tsmart_uart_config;
/*----------------------- Debug Mode ----------------------------------------*/
/*----------------------- Initialize resources ------------------------------*/
if(TSMART_WIFI_Init() != TSMART_PASS){
return TSMART_FAIL;
}
/* Initialize Debug UART */
tsmart_uart_config.baud_rate = 115200;
tsmart_uart_config.flow_control = TSMART_UART_FC_NONE;
tsmart_uart_config.parity_bit = TSMART_UART_PARITY_NONE;
tsmart_uart_config.word_length = TSMART_UART_WORDLENGTH_8B;
tsmart_uart_config.stop_bit = TSMART_UART_STOPBITS_1;
tsmart_uart_config.rx_buf_sz = APP_RX_BUFFER_SZ;
tsmart_uart_config.rx_buf = app_rx_buf;
tsmart_uart_config.use_dma = TSMART_UART_DMA_RX_TX;
tsmart_uart_config.use_tim = TSMART_UART_TIM_SW;
TSMART_UART_Init(&DEBUG_UART, &tsmart_uart_config);
/*----------------------- Application task ----------------------------------*/
/* Multi-task protection */
application_mutex = xSemaphoreCreateMutex();
if (application_mutex == NULL){
return TSMART_FAIL;
}
xSemaphoreTake(application_mutex, portMAX_DELAY);
/* Create wifi client task */
if(xTaskCreate(vWIFI_CLIENT, "WIFI_CLIENT", 2048, NULL, 8, NULL) != pdPASS){
return TSMART_FAIL;
}
/* Create wifi server task */
if(xTaskCreate(vWIFI_SERVER, "WIFI_SERVER", 2048, NULL, 9, NULL) != pdPASS){
return TSMART_FAIL;
}
/* Everything OK */
return TSMART_PASS;
}