Add a recv buffer per socket.

* WINC partial recv bug workaround.
This commit is contained in:
iabdalkader 2018-08-14 15:15:51 +02:00
parent fd46a946e2
commit 673fca8432
6 changed files with 57 additions and 33 deletions

View File

@ -56,7 +56,7 @@
#define OMV_FB_SIZE (151K) // FB memory: header + QVGA/GS image
#define OMV_FB_ALLOC_SIZE (12K) // minimum fb alloc size
#define OMV_STACK_SIZE (4K)
#define OMV_HEAP_SIZE (52K)
#define OMV_HEAP_SIZE (51K)
#define OMV_LINE_BUF_SIZE (2K) // Image line buffer round(320 * 2BPP * 2 buffers).
#define OMV_MSC_BUF_SIZE (2K) // USB MSC bot data

View File

@ -55,7 +55,7 @@
#define OMV_FB_SIZE (301K) // FB memory: header + VGA/GS image
#define OMV_FB_ALLOC_SIZE (83K) // minimum fb alloc size
#define OMV_STACK_SIZE (4K)
#define OMV_HEAP_SIZE (55K)
#define OMV_HEAP_SIZE (54K)
#define OMV_LINE_BUF_SIZE (3K) // Image line buffer round(640 * 2BPP * 2 buffers).
#define OMV_MSC_BUF_SIZE (2K) // USB MSC bot data

View File

