Unfortunately, I couldn't send you whole my project, but I can show my lwip config and code, where I use sockets. If it is really needed, I can try to create small project with only this tasks. (sorry, I can't send whole project.)
1-st task with UDP socket:
const upx_request_t* p_req = NULL;
const upx_reply_t* p_rep = NULL;
int socket_fd;
struct sockaddr_in self;
struct sockaddr_in client;
size_t client_len;
int bytes_recv = 0;
int bytes_sent = 0;
hal_base_type status = hal_queue_fail;
while ( (socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
hal_task_delay(SHORT_DELAY);
}
memset(&self, 0, sizeof(struct sockaddr_in));
self.sin_family = AF_INET;
self.sin_len = sizeof(self);
self.sin_addr.s_addr = htonl(INADDR_ANY);
self.sin_port = htons(PRGSERVER_PORT);
while ( bind(socket_fd,
(struct sockaddr*)&self,
sizeof(struct sockaddr_in)) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
LOG(LOG_PRGSERVER, LOG_DEVEL, "Bind to port: %u", PRGSERVER_PORT);
while (true) {
memset(&req, 0, sizeof(upx_request_t));
bytes_recv = recvfrom(socket_fd, &req,
sizeof(req),
0,
(struct sockaddr *)&client,
&client_len);
req.header.num = ntohl(req.header.num);
LOG(LOG_PRGSERVER, LOG_NOTICE, "Received: %d bytes", bytes_recv);
if(bytes_recv < UPX_MIN_DATA_LENGTH) {
LOG(LOG_PRGSERVER,
LOG_ERROR,
"Insufficient UPX length: %d bytes. Minimum is: %d bytes",
bytes_recv,
UPX_MIN_DATA_LENGTH);
continue;
}
p_req = &req;
do {
status = hal_queue_send(q_upx_request,
&p_req,
UPX_QUEUE_SEND_WAIT);
} while ( hal_queue_ok != status);
do {
status = hal_queue_receive(q_upx_reply,
&p_rep,
UPX_QUEUE_RECEIVE_WAIT);
} while ( hal_queue_ok != status);
if( ! p_rep) {
continue;
}
size_t send_len = sizeof(p_rep->id) + req.header.fld.len + 1;
bytes_sent = sendto(socket_fd,
p_rep,
send_len,
0,
(struct sockaddr *)&client,
client_len);
LOG(LOG_PRGSERVER, LOG_NOTICE, "Sent: %d bytes", bytes_sent);
}
2-nd task with TCP socket:
struct sockaddr_in self;
struct sockaddr_in client;
int client_fd;
int socket_fd;
int addr_len = sizeof( struct sockaddr_in );
while ( (socket_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
memset((char *)&self, 0, sizeof(self));
self.sin_family = AF_INET;
self.sin_len = sizeof(self);
self.sin_addr.s_addr = htonl(INADDR_ANY);
self.sin_port = ntohs( ( ( uint16_t ) LOG_PORT ) );
while( bind( socket_fd, ( struct sockaddr *) &self, sizeof( self ) ) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
while( listen( socket_fd, LISTEN_SOCKET_BACKLOG ) != 0 ) {
hal_task_delay(SHORT_DELAY);
}
while(true) {
while( (client_fd = accept( socket_fd,
( struct sockaddr * ) &client,
( u32_t * ) &addr_len )) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
while(true) {
if(hal_queue_ok == hal_queue_receive(q_log_net,
&msg,
LOG_NET_QUEUE_RECEIVE_WAIT)) {
if( sendto(client_fd,
&(msg.message),
msg.length,
0,
(struct sockaddr *)&client,
addr_len) < 0) {
break;
}
}
}
close(client_fd);
}
3-rd task with TCP socket:
register_commands();
hal_base_type status = hal_fail;
struct sockaddr_in self;
struct sockaddr_in client;
int client_fd;
int socket_fd;
int addr_len = sizeof( struct sockaddr_in );
char c_in = 0;
uint8_t c_in_index = 0;
signed char* p_out_string = NULL;
int8_t input_string[ MAX_CMD_LEN ];
int bytes = 0;
while ( (socket_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
memset((char *)&self, 0, sizeof(self));
self.sin_family = AF_INET;
self.sin_len = sizeof(self);
self.sin_addr.s_addr = htonl(INADDR_ANY);
self.sin_port = ntohs( ( ( uint16_t ) TELNET_PORT ) );
while( bind( socket_fd, ( struct sockaddr *) &self, sizeof( self ) ) < 0 ) {
hal_task_delay(SHORT_DELAY);
}
LOG(LOG_COMMAND_CENTER, LOG_DEVEL, "Bind to port: %u", TELNET_PORT);
while( listen( socket_fd, LISTEN_SOCKET_BACKLOG ) != 0 ) {
hal_task_delay(SHORT_DELAY);
}
while(true) {
while( (client_fd = accept( socket_fd,
( struct sockaddr * ) &client,
( u32_t * ) &addr_len )) < 0L ) {
hal_task_delay(SHORT_DELAY);
hal_yield();
}
memset(input_string, 0x00, MAX_CMD_LEN);
p_out_string = FreeRTOS_CLIGetOutputBuffer();
while (send( client_fd, GREETING,
strlen( ( const char * ) GREETING ), 0 ) < 0) {
hal_task_delay(SHORT_DELAY);
}
while (send( client_fd, "version: ",
strlen( ( const char * ) "version: " ), 0 ) < 0) {
hal_task_delay(SHORT_DELAY);
}
while (send( client_fd, git_revision,
strlen( ( const char * ) git_revision ), 0 ) < 0) {
hal_task_delay(SHORT_DELAY);
}
while (send( client_fd, PROMPT,
strlen( ( const char * ) PROMPT ), 0 ) < 0) {
hal_task_delay(SHORT_DELAY);
}
c_in_index = 0;
memset( input_string, 0x00, MAX_CMD_LEN );
do {
if ( (bytes = recv( client_fd, &c_in, sizeof( c_in ), 0 )) <= 0L ) {
break;
}
// if(!is_character_allowed(c_in)) {
// continue;
// }
if( c_in == '\n' ) {
if( strncmp( QUIT_CMD, ( const char * ) input_string,
strlen(QUIT_CMD) ) == 0 ) {
bytes = 0L;
} else {
do {
p_out_string[0]=0x00;
status = FreeRTOS_CLIProcessCommand( input_string,
p_out_string,
configCOMMAND_INT_MAX_OUTPUT_SIZE );
send( client_fd, p_out_string,
strlen( ( const char * ) p_out_string ), 0 );
} while( status != hal_fail );
c_in_index = 0;
memset( input_string, 0x00, MAX_CMD_LEN );
send( client_fd, PROMPT,
strlen( ( const char * ) PROMPT ), 0 );
}
} else if( (c_in == '\b') && (c_in_index > 0) ) {
c_in_index--;
input_string[ c_in_index ] = '\0';
} else if( (c_in_index < MAX_CMD_LEN) && (c_in != '\r') ) {
input_string[ c_in_index ] = c_in;
c_in_index++;
}
} while( bytes > 0L );
close(client_fd);
}
Shortly, in UDP task, I receive UDP packet, process it, and send reply.
The 2-nd task is a log server, when I connects to port LOG_PORT, it start send log messages to the connected client.
The 3-rd task is something like telnet server, it receives commands and sends result to the client.
I've always only one client for each task.
In my application I have some hardware abstraction layer(hal), all functions like hal_queue_receive is macroses, that expands to FreeRTOS xQueueReceive call, for example.
My CPU have cortex-m4 architecture, if it is important.