add LocalTalk over TCP

This commit is contained in:
Jesús A. Álvarez 2024-03-24 21:51:25 +01:00
parent fdbf6aab7e
commit 8ba6622310
10 changed files with 517 additions and 27 deletions

View File

@ -244,6 +244,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2834204B2B96558700D7DB68 /* LTOVRUDP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTOVRUDP.h; sourceTree = "<group>"; };
283422CA1CF8EF8C0088B634 /* MacPlus4M.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MacPlus4M.framework; sourceTree = BUILT_PRODUCTS_DIR; };
283422D71CF8EFD80088B634 /* EmulatorProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EmulatorProtocol.h; sourceTree = "<group>"; };
283422E71CF8F1C80088B634 /* CNFUDOSG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNFUDOSG.h; sourceTree = "<group>"; };
@ -257,6 +258,7 @@
283423EE1CFA329C0088B634 /* Icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@3x.png"; sourceTree = "<group>"; };
283CA9821DF47AF300B33D5E /* BTCMouse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTCMouse.h; sourceTree = "<group>"; };
285A8C901D05AFD3002993DE /* PlugIn-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "PlugIn-Info.plist"; sourceTree = "<group>"; };
287006E92BB032E300A5EB51 /* LTOVRTCP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTOVRTCP.h; sourceTree = "<group>"; };
28848B601CDE97D600B86C45 /* InsertDiskViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsertDiskViewController.h; sourceTree = "<group>"; };
28848B611CDE97D600B86C45 /* InsertDiskViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InsertDiskViewController.m; sourceTree = "<group>"; };
28848B631CDE97E900B86C45 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = "<group>"; };
@ -556,6 +558,7 @@
isa = PBXGroup;
children = (
28E3B831251D195D007C273F /* PICOMMON.h */,
2834204B2B96558700D7DB68 /* LTOVRUDP.h */,
28E3B7D2251D0F13007C273F /* ADBEMDEV.c */,
28E3B7DE251D0F13007C273F /* ASCEMDEV.c */,
28E3B7CE251D0F12007C273F /* GLOBGLUE.c */,
@ -638,6 +641,7 @@
283422EF1CF8F33A0088B634 /* Emulator Bundles */,
28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */,
28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */,
287006E92BB032E300A5EB51 /* LTOVRTCP.h */,
);
path = "Mini vMac";
sourceTree = "<group>";

View File