@ -437,7 +437,7 @@ static mp_uint_t py_winc_socket_send(mod_network_socket_obj_t *socket, const byt
static mp_uint_t py_winc_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno)
{
int ret = winc_socket_recv(socket->fd, buf, len, socket->timeout);
int ret = winc_socket_recv(socket->fd, buf, len, &socket->sockbuf, socket->timeout);
if (ret < 0) {
*_errno = ret;
py_winc_socket_close(socket);

View File

@ -69,6 +69,7 @@ static int udpbcast_fd = -1;
static int udpbcast_time = 0;
static uint8_t ip_addr[WINC_IP_ADDR_LEN] = {};
static char udpbcast_string[UDPCAST_STRING_SIZE] = {};
static winc_socket_buf_t sockbuf;
int wifidbg_init(wifidbg_config_t *config)
{
@ -130,8 +131,8 @@ void wifidbg_dispatch()
uint8_t buf[BUFFER_SIZE];
sockaddr client_sockaddr;
if (udpbcast_fd < 0) {
// Create broadcast socket
if (client_fd < 0 && udpbcast_fd < 0) {
// Create broadcast socket.
MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT)
if ((udpbcast_fd = winc_socket_socket(SOCK_DGRAM)) < 0) {
@ -142,18 +143,21 @@ void wifidbg_dispatch()
close_udpbcast_socket();
return;
}
return;
}
if ((udpbcast_fd >= 0) && (!(udpbcast_time++ % 100))) {
// Create broadcast socket
if (client_fd < 0 && (udpbcast_fd >= 0) && (!(udpbcast_time++ % 1000))) {
// Broadcast message to the IDE.
MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT)
if ((ret = winc_socket_sendto(udpbcast_fd,
(uint8_t *) udpbcast_string, strlen(udpbcast_string) + 1,
&udpbcast_sockaddr, 500)) < 0) {
if ((ret = winc_socket_sendto(udpbcast_fd, (uint8_t *) udpbcast_string,
strlen(udpbcast_string) + 1, &udpbcast_sockaddr, 500)) < 0) {
close_udpbcast_socket();
return;
}
return;
}
if (server_fd < 0) {
@ -173,9 +177,12 @@ void wifidbg_dispatch()
close_server_socket();
return;
}
return;
}
if (client_fd < 0) {
sockbuf.size = sockbuf.idx = 0;
// Call accept.
if ((ret = winc_socket_accept(server_fd,
&client_sockaddr, &client_fd, 10)) < 0) {
@ -186,17 +193,23 @@ void wifidbg_dispatch()
}
return;
}
return;
}
if ((ret = winc_socket_recv(client_fd, buf, 8, 10)) < 0) {
if ((ret = winc_socket_recv(client_fd, buf, 6, &sockbuf, 10)) < 0) {
if (TIMEDOUT(ret)) {
return;
} else {
close_server_socket();
close_all_sockets();
return;
}
}
if (ret != 6 || buf[0] != 0x30) {
return;
}
uint8_t request = buf[1];
uint32_t xfer_length = *((uint32_t*)(buf+2));
usbdbg_control(buf+6, request, xfer_length);
@ -214,7 +227,7 @@ void wifidbg_dispatch()
} else {
// Host-to-device data phase
int bytes = MIN(xfer_length, BUFFER_SIZE);
if ((ret = winc_socket_recv(client_fd, buf, bytes, 500)) < 0) {
if ((ret = winc_socket_recv(client_fd, buf, bytes, &sockbuf, 500)) < 0) {
close_all_sockets();
return;
}

View File

@ -14,6 +14,7 @@
#define WINC_MAX_SSID_LEN (33)
#define WINC_MAX_PSK_LEN (65)
#define WINC_MAX_BOARD_NAME_LEN (33)
#define WINC_SOCKBUF_SIZE (1400)
#define MAKE_SOCKADDR(addr, ip, port) \
struct sockaddr addr; \
@ -81,6 +82,13 @@ typedef struct {
uint16_t timeout;
} winc_socket_t;
// Sock buffer workaround for WINC's recv issue.
typedef struct {
int idx;
int size;
uint8_t buf[WINC_SOCKBUF_SIZE];
} winc_socket_buf_t;
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
@ -107,7 +115,7 @@ int winc_socket_listen(int fd, uint32_t backlog);
int winc_socket_accept(int fd, sockaddr *addr, int *fd_out, uint32_t timeout);
int winc_socket_connect(int fd, sockaddr *addr, uint32_t timeout);
int winc_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout);
int winc_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout);
int winc_socket_recv(int fd, uint8_t *buf, uint32_t len, winc_socket_buf_t *sockbuf, uint32_t timeout);
int winc_socket_sendto(int fd, const uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout);
int winc_socket_recvfrom(int fd, uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout);
int winc_socket_setsockopt(int fd, uint32_t level, uint32_t opt, const void *optval, uint32_t optlen);

View File

@ -385,13 +385,6 @@ static int winc_async_request(uint8_t msg_type, void *ret, uint32_t timeout)
async_request_data = ret;
async_request_done = false;
async_request_type = msg_type;
if (msg_type != SOCKET_MSG_ACCEPT) {
// Only use async timeout for accept since it doesn't have a timeout arg.
// For other calls that have a timeout arg, we use a large async timeout.
timeout = 1000;
}
uint32_t tick_start = HAL_GetTick();
// Wait for async request to finish.
@ -769,22 +762,32 @@ int winc_socket_send(int fd, const uint8_t *buf, uint32_t len, uint32_t timeout)
return bytes;
}
int winc_socket_recv(int fd, uint8_t *buf, uint32_t len, uint32_t timeout)
int winc_socket_recv(int fd, uint8_t *buf, uint32_t len, winc_socket_buf_t *sockbuf, uint32_t timeout)
{
// cap length at SOCKET_BUFFER_MAX_LENGTH
len = MIN(len, SOCKET_BUFFER_MAX_LENGTH);
if (sockbuf->size == 0) { // No buffered data.
sockbuf->idx = 0; // Reset sockbuf index.
// do the recv
int ret = WINC1500_EXPORT(recv)(fd, buf, len, timeout);
if (ret == SOCK_ERR_NO_ERROR) {
// Do async request
ret = winc_async_request(SOCKET_MSG_RECV, &len, timeout);
int recv_bytes;
// Set recv to the maximum possible packet size.
int ret = WINC1500_EXPORT(recv)(fd, sockbuf->buf, SOCKET_BUFFER_MAX_LENGTH, timeout);
if (ret == SOCK_ERR_NO_ERROR) {
// Do async request
// sockbuf->size is the actual size of the recv'd packet.
ret = winc_async_request(SOCKET_MSG_RECV, &recv_bytes, timeout);
}
if (ret != SOCK_ERR_NO_ERROR || recv_bytes <= 0) {
return (recv_bytes <= 0)? recv_bytes : ret;
}
sockbuf->size = recv_bytes;
}
if (ret != SOCK_ERR_NO_ERROR) {
return ret;
}
return len;
uint32_t bytes = MIN(len, sockbuf->size);
memcpy(buf, sockbuf->buf+sockbuf->idx, bytes);
sockbuf->idx += bytes;
sockbuf->size -= bytes;
return bytes;
}
int winc_socket_sendto(int fd, const uint8_t *buf, uint32_t len, sockaddr *addr, uint32_t timeout)