MyTetra Share
Делитесь знаниями!
server.c
Время создания: 28.11.2018 17:34
Раздел: Electronics - Microcontrollers - STM32 - Hunter - v3.2

#include "server.h"


/*##################################################################################

EXTERNAL VARIABLES

##################################################################################*/

extern UART_HandleTypeDef huart6;

extern USART_prop_ptr usartProp;

//extern char dataPacket[64];



/*##################################################################################

INTERNAL GLOBAL VARIABLES

##################################################################################*/

struct tcp_pcb* server_pcb;


char tcpDataPacket[TCP_WND+1];

uint32_t tcpDataLen = 0;

uint8_t serverHasConnection = 0;



/*##################################################################################

STATIC FUNCTIONS DEFINITIONS

##################################################################################*/

static err_t tcpServerAccept(void *arg, struct tcp_pcb *newpcb, err_t err);

static err_t tcpServerRecvClbck(void *arg, struct tcp_pcb *tpcb, struct pbuf *p , err_t err);

static void tcpServerErrorClbck(void *arg, err_t err);

static err_t tcpServerPollClbck(void *arg, struct tcp_pcb *tpcb);

static err_t tcpServerSentClbck(void *arg, struct tcp_pcb *tpcb, u16_t len);

static void tcpServerSendData(struct tcp_pcb *tpcb, struct ServerStruct *es);

static void tcpServerCloseConnection(struct tcp_pcb *tpcb, struct ServerStruct *es);


static void tcpStoreData(struct tcp_pcb *tpcb, struct ServerStruct *es);



/*##################################################################################

FUNCTIONS

##################################################################################*/

/*==============================================

tcp_recv(…) - Is used to initialize callback function

tcp_sent(…) - Specify a callback function

tcp_sndbuf(…) - Get the maximum amount of data that can be sent

tcp_write(…) - To enqueue the data

tcp_output(…) - To force the data to be sent

==============================================*/


/*==============================================

LWIP Client Incoming

* @param arg: not used

* @param newpcb: pointer on tcp_pcb struct for the newly created tcp connection

* @param err: not used

* @retval err_t: error status

==============================================*/

static err_t tcpServerAccept(void *arg, struct tcp_pcb *newpcb, err_t err)

{

err_t ret_err;

#ifdef __MDEBUG__

if(serverHasConnection < MEMP_NUM_TCP_PCB)

{

#endif

LWIP_UNUSED_ARG(arg);

LWIP_UNUSED_ARG(err);

tcp_setprio(newpcb, TCP_PRIO_MIN);

struct ServerStruct *es; //allocate structure es to maintain tcp connection informations

es = (struct ServerStruct *)mem_malloc(sizeof(struct ServerStruct));

if (es != NULL)

{

es->state = ES_S_ACCEPTED;

es->server_pcb = newpcb;

es->p = NULL;


tcp_arg(newpcb, es);

tcp_recv(newpcb, tcpServerRecvClbck); //initialize tcp_recv callback function

tcp_err(newpcb, tcpServerErrorClbck); //initialize tcp_err callback function

tcp_sent(newpcb, tcpServerSentClbck); //initialize tcp_sent callback function

tcp_poll(newpcb, tcpServerPollClbck, 0); //initialize tcp_poll callback function

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV: GOT_CONNECTION\n\r", 24, 0x0F);


++serverHasConnection;

//#ifdef __MDEBUG__

if(serverHasConnection >= MEMP_NUM_TCP_PCB)

{

}

//#endif

ret_err = ERR_OK;

}

else

{

tcpServerCloseConnection(newpcb, es);

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_ACCEPT_ERR_MEM\n\r", 23, 0x0F);

ret_err = ERR_MEM;

}

#ifdef __MDEBUG__

}

else

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_NOFREESLOTS\n\r", 20, 0x0F);

ret_err = ERR_ABRT;

}

#endif

return ret_err;

}


/*==============================================

TCP Server Receive Callback

==============================================*/

static err_t tcpServerRecvClbck(void *arg, struct tcp_pcb *tpcb, struct pbuf *p , err_t err)

