diff --git a/Mini vMac/LTOVRTCP.h b/Mini vMac/LTOVRTCP.h index b893a10..404cf23 100644 --- a/Mini vMac/LTOVRTCP.h +++ b/Mini vMac/LTOVRTCP.h @@ -20,21 +20,6 @@ #define TCP_dolog (dbglog_HAVE && 0) -#ifndef use_winsock -#define use_winsock 0 -#endif - -#if use_winsock -#define my_INVALID_SOCKET INVALID_SOCKET -#define my_SOCKET SOCKET -#define my_closesocket closesocket -#define socklen_t int -#else -#define my_INVALID_SOCKET (-1) -#define my_SOCKET int -#define my_closesocket close -#endif - #if TCP_dolog LOCALPROC dbglog_writeSockErr(char *s) { @@ -55,52 +40,46 @@ LOCALPROC dbglog_writeSockErr(char *s) /* Transmit buffer for localtalk data and its metadata */ -LOCALVAR ui3b tx_buffer[6 + LT_TxBfMxSz] = -"LLpppp"; - +LOCALVAR ui3b tx_buffer[6 + LT_TxBfMxSz] = "LLpppp"; /* Receive buffer for LocalTalk data and its metadata */ LOCALVAR unsigned int rx_buffer_allocation = 1800; -LOCALVAR my_SOCKET sock_fd = my_INVALID_SOCKET; -LOCALVAR blnr tcp_ok = falseblnr; +LOCALVAR nw_connection_t connection = nil; +LOCALVAR NSData *nextPacket; -#if use_winsock -LOCALVAR blnr have_winsock = falseblnr; -#endif +void welcome_next_packet(void) +{ + // schedule receiving length + nw_connection_receive(connection, 2, 2, ^(dispatch_data_t _Nullable content, nw_content_context_t _Nullable context, bool is_complete, nw_error_t _Nullable error) { + uint8_t buf[2]; + if (error != nil) { + NSLog(@"ERROR RECEIVING LENGTH: %@", error); + return; + } + [(NSData*)content getBytes:buf length:2]; + uint16_t length = (buf[0] << 8) | buf[1]; + + // schedule receiving packet + nw_connection_receive(connection, (uint32_t)length, (uint32_t)length, ^(dispatch_data_t _Nullable content, nw_content_context_t _Nullable context, bool is_complete, nw_error_t _Nullable error) { + if (error != nil) { + NSLog(@"ERROR RECEIVING DATA: %@", error); + return; + } + nextPacket = (NSData*)content; + }); + }); +} LOCALPROC start_tcp(void) { -#if use_winsock - WSADATA wsaData; -#endif - struct sockaddr_in addr; - -#if use_winsock - if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { -#if TCP_dolog - dbglog_writeln("WSAStartup fails"); -#endif - return; - } - have_winsock = trueblnr; -#endif - - if (my_INVALID_SOCKET == (sock_fd = - socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) - { -#if TCP_dolog - dbglog_writeSockErr("socket"); -#endif - return; - } - /* find server from LTOVRTCP_SERVER env, should be in the form 1.2.3.4:12345 */ char *server = NULL; char buf[32]; short port = 0; + char *portStr = NULL; if ((server = getenv("LTOVRTCP_SERVER")) && strlen(server) < sizeof(buf)) { strcpy(buf, server); char *separator = strchr(buf, ':'); @@ -111,6 +90,7 @@ LOCALPROC start_tcp(void) separator++; if (strlen(separator) > 1) { port = (short)atoi(separator); + portStr = separator; } } @@ -119,42 +99,17 @@ LOCALPROC start_tcp(void) } /* connect to server */ - memset((char*)&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(buf); - addr.sin_port = htons(port); -#if ! use_winsock - errno = 0; -#endif - if (0 != connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr))) { -#if TCP_dolog - dbglog_writeSockErr("connect"); -#endif - MacMsg("Could not connect to LocalTalk server", strerror(errno), falseblnr); - return; - } -#if TCP_dolog - dbglog_writeln("tcp connected"); -#endif - - /* non-blocking I/O is good for the soul */ -#if use_winsock - { - int iResult; - u_long iMode = 1; - - iResult = ioctlsocket(sock_fd, FIONBIO, &iMode); - if (iResult != NO_ERROR) { - /* - printf("ioctlsocket failed with error: %ld\n", iResult); - */ - } - } -#else - fcntl(sock_fd, F_SETFL, O_NONBLOCK); -#endif - - tcp_ok = trueblnr; + nw_endpoint_t endpoint = nw_endpoint_create_host(buf, portStr); + nw_parameters_t params = nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, ^(nw_protocol_options_t _Nonnull options) { + nw_tcp_options_set_no_delay(options, true); + }); + connection = nw_connection_create(endpoint, params); + nw_connection_set_state_changed_handler(connection, ^(nw_connection_state_t state, nw_error_t _Nullable error) { + NSLog(@"connection state %@: %@", @[@"invalid", @"waiting", @"preparing", @"ready", @"failed", @"cancelled"][state], error); + }); + nw_connection_set_queue(connection, dispatch_get_main_queue()); + nw_connection_start(connection); + welcome_next_packet(); } LOCALVAR unsigned char *MyRxBuffer = NULL; @@ -166,7 +121,6 @@ LOCALVAR unsigned char *MyRxBuffer = NULL; LOCALFUNC blnr InitLocalTalk(void) { LT_PickStampNodeHint(); - LT_TxBuffer = &tx_buffer[6]; MyRxBuffer = malloc(rx_buffer_allocation); @@ -183,23 +137,7 @@ LOCALFUNC blnr InitLocalTalk(void) LOCALPROC UnInitLocalTalk(void) { - if (my_INVALID_SOCKET != sock_fd) { - if (0 != my_closesocket(sock_fd)) { -#if TCP_dolog - dbglog_writeSockErr("my_closesocket sock_fd"); -#endif - } - } - -#if use_winsock - if (have_winsock) { - if (0 != WSACleanup()) { -#if TCP_dolog - dbglog_writeSockErr("WSACleanup"); -#endif - } - } -#endif + nw_connection_cancel(connection); if (NULL != MyRxBuffer) { free(MyRxBuffer); @@ -238,25 +176,19 @@ LOCALPROC embedMyPID(void) GLOBALOSGLUPROC LT_TransmitPacket(void) { - size_t bytes; - /* Write the packet to TCP */ #if TCP_dolog dbglog_writeln("writing to tcp"); #endif embedPacketLength(LT_TxBuffSz + 4); embedMyPID(); - if (tcp_ok) { - - bytes = send(sock_fd, - (const void *)tx_buffer, LT_TxBuffSz + 6, 0); -#if TCP_dolog - dbglog_writeCStr("sent "); - dbglog_writeNum(bytes); - dbglog_writeCStr(" bytes"); - dbglog_writeReturn(); -#endif - (void) bytes; /* avoid warning about unused */ - } + char *buf = malloc(LT_TxBfMxSz + 6); + memcpy(buf, tx_buffer, LT_TxBfMxSz + 6); + dispatch_data_t data = dispatch_data_create(buf, LT_TxBuffSz + 6, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE); + nw_connection_send(connection, data, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t _Nullable error) { + if (error) { + NSLog(@"nw_connection_send error %@", error); + } + }); } /* @@ -305,68 +237,18 @@ LOCALFUNC int packetIsOneISent(void) LOCALFUNC int GetNextPacket(void) { - unsigned char* device_buffer = MyRxBuffer; - if (tcp_ok == falseblnr) - { + if (nextPacket == nil) { return 0; } -#if ! use_winsock - errno = 0; -#endif - /* peek length */ - ssize_t bytes = recv(sock_fd, (void *)device_buffer, 2, MSG_PEEK); - if (bytes == 2) - { - int incoming_length = (device_buffer[0] << 8) + device_buffer[1]; - bytes = recv(sock_fd, (void*)device_buffer, 2 + incoming_length, MSG_PEEK); - if (bytes == 2 + incoming_length) - { - /* read the packet */ - bytes = recv(sock_fd, (void*)device_buffer, 2 + incoming_length, 0); - } - } - - if (bytes < 0) { -#if use_winsock - if (WSAEWOULDBLOCK != WSAGetLastError()) -#else - if (ECONNRESET == errno || ETIMEDOUT == errno) - { - MacMsg("Lost connection to LocalTalk server", strerror(errno), falseblnr); -#if TCP_dolog - dbglog_writeCStr("tcp error "); - dbglog_writeCStr(strerror(errno)); - dbglog_writeReturn(); -#endif - tcp_ok = falseblnr; - my_closesocket(sock_fd); - sock_fd = my_INVALID_SOCKET; - } - else if (EAGAIN != errno) -#endif - { -#if TCP_dolog - dbglog_writeCStr("ret"); - dbglog_writeNum(bytes); - dbglog_writeCStr(", bufsize "); - dbglog_writeNum(rx_buffer_allocation); -#if ! use_winsock - dbglog_writeCStr(", errno = "); - dbglog_writeCStr(strerror(errno)); -#endif - dbglog_writeReturn(); -#endif - } + int bytes = (int)nextPacket.length; + if (bytes <= rx_buffer_allocation) { + [nextPacket getBytes:MyRxBuffer length:bytes]; } else { -#if TCP_dolog - dbglog_writeCStr("got "); - dbglog_writeNum(bytes); - dbglog_writeCStr(", bufsize "); - dbglog_writeNum(rx_buffer_allocation); - dbglog_writeReturn(); -#endif + bytes = 0; } + nextPacket = nil; + welcome_next_packet(); return bytes; } @@ -392,12 +274,12 @@ label_retry: { #if TCP_dolog dbglog_writeCStr("passing "); - dbglog_writeNum(bytes - 6); + dbglog_writeNum(bytes - 4); dbglog_writeCStr(" bytes to receiver"); dbglog_writeReturn(); #endif - LT_RxBuffer = MyRxBuffer + 6; - LT_RxBuffSz = bytes - 6; + LT_RxBuffer = MyRxBuffer + 4; + LT_RxBuffSz = bytes - 4; } } } diff --git a/Mini vMac/MYOSGLUE.m b/Mini vMac/MYOSGLUE.m index 02650c7..90037cf 100644 --- a/Mini vMac/MYOSGLUE.m +++ b/Mini vMac/MYOSGLUE.m @@ -112,8 +112,7 @@ LOCALPROC dbglog_close0(void) { #include "PBUFSTDC.h" #if EmLocalTalk -#include -#include +#import #include "LTOVRTCP.h" #endif