--- /dev/null
+/*
+ * Copyright 1994-2012 The MathWorks, Inc.
+ *
+ * Modified for RPP target by Jakub NejedlĂ˝ <nejedjak@fel.cvut.cz>
+ *
+ * File: rtiostream_tcpip.c
+ *
+ * Abstract:
+
+ */
+
+#include "rtiostream.h"
+
+#include "rpp/rpp.h"
+
+#include "lwip/mem.h"
+#include "lwip/raw.h"
+#include "lwip/icmp.h"
+#include "lwip/netif.h"
+#include "lwip/sys.h"
+#include "lwip/timers.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/sockets.h"
+#include "lwip/inet.h"
+
+
+typedef int SOCKET;
+typedef const char * send_buffer_t;
+typedef socklen_t rtiostream_socklen_t;
+
+SOCKET socketBase = 0;
+SOCKET socketNum = 0;
+
+int sockStatus = 0;
+
+
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+
+#define RECEIVE_TIMEOUT 1000 //ms
+#define PORT_RPP 17725U
+
+#define INT_MAX 2147483647
+
+# define INVALID_SOCKET (-1)
+# define SOCK_ERR (-1)
+
+
+int ethinit(){
+ // // test eth init
+ int8_t retVal = rpp_eth_init_postInit(0, NULL); /* post OS startup init of eth (LwIP) for application usage -- waits for a while, for auto-negotiation of ethernet speed and DHCP if used */
+
+ switch (retVal) {
+ case FAILURE:
+ rpp_sci_printf("already initialized\n");
+ break;
+ case NETIF_ADD_ERR:
+ rpp_sci_printf("initialization of physical part of ethernet failed\n");
+ break;
+ case DHCP_MEM_ERR:
+ rpp_sci_printf("DHCP couldn't be started due to insufficient memory\n");
+ break;
+ case PHY_LINK_DOWN:
+ rpp_sci_printf("cable is not connected\n");
+ break;
+ default:
+ rpp_sci_printf("ethinit DONE\n");
+ }
+ return retVal;
+}
+
+int acceptComunication(){
+
+ // accept communication
+ struct sockaddr_in clientAddr;
+ rtiostream_socklen_t sFdAddSize = sizeof(struct sockaddr_in);
+
+ sockStatus = lwip_accept(socketBase, (struct sockaddr *)&clientAddr, &sFdAddSize);
+ socketNum = sockStatus;
+
+ if (sockStatus == INVALID_SOCKET) {
+ rpp_sci_printf("accept() for comm socket failed.\n");
+ lwip_close(socketBase);
+ return RTIOSTREAM_ERROR;
+ }
+
+ return sockStatus;
+
+}
+
+
+/****** VISIBLE FUNCTIONS ***************/
+
+/* Function: rtIOStreamOpen =================================================
+ * Abstract:
+ * Open the connection with the target.
+ */
+int rtIOStreamOpen(int argc, void * argv[])
+{
+
+ // rpp_sci_printf("## Open ##\n");
+
+ if (!isPostInitialized()) {
+ int errStat = ethinit();
+ if (errStat < 0){
+ rpp_sci_printf("Eth not initialized");
+ return RTIOSTREAM_ERROR;
+ }
+ }
+
+ // socket creation
+ socketBase = lwip_socket(AF_INET, SOCK_STREAM, 0);
+ if (socketBase == -1){
+ rpp_sci_printf("ERR: lwip socket init\r\n");
+ return RTIOSTREAM_ERROR;
+ }
+
+ // socket options
+ int option = 1;
+ sockStatus = lwip_setsockopt(socketBase,SOL_SOCKET,SO_KEEPALIVE,(char*)&option,sizeof(option));
+ if (sockStatus == -1){
+ rpp_sci_printf("ERR: lwip socket opts\r\n");
+ return RTIOSTREAM_ERROR;
+ }
+
+ // Bind socket
+ struct sockaddr_in serverAddr;
+ rtiostream_socklen_t socketSize = (rtiostream_socklen_t) sizeof(struct sockaddr_in);
+
+ serverAddr.sin_family = AF_INET;
+ serverAddr.sin_port = htons((unsigned short int) PORT_RPP);
+ serverAddr.sin_addr.s_addr = htonl(INADDR_ANY );
+
+
+ sockStatus = lwip_bind(socketBase, (struct sockaddr *) &serverAddr, socketSize);
+ if (sockStatus == -1){
+ rpp_sci_printf("bind() call failed. \r\n");
+ lwip_close(socketBase);
+ return RTIOSTREAM_ERROR;
+ }
+
+ // listen socket
+ sockStatus = lwip_listen(socketBase, 2);
+ if (sockStatus == SOCK_ERR) {
+ rpp_sci_printf("listen() call failed.\n");
+ lwip_close(socketBase);
+ return RTIOSTREAM_ERROR;
+ }
+
+ int sockStatus = acceptComunication();
+
+ return sockStatus;
+}
+
+
+/* Function: rtIOStreamSend =====================================================
+ * Abstract:
+ * Sends the specified number of bytes on the comm line. Returns the number of
+ * bytes sent (if successful) or a negative value if an error occurred. As long
+ * as an error does not occur, this function is guaranteed to set the requested
+ * number of bytes.
+ */
+int rtIOStreamSend(
+ int streamID,
+ const void * const src,
+ size_t size,
+ size_t *sizeSent)
+{
+
+ int nSend;
+ const void *sendSrc = src;
+
+ /* Ensure size is not out of range for socket API send function */
+ int sizeLim = (int) MIN(size, INT_MAX);
+
+ nSend = lwip_send(socketNum, (send_buffer_t)sendSrc, sizeLim, 0);
+
+ if(nSend == -1){
+ return RTIOSTREAM_ERROR;
+ }
+ *sizeSent = (size_t)nSend;
+
+ return nSend;
+}
+
+
+int testCounter = 0;
+
+/* Function: rtIOStreamRecv ================================================
+ * Abstract:
+ * Attempts to gets the specified number of bytes from socket.
+ * The number of bytes read is returned via the 'sizeRecvd' parameter.
+ * RTIOSTREAM_NO_ERROR is returned on success, RTIOSTREAM_ERROR is returned on
+ * failure.
+ * Function waiting for reconecting if read EOF from stream.
+ *
+ */
+int rtIOStreamRecv(
+ int streamID,
+ void * const dst,
+ size_t size,
+ size_t * sizeRecvd)
+{
+
+ int nRecv = 0;
+
+ /* Ensure size is not out of range for socket API recv function */
+ int sizeLim = (int) MIN(size, INT_MAX);
+
+ nRecv = lwip_recv(socketNum, dst, sizeLim, 0U);
+
+ if (nRecv == 0 ){
+ lwip_close(socketNum);
+
+ int sockStatus = acceptComunication();
+ if (sockStatus == RTIOSTREAM_ERROR){
+ rpp_sci_printf("acceptComunication() failed reconnecting \n");
+ }
+
+ }
+
+ if (nRecv == -1) {
+ return RTIOSTREAM_ERROR;
+ }
+ *sizeRecvd = (size_t) nRecv;
+
+ return RTIOSTREAM_NO_ERROR;
+
+}
+
+
+/* Function: rtIOStreamClose ================================================
+ * Abstract:
+ * Close the connection.
+ *
+ */
+int rtIOStreamClose(int streamID)
+{
+ lwip_close(socketNum);
+ lwip_close(socketBase);
+ return RTIOSTREAM_NO_ERROR;
+}