@ -68,7 +68,14 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:defaultValues];
[defaults addObserver:self forKeyPath:@"speedValue" options:0 context:NULL];
for (NSString *key in @[@"speedValue", @"autoSlow", @"localTalkServer"]) {
[defaults addObserver:self forKeyPath:key options:0 context:NULL];
}
NSString *localTalkServer = [defaults valueForKey:@"localTalkServer"];
if (localTalkServer.length > 0) {
setenv("LTOVRTCP_SERVER", localTalkServer.UTF8String, 1);
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
@ -78,6 +85,13 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
sharedEmulator.speed = [defaults integerForKey:@"speedValue"];
} else if ([keyPath isEqualToString:@"autoSlow"]) {
sharedEmulator.autoSlow = [defaults integerForKey:@"autoSlow"];
} else if ([keyPath isEqualToString:@"localTalkServer"]) {
NSString *localTalkServer = [defaults stringForKey:@"localTalkServer"];
if (localTalkServer.length > 0) {
setenv("LTOVRTCP_SERVER", localTalkServer.UTF8String, 1);
} else {
unsetenv("LTOVRTCP_SERVER");
}
}
}
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -21,7 +21,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="70W-4V-tYr" customClass="ScreenView">
<rect key="frame" x="0.0" y="44" width="375" height="734"/>
<rect key="frame" x="0.0" y="50" width="375" height="728"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<visualEffectView hidden="YES" opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="o5Z-in-kcg">
@ -218,12 +218,12 @@
<objects>
<tableViewController id="WUA-f8-k8g" customClass="SettingsViewController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="9gA-gD-7Wx">
<rect key="frame" x="0.0" y="0.0" width="375" height="758"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="802"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="speed" id="v4I-0T-H8m">
<rect key="frame" x="0.0" y="49" width="375" height="44"/>
<rect key="frame" x="0.0" y="55.333332061767578" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="v4I-0T-H8m" id="cO5-De-1JT">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -253,7 +253,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="mouse" id="JgY-zN-3ID">
<rect key="frame" x="0.0" y="93" width="375" height="44"/>
<rect key="frame" x="0.0" y="99.333332061767578" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JgY-zN-3ID" id="iUk-se-WGk">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -282,7 +282,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="keyboard" textLabel="6WO-0z-y7c" style="IBUITableViewCellStyleDefault" id="q7C-00-4ss">
<rect key="frame" x="0.0" y="137" width="375" height="44"/>
<rect key="frame" x="0.0" y="143.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="q7C-00-4ss" id="yUn-mI-DwM">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -298,7 +298,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationWidth="60" reuseIdentifier="machine" textLabel="znE-ML-UrQ" detailTextLabel="xcq-HY-ZDe" style="IBUITableViewCellStyleSubtitle" id="MGj-K1-5lZ">
<rect key="frame" x="0.0" y="181" width="375" height="44"/>
<rect key="frame" x="0.0" y="187.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MGj-K1-5lZ" id="ueO-zm-JQP">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -322,7 +322,7 @@
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="display" id="P6n-Bf-s6h">
<rect key="frame" x="0.0" y="225" width="375" height="44"/>
<rect key="frame" x="0.0" y="231.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="P6n-Bf-s6h" id="NgN-Fe-hXo">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -348,7 +348,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="about" textLabel="YWX-qF-gPj" detailTextLabel="xr3-v1-hzM" style="IBUITableViewCellStyleValue1" id="Mon-vq-IrO">
<rect key="frame" x="0.0" y="269" width="375" height="44"/>
<rect key="frame" x="0.0" y="275.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Mon-vq-IrO" id="mGZ-Jb-6j4">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -371,7 +371,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="toggle" textLabel="a1l-XI-MEz" style="IBUITableViewCellStyleDefault" id="1nB-54-Qfk">
<rect key="frame" x="0.0" y="313" width="375" height="44"/>
<rect key="frame" x="0.0" y="319.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1nB-54-Qfk" id="fZu-5X-Z4B">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -386,6 +386,22 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="field" textLabel="80H-xx-UOs" style="IBUITableViewCellStyleDefault" id="azx-Sd-SM5">
<rect key="frame" x="0.0" y="363.33333206176758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="azx-Sd-SM5" id="XCA-vd-f7d">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="80H-xx-UOs">
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<sections/>
<connections>
@ -435,7 +451,7 @@
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Cuq-Py-BdB">
<rect key="frame" x="0.0" y="675" width="375" height="49"/>
<rect key="frame" x="0.0" y="758" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
@ -451,12 +467,12 @@
<objects>
<tableViewController id="mbX-kA-h6M" customClass="InsertDiskViewController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="EFr-QR-Vqc">
<rect key="frame" x="0.0" y="0.0" width="375" height="758"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="802"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="cell" textLabel="8ef-Se-DXA" detailTextLabel="CbL-Kq-e9s" style="IBUITableViewCellStyleValue1" id="iZQ-DG-qho" customClass="FileTableViewCell">
<rect key="frame" x="0.0" y="44.666666030883789" width="375" height="44"/>
<rect key="frame" x="0.0" y="50" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="iZQ-DG-qho" id="pcB-3f-clB">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -542,7 +558,7 @@
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="secondaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

403
Mini vMac/LTOVRTCP.h Normal file
View File

@ -0,0 +1,403 @@
/*
LTOVRTCP.h
Copyright (C) 2012 Michael Fort, Paul C. Pratt, Rob Mitchelmore
You can redistribute this file and/or modify it under the terms
of version 2 of the GNU General Public License as published by
the Free Software Foundation. You should have received a copy
of the license along with this file; see the file COPYING.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
license for more details.
*/
/*
LocalTalk OVeR Transmission Control Protocol
*/
#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)
{
dbglog_writeCStr(s);
dbglog_writeCStr(": err ");
#if use_winsock
dbglog_writeNum(WSAGetLastError());
#else
dbglog_writeNum(errno);
dbglog_writeCStr(" (");
dbglog_writeCStr(strerror(errno));
dbglog_writeCStr(")");
#endif
dbglog_writeReturn();
}
#endif
/*
Transmit buffer for localtalk data and its metadata
*/
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;
#if use_winsock
LOCALVAR blnr have_winsock = falseblnr;
#endif
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;
if ((server = getenv("LTOVRTCP_SERVER")) && strlen(server) < sizeof(buf)) {
strcpy(buf, server);
char *separator = strchr(buf, ':');
if (separator == NULL) {
return;
}
*separator = 0;
separator++;
if (strlen(separator) > 1) {
port = (short)atoi(separator);
}
}
if (port == 0) {
return;
}
/* 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;
}
LOCALVAR unsigned char *MyRxBuffer = NULL;
/*
External function needed at startup to initialize the LocalTalk
functionality.
*/
LOCALFUNC blnr InitLocalTalk(void)
{
LT_PickStampNodeHint();
LT_TxBuffer = &tx_buffer[6];
MyRxBuffer = malloc(rx_buffer_allocation);
if (NULL == MyRxBuffer) {
return falseblnr;
}
/* Set up TCP socket */
start_tcp();
/* Initialized properly */
return trueblnr;
}
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
if (NULL != MyRxBuffer) {
free(MyRxBuffer);
}
}
LOCALPROC embedPacketLength(ui4r length)
{
/*
embeds the length of the packet in the packet as a 16-bit big endian
*/
tx_buffer[0] = (length >> 8) & 0xff;
tx_buffer[1] = length & 0xff;
}
LOCALPROC embedMyPID(void)
{
/*
embeds my process ID in network byte order in the start of the
Tx buffer we assume a pid is at most 32 bits. As far as I know
there's no actual implementation of POSIX with 64-bit PIDs so we
should be ok.
*/
int i;
#if LT_MayHaveEcho
ui5r v = LT_MyStamp;
#else
ui5r v = (ui5r)getpid();
#endif
for (i = 0; i < 4; i++) {
tx_buffer[2+i] = (v >> (3 - i)*8) & 0xff;
}
}
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 */
}
}
/*
pidInPacketIsMine returns 1 if the process ID embedded in the packet
is the same as the process ID of the current process
*/
LOCALFUNC int pidInPacketIsMine(void)
{
/* is the PID in the packet my own PID? */
int i;
ui5r v;
#if LT_MayHaveEcho
v = LT_MyStamp;
#else
v = (ui5r)getpid();
#endif
for (i = 0; i < 4; i++) {
if (MyRxBuffer[i] != ((v >> (3 - i)*8) & 0xff)) {
return 0;
}
}
return 1;
}
/*
packetIsOneISent returns 1 if this looks like a packet that this
process sent and 0 if it looks like a packet that a different
process sent. This provides loopback protection so that we do not
try to consume packets that we sent ourselves. We do this by
checking the process ID embedded in the packet and the IP address
the packet was sent from. It would be neater to just look at the
LocalTalk node ID embedded in the LLAP packet, but this doesn't
actually work, because during address acquisition it is entirely
legitimate (and, in the case of collision, *required*) for another
node to send a packet from what we think is our own node ID.
*/
#if ! LT_MayHaveEcho
LOCALFUNC int packetIsOneISent(void)
{
return pidInPacketIsMine();
}
#endif
LOCALFUNC int GetNextPacket(void)
{
unsigned char* device_buffer = MyRxBuffer;
if (tcp_ok == falseblnr)
{
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
}
} else {
#if TCP_dolog
dbglog_writeCStr("got ");
dbglog_writeNum(bytes);
dbglog_writeCStr(", bufsize ");
dbglog_writeNum(rx_buffer_allocation);
dbglog_writeReturn();
#endif
}
return bytes;
}
GLOBALOSGLUPROC LT_ReceivePacket(void)
{
int bytes;
#if ! LT_MayHaveEcho
label_retry:
#endif
bytes = GetNextPacket();
if (bytes > 0) {
#if LT_MayHaveEcho
CertainlyNotMyPacket = ! pidInPacketIsMine();
#endif
#if ! LT_MayHaveEcho
if (packetIsOneISent()) {
goto label_retry;
}
#endif
{
#if TCP_dolog
dbglog_writeCStr("passing ");
dbglog_writeNum(bytes - 6);
dbglog_writeCStr(" bytes to receiver");
dbglog_writeReturn();
#endif
LT_RxBuffer = MyRxBuffer + 6;
LT_RxBuffSz = bytes - 6;
}
}
}

View File

