diff --git a/mongoose.c b/mongoose.c index ffcfb3ccd32c16e0f6794638b3a0e5c5a71c6e9c..a5ffa8d7e629bcafb80df97f2ef47e9025d1ff4c 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7866,7 +7866,7 @@ void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len, if (inet_ntop(sa->sa.sa_family, addr, start, capacity) == NULL) { *buf = '\0'; } -#elif defined(_WIN32) || MG_LWIP +#elif defined(_WIN32) || MG_LWIP || (MG_NET_IF == MG_NET_IF_PIC32_HARMONY) /* Only Windoze Vista (and newer) have inet_ntop() */ strncpy(buf, inet_ntoa(sa->sin.sin_addr), len); #else @@ -12316,3 +12316,240 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) { } #endif +#ifdef MG_MODULE_LINES +#line 1 "common/platforms/pic32_harmony/pic32_harmony_net_if.c" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#if CS_PLATFORM == CS_P_PIC32_HARMONY + +int mg_if_create_conn(struct mg_connection *nc) { + (void) nc; + return 1; +} + +void mg_if_recved(struct mg_connection *nc, size_t len) { + (void) nc; + (void) len; +} + +void mg_ev_mgr_add_conn(struct mg_connection *nc) { + (void) nc; +} + +void mg_ev_mgr_init(struct mg_mgr *mgr) { + (void) mgr; + (void) mg_get_errno(); /* Shutup compiler */ +} + +void mg_ev_mgr_free(struct mg_mgr *mgr) { + (void) mgr; +} + +void mg_ev_mgr_remove_conn(struct mg_connection *nc) { + (void) nc; +} + +void mg_if_destroy_conn(struct mg_connection *nc) { + if (nc->sock == INVALID_SOCKET) return; + /* For UDP, only close outgoing sockets or listeners. */ + if (!(nc->flags & MG_F_UDP)) { + /* Close TCP */ + TCPIP_TCP_Close((TCP_SOCKET) nc->sock); + } else if (nc->listener == NULL) { + /* Only close outgoing UDP or listeners. */ + TCPIP_UDP_Close((UDP_SOCKET) nc->sock); + } + + nc->sock = INVALID_SOCKET; +} + +int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { + nc->sock = TCPIP_UDP_ServerOpen( + sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 + : IP_ADDRESS_TYPE_IPV6, + ntohs(sa->sin.sin_port), + sa->sin.sin_addr.s_addr == 0 ? 0 : (IP_MULTI_ADDRESS *) &sa->sin); + if (nc->sock == INVALID_SOCKET) { + return -1; + } + return 0; +} + +void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { + mbuf_append(&nc->send_mbuf, buf, len); +} + +void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { + mbuf_append(&nc->send_mbuf, buf, len); +} + +int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { + nc->sock = TCPIP_TCP_ServerOpen( + sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 + : IP_ADDRESS_TYPE_IPV6, + ntohs(sa->sin.sin_port), + sa->sin.sin_addr.s_addr == 0 ? 0 : (IP_MULTI_ADDRESS *) &sa->sin); + memcpy(&nc->sa, sa, sizeof(*sa)); + if (nc->sock == INVALID_SOCKET) { + return -1; + } + return 0; +} + +static int mg_accept_conn(struct mg_connection *lc) { + struct mg_connection *nc; + TCP_SOCKET_INFO si; + union socket_address sa; + + nc = mg_if_accept_new_conn(lc); + + if (nc == NULL) { + return 0; + } + + nc->sock = lc->sock; + nc->flags &= ~MG_F_LISTENING; + + if (!TCPIP_TCP_SocketInfoGet((TCP_SOCKET) nc->sock, &si)) { + return 0; + } + + if (si.addressType == IP_ADDRESS_TYPE_IPV4) { + sa.sin.sin_family = AF_INET; + sa.sin.sin_port = htons(si.remotePort); + sa.sin.sin_addr.s_addr = si.remoteIPaddress.v4Add.Val; + } else { + /* TODO(alashkin): do something with _potential_ IPv6 */ + memset(&sa, 0, sizeof(sa)); + } + + mg_if_accept_tcp_cb(nc, (union socket_address *) &sa, sizeof(sa)); + + return mg_if_listen_tcp(lc, &lc->sa) >= 0; +} + +char *inet_ntoa(struct in_addr in) { + static char addr[17]; + snprintf(addr, sizeof(addr), "%d.%d.%d.%d", (int) in.S_un.S_un_b.s_b1, + (int) in.S_un.S_un_b.s_b2, (int) in.S_un.S_un_b.s_b3, + (int) in.S_un.S_un_b.s_b4); + return addr; +} + +static void mg_handle_send(struct mg_connection *nc) { + uint16_t bytes_written = 0; + if (nc->flags & MG_F_UDP) { + bytes_written = TCPIP_UDP_TxPutIsReady((UDP_SOCKET) nc->sock, 0); + if (bytes_written >= nc->send_mbuf.len) { + if (TCPIP_UDP_ArrayPut((UDP_SOCKET) nc->sock, + (uint8_t *) nc->send_mbuf.buf, + nc->send_mbuf.len) != nc->send_mbuf.len) { + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + bytes_written = 0; + } + } + } else { + bytes_written = TCPIP_TCP_FifoTxFreeGet((TCP_SOCKET) nc->sock); + if (bytes_written != 0) { + if (bytes_written > nc->send_mbuf.len) { + bytes_written = nc->send_mbuf.len; + } + if (TCPIP_TCP_ArrayPut((TCP_SOCKET) nc->sock, + (uint8_t *) nc->send_mbuf.buf, + bytes_written) != bytes_written) { + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + bytes_written = 0; + } + } + } + + if (bytes_written != 0) { + mbuf_remove(&nc->send_mbuf, bytes_written); + mg_if_sent_cb(nc, bytes_written); + } +} + +static void mg_handle_recv(struct mg_connection *nc) { + uint16_t bytes_read = 0; + uint8_t *buf = NULL; + if (nc->flags & MG_F_UDP) { + bytes_read = TCPIP_UDP_GetIsReady((UDP_SOCKET) nc->sock); + if (bytes_read != 0 && + (nc->recv_mbuf_limit == -1 || + nc->recv_mbuf.len + bytes_read < nc->recv_mbuf_limit)) { + buf = (uint8_t *) MG_MALLOC(bytes_read); + if (TCPIP_UDP_ArrayGet((UDP_SOCKET) nc->sock, buf, bytes_read) != + bytes_read) { + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + bytes_read = 0; + MG_FREE(buf); + } + } + } else { + bytes_read = TCPIP_TCP_GetIsReady((TCP_SOCKET) nc->sock); + if (bytes_read != 0) { + if (nc->recv_mbuf_limit != -1 && + nc->recv_mbuf_limit - nc->recv_mbuf.len > bytes_read) { + bytes_read = nc->recv_mbuf_limit - nc->recv_mbuf.len; + } + buf = (uint8_t *) MG_MALLOC(bytes_read); + if (TCPIP_TCP_ArrayGet((TCP_SOCKET) nc->sock, buf, bytes_read) != + bytes_read) { + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + MG_FREE(buf); + bytes_read = 0; + } + } + } + + if (bytes_read != 0) { + mg_if_recv_tcp_cb(nc, buf, bytes_read); + } +} + +time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { + double now = mg_time(); + struct mg_connection *nc, *tmp; + + for (nc = mgr->active_connections; nc != NULL; nc = tmp) { + tmp = nc->next; + + if (nc->flags & MG_F_CONNECTING) { + /* processing connections */ + if (nc->flags & MG_F_UDP || + TCPIP_TCP_IsConnected((TCP_SOCKET) nc->sock)) { + mg_if_connect_cb(nc, 0); + } + } else if (nc->flags & MG_F_LISTENING) { + if (TCPIP_TCP_IsConnected((TCP_SOCKET) nc->sock)) { + /* accept new connections */ + mg_accept_conn(nc); + } + } else { + if (nc->send_mbuf.len != 0) { + mg_handle_send(nc); + } + + if (nc->recv_mbuf_limit == -1 || + nc->recv_mbuf.len < nc->recv_mbuf_limit) { + mg_handle_recv(nc); + } + } + } + + for (nc = mgr->active_connections; nc != NULL; nc = tmp) { + tmp = nc->next; + if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) || + (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE))) { + mg_close_conn(nc); + } + } + + return now; +} + +#endif /* CS_PLATFORM == CS_P_PIC32_HARMONY */ diff --git a/mongoose.h b/mongoose.h index ddf1c943490add9b4d4c3e3deb46d8e9f11f0976..561c8207c79b33de106ba17a5837a932d42d3e70 100644 --- a/mongoose.h +++ b/mongoose.h @@ -52,6 +52,7 @@ #define CS_P_WINCE 8 #define CS_P_NXP_KINETIS 9 #define CS_P_NRF52 10 +#define CS_P_PIC32_HARMONY 11 /* If not specified explicitly, we guess platform by defines. */ #ifndef CS_PLATFORM @@ -71,6 +72,8 @@ #define CS_PLATFORM CS_P_MBED #elif defined(FRDM_K64F) || defined(FREEDOM) #define CS_PLATFORM CS_P_NXP_KINETIS +#elif defined(PIC32) +#define CS_PLATFORM CS_P_PIC32_HARMONY #endif #ifndef CS_PLATFORM @@ -82,6 +85,7 @@ #define MG_NET_IF_SOCKET 1 #define MG_NET_IF_SIMPLELINK 2 #define MG_NET_IF_LWIP_LOW_LEVEL 3 +#define MG_NET_IF_PIC32_HARMONY 4 /* Amalgamated: #include "common/platforms/platform_unix.h" */ /* Amalgamated: #include "common/platforms/platform_windows.h" */ @@ -92,6 +96,7 @@ /* Amalgamated: #include "common/platforms/platform_nrf52.h" */ /* Amalgamated: #include "common/platforms/platform_wince.h" */ /* Amalgamated: #include "common/platforms/platform_nxp_kinetis.h" */ +/* Amalgamated: #include "common/platforms/platform_pic32_harmony.h" */ /* Common stuff */ @@ -1191,6 +1196,40 @@ typedef struct stat cs_stat_t; #endif /* CS_PLATFORM == CS_P_NXP_KINETIS */ #endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ */ #ifdef MG_MODULE_LINES +#line 1 "common/platforms/platform_pic32_harmony.h" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_ +#define CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_ + +#if CS_PLATFORM == CS_P_PIC32_HARMONY + +#define MG_NET_IF MG_NET_IF_PIC32_HARMONY + +#include <stdint.h> +#include <time.h> +#include <ctype.h> +#include <stdlib.h> + +#include <system_config.h> +#include <system_definitions.h> + +typedef TCP_SOCKET sock_t; +#define to64(x) strtoll(x, NULL, 10) + +#define SIZE_T_FMT "lu" +#define INT64_FMT "lld" + +char* inet_ntoa(struct in_addr in); + +#endif /* CS_PLATFORM == CS_P_PIC32_HARMONY */ + +#endif /* CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_ */ +#ifdef MG_MODULE_LINES #line 1 "common/platforms/lwip/mg_lwip.h" #endif /*