{

err_t ret_err;

struct ServerStruct *es;

LWIP_ASSERT("arg != NULL", arg != NULL);

es = (struct ServerStruct *)arg;

if(p == NULL) /* if we receive an empty tcp frame from client => close connection */

{

es->state = ES_S_CLOSING;

if(es->p == NULL)

{

//tcp_recved(tpcb, p->tot_len);

tcpServerCloseConnection(tpcb, es); /* we're done sending, close connection */

}

else

{

/* we're not done yet */

tcp_sent(tpcb, tcpServerSentClbck); //acknowledge received packet

tcpServerSendData(tpcb, es); //send remaining data

}

ret_err = ERR_OK;

}

/* a non empty frame was received from client but for some reason err != ERR_OK */

else if(err != ERR_OK)

{

if(p != NULL) //some data in buffer, free it

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRVDBG: recv_busy\n\r", 22, 0x0F);

es->p = NULL;

pbuf_free(p);

}

ret_err = err;

}

else if(es->state == ES_S_ACCEPTED) //accepted 1st part of packet

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRVDBG: s_accepted\n\r", 23, 0x0F);

es->state = ES_S_RECEIVED;

es->p = p;

tcp_sent(tpcb, tcpServerSentClbck);

/////////////////////=========================////////////////////////

//some action after receiving new part of data:

//tcpServerSendData(tpcb, es);

tcpStoreData(tpcb, es);

/////////////////////=========================////////////////////////

ret_err = ERR_OK;

}

else if(es->state == ES_S_RECEIVED) //receiving other parts of packet

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRVDBG: s_received ", 22, 0x0F);

if(es->p == NULL)

{

HAL_UART_Transmit(&huart6, (uint8_t*)"OK\n\r", 4, 0x0F);

es->p = p;

//tcpServerSendData(tpcb, es);

tcpStoreData(tpcb, es);

}

else

{

HAL_UART_Transmit(&huart6, (uint8_t*)"--\n\r", 4, 0x0F);

struct pbuf* ptr;

ptr = es->p;

pbuf_chain(ptr, p);

}

ret_err = ERR_OK;

}

else //free buffer

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRVDBG: recv_end\n\r", 22, 0x0F);

tcp_recved(tpcb, p->tot_len);

es->p = NULL;

pbuf_free(p);

ret_err = ERR_OK;

}

/*

if(tcpDataLen > 5)

{

strncpy(tcpDataPacket + tcpDataLen, "\r\n", 2);

tcpDataLen += 2;

tcp_write(tpcb, tcpDataPacket, tcpDataLen, 1);

tcpDataLen = 0;

}

*/

return ret_err;

}


/*==============================================

TCP Server Error Callback

==============================================*/

static void tcpServerErrorClbck(void *arg, err_t err)

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_ERR\n\r", 12, 0x0F);

}


/*==============================================

TCP Server Poll Callback

==============================================*/

static err_t tcpServerPollClbck(void *arg, struct tcp_pcb *tpcb)

{

err_t ret_err;

struct ServerStruct *es;

es = (struct ServerStruct*)arg;

//turn on LED

if(es != NULL)

{

if(es->p != NULL)

{

//some error?

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_POLL_BUFF\n\r", 18, 0x0F);

}

else

{

if(es->state == ES_S_CLOSING)

{

tcpServerCloseConnection(tpcb, es);

}

/////////////////////=========================////////////////////////

// if(usartProp.isText)

// {

// usartProp.isText = 0;

// }

/////////////////////=========================////////////////////////

}

ret_err = ERR_OK;

}

else

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_POLL_ABRT\n\r", 18, 0x0F);

tcp_abort(tpcb);

ret_err = ERR_ABRT;

}

return ret_err;

}


/*==============================================

TCP Server Sent Callback

==============================================*/

static err_t tcpServerSentClbck(void *arg, struct tcp_pcb *tpcb, u16_t len)