@ -107,6 +107,12 @@ LOCALPROC dbglog_close0(void) {
#include "COMOSGLU.h"
#include "PBUFSTDC.h"
#if EmLocalTalk
#include <sys/socket.h>
#include <arpa/inet.h>
#include "LTOVRTCP.h"
#endif
#pragma mark - Cocoa Stuff
LOCALFUNC blnr FindNamedChildFilePath(NSString *parentPath, char *ChildName, NSString **childPath) {
@ -1492,10 +1498,14 @@ LOCALFUNC blnr InitOSGLU(void) {
#endif
if (LoadInitialImages())
if (LoadMacRom())
if (InitLocationDat()) {
InitKeyCodes();
IsOk = trueblnr;
}
if (InitLocationDat())
#if EmLocalTalk
if (InitLocalTalk())
#endif
if (true) {
InitKeyCodes();
IsOk = trueblnr;
}
}
return IsOk;
@ -1508,6 +1518,9 @@ LOCALPROC CheckSavedMacMsg(void) {
}
LOCALPROC UnInitOSGLU(void) {
#if EmLocalTalk
UnInitLocalTalk();
#endif
#if MySoundEnabled
MySound_Stop();
#endif

View File

@ -35,7 +35,8 @@
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define EmLocalTalk 1
#define LT_MayHaveEcho 0
#define AutoLocation 1
#define AutoTimeZone 1

View File

@ -35,7 +35,8 @@
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define EmLocalTalk 1
#define LT_MayHaveEcho 0
#define AutoLocation 1
#define AutoTimeZone 1

View File

@ -35,7 +35,8 @@
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define EmLocalTalk 1
#define LT_MayHaveEcho 0
#define AutoLocation 1
#define AutoTimeZone 1

View File

@ -36,7 +36,8 @@
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define EmLocalTalk 1
#define LT_MayHaveEcho 0
#define AutoLocation 1
#define AutoTimeZone 1

View File

@ -19,7 +19,9 @@ typedef enum : NSInteger {
SettingsSectionKeyboard,
SettingsSectionDisplay,
SettingsSectionMachine,
SettingsSectionAbout
SettingsSectionNetwork,
SettingsSectionAbout,
SettingsSectionCount
} SettingsSection;
@implementation SettingsViewController
@ -154,10 +156,21 @@ typedef enum : NSInteger {
}
}
- (void)changeLocaltalkServer:(UITextField*)sender {
if ([sender isKindOfClass:[UITextField class]]) {
NSLog(@"Changed server to %@", sender.text);
if (sender.text.length == 0) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"localTalkServer"];
} else {
[[NSUserDefaults standardUserDefaults] setValue:sender.text forKey:@"localTalkServer"];
}
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 6;
return SettingsSectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
@ -196,6 +209,8 @@ typedef enum : NSInteger {
return NSLocalizedString(@"Display Scaling", nil);
case SettingsSectionAbout:
return aboutTitle;
case SettingsSectionNetwork:
return NSLocalizedString(@"Network", nil);
default:return nil;
}
}
@ -269,7 +284,7 @@ typedef enum : NSInteger {
cell.textLabel.text = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
cell.detailTextLabel.text = [bundle objectForInfoDictionaryKey:@"CFBundleGetInfoString"];
}
if (rowHasHeader) {
cell.imageView.image = nil;
cell.indentationLevel = 1;
@ -297,6 +312,9 @@ typedef enum : NSInteger {
} else {
filterControl.selectedSegmentIndex = 1;
}
} else if (section == SettingsSectionNetwork) {
cell = [self fieldCellForTableView:tableView indexPath:indexPath action:@selector(changeLocaltalkServer:) placeholder:@"address:port" text:[defaults valueForKey:@"localTalkServer"]];
cell.textLabel.text = @"LocalTalk Server";
}
return cell;
}
@ -391,4 +409,22 @@ typedef enum : NSInteger {
return cell;
}
- (UITableViewCell*)fieldCellForTableView:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath action:(SEL)action placeholder:(NSString*)placeholder text:(NSString*)text {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"field" forIndexPath:indexPath];
UITextField *cellField = (UITextField*)cell.accessoryView;
if (cellField == nil) {
CGRect bounds = cell.bounds;
bounds.size.width /= 2;
cellField = [[UITextField alloc] initWithFrame:bounds];
cell.accessoryView = cellField;
} else {
[cellField removeTarget:nil action:nil forControlEvents:UIControlEventAllEvents];
}
cellField.text = text;
cellField.placeholder = placeholder;
cellField.textAlignment = NSTextAlignmentRight;
[cellField addTarget:self action:action forControlEvents:UIControlEventEditingDidEnd|UIControlEventEditingDidEndOnExit];
return cell;
}
@end