1*ebfedea0SLionel Sambuc /*
2*ebfedea0SLionel Sambuc * A simple socket-like package.
3*ebfedea0SLionel Sambuc * This could undoubtedly be improved, since it does polling and busy-waiting.
4*ebfedea0SLionel Sambuc * At least it uses asynch I/O and implements timeouts!
5*ebfedea0SLionel Sambuc *
6*ebfedea0SLionel Sambuc * Other funkiness includes the use of my own (possibly brain-damaged) error-handling infrastructure.
7*ebfedea0SLionel Sambuc *
8*ebfedea0SLionel Sambuc * -Roy Wood (roy@centricsystems.ca)
9*ebfedea0SLionel Sambuc *
10*ebfedea0SLionel Sambuc */
11*ebfedea0SLionel Sambuc
12*ebfedea0SLionel Sambuc
13*ebfedea0SLionel Sambuc /* ====================================================================
14*ebfedea0SLionel Sambuc * Copyright (c) 1998-1999 The OpenSSL Project. All rights reserved.
15*ebfedea0SLionel Sambuc *
16*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
17*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
18*ebfedea0SLionel Sambuc * are met:
19*ebfedea0SLionel Sambuc *
20*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
21*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
22*ebfedea0SLionel Sambuc *
23*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
24*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in
25*ebfedea0SLionel Sambuc * the documentation and/or other materials provided with the
26*ebfedea0SLionel Sambuc * distribution.
27*ebfedea0SLionel Sambuc *
28*ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this
29*ebfedea0SLionel Sambuc * software must display the following acknowledgment:
30*ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
31*ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
32*ebfedea0SLionel Sambuc *
33*ebfedea0SLionel Sambuc * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
34*ebfedea0SLionel Sambuc * endorse or promote products derived from this software without
35*ebfedea0SLionel Sambuc * prior written permission. For written permission, please contact
36*ebfedea0SLionel Sambuc * openssl-core@openssl.org.
37*ebfedea0SLionel Sambuc *
38*ebfedea0SLionel Sambuc * 5. Products derived from this software may not be called "OpenSSL"
39*ebfedea0SLionel Sambuc * nor may "OpenSSL" appear in their names without prior written
40*ebfedea0SLionel Sambuc * permission of the OpenSSL Project.
41*ebfedea0SLionel Sambuc *
42*ebfedea0SLionel Sambuc * 6. Redistributions of any form whatsoever must retain the following
43*ebfedea0SLionel Sambuc * acknowledgment:
44*ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
45*ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
46*ebfedea0SLionel Sambuc *
47*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
48*ebfedea0SLionel Sambuc * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50*ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
51*ebfedea0SLionel Sambuc * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52*ebfedea0SLionel Sambuc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53*ebfedea0SLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54*ebfedea0SLionel Sambuc * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55*ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56*ebfedea0SLionel Sambuc * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57*ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58*ebfedea0SLionel Sambuc * OF THE POSSIBILITY OF SUCH DAMAGE.
59*ebfedea0SLionel Sambuc * ====================================================================
60*ebfedea0SLionel Sambuc *
61*ebfedea0SLionel Sambuc * This product includes cryptographic software written by Eric Young
62*ebfedea0SLionel Sambuc * (eay@cryptsoft.com). This product includes software written by Tim
63*ebfedea0SLionel Sambuc * Hudson (tjh@cryptsoft.com).
64*ebfedea0SLionel Sambuc *
65*ebfedea0SLionel Sambuc */
66*ebfedea0SLionel Sambuc
67*ebfedea0SLionel Sambuc
68*ebfedea0SLionel Sambuc
69*ebfedea0SLionel Sambuc
70*ebfedea0SLionel Sambuc
71*ebfedea0SLionel Sambuc #include "MacSocket.h"
72*ebfedea0SLionel Sambuc
73*ebfedea0SLionel Sambuc #include <Threads.h>
74*ebfedea0SLionel Sambuc
75*ebfedea0SLionel Sambuc #include <OpenTransport.h>
76*ebfedea0SLionel Sambuc #include <OpenTpTInternet.h>
77*ebfedea0SLionel Sambuc #include <OpenTptClient.h>
78*ebfedea0SLionel Sambuc
79*ebfedea0SLionel Sambuc
80*ebfedea0SLionel Sambuc
81*ebfedea0SLionel Sambuc #include "CPStringUtils.hpp"
82*ebfedea0SLionel Sambuc #include "ErrorHandling.hpp"
83*ebfedea0SLionel Sambuc
84*ebfedea0SLionel Sambuc
85*ebfedea0SLionel Sambuc // #define MACSOCKET_DEBUG 1
86*ebfedea0SLionel Sambuc
87*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
88*ebfedea0SLionel Sambuc #include <stdio.h>
89*ebfedea0SLionel Sambuc #endif
90*ebfedea0SLionel Sambuc
91*ebfedea0SLionel Sambuc
92*ebfedea0SLionel Sambuc
93*ebfedea0SLionel Sambuc extern int errno;
94*ebfedea0SLionel Sambuc
95*ebfedea0SLionel Sambuc
96*ebfedea0SLionel Sambuc #define kMaxNumSockets 4
97*ebfedea0SLionel Sambuc
98*ebfedea0SLionel Sambuc
99*ebfedea0SLionel Sambuc struct SocketStruct
100*ebfedea0SLionel Sambuc {
101*ebfedea0SLionel Sambuc Boolean mIsInUse;
102*ebfedea0SLionel Sambuc
103*ebfedea0SLionel Sambuc Boolean mEndpointIsBound;
104*ebfedea0SLionel Sambuc
105*ebfedea0SLionel Sambuc Boolean mLocalEndIsConnected;
106*ebfedea0SLionel Sambuc Boolean mRemoteEndIsConnected;
107*ebfedea0SLionel Sambuc
108*ebfedea0SLionel Sambuc Boolean mReceivedTOpenComplete;
109*ebfedea0SLionel Sambuc Boolean mReceivedTBindComplete;
110*ebfedea0SLionel Sambuc Boolean mReceivedTConnect;
111*ebfedea0SLionel Sambuc Boolean mReceivedTListen;
112*ebfedea0SLionel Sambuc Boolean mReceivedTPassCon;
113*ebfedea0SLionel Sambuc Boolean mReceivedTDisconnect;
114*ebfedea0SLionel Sambuc Boolean mReceivedTOrdRel;
115*ebfedea0SLionel Sambuc Boolean mReceivedTDisconnectComplete;
116*ebfedea0SLionel Sambuc
117*ebfedea0SLionel Sambuc long mTimeoutTicks;
118*ebfedea0SLionel Sambuc long mOperationStartTicks;
119*ebfedea0SLionel Sambuc
120*ebfedea0SLionel Sambuc MacSocket_IdleWaitCallback mIdleWaitCallback;
121*ebfedea0SLionel Sambuc void *mUserRefPtr;
122*ebfedea0SLionel Sambuc
123*ebfedea0SLionel Sambuc OTEventCode mExpectedCode;
124*ebfedea0SLionel Sambuc OTResult mAsyncOperationResult;
125*ebfedea0SLionel Sambuc
126*ebfedea0SLionel Sambuc EndpointRef mEndPointRef;
127*ebfedea0SLionel Sambuc TBind *mBindRequestedAddrInfo;
128*ebfedea0SLionel Sambuc TBind *mAssignedAddrInfo;
129*ebfedea0SLionel Sambuc TCall *mRemoteAddrInfo;
130*ebfedea0SLionel Sambuc
131*ebfedea0SLionel Sambuc Boolean mReadyToReadData;
132*ebfedea0SLionel Sambuc Boolean mReadyToWriteData;
133*ebfedea0SLionel Sambuc
134*ebfedea0SLionel Sambuc Ptr mReadBuffer;
135*ebfedea0SLionel Sambuc Ptr mWriteBuffer;
136*ebfedea0SLionel Sambuc
137*ebfedea0SLionel Sambuc int mLastError;
138*ebfedea0SLionel Sambuc char mErrMessage[256];
139*ebfedea0SLionel Sambuc };
140*ebfedea0SLionel Sambuc
141*ebfedea0SLionel Sambuc typedef struct SocketStruct SocketStruct;
142*ebfedea0SLionel Sambuc
143*ebfedea0SLionel Sambuc
144*ebfedea0SLionel Sambuc static SocketStruct sSockets[kMaxNumSockets];
145*ebfedea0SLionel Sambuc static Boolean sSocketsSetup = false;
146*ebfedea0SLionel Sambuc
147*ebfedea0SLionel Sambuc
148*ebfedea0SLionel Sambuc
149*ebfedea0SLionel Sambuc
150*ebfedea0SLionel Sambuc static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
151*ebfedea0SLionel Sambuc
152*ebfedea0SLionel Sambuc static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
153*ebfedea0SLionel Sambuc
154*ebfedea0SLionel Sambuc static Boolean SocketIndexIsValid(const int inSocketNum);
155*ebfedea0SLionel Sambuc
156*ebfedea0SLionel Sambuc static void InitSocket(SocketStruct *ioSocket);
157*ebfedea0SLionel Sambuc
158*ebfedea0SLionel Sambuc static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
159*ebfedea0SLionel Sambuc
160*ebfedea0SLionel Sambuc static Boolean TimeoutElapsed(const SocketStruct *inSocket);
161*ebfedea0SLionel Sambuc
162*ebfedea0SLionel Sambuc static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
163*ebfedea0SLionel Sambuc
164*ebfedea0SLionel Sambuc
165*ebfedea0SLionel Sambuc
MacSocket_GetSocketErrorInfo(const int inSocketNum,int * outSocketErrCode,char * outSocketErrString,const int inSocketErrStringMaxLength)166*ebfedea0SLionel Sambuc void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength)
167*ebfedea0SLionel Sambuc {
168*ebfedea0SLionel Sambuc if (outSocketErrCode != nil)
169*ebfedea0SLionel Sambuc {
170*ebfedea0SLionel Sambuc *outSocketErrCode = -1;
171*ebfedea0SLionel Sambuc }
172*ebfedea0SLionel Sambuc
173*ebfedea0SLionel Sambuc if (outSocketErrString != nil)
174*ebfedea0SLionel Sambuc {
175*ebfedea0SLionel Sambuc CopyCStrToCStr("",outSocketErrString,inSocketErrStringMaxLength);
176*ebfedea0SLionel Sambuc }
177*ebfedea0SLionel Sambuc
178*ebfedea0SLionel Sambuc
179*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
180*ebfedea0SLionel Sambuc {
181*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
182*ebfedea0SLionel Sambuc
183*ebfedea0SLionel Sambuc
184*ebfedea0SLionel Sambuc if (outSocketErrCode != nil)
185*ebfedea0SLionel Sambuc {
186*ebfedea0SLionel Sambuc *outSocketErrCode = theSocketStruct->mLastError;
187*ebfedea0SLionel Sambuc }
188*ebfedea0SLionel Sambuc
189*ebfedea0SLionel Sambuc if (outSocketErrString != nil)
190*ebfedea0SLionel Sambuc {
191*ebfedea0SLionel Sambuc CopyCStrToCStr(theSocketStruct->mErrMessage,outSocketErrString,inSocketErrStringMaxLength);
192*ebfedea0SLionel Sambuc }
193*ebfedea0SLionel Sambuc }
194*ebfedea0SLionel Sambuc }
195*ebfedea0SLionel Sambuc
196*ebfedea0SLionel Sambuc
MacSocket_SetUserRefPtr(const int inSocketNum,void * inNewRefPtr)197*ebfedea0SLionel Sambuc void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr)
198*ebfedea0SLionel Sambuc {
199*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
200*ebfedea0SLionel Sambuc {
201*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
202*ebfedea0SLionel Sambuc
203*ebfedea0SLionel Sambuc theSocketStruct->mUserRefPtr = inNewRefPtr;
204*ebfedea0SLionel Sambuc }
205*ebfedea0SLionel Sambuc }
206*ebfedea0SLionel Sambuc
207*ebfedea0SLionel Sambuc
208*ebfedea0SLionel Sambuc
MacSocket_GetLocalIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)209*ebfedea0SLionel Sambuc void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
210*ebfedea0SLionel Sambuc {
211*ebfedea0SLionel Sambuc if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
212*ebfedea0SLionel Sambuc {
213*ebfedea0SLionel Sambuc char tempString[256];
214*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
215*ebfedea0SLionel Sambuc
216*ebfedea0SLionel Sambuc
217*ebfedea0SLionel Sambuc CopyCStrToCStr("",tempString,sizeof(tempString));
218*ebfedea0SLionel Sambuc
219*ebfedea0SLionel Sambuc if (theSocketStruct->mAssignedAddrInfo != nil)
220*ebfedea0SLionel Sambuc {
221*ebfedea0SLionel Sambuc InetAddress *theInetAddress = (InetAddress *) theSocketStruct->mAssignedAddrInfo->addr.buf;
222*ebfedea0SLionel Sambuc InetHost theInetHost = theInetAddress->fHost;
223*ebfedea0SLionel Sambuc
224*ebfedea0SLionel Sambuc if (theInetHost == 0)
225*ebfedea0SLionel Sambuc {
226*ebfedea0SLionel Sambuc InetInterfaceInfo theInetInterfaceInfo;
227*ebfedea0SLionel Sambuc
228*ebfedea0SLionel Sambuc if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
229*ebfedea0SLionel Sambuc {
230*ebfedea0SLionel Sambuc theInetHost = theInetInterfaceInfo.fAddress;
231*ebfedea0SLionel Sambuc }
232*ebfedea0SLionel Sambuc }
233*ebfedea0SLionel Sambuc
234*ebfedea0SLionel Sambuc ::OTInetHostToString(theInetHost,tempString);
235*ebfedea0SLionel Sambuc
236*ebfedea0SLionel Sambuc ConcatCStrToCStr(":",tempString,sizeof(tempString));
237*ebfedea0SLionel Sambuc ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
238*ebfedea0SLionel Sambuc }
239*ebfedea0SLionel Sambuc
240*ebfedea0SLionel Sambuc CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
241*ebfedea0SLionel Sambuc }
242*ebfedea0SLionel Sambuc }
243*ebfedea0SLionel Sambuc
244*ebfedea0SLionel Sambuc
245*ebfedea0SLionel Sambuc
MacSocket_GetRemoteIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)246*ebfedea0SLionel Sambuc void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
247*ebfedea0SLionel Sambuc {
248*ebfedea0SLionel Sambuc if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
249*ebfedea0SLionel Sambuc {
250*ebfedea0SLionel Sambuc char tempString[256];
251*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
252*ebfedea0SLionel Sambuc
253*ebfedea0SLionel Sambuc
254*ebfedea0SLionel Sambuc CopyCStrToCStr("",tempString,sizeof(tempString));
255*ebfedea0SLionel Sambuc
256*ebfedea0SLionel Sambuc if (theSocketStruct->mRemoteAddrInfo != nil)
257*ebfedea0SLionel Sambuc {
258*ebfedea0SLionel Sambuc InetAddress *theInetAddress = (InetAddress *) theSocketStruct->mRemoteAddrInfo->addr.buf;
259*ebfedea0SLionel Sambuc InetHost theInetHost = theInetAddress->fHost;
260*ebfedea0SLionel Sambuc
261*ebfedea0SLionel Sambuc if (theInetHost == 0)
262*ebfedea0SLionel Sambuc {
263*ebfedea0SLionel Sambuc InetInterfaceInfo theInetInterfaceInfo;
264*ebfedea0SLionel Sambuc
265*ebfedea0SLionel Sambuc if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
266*ebfedea0SLionel Sambuc {
267*ebfedea0SLionel Sambuc theInetHost = theInetInterfaceInfo.fAddress;
268*ebfedea0SLionel Sambuc }
269*ebfedea0SLionel Sambuc }
270*ebfedea0SLionel Sambuc
271*ebfedea0SLionel Sambuc ::OTInetHostToString(theInetHost,tempString);
272*ebfedea0SLionel Sambuc
273*ebfedea0SLionel Sambuc ConcatCStrToCStr(":",tempString,sizeof(tempString));
274*ebfedea0SLionel Sambuc ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
275*ebfedea0SLionel Sambuc }
276*ebfedea0SLionel Sambuc
277*ebfedea0SLionel Sambuc CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
278*ebfedea0SLionel Sambuc }
279*ebfedea0SLionel Sambuc }
280*ebfedea0SLionel Sambuc
281*ebfedea0SLionel Sambuc
282*ebfedea0SLionel Sambuc
MacSocket_RemoteEndIsClosing(const int inSocketNum)283*ebfedea0SLionel Sambuc Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
284*ebfedea0SLionel Sambuc {
285*ebfedea0SLionel Sambuc Boolean theResult = false;
286*ebfedea0SLionel Sambuc
287*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
288*ebfedea0SLionel Sambuc {
289*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
290*ebfedea0SLionel Sambuc
291*ebfedea0SLionel Sambuc theResult = theSocketStruct->mReceivedTOrdRel;
292*ebfedea0SLionel Sambuc }
293*ebfedea0SLionel Sambuc
294*ebfedea0SLionel Sambuc return(theResult);
295*ebfedea0SLionel Sambuc }
296*ebfedea0SLionel Sambuc
297*ebfedea0SLionel Sambuc
298*ebfedea0SLionel Sambuc
MacSocket_ListenCompleted(const int inSocketNum)299*ebfedea0SLionel Sambuc Boolean MacSocket_ListenCompleted(const int inSocketNum)
300*ebfedea0SLionel Sambuc {
301*ebfedea0SLionel Sambuc Boolean theResult = false;
302*ebfedea0SLionel Sambuc
303*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
304*ebfedea0SLionel Sambuc {
305*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
306*ebfedea0SLionel Sambuc
307*ebfedea0SLionel Sambuc theResult = theSocketStruct->mReceivedTPassCon;
308*ebfedea0SLionel Sambuc }
309*ebfedea0SLionel Sambuc
310*ebfedea0SLionel Sambuc return(theResult);
311*ebfedea0SLionel Sambuc }
312*ebfedea0SLionel Sambuc
313*ebfedea0SLionel Sambuc
314*ebfedea0SLionel Sambuc
MacSocket_RemoteEndIsOpen(const int inSocketNum)315*ebfedea0SLionel Sambuc Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum)
316*ebfedea0SLionel Sambuc {
317*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
318*ebfedea0SLionel Sambuc {
319*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
320*ebfedea0SLionel Sambuc
321*ebfedea0SLionel Sambuc return(theSocketStruct->mRemoteEndIsConnected);
322*ebfedea0SLionel Sambuc }
323*ebfedea0SLionel Sambuc
324*ebfedea0SLionel Sambuc else
325*ebfedea0SLionel Sambuc {
326*ebfedea0SLionel Sambuc return(false);
327*ebfedea0SLionel Sambuc }
328*ebfedea0SLionel Sambuc }
329*ebfedea0SLionel Sambuc
330*ebfedea0SLionel Sambuc
331*ebfedea0SLionel Sambuc
MacSocket_LocalEndIsOpen(const int inSocketNum)332*ebfedea0SLionel Sambuc Boolean MacSocket_LocalEndIsOpen(const int inSocketNum)
333*ebfedea0SLionel Sambuc {
334*ebfedea0SLionel Sambuc if (SocketIndexIsValid(inSocketNum))
335*ebfedea0SLionel Sambuc {
336*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[inSocketNum]);
337*ebfedea0SLionel Sambuc
338*ebfedea0SLionel Sambuc return(theSocketStruct->mLocalEndIsConnected);
339*ebfedea0SLionel Sambuc }
340*ebfedea0SLionel Sambuc
341*ebfedea0SLionel Sambuc else
342*ebfedea0SLionel Sambuc {
343*ebfedea0SLionel Sambuc return(false);
344*ebfedea0SLionel Sambuc }
345*ebfedea0SLionel Sambuc }
346*ebfedea0SLionel Sambuc
347*ebfedea0SLionel Sambuc
348*ebfedea0SLionel Sambuc
TimeoutElapsed(const SocketStruct * inSocket)349*ebfedea0SLionel Sambuc static Boolean TimeoutElapsed(const SocketStruct *inSocket)
350*ebfedea0SLionel Sambuc {
351*ebfedea0SLionel Sambuc Boolean timeIsUp = false;
352*ebfedea0SLionel Sambuc
353*ebfedea0SLionel Sambuc if (inSocket != nil && inSocket->mTimeoutTicks > 0 && ::TickCount() > inSocket->mOperationStartTicks + inSocket->mTimeoutTicks)
354*ebfedea0SLionel Sambuc {
355*ebfedea0SLionel Sambuc timeIsUp = true;
356*ebfedea0SLionel Sambuc }
357*ebfedea0SLionel Sambuc
358*ebfedea0SLionel Sambuc
359*ebfedea0SLionel Sambuc return(timeIsUp);
360*ebfedea0SLionel Sambuc }
361*ebfedea0SLionel Sambuc
362*ebfedea0SLionel Sambuc
363*ebfedea0SLionel Sambuc
SocketIndexIsValid(const int inSocketNum)364*ebfedea0SLionel Sambuc static Boolean SocketIndexIsValid(const int inSocketNum)
365*ebfedea0SLionel Sambuc {
366*ebfedea0SLionel Sambuc if (inSocketNum >= 0 && inSocketNum < kMaxNumSockets && sSockets[inSocketNum].mEndPointRef != kOTInvalidEndpointRef)
367*ebfedea0SLionel Sambuc {
368*ebfedea0SLionel Sambuc return(true);
369*ebfedea0SLionel Sambuc }
370*ebfedea0SLionel Sambuc
371*ebfedea0SLionel Sambuc else
372*ebfedea0SLionel Sambuc {
373*ebfedea0SLionel Sambuc return(false);
374*ebfedea0SLionel Sambuc }
375*ebfedea0SLionel Sambuc }
376*ebfedea0SLionel Sambuc
377*ebfedea0SLionel Sambuc
378*ebfedea0SLionel Sambuc
InitSocket(SocketStruct * ioSocket)379*ebfedea0SLionel Sambuc static void InitSocket(SocketStruct *ioSocket)
380*ebfedea0SLionel Sambuc {
381*ebfedea0SLionel Sambuc ioSocket->mIsInUse = false;
382*ebfedea0SLionel Sambuc
383*ebfedea0SLionel Sambuc ioSocket->mEndpointIsBound = false;
384*ebfedea0SLionel Sambuc
385*ebfedea0SLionel Sambuc ioSocket->mLocalEndIsConnected = false;
386*ebfedea0SLionel Sambuc ioSocket->mRemoteEndIsConnected = false;
387*ebfedea0SLionel Sambuc
388*ebfedea0SLionel Sambuc ioSocket->mReceivedTOpenComplete = false;
389*ebfedea0SLionel Sambuc ioSocket->mReceivedTBindComplete = false;
390*ebfedea0SLionel Sambuc ioSocket->mReceivedTConnect = false;
391*ebfedea0SLionel Sambuc ioSocket->mReceivedTListen = false;
392*ebfedea0SLionel Sambuc ioSocket->mReceivedTPassCon = false;
393*ebfedea0SLionel Sambuc ioSocket->mReceivedTDisconnect = false;
394*ebfedea0SLionel Sambuc ioSocket->mReceivedTOrdRel = false;
395*ebfedea0SLionel Sambuc ioSocket->mReceivedTDisconnectComplete = false;
396*ebfedea0SLionel Sambuc
397*ebfedea0SLionel Sambuc ioSocket->mTimeoutTicks = 30 * 60;
398*ebfedea0SLionel Sambuc ioSocket->mOperationStartTicks = -1;
399*ebfedea0SLionel Sambuc
400*ebfedea0SLionel Sambuc ioSocket->mIdleWaitCallback = nil;
401*ebfedea0SLionel Sambuc ioSocket->mUserRefPtr = nil;
402*ebfedea0SLionel Sambuc
403*ebfedea0SLionel Sambuc ioSocket->mExpectedCode = 0;
404*ebfedea0SLionel Sambuc ioSocket->mAsyncOperationResult = noErr;
405*ebfedea0SLionel Sambuc
406*ebfedea0SLionel Sambuc ioSocket->mEndPointRef = kOTInvalidEndpointRef;
407*ebfedea0SLionel Sambuc
408*ebfedea0SLionel Sambuc ioSocket->mBindRequestedAddrInfo = nil;
409*ebfedea0SLionel Sambuc ioSocket->mAssignedAddrInfo = nil;
410*ebfedea0SLionel Sambuc ioSocket->mRemoteAddrInfo = nil;
411*ebfedea0SLionel Sambuc
412*ebfedea0SLionel Sambuc ioSocket->mReadyToReadData = false;
413*ebfedea0SLionel Sambuc ioSocket->mReadyToWriteData = true;
414*ebfedea0SLionel Sambuc
415*ebfedea0SLionel Sambuc ioSocket->mReadBuffer = nil;
416*ebfedea0SLionel Sambuc ioSocket->mWriteBuffer = nil;
417*ebfedea0SLionel Sambuc
418*ebfedea0SLionel Sambuc ioSocket->mLastError = noErr;
419*ebfedea0SLionel Sambuc CopyCStrToCStr("",ioSocket->mErrMessage,sizeof(ioSocket->mErrMessage));
420*ebfedea0SLionel Sambuc }
421*ebfedea0SLionel Sambuc
422*ebfedea0SLionel Sambuc
423*ebfedea0SLionel Sambuc
PrepareForAsyncOperation(SocketStruct * ioSocket,const OTEventCode inExpectedCode)424*ebfedea0SLionel Sambuc static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode)
425*ebfedea0SLionel Sambuc {
426*ebfedea0SLionel Sambuc ioSocket->mOperationStartTicks = ::TickCount();
427*ebfedea0SLionel Sambuc
428*ebfedea0SLionel Sambuc ioSocket->mAsyncOperationResult = noErr;
429*ebfedea0SLionel Sambuc
430*ebfedea0SLionel Sambuc ioSocket->mExpectedCode = inExpectedCode;
431*ebfedea0SLionel Sambuc }
432*ebfedea0SLionel Sambuc
433*ebfedea0SLionel Sambuc
434*ebfedea0SLionel Sambuc // The wait function....
435*ebfedea0SLionel Sambuc
MyBusyWait(SocketStruct * ioSocket,Boolean returnImmediatelyOnError,OTResult * outOTResult,Boolean * inAsyncOperationCompleteFlag)436*ebfedea0SLionel Sambuc static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
437*ebfedea0SLionel Sambuc {
438*ebfedea0SLionel Sambuc OSErr errCode = noErr;
439*ebfedea0SLionel Sambuc OTResult theOTResult = noErr;
440*ebfedea0SLionel Sambuc
441*ebfedea0SLionel Sambuc
442*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(ioSocket,"MyBusyWait: Bad parameter, ioSocket = nil");
443*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(inAsyncOperationCompleteFlag,"MyBusyWait: Bad parameter, inAsyncOperationCompleteFlag = nil");
444*ebfedea0SLionel Sambuc
445*ebfedea0SLionel Sambuc for (;;)
446*ebfedea0SLionel Sambuc {
447*ebfedea0SLionel Sambuc if (*inAsyncOperationCompleteFlag)
448*ebfedea0SLionel Sambuc {
449*ebfedea0SLionel Sambuc theOTResult = ioSocket->mAsyncOperationResult;
450*ebfedea0SLionel Sambuc
451*ebfedea0SLionel Sambuc break;
452*ebfedea0SLionel Sambuc }
453*ebfedea0SLionel Sambuc
454*ebfedea0SLionel Sambuc if (ioSocket->mIdleWaitCallback != nil)
455*ebfedea0SLionel Sambuc {
456*ebfedea0SLionel Sambuc theOTResult = (*(ioSocket->mIdleWaitCallback))(ioSocket->mUserRefPtr);
457*ebfedea0SLionel Sambuc
458*ebfedea0SLionel Sambuc if (theOTResult != noErr && returnImmediatelyOnError)
459*ebfedea0SLionel Sambuc {
460*ebfedea0SLionel Sambuc break;
461*ebfedea0SLionel Sambuc }
462*ebfedea0SLionel Sambuc }
463*ebfedea0SLionel Sambuc
464*ebfedea0SLionel Sambuc if (TimeoutElapsed(ioSocket))
465*ebfedea0SLionel Sambuc {
466*ebfedea0SLionel Sambuc theOTResult = kMacSocket_TimeoutErr;
467*ebfedea0SLionel Sambuc
468*ebfedea0SLionel Sambuc break;
469*ebfedea0SLionel Sambuc }
470*ebfedea0SLionel Sambuc }
471*ebfedea0SLionel Sambuc
472*ebfedea0SLionel Sambuc
473*ebfedea0SLionel Sambuc EXITPOINT:
474*ebfedea0SLionel Sambuc
475*ebfedea0SLionel Sambuc if (outOTResult != nil)
476*ebfedea0SLionel Sambuc {
477*ebfedea0SLionel Sambuc *outOTResult = theOTResult;
478*ebfedea0SLionel Sambuc }
479*ebfedea0SLionel Sambuc
480*ebfedea0SLionel Sambuc return(errCode);
481*ebfedea0SLionel Sambuc }
482*ebfedea0SLionel Sambuc
483*ebfedea0SLionel Sambuc
484*ebfedea0SLionel Sambuc
485*ebfedea0SLionel Sambuc // I used to do thread switching, but stopped. It could easily be rolled back in though....
486*ebfedea0SLionel Sambuc
OTNonYieldingNotifier(void * contextPtr,OTEventCode code,OTResult result,void * cookie)487*ebfedea0SLionel Sambuc static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
488*ebfedea0SLionel Sambuc {
489*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = (SocketStruct *) contextPtr;
490*ebfedea0SLionel Sambuc
491*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
492*ebfedea0SLionel Sambuc {
493*ebfedea0SLionel Sambuc if (theSocketStruct->mExpectedCode != 0 && code == theSocketStruct->mExpectedCode)
494*ebfedea0SLionel Sambuc {
495*ebfedea0SLionel Sambuc theSocketStruct->mAsyncOperationResult = result;
496*ebfedea0SLionel Sambuc
497*ebfedea0SLionel Sambuc theSocketStruct->mExpectedCode = 0;
498*ebfedea0SLionel Sambuc }
499*ebfedea0SLionel Sambuc
500*ebfedea0SLionel Sambuc
501*ebfedea0SLionel Sambuc switch (code)
502*ebfedea0SLionel Sambuc {
503*ebfedea0SLionel Sambuc case T_OPENCOMPLETE:
504*ebfedea0SLionel Sambuc {
505*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTOpenComplete = true;
506*ebfedea0SLionel Sambuc
507*ebfedea0SLionel Sambuc theSocketStruct->mEndPointRef = (EndpointRef) cookie;
508*ebfedea0SLionel Sambuc
509*ebfedea0SLionel Sambuc break;
510*ebfedea0SLionel Sambuc }
511*ebfedea0SLionel Sambuc
512*ebfedea0SLionel Sambuc
513*ebfedea0SLionel Sambuc case T_BINDCOMPLETE:
514*ebfedea0SLionel Sambuc {
515*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTBindComplete = true;
516*ebfedea0SLionel Sambuc
517*ebfedea0SLionel Sambuc break;
518*ebfedea0SLionel Sambuc }
519*ebfedea0SLionel Sambuc
520*ebfedea0SLionel Sambuc
521*ebfedea0SLionel Sambuc case T_CONNECT:
522*ebfedea0SLionel Sambuc {
523*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTConnect = true;
524*ebfedea0SLionel Sambuc
525*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = true;
526*ebfedea0SLionel Sambuc
527*ebfedea0SLionel Sambuc theSocketStruct->mRemoteEndIsConnected = true;
528*ebfedea0SLionel Sambuc
529*ebfedea0SLionel Sambuc break;
530*ebfedea0SLionel Sambuc }
531*ebfedea0SLionel Sambuc
532*ebfedea0SLionel Sambuc
533*ebfedea0SLionel Sambuc case T_LISTEN:
534*ebfedea0SLionel Sambuc {
535*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTListen = true;
536*ebfedea0SLionel Sambuc
537*ebfedea0SLionel Sambuc break;
538*ebfedea0SLionel Sambuc }
539*ebfedea0SLionel Sambuc
540*ebfedea0SLionel Sambuc
541*ebfedea0SLionel Sambuc case T_PASSCON:
542*ebfedea0SLionel Sambuc {
543*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTPassCon = true;
544*ebfedea0SLionel Sambuc
545*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = true;
546*ebfedea0SLionel Sambuc
547*ebfedea0SLionel Sambuc theSocketStruct->mRemoteEndIsConnected = true;
548*ebfedea0SLionel Sambuc
549*ebfedea0SLionel Sambuc break;
550*ebfedea0SLionel Sambuc }
551*ebfedea0SLionel Sambuc
552*ebfedea0SLionel Sambuc
553*ebfedea0SLionel Sambuc case T_DATA:
554*ebfedea0SLionel Sambuc {
555*ebfedea0SLionel Sambuc theSocketStruct->mReadyToReadData = true;
556*ebfedea0SLionel Sambuc
557*ebfedea0SLionel Sambuc break;
558*ebfedea0SLionel Sambuc }
559*ebfedea0SLionel Sambuc
560*ebfedea0SLionel Sambuc case T_GODATA:
561*ebfedea0SLionel Sambuc {
562*ebfedea0SLionel Sambuc theSocketStruct->mReadyToWriteData = true;
563*ebfedea0SLionel Sambuc
564*ebfedea0SLionel Sambuc break;
565*ebfedea0SLionel Sambuc }
566*ebfedea0SLionel Sambuc
567*ebfedea0SLionel Sambuc case T_DISCONNECT:
568*ebfedea0SLionel Sambuc {
569*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTDisconnect = true;
570*ebfedea0SLionel Sambuc
571*ebfedea0SLionel Sambuc theSocketStruct->mRemoteEndIsConnected = false;
572*ebfedea0SLionel Sambuc
573*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = false;
574*ebfedea0SLionel Sambuc
575*ebfedea0SLionel Sambuc ::OTRcvDisconnect(theSocketStruct->mEndPointRef,nil);
576*ebfedea0SLionel Sambuc
577*ebfedea0SLionel Sambuc break;
578*ebfedea0SLionel Sambuc }
579*ebfedea0SLionel Sambuc
580*ebfedea0SLionel Sambuc case T_ORDREL:
581*ebfedea0SLionel Sambuc {
582*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTOrdRel = true;
583*ebfedea0SLionel Sambuc
584*ebfedea0SLionel Sambuc // We can still write data, so don't clear mRemoteEndIsConnected
585*ebfedea0SLionel Sambuc
586*ebfedea0SLionel Sambuc ::OTRcvOrderlyDisconnect(theSocketStruct->mEndPointRef);
587*ebfedea0SLionel Sambuc
588*ebfedea0SLionel Sambuc break;
589*ebfedea0SLionel Sambuc }
590*ebfedea0SLionel Sambuc
591*ebfedea0SLionel Sambuc case T_DISCONNECTCOMPLETE:
592*ebfedea0SLionel Sambuc {
593*ebfedea0SLionel Sambuc theSocketStruct->mReceivedTDisconnectComplete = true;
594*ebfedea0SLionel Sambuc
595*ebfedea0SLionel Sambuc theSocketStruct->mRemoteEndIsConnected = false;
596*ebfedea0SLionel Sambuc
597*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = false;
598*ebfedea0SLionel Sambuc
599*ebfedea0SLionel Sambuc break;
600*ebfedea0SLionel Sambuc }
601*ebfedea0SLionel Sambuc }
602*ebfedea0SLionel Sambuc }
603*ebfedea0SLionel Sambuc /*
604*ebfedea0SLionel Sambuc T_LISTEN OTListen
605*ebfedea0SLionel Sambuc T_CONNECT OTRcvConnect
606*ebfedea0SLionel Sambuc T_DATA OTRcv, OTRcvUData
607*ebfedea0SLionel Sambuc T_DISCONNECT OTRcvDisconnect
608*ebfedea0SLionel Sambuc T_ORDREL OTRcvOrderlyDisconnect
609*ebfedea0SLionel Sambuc T_GODATA OTSnd, OTSndUData, OTLook
610*ebfedea0SLionel Sambuc T_PASSCON none
611*ebfedea0SLionel Sambuc
612*ebfedea0SLionel Sambuc T_EXDATA OTRcv
613*ebfedea0SLionel Sambuc T_GOEXDATA OTSnd, OTLook
614*ebfedea0SLionel Sambuc T_UDERR OTRcvUDErr
615*ebfedea0SLionel Sambuc */
616*ebfedea0SLionel Sambuc }
617*ebfedea0SLionel Sambuc
618*ebfedea0SLionel Sambuc
619*ebfedea0SLionel Sambuc
620*ebfedea0SLionel Sambuc // Initialize the main socket data structure
621*ebfedea0SLionel Sambuc
MacSocket_Startup(void)622*ebfedea0SLionel Sambuc OSErr MacSocket_Startup(void)
623*ebfedea0SLionel Sambuc {
624*ebfedea0SLionel Sambuc if (!sSocketsSetup)
625*ebfedea0SLionel Sambuc {
626*ebfedea0SLionel Sambuc for (int i = 0;i < kMaxNumSockets;i++)
627*ebfedea0SLionel Sambuc {
628*ebfedea0SLionel Sambuc InitSocket(&(sSockets[i]));
629*ebfedea0SLionel Sambuc }
630*ebfedea0SLionel Sambuc
631*ebfedea0SLionel Sambuc ::InitOpenTransport();
632*ebfedea0SLionel Sambuc
633*ebfedea0SLionel Sambuc sSocketsSetup = true;
634*ebfedea0SLionel Sambuc }
635*ebfedea0SLionel Sambuc
636*ebfedea0SLionel Sambuc
637*ebfedea0SLionel Sambuc return(noErr);
638*ebfedea0SLionel Sambuc }
639*ebfedea0SLionel Sambuc
640*ebfedea0SLionel Sambuc
641*ebfedea0SLionel Sambuc
642*ebfedea0SLionel Sambuc // Cleanup before exiting
643*ebfedea0SLionel Sambuc
MacSocket_Shutdown(void)644*ebfedea0SLionel Sambuc OSErr MacSocket_Shutdown(void)
645*ebfedea0SLionel Sambuc {
646*ebfedea0SLionel Sambuc if (sSocketsSetup)
647*ebfedea0SLionel Sambuc {
648*ebfedea0SLionel Sambuc for (int i = 0;i < kMaxNumSockets;i++)
649*ebfedea0SLionel Sambuc {
650*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[i]);
651*ebfedea0SLionel Sambuc
652*ebfedea0SLionel Sambuc if (theSocketStruct->mIsInUse)
653*ebfedea0SLionel Sambuc {
654*ebfedea0SLionel Sambuc if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
655*ebfedea0SLionel Sambuc {
656*ebfedea0SLionel Sambuc OTResult theOTResult;
657*ebfedea0SLionel Sambuc
658*ebfedea0SLionel Sambuc
659*ebfedea0SLionel Sambuc // Since we're killing the endpoint, I don't bother to send the disconnect (sorry!)
660*ebfedea0SLionel Sambuc
661*ebfedea0SLionel Sambuc /*
662*ebfedea0SLionel Sambuc if (theSocketStruct->mLocalEndIsConnected)
663*ebfedea0SLionel Sambuc {
664*ebfedea0SLionel Sambuc // This is an abortive action, so we do a hard disconnect instead of an OTSndOrderlyDisconnect
665*ebfedea0SLionel Sambuc
666*ebfedea0SLionel Sambuc theOTResult = ::OTSndDisconnect(theSocketStruct->mEndPointRef, nil);
667*ebfedea0SLionel Sambuc
668*ebfedea0SLionel Sambuc // Now we have to watch for T_DISCONNECTCOMPLETE event
669*ebfedea0SLionel Sambuc
670*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = false;
671*ebfedea0SLionel Sambuc }
672*ebfedea0SLionel Sambuc */
673*ebfedea0SLionel Sambuc
674*ebfedea0SLionel Sambuc theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
675*ebfedea0SLionel Sambuc
676*ebfedea0SLionel Sambuc
677*ebfedea0SLionel Sambuc theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
678*ebfedea0SLionel Sambuc }
679*ebfedea0SLionel Sambuc
680*ebfedea0SLionel Sambuc if (theSocketStruct->mBindRequestedAddrInfo != nil)
681*ebfedea0SLionel Sambuc {
682*ebfedea0SLionel Sambuc ::OTFree((void *) theSocketStruct->mBindRequestedAddrInfo,T_BIND);
683*ebfedea0SLionel Sambuc
684*ebfedea0SLionel Sambuc theSocketStruct->mBindRequestedAddrInfo = nil;
685*ebfedea0SLionel Sambuc }
686*ebfedea0SLionel Sambuc
687*ebfedea0SLionel Sambuc if (theSocketStruct->mAssignedAddrInfo != nil)
688*ebfedea0SLionel Sambuc {
689*ebfedea0SLionel Sambuc ::OTFree((void *) theSocketStruct->mAssignedAddrInfo,T_BIND);
690*ebfedea0SLionel Sambuc
691*ebfedea0SLionel Sambuc theSocketStruct->mAssignedAddrInfo = nil;
692*ebfedea0SLionel Sambuc }
693*ebfedea0SLionel Sambuc
694*ebfedea0SLionel Sambuc if (theSocketStruct->mRemoteAddrInfo != nil)
695*ebfedea0SLionel Sambuc {
696*ebfedea0SLionel Sambuc ::OTFree((void *) theSocketStruct->mRemoteAddrInfo,T_CALL);
697*ebfedea0SLionel Sambuc
698*ebfedea0SLionel Sambuc theSocketStruct->mRemoteAddrInfo = nil;
699*ebfedea0SLionel Sambuc }
700*ebfedea0SLionel Sambuc
701*ebfedea0SLionel Sambuc
702*ebfedea0SLionel Sambuc }
703*ebfedea0SLionel Sambuc }
704*ebfedea0SLionel Sambuc
705*ebfedea0SLionel Sambuc ::CloseOpenTransport();
706*ebfedea0SLionel Sambuc
707*ebfedea0SLionel Sambuc sSocketsSetup = false;
708*ebfedea0SLionel Sambuc }
709*ebfedea0SLionel Sambuc
710*ebfedea0SLionel Sambuc return(noErr);
711*ebfedea0SLionel Sambuc }
712*ebfedea0SLionel Sambuc
713*ebfedea0SLionel Sambuc
714*ebfedea0SLionel Sambuc
715*ebfedea0SLionel Sambuc
716*ebfedea0SLionel Sambuc
717*ebfedea0SLionel Sambuc
718*ebfedea0SLionel Sambuc // Allocate a socket
719*ebfedea0SLionel Sambuc
MacSocket_socket(int * outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void * inUserRefPtr)720*ebfedea0SLionel Sambuc OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr)
721*ebfedea0SLionel Sambuc {
722*ebfedea0SLionel Sambuc // Gotta roll support back in for threads eventually.....
723*ebfedea0SLionel Sambuc
724*ebfedea0SLionel Sambuc #pragma unused(inDoThreadSwitching)
725*ebfedea0SLionel Sambuc
726*ebfedea0SLionel Sambuc
727*ebfedea0SLionel Sambuc OSErr errCode = noErr;
728*ebfedea0SLionel Sambuc
729*ebfedea0SLionel Sambuc
730*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(outSocketNum,"MacSocket_socket: Bad parameter, outSocketNum == nil");
731*ebfedea0SLionel Sambuc
732*ebfedea0SLionel Sambuc *outSocketNum = -1;
733*ebfedea0SLionel Sambuc
734*ebfedea0SLionel Sambuc
735*ebfedea0SLionel Sambuc // Find an unused socket
736*ebfedea0SLionel Sambuc
737*ebfedea0SLionel Sambuc for (int i = 0;i < kMaxNumSockets;i++)
738*ebfedea0SLionel Sambuc {
739*ebfedea0SLionel Sambuc if (sSockets[i].mIsInUse == false)
740*ebfedea0SLionel Sambuc {
741*ebfedea0SLionel Sambuc OTResult theOTResult;
742*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = &(sSockets[i]);
743*ebfedea0SLionel Sambuc
744*ebfedea0SLionel Sambuc
745*ebfedea0SLionel Sambuc InitSocket(theSocketStruct);
746*ebfedea0SLionel Sambuc
747*ebfedea0SLionel Sambuc theSocketStruct->mIdleWaitCallback = inIdleWaitCallback;
748*ebfedea0SLionel Sambuc theSocketStruct->mUserRefPtr = inUserRefPtr;
749*ebfedea0SLionel Sambuc
750*ebfedea0SLionel Sambuc theSocketStruct->mTimeoutTicks = inTimeoutTicks;
751*ebfedea0SLionel Sambuc
752*ebfedea0SLionel Sambuc
753*ebfedea0SLionel Sambuc // Set up OT endpoint
754*ebfedea0SLionel Sambuc
755*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_OPENCOMPLETE);
756*ebfedea0SLionel Sambuc
757*ebfedea0SLionel Sambuc theOTResult = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),0,nil,OTNonYieldingNotifier,(void *) theSocketStruct);
758*ebfedea0SLionel Sambuc
759*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
760*ebfedea0SLionel Sambuc
761*ebfedea0SLionel Sambuc BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOpenComplete)));
762*ebfedea0SLionel Sambuc
763*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
764*ebfedea0SLionel Sambuc
765*ebfedea0SLionel Sambuc
766*ebfedea0SLionel Sambuc *outSocketNum = i;
767*ebfedea0SLionel Sambuc
768*ebfedea0SLionel Sambuc errCode = noErr;
769*ebfedea0SLionel Sambuc
770*ebfedea0SLionel Sambuc theSocketStruct->mIsInUse = true;
771*ebfedea0SLionel Sambuc
772*ebfedea0SLionel Sambuc break;
773*ebfedea0SLionel Sambuc }
774*ebfedea0SLionel Sambuc
775*ebfedea0SLionel Sambuc else if (i == kMaxNumSockets - 1)
776*ebfedea0SLionel Sambuc {
777*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_socket: No sockets available");
778*ebfedea0SLionel Sambuc }
779*ebfedea0SLionel Sambuc }
780*ebfedea0SLionel Sambuc
781*ebfedea0SLionel Sambuc
782*ebfedea0SLionel Sambuc EXITPOINT:
783*ebfedea0SLionel Sambuc
784*ebfedea0SLionel Sambuc errno = errCode;
785*ebfedea0SLionel Sambuc
786*ebfedea0SLionel Sambuc return(errCode);
787*ebfedea0SLionel Sambuc }
788*ebfedea0SLionel Sambuc
789*ebfedea0SLionel Sambuc
790*ebfedea0SLionel Sambuc
791*ebfedea0SLionel Sambuc
MacSocket_listen(const int inSocketNum,const int inPortNum)792*ebfedea0SLionel Sambuc OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
793*ebfedea0SLionel Sambuc {
794*ebfedea0SLionel Sambuc OSErr errCode = noErr;
795*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = nil;
796*ebfedea0SLionel Sambuc
797*ebfedea0SLionel Sambuc
798*ebfedea0SLionel Sambuc if (!SocketIndexIsValid(inSocketNum))
799*ebfedea0SLionel Sambuc {
800*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_listen: Invalid socket number specified");
801*ebfedea0SLionel Sambuc }
802*ebfedea0SLionel Sambuc
803*ebfedea0SLionel Sambuc
804*ebfedea0SLionel Sambuc theSocketStruct = &(sSockets[inSocketNum]);
805*ebfedea0SLionel Sambuc
806*ebfedea0SLionel Sambuc
807*ebfedea0SLionel Sambuc OTResult theOTResult;
808*ebfedea0SLionel Sambuc
809*ebfedea0SLionel Sambuc
810*ebfedea0SLionel Sambuc if (theSocketStruct->mBindRequestedAddrInfo == nil)
811*ebfedea0SLionel Sambuc {
812*ebfedea0SLionel Sambuc theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
813*ebfedea0SLionel Sambuc
814*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
815*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
816*ebfedea0SLionel Sambuc }
817*ebfedea0SLionel Sambuc
818*ebfedea0SLionel Sambuc if (theSocketStruct->mAssignedAddrInfo == nil)
819*ebfedea0SLionel Sambuc {
820*ebfedea0SLionel Sambuc theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
821*ebfedea0SLionel Sambuc
822*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
823*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
824*ebfedea0SLionel Sambuc }
825*ebfedea0SLionel Sambuc
826*ebfedea0SLionel Sambuc if (theSocketStruct->mRemoteAddrInfo == nil)
827*ebfedea0SLionel Sambuc {
828*ebfedea0SLionel Sambuc theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
829*ebfedea0SLionel Sambuc
830*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
831*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
832*ebfedea0SLionel Sambuc }
833*ebfedea0SLionel Sambuc
834*ebfedea0SLionel Sambuc
835*ebfedea0SLionel Sambuc if (!theSocketStruct->mEndpointIsBound)
836*ebfedea0SLionel Sambuc {
837*ebfedea0SLionel Sambuc InetInterfaceInfo theInetInterfaceInfo;
838*ebfedea0SLionel Sambuc
839*ebfedea0SLionel Sambuc theOTResult = ::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface);
840*ebfedea0SLionel Sambuc
841*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't determine OT interface info, OTInetGetInterfaceInfo() = ",theOTResult);
842*ebfedea0SLionel Sambuc
843*ebfedea0SLionel Sambuc
844*ebfedea0SLionel Sambuc InetAddress *theInetAddress = (InetAddress *) theSocketStruct->mBindRequestedAddrInfo->addr.buf;
845*ebfedea0SLionel Sambuc
846*ebfedea0SLionel Sambuc // theInetAddress->fAddressType = AF_INET;
847*ebfedea0SLionel Sambuc // theInetAddress->fPort = inPortNum;
848*ebfedea0SLionel Sambuc // theInetAddress->fHost = theInetInterfaceInfo.fAddress;
849*ebfedea0SLionel Sambuc
850*ebfedea0SLionel Sambuc ::OTInitInetAddress(theInetAddress,inPortNum,theInetInterfaceInfo.fAddress);
851*ebfedea0SLionel Sambuc
852*ebfedea0SLionel Sambuc theSocketStruct->mBindRequestedAddrInfo->addr.len = sizeof(InetAddress);
853*ebfedea0SLionel Sambuc
854*ebfedea0SLionel Sambuc theSocketStruct->mBindRequestedAddrInfo->qlen = 1;
855*ebfedea0SLionel Sambuc
856*ebfedea0SLionel Sambuc
857*ebfedea0SLionel Sambuc theOTResult = ::OTSetSynchronous(theSocketStruct->mEndPointRef);
858*ebfedea0SLionel Sambuc
859*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetSynchronous() = ",theOTResult);
860*ebfedea0SLionel Sambuc
861*ebfedea0SLionel Sambuc theOTResult = NegotiateIPReuseAddrOption(theSocketStruct->mEndPointRef,true);
862*ebfedea0SLionel Sambuc
863*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT IP address reuse flag, NegotiateIPReuseAddrOption() = ",theOTResult);
864*ebfedea0SLionel Sambuc
865*ebfedea0SLionel Sambuc theOTResult = ::OTSetAsynchronous(theSocketStruct->mEndPointRef);
866*ebfedea0SLionel Sambuc
867*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetAsynchronous() = ",theOTResult);
868*ebfedea0SLionel Sambuc
869*ebfedea0SLionel Sambuc
870*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
871*ebfedea0SLionel Sambuc
872*ebfedea0SLionel Sambuc theOTResult = ::OTBind(theSocketStruct->mEndPointRef,theSocketStruct->mBindRequestedAddrInfo,theSocketStruct->mAssignedAddrInfo);
873*ebfedea0SLionel Sambuc
874*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
875*ebfedea0SLionel Sambuc
876*ebfedea0SLionel Sambuc BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
877*ebfedea0SLionel Sambuc
878*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
879*ebfedea0SLionel Sambuc
880*ebfedea0SLionel Sambuc
881*ebfedea0SLionel Sambuc theSocketStruct->mEndpointIsBound = true;
882*ebfedea0SLionel Sambuc }
883*ebfedea0SLionel Sambuc
884*ebfedea0SLionel Sambuc
885*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_LISTEN);
886*ebfedea0SLionel Sambuc
887*ebfedea0SLionel Sambuc theOTResult = ::OTListen(theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
888*ebfedea0SLionel Sambuc
889*ebfedea0SLionel Sambuc if (theOTResult == noErr)
890*ebfedea0SLionel Sambuc {
891*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_PASSCON);
892*ebfedea0SLionel Sambuc
893*ebfedea0SLionel Sambuc theOTResult = ::OTAccept(theSocketStruct->mEndPointRef,theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
894*ebfedea0SLionel Sambuc
895*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't begin OT accept, OTAccept() = ",theOTResult);
896*ebfedea0SLionel Sambuc
897*ebfedea0SLionel Sambuc BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTPassCon)));
898*ebfedea0SLionel Sambuc
899*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't accept OT connection, OTAccept() = ",theOTResult);
900*ebfedea0SLionel Sambuc }
901*ebfedea0SLionel Sambuc
902*ebfedea0SLionel Sambuc else if (theOTResult == kOTNoDataErr)
903*ebfedea0SLionel Sambuc {
904*ebfedea0SLionel Sambuc theOTResult = noErr;
905*ebfedea0SLionel Sambuc }
906*ebfedea0SLionel Sambuc
907*ebfedea0SLionel Sambuc else
908*ebfedea0SLionel Sambuc {
909*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBail("MacSocket_listen: Can't begin OT listen, OTListen() = ",theOTResult);
910*ebfedea0SLionel Sambuc }
911*ebfedea0SLionel Sambuc
912*ebfedea0SLionel Sambuc
913*ebfedea0SLionel Sambuc errCode = noErr;
914*ebfedea0SLionel Sambuc
915*ebfedea0SLionel Sambuc
916*ebfedea0SLionel Sambuc EXITPOINT:
917*ebfedea0SLionel Sambuc
918*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
919*ebfedea0SLionel Sambuc {
920*ebfedea0SLionel Sambuc theSocketStruct->mLastError = noErr;
921*ebfedea0SLionel Sambuc
922*ebfedea0SLionel Sambuc CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
923*ebfedea0SLionel Sambuc
924*ebfedea0SLionel Sambuc if (errCode != noErr)
925*ebfedea0SLionel Sambuc {
926*ebfedea0SLionel Sambuc theSocketStruct->mLastError = errCode;
927*ebfedea0SLionel Sambuc
928*ebfedea0SLionel Sambuc CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
929*ebfedea0SLionel Sambuc }
930*ebfedea0SLionel Sambuc }
931*ebfedea0SLionel Sambuc
932*ebfedea0SLionel Sambuc errno = errCode;
933*ebfedea0SLionel Sambuc
934*ebfedea0SLionel Sambuc return(errCode);
935*ebfedea0SLionel Sambuc }
936*ebfedea0SLionel Sambuc
937*ebfedea0SLionel Sambuc
938*ebfedea0SLionel Sambuc
939*ebfedea0SLionel Sambuc
MacSocket_connect(const int inSocketNum,char * inTargetAddressAndPort)940*ebfedea0SLionel Sambuc OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
941*ebfedea0SLionel Sambuc {
942*ebfedea0SLionel Sambuc OSErr errCode = noErr;
943*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = nil;
944*ebfedea0SLionel Sambuc
945*ebfedea0SLionel Sambuc
946*ebfedea0SLionel Sambuc if (!SocketIndexIsValid(inSocketNum))
947*ebfedea0SLionel Sambuc {
948*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_connect: Invalid socket number specified");
949*ebfedea0SLionel Sambuc }
950*ebfedea0SLionel Sambuc
951*ebfedea0SLionel Sambuc theSocketStruct = &(sSockets[inSocketNum]);
952*ebfedea0SLionel Sambuc
953*ebfedea0SLionel Sambuc if (theSocketStruct->mEndpointIsBound)
954*ebfedea0SLionel Sambuc {
955*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_connect: Socket previously bound");
956*ebfedea0SLionel Sambuc }
957*ebfedea0SLionel Sambuc
958*ebfedea0SLionel Sambuc
959*ebfedea0SLionel Sambuc OTResult theOTResult;
960*ebfedea0SLionel Sambuc
961*ebfedea0SLionel Sambuc theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
962*ebfedea0SLionel Sambuc
963*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
964*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
965*ebfedea0SLionel Sambuc
966*ebfedea0SLionel Sambuc
967*ebfedea0SLionel Sambuc theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
968*ebfedea0SLionel Sambuc
969*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
970*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
971*ebfedea0SLionel Sambuc
972*ebfedea0SLionel Sambuc
973*ebfedea0SLionel Sambuc theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
974*ebfedea0SLionel Sambuc
975*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
976*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
977*ebfedea0SLionel Sambuc
978*ebfedea0SLionel Sambuc
979*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
980*ebfedea0SLionel Sambuc
981*ebfedea0SLionel Sambuc theOTResult = ::OTBind(theSocketStruct->mEndPointRef,nil,theSocketStruct->mAssignedAddrInfo);
982*ebfedea0SLionel Sambuc
983*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
984*ebfedea0SLionel Sambuc
985*ebfedea0SLionel Sambuc BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
986*ebfedea0SLionel Sambuc
987*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
988*ebfedea0SLionel Sambuc
989*ebfedea0SLionel Sambuc theSocketStruct->mEndpointIsBound = true;
990*ebfedea0SLionel Sambuc
991*ebfedea0SLionel Sambuc
992*ebfedea0SLionel Sambuc TCall sndCall;
993*ebfedea0SLionel Sambuc DNSAddress hostDNSAddress;
994*ebfedea0SLionel Sambuc
995*ebfedea0SLionel Sambuc // Set up target address
996*ebfedea0SLionel Sambuc
997*ebfedea0SLionel Sambuc sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
998*ebfedea0SLionel Sambuc sndCall.addr.len = ::OTInitDNSAddress(&hostDNSAddress,inTargetAddressAndPort);
999*ebfedea0SLionel Sambuc sndCall.opt.buf = nil;
1000*ebfedea0SLionel Sambuc sndCall.opt.len = 0;
1001*ebfedea0SLionel Sambuc sndCall.udata.buf = nil;
1002*ebfedea0SLionel Sambuc sndCall.udata.len = 0;
1003*ebfedea0SLionel Sambuc sndCall.sequence = 0;
1004*ebfedea0SLionel Sambuc
1005*ebfedea0SLionel Sambuc // Connect!
1006*ebfedea0SLionel Sambuc
1007*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,T_CONNECT);
1008*ebfedea0SLionel Sambuc
1009*ebfedea0SLionel Sambuc theOTResult = ::OTConnect(theSocketStruct->mEndPointRef,&sndCall,nil);
1010*ebfedea0SLionel Sambuc
1011*ebfedea0SLionel Sambuc if (theOTResult == kOTNoDataErr)
1012*ebfedea0SLionel Sambuc {
1013*ebfedea0SLionel Sambuc theOTResult = noErr;
1014*ebfedea0SLionel Sambuc }
1015*ebfedea0SLionel Sambuc
1016*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1017*ebfedea0SLionel Sambuc
1018*ebfedea0SLionel Sambuc BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTConnect)));
1019*ebfedea0SLionel Sambuc
1020*ebfedea0SLionel Sambuc if (theOTResult == kMacSocket_TimeoutErr)
1021*ebfedea0SLionel Sambuc {
1022*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_connect: Can't connect OT endpoint, OTConnect() = kMacSocket_TimeoutErr");
1023*ebfedea0SLionel Sambuc }
1024*ebfedea0SLionel Sambuc
1025*ebfedea0SLionel Sambuc else
1026*ebfedea0SLionel Sambuc {
1027*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1028*ebfedea0SLionel Sambuc }
1029*ebfedea0SLionel Sambuc
1030*ebfedea0SLionel Sambuc theOTResult = ::OTRcvConnect(theSocketStruct->mEndPointRef,nil);
1031*ebfedea0SLionel Sambuc
1032*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't complete connect on OT endpoint, OTRcvConnect() = ",theOTResult);
1033*ebfedea0SLionel Sambuc
1034*ebfedea0SLionel Sambuc
1035*ebfedea0SLionel Sambuc errCode = noErr;
1036*ebfedea0SLionel Sambuc
1037*ebfedea0SLionel Sambuc
1038*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1039*ebfedea0SLionel Sambuc printf("MacSocket_connect: connect completed\n");
1040*ebfedea0SLionel Sambuc #endif
1041*ebfedea0SLionel Sambuc
1042*ebfedea0SLionel Sambuc EXITPOINT:
1043*ebfedea0SLionel Sambuc
1044*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
1045*ebfedea0SLionel Sambuc {
1046*ebfedea0SLionel Sambuc theSocketStruct->mLastError = noErr;
1047*ebfedea0SLionel Sambuc
1048*ebfedea0SLionel Sambuc CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1049*ebfedea0SLionel Sambuc
1050*ebfedea0SLionel Sambuc if (errCode != noErr)
1051*ebfedea0SLionel Sambuc {
1052*ebfedea0SLionel Sambuc theSocketStruct->mLastError = errCode;
1053*ebfedea0SLionel Sambuc
1054*ebfedea0SLionel Sambuc CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1055*ebfedea0SLionel Sambuc }
1056*ebfedea0SLionel Sambuc }
1057*ebfedea0SLionel Sambuc
1058*ebfedea0SLionel Sambuc errno = errCode;
1059*ebfedea0SLionel Sambuc
1060*ebfedea0SLionel Sambuc return(errCode);
1061*ebfedea0SLionel Sambuc }
1062*ebfedea0SLionel Sambuc
1063*ebfedea0SLionel Sambuc
1064*ebfedea0SLionel Sambuc
1065*ebfedea0SLionel Sambuc
1066*ebfedea0SLionel Sambuc // Close a connection
1067*ebfedea0SLionel Sambuc
MacSocket_close(const int inSocketNum)1068*ebfedea0SLionel Sambuc OSErr MacSocket_close(const int inSocketNum)
1069*ebfedea0SLionel Sambuc {
1070*ebfedea0SLionel Sambuc OSErr errCode = noErr;
1071*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = nil;
1072*ebfedea0SLionel Sambuc
1073*ebfedea0SLionel Sambuc
1074*ebfedea0SLionel Sambuc if (!SocketIndexIsValid(inSocketNum))
1075*ebfedea0SLionel Sambuc {
1076*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_close: Invalid socket number specified");
1077*ebfedea0SLionel Sambuc }
1078*ebfedea0SLionel Sambuc
1079*ebfedea0SLionel Sambuc
1080*ebfedea0SLionel Sambuc theSocketStruct = &(sSockets[inSocketNum]);
1081*ebfedea0SLionel Sambuc
1082*ebfedea0SLionel Sambuc if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
1083*ebfedea0SLionel Sambuc {
1084*ebfedea0SLionel Sambuc OTResult theOTResult = noErr;
1085*ebfedea0SLionel Sambuc
1086*ebfedea0SLionel Sambuc // Try to play nice
1087*ebfedea0SLionel Sambuc
1088*ebfedea0SLionel Sambuc if (theSocketStruct->mReceivedTOrdRel)
1089*ebfedea0SLionel Sambuc {
1090*ebfedea0SLionel Sambuc // Already did an OTRcvOrderlyDisconnect() in the notifier
1091*ebfedea0SLionel Sambuc
1092*ebfedea0SLionel Sambuc if (theSocketStruct->mLocalEndIsConnected)
1093*ebfedea0SLionel Sambuc {
1094*ebfedea0SLionel Sambuc theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1095*ebfedea0SLionel Sambuc
1096*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = false;
1097*ebfedea0SLionel Sambuc }
1098*ebfedea0SLionel Sambuc }
1099*ebfedea0SLionel Sambuc
1100*ebfedea0SLionel Sambuc else if (theSocketStruct->mLocalEndIsConnected)
1101*ebfedea0SLionel Sambuc {
1102*ebfedea0SLionel Sambuc theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1103*ebfedea0SLionel Sambuc
1104*ebfedea0SLionel Sambuc theSocketStruct->mLocalEndIsConnected = false;
1105*ebfedea0SLionel Sambuc
1106*ebfedea0SLionel Sambuc // Wait for other end to hang up too!
1107*ebfedea0SLionel Sambuc
1108*ebfedea0SLionel Sambuc // PrepareForAsyncOperation(theSocketStruct,T_ORDREL);
1109*ebfedea0SLionel Sambuc //
1110*ebfedea0SLionel Sambuc // errCode = MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOrdRel));
1111*ebfedea0SLionel Sambuc }
1112*ebfedea0SLionel Sambuc
1113*ebfedea0SLionel Sambuc
1114*ebfedea0SLionel Sambuc if (theOTResult != noErr)
1115*ebfedea0SLionel Sambuc {
1116*ebfedea0SLionel Sambuc ::OTCloseProvider(theSocketStruct->mEndPointRef);
1117*ebfedea0SLionel Sambuc }
1118*ebfedea0SLionel Sambuc
1119*ebfedea0SLionel Sambuc else
1120*ebfedea0SLionel Sambuc {
1121*ebfedea0SLionel Sambuc theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
1122*ebfedea0SLionel Sambuc }
1123*ebfedea0SLionel Sambuc
1124*ebfedea0SLionel Sambuc theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
1125*ebfedea0SLionel Sambuc
1126*ebfedea0SLionel Sambuc errCode = theOTResult;
1127*ebfedea0SLionel Sambuc }
1128*ebfedea0SLionel Sambuc
1129*ebfedea0SLionel Sambuc
1130*ebfedea0SLionel Sambuc theSocketStruct->mIsInUse = false;
1131*ebfedea0SLionel Sambuc
1132*ebfedea0SLionel Sambuc
1133*ebfedea0SLionel Sambuc EXITPOINT:
1134*ebfedea0SLionel Sambuc
1135*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
1136*ebfedea0SLionel Sambuc {
1137*ebfedea0SLionel Sambuc theSocketStruct->mLastError = noErr;
1138*ebfedea0SLionel Sambuc
1139*ebfedea0SLionel Sambuc CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1140*ebfedea0SLionel Sambuc
1141*ebfedea0SLionel Sambuc if (errCode != noErr)
1142*ebfedea0SLionel Sambuc {
1143*ebfedea0SLionel Sambuc theSocketStruct->mLastError = errCode;
1144*ebfedea0SLionel Sambuc
1145*ebfedea0SLionel Sambuc CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1146*ebfedea0SLionel Sambuc }
1147*ebfedea0SLionel Sambuc }
1148*ebfedea0SLionel Sambuc
1149*ebfedea0SLionel Sambuc errno = errCode;
1150*ebfedea0SLionel Sambuc
1151*ebfedea0SLionel Sambuc return(errCode);
1152*ebfedea0SLionel Sambuc }
1153*ebfedea0SLionel Sambuc
1154*ebfedea0SLionel Sambuc
1155*ebfedea0SLionel Sambuc
1156*ebfedea0SLionel Sambuc
1157*ebfedea0SLionel Sambuc // Receive some bytes
1158*ebfedea0SLionel Sambuc
MacSocket_recv(const int inSocketNum,void * outBuff,int outBuffLength,const Boolean inBlock)1159*ebfedea0SLionel Sambuc int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
1160*ebfedea0SLionel Sambuc {
1161*ebfedea0SLionel Sambuc OSErr errCode = noErr;
1162*ebfedea0SLionel Sambuc int totalBytesRead = 0;
1163*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = nil;
1164*ebfedea0SLionel Sambuc
1165*ebfedea0SLionel Sambuc
1166*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(outBuff,"MacSocket_recv: Bad parameter, outBuff = nil");
1167*ebfedea0SLionel Sambuc
1168*ebfedea0SLionel Sambuc if (outBuffLength <= 0)
1169*ebfedea0SLionel Sambuc {
1170*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_recv: Bad parameter, outBuffLength <= 0");
1171*ebfedea0SLionel Sambuc }
1172*ebfedea0SLionel Sambuc
1173*ebfedea0SLionel Sambuc if (!SocketIndexIsValid(inSocketNum))
1174*ebfedea0SLionel Sambuc {
1175*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_recv: Invalid socket number specified");
1176*ebfedea0SLionel Sambuc }
1177*ebfedea0SLionel Sambuc
1178*ebfedea0SLionel Sambuc theSocketStruct = &(sSockets[inSocketNum]);
1179*ebfedea0SLionel Sambuc
1180*ebfedea0SLionel Sambuc if (!theSocketStruct->mLocalEndIsConnected)
1181*ebfedea0SLionel Sambuc {
1182*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_recv: Socket not connected");
1183*ebfedea0SLionel Sambuc }
1184*ebfedea0SLionel Sambuc
1185*ebfedea0SLionel Sambuc if (theSocketStruct->mReceivedTOrdRel)
1186*ebfedea0SLionel Sambuc {
1187*ebfedea0SLionel Sambuc totalBytesRead = 0;
1188*ebfedea0SLionel Sambuc
1189*ebfedea0SLionel Sambuc goto EXITPOINT;
1190*ebfedea0SLionel Sambuc }
1191*ebfedea0SLionel Sambuc
1192*ebfedea0SLionel Sambuc
1193*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,0);
1194*ebfedea0SLionel Sambuc
1195*ebfedea0SLionel Sambuc for (;;)
1196*ebfedea0SLionel Sambuc {
1197*ebfedea0SLionel Sambuc int bytesRead;
1198*ebfedea0SLionel Sambuc OTResult theOTResult;
1199*ebfedea0SLionel Sambuc
1200*ebfedea0SLionel Sambuc
1201*ebfedea0SLionel Sambuc theOTResult = ::OTRcv(theSocketStruct->mEndPointRef,(void *) ((unsigned long) outBuff + (unsigned long) totalBytesRead),outBuffLength - totalBytesRead,nil);
1202*ebfedea0SLionel Sambuc
1203*ebfedea0SLionel Sambuc if (theOTResult >= 0)
1204*ebfedea0SLionel Sambuc {
1205*ebfedea0SLionel Sambuc bytesRead = theOTResult;
1206*ebfedea0SLionel Sambuc
1207*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1208*ebfedea0SLionel Sambuc printf("MacSocket_recv: read %d bytes in part\n",bytesRead);
1209*ebfedea0SLionel Sambuc #endif
1210*ebfedea0SLionel Sambuc }
1211*ebfedea0SLionel Sambuc
1212*ebfedea0SLionel Sambuc else if (theOTResult == kOTNoDataErr)
1213*ebfedea0SLionel Sambuc {
1214*ebfedea0SLionel Sambuc bytesRead = 0;
1215*ebfedea0SLionel Sambuc }
1216*ebfedea0SLionel Sambuc
1217*ebfedea0SLionel Sambuc else
1218*ebfedea0SLionel Sambuc {
1219*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBail("MacSocket_recv: Can't receive OT data, OTRcv() = ",theOTResult);
1220*ebfedea0SLionel Sambuc }
1221*ebfedea0SLionel Sambuc
1222*ebfedea0SLionel Sambuc
1223*ebfedea0SLionel Sambuc totalBytesRead += bytesRead;
1224*ebfedea0SLionel Sambuc
1225*ebfedea0SLionel Sambuc
1226*ebfedea0SLionel Sambuc if (totalBytesRead <= 0)
1227*ebfedea0SLionel Sambuc {
1228*ebfedea0SLionel Sambuc if (theSocketStruct->mReceivedTOrdRel)
1229*ebfedea0SLionel Sambuc {
1230*ebfedea0SLionel Sambuc break;
1231*ebfedea0SLionel Sambuc }
1232*ebfedea0SLionel Sambuc
1233*ebfedea0SLionel Sambuc // This seems pretty stupid to me now. Maybe I'll delete this blocking garbage.
1234*ebfedea0SLionel Sambuc
1235*ebfedea0SLionel Sambuc if (inBlock)
1236*ebfedea0SLionel Sambuc {
1237*ebfedea0SLionel Sambuc if (TimeoutElapsed(theSocketStruct))
1238*ebfedea0SLionel Sambuc {
1239*ebfedea0SLionel Sambuc SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_recv: Receive operation timed-out");
1240*ebfedea0SLionel Sambuc }
1241*ebfedea0SLionel Sambuc
1242*ebfedea0SLionel Sambuc if (theSocketStruct->mIdleWaitCallback != nil)
1243*ebfedea0SLionel Sambuc {
1244*ebfedea0SLionel Sambuc theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1245*ebfedea0SLionel Sambuc
1246*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfError(theOTResult,"MacSocket_recv: User cancelled operation");
1247*ebfedea0SLionel Sambuc }
1248*ebfedea0SLionel Sambuc
1249*ebfedea0SLionel Sambuc continue;
1250*ebfedea0SLionel Sambuc }
1251*ebfedea0SLionel Sambuc }
1252*ebfedea0SLionel Sambuc
1253*ebfedea0SLionel Sambuc
1254*ebfedea0SLionel Sambuc break;
1255*ebfedea0SLionel Sambuc }
1256*ebfedea0SLionel Sambuc
1257*ebfedea0SLionel Sambuc errCode = noErr;
1258*ebfedea0SLionel Sambuc
1259*ebfedea0SLionel Sambuc
1260*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1261*ebfedea0SLionel Sambuc printf("MacSocket_recv: read %d bytes in total\n",totalBytesRead);
1262*ebfedea0SLionel Sambuc #endif
1263*ebfedea0SLionel Sambuc
1264*ebfedea0SLionel Sambuc
1265*ebfedea0SLionel Sambuc EXITPOINT:
1266*ebfedea0SLionel Sambuc
1267*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
1268*ebfedea0SLionel Sambuc {
1269*ebfedea0SLionel Sambuc theSocketStruct->mLastError = noErr;
1270*ebfedea0SLionel Sambuc
1271*ebfedea0SLionel Sambuc CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1272*ebfedea0SLionel Sambuc
1273*ebfedea0SLionel Sambuc if (errCode != noErr)
1274*ebfedea0SLionel Sambuc {
1275*ebfedea0SLionel Sambuc theSocketStruct->mLastError = errCode;
1276*ebfedea0SLionel Sambuc
1277*ebfedea0SLionel Sambuc CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1278*ebfedea0SLionel Sambuc }
1279*ebfedea0SLionel Sambuc }
1280*ebfedea0SLionel Sambuc
1281*ebfedea0SLionel Sambuc errno = errCode;
1282*ebfedea0SLionel Sambuc
1283*ebfedea0SLionel Sambuc return(totalBytesRead);
1284*ebfedea0SLionel Sambuc }
1285*ebfedea0SLionel Sambuc
1286*ebfedea0SLionel Sambuc
1287*ebfedea0SLionel Sambuc
1288*ebfedea0SLionel Sambuc // Send some bytes
1289*ebfedea0SLionel Sambuc
MacSocket_send(const int inSocketNum,const void * inBuff,int inBuffLength)1290*ebfedea0SLionel Sambuc int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
1291*ebfedea0SLionel Sambuc {
1292*ebfedea0SLionel Sambuc OSErr errCode = noErr;
1293*ebfedea0SLionel Sambuc int bytesSent = 0;
1294*ebfedea0SLionel Sambuc SocketStruct *theSocketStruct = nil;
1295*ebfedea0SLionel Sambuc
1296*ebfedea0SLionel Sambuc
1297*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfNil(inBuff,"MacSocket_send: Bad parameter, inBuff = nil");
1298*ebfedea0SLionel Sambuc
1299*ebfedea0SLionel Sambuc if (inBuffLength <= 0)
1300*ebfedea0SLionel Sambuc {
1301*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_send: Bad parameter, inBuffLength <= 0");
1302*ebfedea0SLionel Sambuc }
1303*ebfedea0SLionel Sambuc
1304*ebfedea0SLionel Sambuc if (!SocketIndexIsValid(inSocketNum))
1305*ebfedea0SLionel Sambuc {
1306*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_send: Invalid socket number specified");
1307*ebfedea0SLionel Sambuc }
1308*ebfedea0SLionel Sambuc
1309*ebfedea0SLionel Sambuc
1310*ebfedea0SLionel Sambuc theSocketStruct = &(sSockets[inSocketNum]);
1311*ebfedea0SLionel Sambuc
1312*ebfedea0SLionel Sambuc if (!theSocketStruct->mLocalEndIsConnected)
1313*ebfedea0SLionel Sambuc {
1314*ebfedea0SLionel Sambuc SetErrorMessageAndBail("MacSocket_send: Socket not connected");
1315*ebfedea0SLionel Sambuc }
1316*ebfedea0SLionel Sambuc
1317*ebfedea0SLionel Sambuc
1318*ebfedea0SLionel Sambuc OTResult theOTResult;
1319*ebfedea0SLionel Sambuc
1320*ebfedea0SLionel Sambuc
1321*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,0);
1322*ebfedea0SLionel Sambuc
1323*ebfedea0SLionel Sambuc while (bytesSent < inBuffLength)
1324*ebfedea0SLionel Sambuc {
1325*ebfedea0SLionel Sambuc if (theSocketStruct->mIdleWaitCallback != nil)
1326*ebfedea0SLionel Sambuc {
1327*ebfedea0SLionel Sambuc theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1328*ebfedea0SLionel Sambuc
1329*ebfedea0SLionel Sambuc SetErrorMessageAndBailIfError(theOTResult,"MacSocket_send: User cancelled");
1330*ebfedea0SLionel Sambuc }
1331*ebfedea0SLionel Sambuc
1332*ebfedea0SLionel Sambuc
1333*ebfedea0SLionel Sambuc theOTResult = ::OTSnd(theSocketStruct->mEndPointRef,(void *) ((unsigned long) inBuff + bytesSent),inBuffLength - bytesSent,0);
1334*ebfedea0SLionel Sambuc
1335*ebfedea0SLionel Sambuc if (theOTResult >= 0)
1336*ebfedea0SLionel Sambuc {
1337*ebfedea0SLionel Sambuc bytesSent += theOTResult;
1338*ebfedea0SLionel Sambuc
1339*ebfedea0SLionel Sambuc theOTResult = noErr;
1340*ebfedea0SLionel Sambuc
1341*ebfedea0SLionel Sambuc // Reset timer....
1342*ebfedea0SLionel Sambuc
1343*ebfedea0SLionel Sambuc PrepareForAsyncOperation(theSocketStruct,0);
1344*ebfedea0SLionel Sambuc }
1345*ebfedea0SLionel Sambuc
1346*ebfedea0SLionel Sambuc if (theOTResult == kOTFlowErr)
1347*ebfedea0SLionel Sambuc {
1348*ebfedea0SLionel Sambuc if (TimeoutElapsed(theSocketStruct))
1349*ebfedea0SLionel Sambuc {
1350*ebfedea0SLionel Sambuc SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_send: Send timed-out")
1351*ebfedea0SLionel Sambuc }
1352*ebfedea0SLionel Sambuc
1353*ebfedea0SLionel Sambuc theOTResult = noErr;
1354*ebfedea0SLionel Sambuc }
1355*ebfedea0SLionel Sambuc
1356*ebfedea0SLionel Sambuc SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_send: Can't send OT data, OTSnd() = ",theOTResult);
1357*ebfedea0SLionel Sambuc }
1358*ebfedea0SLionel Sambuc
1359*ebfedea0SLionel Sambuc
1360*ebfedea0SLionel Sambuc errCode = noErr;
1361*ebfedea0SLionel Sambuc
1362*ebfedea0SLionel Sambuc #ifdef MACSOCKET_DEBUG
1363*ebfedea0SLionel Sambuc printf("MacSocket_send: sent %d bytes\n",bytesSent);
1364*ebfedea0SLionel Sambuc #endif
1365*ebfedea0SLionel Sambuc
1366*ebfedea0SLionel Sambuc
1367*ebfedea0SLionel Sambuc EXITPOINT:
1368*ebfedea0SLionel Sambuc
1369*ebfedea0SLionel Sambuc if (theSocketStruct != nil)
1370*ebfedea0SLionel Sambuc {
1371*ebfedea0SLionel Sambuc theSocketStruct->mLastError = noErr;
1372*ebfedea0SLionel Sambuc
1373*ebfedea0SLionel Sambuc CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1374*ebfedea0SLionel Sambuc
1375*ebfedea0SLionel Sambuc if (errCode != noErr)
1376*ebfedea0SLionel Sambuc {
1377*ebfedea0SLionel Sambuc theSocketStruct->mLastError = errCode;
1378*ebfedea0SLionel Sambuc
1379*ebfedea0SLionel Sambuc CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1380*ebfedea0SLionel Sambuc }
1381*ebfedea0SLionel Sambuc }
1382*ebfedea0SLionel Sambuc
1383*ebfedea0SLionel Sambuc if (errCode != noErr)
1384*ebfedea0SLionel Sambuc {
1385*ebfedea0SLionel Sambuc ::SysBeep(1);
1386*ebfedea0SLionel Sambuc }
1387*ebfedea0SLionel Sambuc
1388*ebfedea0SLionel Sambuc errno = errCode;
1389*ebfedea0SLionel Sambuc
1390*ebfedea0SLionel Sambuc return(bytesSent);
1391*ebfedea0SLionel Sambuc }
1392*ebfedea0SLionel Sambuc
1393*ebfedea0SLionel Sambuc
1394*ebfedea0SLionel Sambuc
1395*ebfedea0SLionel Sambuc
1396*ebfedea0SLionel Sambuc
NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)1397*ebfedea0SLionel Sambuc static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
1398*ebfedea0SLionel Sambuc {
1399*ebfedea0SLionel Sambuc OSStatus errCode;
1400*ebfedea0SLionel Sambuc UInt8 buf[kOTFourByteOptionSize];
1401*ebfedea0SLionel Sambuc TOption* theOTOption;
1402*ebfedea0SLionel Sambuc TOptMgmt theOTRequest;
1403*ebfedea0SLionel Sambuc TOptMgmt theOTResult;
1404*ebfedea0SLionel Sambuc
1405*ebfedea0SLionel Sambuc
1406*ebfedea0SLionel Sambuc if (!OTIsSynchronous(inEndpoint))
1407*ebfedea0SLionel Sambuc {
1408*ebfedea0SLionel Sambuc SetErrorMessageAndBail("NegotiateIPReuseAddrOption: Open Transport endpoint is not synchronous");
1409*ebfedea0SLionel Sambuc }
1410*ebfedea0SLionel Sambuc
1411*ebfedea0SLionel Sambuc theOTRequest.opt.buf = buf;
1412*ebfedea0SLionel Sambuc theOTRequest.opt.len = sizeof(buf);
1413*ebfedea0SLionel Sambuc theOTRequest.flags = T_NEGOTIATE;
1414*ebfedea0SLionel Sambuc
1415*ebfedea0SLionel Sambuc theOTResult.opt.buf = buf;
1416*ebfedea0SLionel Sambuc theOTResult.opt.maxlen = kOTFourByteOptionSize;
1417*ebfedea0SLionel Sambuc
1418*ebfedea0SLionel Sambuc
1419*ebfedea0SLionel Sambuc theOTOption = (TOption *) buf;
1420*ebfedea0SLionel Sambuc
1421*ebfedea0SLionel Sambuc theOTOption->level = INET_IP;
1422*ebfedea0SLionel Sambuc theOTOption->name = IP_REUSEADDR;
1423*ebfedea0SLionel Sambuc theOTOption->len = kOTFourByteOptionSize;
1424*ebfedea0SLionel Sambuc theOTOption->status = 0;
1425*ebfedea0SLionel Sambuc *((UInt32 *) (theOTOption->value)) = inEnableReuseIP;
1426*ebfedea0SLionel Sambuc
1427*ebfedea0SLionel Sambuc errCode = ::OTOptionManagement(inEndpoint,&theOTRequest,&theOTResult);
1428*ebfedea0SLionel Sambuc
1429*ebfedea0SLionel Sambuc if (errCode == kOTNoError)
1430*ebfedea0SLionel Sambuc {
1431*ebfedea0SLionel Sambuc if (theOTOption->status != T_SUCCESS)
1432*ebfedea0SLionel Sambuc {
1433*ebfedea0SLionel Sambuc errCode = theOTOption->status;
1434*ebfedea0SLionel Sambuc }
1435*ebfedea0SLionel Sambuc
1436*ebfedea0SLionel Sambuc else
1437*ebfedea0SLionel Sambuc {
1438*ebfedea0SLionel Sambuc errCode = kOTNoError;
1439*ebfedea0SLionel Sambuc }
1440*ebfedea0SLionel Sambuc }
1441*ebfedea0SLionel Sambuc
1442*ebfedea0SLionel Sambuc
1443*ebfedea0SLionel Sambuc EXITPOINT:
1444*ebfedea0SLionel Sambuc
1445*ebfedea0SLionel Sambuc errno = errCode;
1446*ebfedea0SLionel Sambuc
1447*ebfedea0SLionel Sambuc return(errCode);
1448*ebfedea0SLionel Sambuc }
1449*ebfedea0SLionel Sambuc
1450*ebfedea0SLionel Sambuc
1451*ebfedea0SLionel Sambuc
1452*ebfedea0SLionel Sambuc
1453*ebfedea0SLionel Sambuc
1454*ebfedea0SLionel Sambuc // Some rough notes....
1455*ebfedea0SLionel Sambuc
1456*ebfedea0SLionel Sambuc
1457*ebfedea0SLionel Sambuc
1458*ebfedea0SLionel Sambuc // OTAckSends(ep);
1459*ebfedea0SLionel Sambuc // OTAckSends(ep) // enable AckSend option
1460*ebfedea0SLionel Sambuc // ......
1461*ebfedea0SLionel Sambuc // buf = OTAllocMem( nbytes); // Allocate nbytes of memory from OT
1462*ebfedea0SLionel Sambuc // OTSnd(ep, buf, nbytes, 0); // send a packet
1463*ebfedea0SLionel Sambuc // ......
1464*ebfedea0SLionel Sambuc // NotifyProc( .... void* theParam) // Notifier Proc
1465*ebfedea0SLionel Sambuc // case T_MEMORYRELEASED: // process event
1466*ebfedea0SLionel Sambuc // OTFreeMem( theParam); // free up memory
1467*ebfedea0SLionel Sambuc // break;
1468*ebfedea0SLionel Sambuc
1469*ebfedea0SLionel Sambuc
1470*ebfedea0SLionel Sambuc
1471*ebfedea0SLionel Sambuc /*
1472*ebfedea0SLionel Sambuc struct InetInterfaceInfo
1473*ebfedea0SLionel Sambuc {
1474*ebfedea0SLionel Sambuc InetHost fAddress;
1475*ebfedea0SLionel Sambuc InetHost fNetmask;
1476*ebfedea0SLionel Sambuc InetHost fBroadcastAddr;
1477*ebfedea0SLionel Sambuc InetHost fDefaultGatewayAddr;
1478*ebfedea0SLionel Sambuc InetHost fDNSAddr;
1479*ebfedea0SLionel Sambuc UInt16 fVersion;
1480*ebfedea0SLionel Sambuc UInt16 fHWAddrLen;
1481*ebfedea0SLionel Sambuc UInt8* fHWAddr;
1482*ebfedea0SLionel Sambuc UInt32 fIfMTU;
1483*ebfedea0SLionel Sambuc UInt8* fReservedPtrs[2];
1484*ebfedea0SLionel Sambuc InetDomainName fDomainName;
1485*ebfedea0SLionel Sambuc UInt32 fIPSecondaryCount;
1486*ebfedea0SLionel Sambuc UInt8 fReserved[252];
1487*ebfedea0SLionel Sambuc };
1488*ebfedea0SLionel Sambuc typedef struct InetInterfaceInfo InetInterfaceInfo;
1489*ebfedea0SLionel Sambuc
1490*ebfedea0SLionel Sambuc
1491*ebfedea0SLionel Sambuc
1492*ebfedea0SLionel Sambuc ((InetAddress *) addr.buf)->fHost
1493*ebfedea0SLionel Sambuc
1494*ebfedea0SLionel Sambuc struct TBind
1495*ebfedea0SLionel Sambuc {
1496*ebfedea0SLionel Sambuc TNetbuf addr;
1497*ebfedea0SLionel Sambuc OTQLen qlen;
1498*ebfedea0SLionel Sambuc };
1499*ebfedea0SLionel Sambuc
1500*ebfedea0SLionel Sambuc typedef struct TBind TBind;
1501*ebfedea0SLionel Sambuc
1502*ebfedea0SLionel Sambuc struct TNetbuf
1503*ebfedea0SLionel Sambuc {
1504*ebfedea0SLionel Sambuc size_t maxlen;
1505*ebfedea0SLionel Sambuc size_t len;
1506*ebfedea0SLionel Sambuc UInt8* buf;
1507*ebfedea0SLionel Sambuc };
1508*ebfedea0SLionel Sambuc
1509*ebfedea0SLionel Sambuc typedef struct TNetbuf TNetbuf;
1510*ebfedea0SLionel Sambuc
1511*ebfedea0SLionel Sambuc
1512*ebfedea0SLionel Sambuc struct InetAddress
1513*ebfedea0SLionel Sambuc {
1514*ebfedea0SLionel Sambuc OTAddressType fAddressType; // always AF_INET
1515*ebfedea0SLionel Sambuc InetPort fPort; // Port number
1516*ebfedea0SLionel Sambuc InetHost fHost; // Host address in net byte order
1517*ebfedea0SLionel Sambuc UInt8 fUnused[8]; // Traditional unused bytes
1518*ebfedea0SLionel Sambuc };
1519*ebfedea0SLionel Sambuc typedef struct InetAddress InetAddress;
1520*ebfedea0SLionel Sambuc */
1521*ebfedea0SLionel Sambuc
1522*ebfedea0SLionel Sambuc
1523*ebfedea0SLionel Sambuc
1524*ebfedea0SLionel Sambuc /*
1525*ebfedea0SLionel Sambuc static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
1526*ebfedea0SLionel Sambuc {
1527*ebfedea0SLionel Sambuc EPInfo* epi = (EPInfo*) context;
1528*ebfedea0SLionel Sambuc
1529*ebfedea0SLionel Sambuc switch (event)
1530*ebfedea0SLionel Sambuc {
1531*ebfedea0SLionel Sambuc case T_LISTEN:
1532*ebfedea0SLionel Sambuc {
1533*ebfedea0SLionel Sambuc DoListenAccept();
1534*ebfedea0SLionel Sambuc return;
1535*ebfedea0SLionel Sambuc }
1536*ebfedea0SLionel Sambuc
1537*ebfedea0SLionel Sambuc case T_ACCEPTCOMPLETE:
1538*ebfedea0SLionel Sambuc {
1539*ebfedea0SLionel Sambuc if (result != kOTNoError)
1540*ebfedea0SLionel Sambuc DBAlert1("Notifier: T_ACCEPTCOMPLETE - result %d",result);
1541*ebfedea0SLionel Sambuc return;
1542*ebfedea0SLionel Sambuc }
1543*ebfedea0SLionel Sambuc
1544*ebfedea0SLionel Sambuc case T_PASSCON:
1545*ebfedea0SLionel Sambuc {
1546*ebfedea0SLionel Sambuc if (result != kOTNoError)
1547*ebfedea0SLionel Sambuc {
1548*ebfedea0SLionel Sambuc DBAlert1("Notifier: T_PASSCON result %d", result);
1549*ebfedea0SLionel Sambuc return;
1550*ebfedea0SLionel Sambuc }
1551*ebfedea0SLionel Sambuc
1552*ebfedea0SLionel Sambuc OTAtomicAdd32(1, &gCntrConnections);
1553*ebfedea0SLionel Sambuc OTAtomicAdd32(1, &gCntrTotalConnections);
1554*ebfedea0SLionel Sambuc OTAtomicAdd32(1, &gCntrIntervalConnects);
1555*ebfedea0SLionel Sambuc
1556*ebfedea0SLionel Sambuc if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1557*ebfedea0SLionel Sambuc {
1558*ebfedea0SLionel Sambuc ReadData(epi);
1559*ebfedea0SLionel Sambuc }
1560*ebfedea0SLionel Sambuc
1561*ebfedea0SLionel Sambuc return;
1562*ebfedea0SLionel Sambuc }
1563*ebfedea0SLionel Sambuc
1564*ebfedea0SLionel Sambuc case T_DATA:
1565*ebfedea0SLionel Sambuc {
1566*ebfedea0SLionel Sambuc if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1567*ebfedea0SLionel Sambuc {
1568*ebfedea0SLionel Sambuc ReadData(epi);
1569*ebfedea0SLionel Sambuc }
1570*ebfedea0SLionel Sambuc
1571*ebfedea0SLionel Sambuc return;
1572*ebfedea0SLionel Sambuc }
1573*ebfedea0SLionel Sambuc
1574*ebfedea0SLionel Sambuc case T_GODATA:
1575*ebfedea0SLionel Sambuc {
1576*ebfedea0SLionel Sambuc SendData(epi);
1577*ebfedea0SLionel Sambuc return;
1578*ebfedea0SLionel Sambuc }
1579*ebfedea0SLionel Sambuc
1580*ebfedea0SLionel Sambuc case T_DISCONNECT:
1581*ebfedea0SLionel Sambuc {
1582*ebfedea0SLionel Sambuc DoRcvDisconnect(epi);
1583*ebfedea0SLionel Sambuc return;
1584*ebfedea0SLionel Sambuc }
1585*ebfedea0SLionel Sambuc
1586*ebfedea0SLionel Sambuc case T_DISCONNECTCOMPLETE:
1587*ebfedea0SLionel Sambuc {
1588*ebfedea0SLionel Sambuc if (result != kOTNoError)
1589*ebfedea0SLionel Sambuc DBAlert1("Notifier: T_DISCONNECT_COMPLETE result %d",result);
1590*ebfedea0SLionel Sambuc
1591*ebfedea0SLionel Sambuc return;
1592*ebfedea0SLionel Sambuc }
1593*ebfedea0SLionel Sambuc
1594*ebfedea0SLionel Sambuc case T_MEMORYRELEASED:
1595*ebfedea0SLionel Sambuc {
1596*ebfedea0SLionel Sambuc OTAtomicAdd32(-1, &epi->outstandingSends);
1597*ebfedea0SLionel Sambuc return;
1598*ebfedea0SLionel Sambuc }
1599*ebfedea0SLionel Sambuc
1600*ebfedea0SLionel Sambuc default:
1601*ebfedea0SLionel Sambuc {
1602*ebfedea0SLionel Sambuc DBAlert1("Notifier: unknown event <%x>", event);
1603*ebfedea0SLionel Sambuc return;
1604*ebfedea0SLionel Sambuc }
1605*ebfedea0SLionel Sambuc }
1606*ebfedea0SLionel Sambuc }
1607*ebfedea0SLionel Sambuc */
1608