{

struct ServerStruct *es;

LWIP_UNUSED_ARG(len);

es = (struct ServerStruct*)arg;

es->retries = 0;

if(es->p != NULL)

{

tcpServerSendData(tpcb, es);

}

else

{

if(es->state == ES_S_CLOSING)

{ tcpServerCloseConnection(tpcb, es); }

}

return ERR_OK;

}


/*==============================================

TCP Send Data from Server

==============================================*/

static void tcpServerSendData(struct tcp_pcb *tpcb, struct ServerStruct *es)

{

struct pbuf *ptr;

err_t wr_err = ERR_OK;

while((wr_err == ERR_OK) &&

(es->p != NULL) &&

(es->p->len <= tcp_sndbuf(tpcb)))

{

ptr = es->p;

wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);


if(wr_err == ERR_OK)

{

u16_t plen;

plen = ptr->len;

es->p = ptr->next;


if(es->p != NULL)

{

pbuf_ref(es->p);

}

pbuf_free(ptr);

tcp_recved(tpcb, plen);

}

else if(wr_err == ERR_MEM)

{

es->p = ptr;

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_SND_ERR_MEM\n\r", 22, 0x0F);

}

else

{

//other problem

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_SND_OTHER\n\r", 18, 0x0F);

}

}

}


/*==============================================

TCP Close Connection

==============================================*/

static void tcpServerCloseConnection(struct tcp_pcb *tpcb, struct ServerStruct *es)

{

HAL_UART_Transmit(&huart6, (uint8_t*)"close\n\r", 7, 0x0F);


if(serverHasConnection)

{

--serverHasConnection;

}

//remove all callbacks

tcp_arg(es->server_pcb, NULL);

tcp_sent(es->server_pcb, NULL);

tcp_recv(es->server_pcb, NULL);

tcp_err(es->server_pcb, NULL);

tcp_poll(es->server_pcb, NULL, 0);

if(es != NULL)

{

mem_free(es);

}

tcp_close(tpcb);

}


/*==============================================

LWIP Server Initialization

==============================================*/

void tcpServerInit(void)

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_INIT\n\r", 14, 0x0F);

server_pcb = tcp_new(); //create new tcp pcb structure

if(server_pcb != NULL)

{

err_t err;

err = tcp_bind(server_pcb, IP_ADDR_ANY, SERVER_LISTEN_PORT); //bind tcp port

if(err == ERR_OK)

{

//HAL_UART_Transmit(&huart6, (uint8_t*)"srvini\n\r", 8, 0x0F);

server_pcb = tcp_listen(server_pcb); //start tcp listening

tcp_accept(server_pcb, tcpServerAccept); //callback function tcpServerAccept when connection occurs

}

else

{

HAL_UART_Transmit(&huart6, (uint8_t*)"TCPSRV_INIT_ERR_MEM\n\r", 22, 0x0F);

memp_free(MEMP_TCP_PCB, server_pcb); //deallocate pcb

}

}

}


/*==============================================

Send String to Server (NOT!!! to connected Host)

==============================================*/

void tcpServerSendString(char* bufStr) //send string to server

{

/*

if(serverHasConnection)

{

usartProp.isText = 1;


tcp_sent(ss->server_pcb, tcpServerSentClbck);

tcp_write(ss->server_pcb, (void*)bufStr, strlen(bufStr), 1);

tcp_recved(ss->server_pcb, strlen(bufStr));

}

else

{

}

usartProp.usartBufCnt = 0;

*/

}


/*==============================================

Save Data from Buffer

==============================================*/

static void tcpStoreData(struct tcp_pcb *tpcb, struct ServerStruct *es)

{

struct pbuf *ptr;

err_t wr_err = ERR_OK;

while((wr_err == ERR_OK) &&

(es->p != NULL) &&

(es->p->len <= tcp_sndbuf(tpcb)))

{

ptr = es->p;

strncpy(tcpDataPacket+tcpDataLen, ptr->payload, ptr->len);

tcpDataLen += ptr->len;


u16_t plen;

plen = ptr->len;

es->p = ptr->next;

if(es->p != NULL)

{

pbuf_ref(es->p);

}

pbuf_free(ptr);

tcp_recved(tpcb, plen);

}

}


Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования