ot_net.cp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:27k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: ot_net.cp,v 1.3.36.1 2004/07/09 02:06:38 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxcom.h"
  50. #include "Mac_net.h"
  51. #include "OT_net.h"
  52. #include "OT_TCP.h"
  53. #include "OT_UDP.h"
  54. #include "hxmm.h"
  55. #include "hxerrors.h"
  56. #include <string.h>
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <ctype.h>
  60. #include "hxslist.h"
  61. ULONG32  OT_net::sMacAddress = 0L;
  62. Boolean  OT_net::sMacAddressValid = FALSE;
  63. Boolean  OT_net::sCheckedOT = FALSE;
  64. Boolean  OT_net::sHaveOT = FALSE;
  65. Boolean  OT_net::sMacAddressStrValid = FALSE;
  66. char  OT_net::sMacAddrStr[16];
  67. #ifdef _CARBON
  68. OTClientContextPtr OT_net::sOToutClientContext = NULL;
  69. #endif
  70. //#define _LOG_DATA 1
  71. #if defined(_DEBUG) && defined (_LOG_DATA)
  72. #define DEBUGSTR(x) DebugStr(x)
  73. #else
  74. #define DEBUGSTR(x)
  75. #endif
  76. OT_net*
  77. OT_net::new_socket(UINT16 type)
  78. {
  79. OT_net  *c = NULL;
  80. switch(type)
  81. {
  82. case HX_TCP_SOCKET:
  83. c = new OT_TCP;
  84. break;
  85. case HX_UDP_SOCKET:
  86. c = new OT_UDP;
  87. break;
  88. }
  89. return(c);
  90. }
  91. // Creator should set the socket reference to a value indicating the socket is not open
  92. OT_net::OT_net (void)
  93. : mActiveName (NULL)
  94. , mRef (0)
  95. , mDataArrived (FALSE)
  96. , mDataFlowOn (FALSE)
  97. , mClosing (FALSE)
  98. , mOtherSideHasClosed (FALSE)
  99. , mWeHaveClosed (FALSE)
  100. , mRelease (FALSE)
  101. , mStartedReceivingData (FALSE)
  102. , mAsyncError(HXR_OK)
  103. , m_lRefCount(0)
  104.      , m_pPendingCallbackListOne(NULL)
  105.      , m_pPendingCallbackListTwo(NULL)
  106.      , m_bUsingListOne(FALSE)
  107.      , m_bUsingListTwo(FALSE)
  108.      , m_bDeferredTaskPending(FALSE)
  109.      , m_bIsQuitting(FALSE)
  110. {
  111. #ifdef _USE_OT_DEFER
  112.     m_OTDeferredCookie = OTCreateDeferredTask(OT_net::DeferredTaskProc, this);
  113. #else
  114.     m_DeferredTaskStruct.dtReserved = 0;
  115.     m_DeferredTaskStruct.dtFlags = 0;
  116. #ifdef _CARBON
  117.     m_DeferredTaskStruct.dtAddr = NewDeferredTaskUPP(OT_net::DeferredTaskProc);;
  118. #else
  119.     m_DeferredTaskStruct.dtAddr = NewDeferredTaskProc(OT_net::DeferredTaskProc);;
  120. #endif
  121.     m_DeferredTaskStruct.dtParam = (long) this; 
  122.     m_DeferredTaskStruct.qType = dtQType;
  123. #endif    
  124.     
  125. }
  126. // ~OT_net should close the socket if it is open
  127. OT_net::~OT_net(void)
  128. {
  129.     m_bIsQuitting = TRUE;
  130.     
  131.     UINT32 timeout = TickCount() + 300L;
  132.     while ( m_bDeferredTaskPending && timeout - TickCount() > 0 )
  133.     {
  134. // sit-n-spin, awaiting completion of callbacks.
  135.     }
  136.     
  137. #ifdef _USE_OT_DEFER
  138.     if (m_OTDeferredCookie != 0)
  139.     {
  140.         OTDestroyDeferredTask(m_OTDeferredCookie);
  141.         m_OTDeferredCookie = 0;
  142.     }
  143. #else
  144.     if (m_DeferredTaskStruct.dtAddr != NULL)
  145.     {
  146. #ifdef _CARBON
  147. DisposeDeferredTaskUPP(m_DeferredTaskStruct.dtAddr);
  148. #else
  149. DisposeRoutineDescriptor(m_DeferredTaskStruct.dtAddr);
  150. #endif
  151. m_DeferredTaskStruct.dtAddr = NULL;
  152.     }    
  153. #endif
  154.     CleanupPendingLists();
  155.     HX_DELETE(m_pPendingCallbackListOne);
  156.     HX_DELETE(m_pPendingCallbackListTwo);
  157. if(mRef) 
  158. OTCloseProvider(mRef);
  159. mRef = 0;
  160. if (mActiveName) 
  161. delete [] mActiveName;
  162. mActiveName = nil;
  163. }
  164. void
  165. OT_net::done (void)
  166. {
  167. mLastError = HXR_OK;
  168. }
  169. #if 1
  170. /*----------------------------------------------------------------------------
  171. OTWait 
  172. Wait for an asynchronous Open Transport stream call to complete.
  173. Exit: function result = error code.
  174. ----------------------------------------------------------------------------*/
  175. HX_RESULT
  176. OT_net::OTWait (void)
  177. {
  178. Boolean cancel = FALSE;
  179. do {
  180. cancel = Mac_net::CheckForCancel();
  181. }
  182. while (!mComplete && !cancel);
  183. if(cancel)
  184. mResult = HXR_BLOCK_CANCELED;
  185. return mResult;
  186. }
  187. #else
  188. /*----------------------------------------------------------------------------
  189. OTWait 
  190. Wait for an asynchronous Open Transport stream call to complete.
  191. Exit: function result = error code.
  192. ----------------------------------------------------------------------------*/
  193. HX_RESULT
  194. OT_net::OTWait (void)
  195. {
  196. EventRecord macEvent;
  197. do {
  198. WaitNextEvent(nullEvent, &macEvent, 0L,NULL);
  199. }
  200. while (!mComplete);
  201. return mResult;
  202. }
  203. #endif
  204. /*----------------------------------------------------------------------------
  205. OTSvcWait 
  206. Wait for an asynchronous Open Transport Internet services call to complete.
  207. Entry: svcInfo = pointer to OTSvcInfo struct.
  208. Exit: function result = error code.
  209. ----------------------------------------------------------------------------*/
  210. HX_RESULT
  211. OT_net::OTSvcWait (OTSvcInfo *svcInfo)
  212. {
  213. Boolean cancel = FALSE;
  214. HX_RESULT theErr = HXR_OK;
  215. do 
  216. {
  217. cancel = Mac_net::CheckForCancel();
  218. }
  219. while (!svcInfo->complete && !cancel);
  220. if(cancel)
  221. theErr = HXR_BLOCK_CANCELED;
  222. else
  223. theErr = svcInfo->result;
  224. return theErr;
  225. }
  226. /*----------------------------------------------------------------------------
  227. NetHaveOT 
  228. Determine whether we have Open Transport.
  229. Exit: function result = true if Open Transport and Open Transport/TCP
  230. are both installed.
  231. ----------------------------------------------------------------------------*/
  232. Boolean 
  233. OT_net::NetHaveOT (void)
  234. {
  235. HX_RESULT theErr = HXR_OK;
  236. long result;
  237. if (!sCheckedOT) 
  238. {
  239. theErr = Gestalt(gestaltOpenTpt, &result);
  240. sHaveOT = theErr == HXR_OK && 
  241. (result & gestaltOpenTptPresentMask) != 0 &&
  242. (result & gestaltOpenTptTCPPresentMask) != 0;
  243. sCheckedOT = true;
  244. }
  245. return sHaveOT;
  246. }
  247. /*----------------------------------------------------------------------------
  248. MyOTInetSvcNotifyProc 
  249. Open Transport notifier proc for an Internet services provider.
  250. Entry: svcIfno = pointer to MyOTInetSvcInfo struct.
  251. code = OT event code.
  252. result = OT result.
  253. cookie = OT cookie.
  254. ----------------------------------------------------------------------------*/
  255. pascal void OT_net::SvcNotifyProc (
  256. void  *stream, 
  257. OTEventCode code,
  258. OTResult  result, 
  259. void  *cookie )
  260. {
  261. OTSvcInfo *svcInfo = (OTSvcInfo *) stream;
  262. switch (code) 
  263. {
  264. case T_OPENCOMPLETE:
  265. case T_DNRSTRINGTOADDRCOMPLETE:
  266. case T_DNRADDRTONAMECOMPLETE:
  267. svcInfo->complete = true;
  268. svcInfo->result = result; 
  269. svcInfo->cookie = cookie;
  270. break;
  271. }
  272. }
  273. /*----------------------------------------------------------------------------
  274. OpenInetServices 
  275. Open an Internet services provider.
  276. Entry: svcInfo = pointer to OTSvcInfo struct for this
  277. provider.
  278. Exit: function result = error code.
  279. ----------------------------------------------------------------------------*/
  280. HX_RESULT
  281.  OT_net::OpenInetServices (OTSvcInfo *svcInfo)
  282. {
  283. HX_RESULT theErr = HXR_OK;
  284. svcInfo->complete = false;
  285. #ifdef _CARBON
  286. theErr = OTAsyncOpenInternetServicesInContext(kDefaultInternetServicesPath, 0,
  287. (OTNotifyUPP)SvcNotifyProc, svcInfo, NULL);
  288. #else
  289. theErr = OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0, 
  290. SvcNotifyProc, svcInfo);
  291. #endif
  292. if(!theErr) theErr = OTSvcWait(svcInfo);
  293. if(!theErr) svcInfo->ref = (InetSvcRef) svcInfo->cookie;
  294. return theErr;
  295. }
  296. /*----------------------------------------------------------------------------
  297. NetGetMyAddr 
  298. Get this Mac's IP address.
  299. Exit: function result = error code.
  300. *addr = the IP address of this Mac.
  301. With Open Transport, if the Mac has more than one IP interface, the
  302. IP address of the default interface is returned.
  303. ----------------------------------------------------------------------------*/
  304. HX_RESULT OT_net::NetGetMyAddr (unsigned long *addr)
  305. {
  306. HX_RESULT theErr = HXR_OK;
  307. InetInterfaceInfo ifaceInfo;
  308. if (!sMacAddressValid) 
  309. {
  310. theErr = OTInetGetInterfaceInfo(&ifaceInfo, kDefaultInetInterface);
  311. if (theErr != HXR_OK) return (theErr);
  312. sMacAddress = ifaceInfo.fAddress;
  313. sMacAddressValid = true;
  314. }
  315. *addr = sMacAddress;
  316. return HXR_OK;
  317. }
  318. HX_RESULT OT_net::NetGetIfaceInfo(InetInterfaceInfo* ifaceInfo)
  319. {
  320.   return (OTInetGetInterfaceInfo(ifaceInfo, kDefaultInetInterface));
  321. }
  322. HX_RESULT
  323. OT_net::blocking(void)
  324. {
  325. return(HXR_OK);
  326. }
  327. HX_RESULT
  328. OT_net::nonblocking(void)
  329. {
  330. return(HXR_OK);
  331. }
  332. /*----------------------------------------------------------------------------
  333. NetGetMyAddrStr 
  334. Get this Mac's IP address as a dotted-decimal string
  335. Exit: function result = error code.
  336. name = this Mac's IP address, as a C-format string.
  337. You must allocate at least 16 bytes for this string.
  338. The returned string has max length 15.
  339. ----------------------------------------------------------------------------*/
  340. HX_RESULT OT_net::NetGetMyAddrStr (char *addrStr)
  341. {
  342. unsigned long addr;
  343. HX_RESULT theErr = HXR_OK;
  344. if (!sMacAddressStrValid) 
  345. {
  346. theErr = NetGetMyAddr(&addr);
  347. if (theErr != HXR_OK) return (theErr);
  348. sprintf(sMacAddrStr, "%ld.%ld.%ld.%ld",
  349. (addr >> 24) & 0xff,
  350. (addr >> 16) & 0xff,
  351. (addr >> 8) & 0xff,
  352.  addr & 0xff);
  353. sMacAddressStrValid = TRUE;
  354. }
  355. strcpy(addrStr, sMacAddrStr);
  356. return HXR_OK;
  357. }
  358. /*----------------------------------------------------------------------------
  359. NetNameToAddr 
  360. Translate a domain name to an IP address.
  361. Entry:  name = C-format domain name string, optionally followed by a
  362. comma, space, or colon and then the port number.
  363. defaultPort = default port number.
  364. Exit: function result = error code.
  365. *addr = IP address.
  366. *port = port number.
  367. ----------------------------------------------------------------------------*/
  368. HX_RESULT OT_net::NetNameToAddr (
  369. char *name, 
  370. unsigned short defaultPort, 
  371. unsigned long *addr, 
  372. unsigned short *port)
  373. {
  374. HX_RESULT theErr = HXR_OK;
  375. InetHostInfo hInfoOT;
  376. char domainName[256];
  377. char *p, *q;
  378. OTSvcInfo svcInfo;
  379. p = name;
  380. q = domainName;
  381. while (*p != 0 && *p != ',' && *p != ' ' && *p != ':') *q++ = *p++;
  382. *q = 0;
  383. q = p;
  384. while (*q == ' ') q++;
  385. if (*q == 0) {
  386. *port = defaultPort;
  387. } else {
  388. p++;
  389. if (!isdigit(*p)) return HXR_BIND;
  390. q = p+1;
  391. while (isdigit(*q)) q++;
  392. while (*q == ' ') q++;
  393. if (*q != 0) return HXR_BIND;
  394. *port = atoi(p);
  395. }
  396. if(conn::is_cached(domainName,addr))
  397. return HXR_OK;
  398. theErr = OTInetStringToHost(domainName, addr);
  399. if (theErr != HXR_OK) {
  400. theErr = OpenInetServices(&svcInfo);
  401. if (theErr == kEINVALErr) return HXR_BIND;
  402. if (theErr != HXR_OK) return (theErr);
  403. svcInfo.complete = false;
  404. theErr = OTInetStringToAddress(svcInfo.ref, domainName, &hInfoOT);
  405. if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo);
  406. OTCloseProvider(svcInfo.ref);
  407. if (theErr != HXR_OK) {
  408. if (theErr == kOTNoDataErr || theErr == kOTBadNameErr) theErr = HXR_BIND;
  409. return (theErr);
  410. }
  411. OTCloseProvider(svcInfo.ref);
  412. }
  413. conn::add_to_cache(domainName, *addr);
  414. if (mActiveName) 
  415. {
  416. delete [] mActiveName;
  417. mActiveName = NULL;
  418. }
  419. mActiveName = (Ptr) new char[ (::strlen (domainName) + 1)];
  420. if (HXR_OK != (theErr = ::MemError ())) return (theErr);
  421. ::strcpy (mActiveName, domainName);
  422. return HXR_OK;
  423. }
  424. /*----------------------------------------------------------------------------
  425. NetAddrToName 
  426. Translate an IP address to a domain name.
  427. Entry: addr = IP address.
  428. Exit: function result = error code.
  429. name = domain name, as a C-format string.
  430. ----------------------------------------------------------------------------*/
  431. HX_RESULT OT_net::NetAddrToName (unsigned long addr, InetDomainName name)
  432. {
  433. HX_RESULT theErr = HXR_OK;
  434. OTSvcInfo svcInfo;
  435. theErr = OpenInetServices(&svcInfo);
  436. if (theErr != HXR_OK) return (theErr);
  437. svcInfo.complete = false;
  438. theErr = OTInetAddressToName(svcInfo.ref, addr, name);
  439. if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo);
  440. OTCloseProvider(svcInfo.ref);
  441. if (theErr != HXR_OK) {
  442. if (theErr == kOTNoDataErr || theErr == kOTBadNameErr) theErr = HXR_BIND;
  443. return (theErr);
  444. }
  445. return HXR_OK;
  446. }
  447. // init_drivers() should do any network driver initialization here
  448. // params is a pointer to a platform specfic defined struct that 
  449. // contains an required initialization data
  450. HX_RESULT
  451. OT_net::init_drivers(void *params)
  452. {
  453. return(NetInit());
  454. }
  455. HX_RESULT OT_net::NetInit (void)
  456. {
  457. HX_RESULT theErr = HXR_OK;
  458. if(NetHaveOT())
  459. {
  460. #ifdef _CARBON
  461. theErr = InitOpenTransportInContext(kInitOTForApplicationMask, &sOToutClientContext);
  462. // in the embedded player case, the above call may fail
  463. // so try again with kInitOTForExtensionMask flag
  464. // sOToutClientContext has to be provided when not calling from an application
  465. if (theErr != HXR_OK)
  466. {
  467. theErr = InitOpenTransportInContext(kInitOTForExtensionMask, &sOToutClientContext);
  468. }
  469. HX_ASSERT( theErr == HXR_OK );
  470. if (theErr != HXR_OK) return HXR_OK;
  471. #else
  472. theErr = InitOpenTransport();
  473. #endif
  474. if (theErr != HXR_OK) return HX_OPEN_DRIVER_ERROR;
  475. }
  476. else
  477. theErr = -1;
  478. return(theErr);
  479. }
  480. // close_drivers() should close any network drivers used by the program
  481. // NOTE: The program MUST not make any other calls to the network drivers
  482. // until init_drivers() has been called
  483. HX_RESULT
  484. OT_net::close_drivers(void *params)
  485. {
  486. if(sHaveOT)
  487. {
  488. #ifdef _CARBON
  489. CloseOpenTransportInContext(sOToutClientContext);
  490. #else
  491. CloseOpenTransport();
  492. #endif
  493. }
  494. return(HXR_OK);
  495. }
  496. HX_RESULT
  497. OT_net::host_to_ip_str(char *host, char *ip, UINT32 ulBufLen)
  498. {
  499. HX_RESULT  theErr = HXR_OK;
  500. ULONG32  addr;
  501. UINT16 port;
  502. theErr = lookup_host(host,&addr, &port);
  503. if(!theErr) OTInetHostToString(addr,ip);
  504. if(theErr) theErr = HXR_BIND;
  505. return(theErr);
  506. }
  507. ULONG32 OT_net::AddRef()
  508. {
  509.     return InterlockedIncrement(&m_lRefCount);
  510. }
  511. ULONG32 OT_net::Release()
  512. {
  513.     if (InterlockedDecrement(&m_lRefCount) > 0)
  514.     {
  515.         return m_lRefCount;
  516.     }
  517.     delete this;
  518.     return 0;
  519. }
  520. HX_RESULT
  521. OT_net::lookup_host (
  522. char  *name, 
  523. ULONG32  *addr, 
  524. UINT16  *port,
  525. UINT16  defaultPort)
  526. {
  527. HX_RESULT theErr = HXR_OK;
  528. InetHostInfo hInfoOT;
  529. char domainName[256];
  530. char *p, *q;
  531. OTSvcInfo svcInfo;
  532. p = name;
  533. q = domainName;
  534. while (*p != 0 && *p != ',' && *p != ' ' && *p != ':') *q++ = *p++;
  535. *q = 0;
  536. q = p;
  537. while (*q == ' ') q++;
  538. if (*q == 0) 
  539. *port = defaultPort;
  540. else 
  541. {
  542. p++;
  543. if (!isdigit(*p)) return HXR_BIND;
  544. q = p+1;
  545. while (isdigit(*q)) q++;
  546. while (*q == ' ') q++;
  547. if (*q != 0) return HXR_BIND;
  548. *port = atoi(p);
  549. }
  550. // check if DNS has been cached
  551. if(conn::is_cached(domainName,addr))
  552. return HXR_OK;
  553. theErr = OTInetStringToHost(domainName, addr);
  554. if (theErr != HXR_OK) 
  555. {
  556. theErr = OpenInetServices(&svcInfo);
  557. if (theErr == kEINVALErr) return HXR_BIND;
  558. if (theErr != HXR_OK) return (theErr);
  559. svcInfo.complete = false;
  560. theErr = OTInetStringToAddress(svcInfo.ref, domainName, &hInfoOT);
  561. if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo);
  562. OTCloseProvider(svcInfo.ref);
  563. if (theErr != HXR_OK) 
  564. {
  565. if (theErr == kOTNoDataErr || theErr == kOTBadNameErr) theErr = HXR_BIND;
  566. return (theErr);
  567. }
  568. *addr = hInfoOT.addrs[0];
  569. }
  570. conn::add_to_cache(domainName, *addr);
  571. return HXR_OK;
  572. }
  573. HX_RESULT OT_net::dns_find_ip_addr(const char * host, UINT16 blocking)
  574. {
  575. if(!host)                 
  576. {
  577. mLastError = HX_INVALID_HOST;
  578. return mLastError;
  579. }
  580. //XXXCWB
  581. // if(get_sock() < 0)                 
  582. // {
  583. // mLastError = HX_NET_SOCKET_INVALID;
  584. // return mLastError;
  585. // }
  586. if (conn::is_cached((char *) host, &mHostIPAddr))
  587. {
  588. mHostIPValid = TRUE;
  589. mDNSDone = TRUE;
  590. if (mCallBack)  
  591. {
  592.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  593. }
  594. return( mLastError = HXR_OK);
  595. }
  596.         char* pTemp = strrchr(host, '.');
  597.         if (pTemp && atoi(pTemp + 1))
  598.         {   /* IP address. */
  599. struct in_addr addr;  
  600. mHostIPValid = FALSE;
  601. mHostIPAddr = 0;
  602. mDNSDone = TRUE;
  603. ::OTInetStringToHost((char*)host, &addr.s_addr); //!!!!!
  604. if ((UINT)addr.s_addr == (UINT)-1) 
  605. {
  606. mLastError = HX_INVALID_HOST;
  607. if (mCallBack)  
  608. {
  609.     mCallBack->Func(DNS_NOTIFICATION, FALSE);
  610. }
  611. return mLastError;
  612. }
  613. mHostIPValid = TRUE;
  614. mHostIPAddr = *(ULONG32 *) &addr;
  615. conn::add_to_cache((char *) host, mHostIPAddr);
  616. if (mCallBack)  
  617. {
  618.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  619. }
  620. return HXR_OK;
  621. if (blocking)
  622. {
  623. struct in_addr addr;  
  624.                     
  625. mHostIPValid = FALSE;
  626. mHostIPAddr = 0;
  627. mDNSDone = TRUE;
  628. InetHostInfo ihost;
  629. OTSvcInfo svcInfo;
  630. OSErr theErr = OpenInetServices(&svcInfo);
  631. if (theErr == kEINVALErr) return HXR_BIND;
  632. if (theErr != HXR_OK) return (theErr);
  633. svcInfo.complete = false;
  634. ::OTInetStringToAddress(svcInfo.ref,(char*)host,&ihost);
  635. if (theErr == HXR_OK) theErr = OTSvcWait(&svcInfo);
  636. OTCloseProvider(svcInfo.ref);
  637. if (!ihost.addrs ) 
  638. {
  639. mLastError = HX_INVALID_HOST;
  640. if (mCallBack)  
  641. {
  642.     mCallBack->Func(DNS_NOTIFICATION, FALSE);
  643. }
  644. return mLastError;
  645. }
  646. memcpy(&addr, ihost.addrs, sizeof(struct in_addr));
  647. mHostIPValid = TRUE;
  648. mHostIPAddr = *(ULONG32 *) &addr;
  649. conn::add_to_cache((char *) host, mHostIPAddr);
  650. if (mCallBack)  
  651. {
  652.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  653. }
  654. return( mLastError = HXR_OK);
  655. }
  656. else // non-blocking
  657. {
  658. mDNSDone     = TRUE;
  659. mHostIPValid = FALSE;
  660. mHostIPAddr  = 0;
  661. HX_RESULT theErr;
  662. MyOTInfo myOTInfo;
  663. ::memset(&myOTInfo, 0, sizeof(myOTInfo));
  664. myOTInfo.hostName = host;
  665. myOTInfo.complete = false;
  666. #ifdef _CARBON
  667. theErr = OTAsyncOpenInternetServicesInContext(kDefaultInternetServicesPath, 0,
  668. ::NewOTNotifyUPP(MyOTNotifyProc), &myOTInfo, NULL);
  669. #else
  670. theErr = OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0,
  671. MyOTNotifyProc, &myOTInfo);
  672. #endif
  673. if (theErr != HXR_OK)
  674. {
  675. return( mLastError = HXR_BIND);
  676. }
  677. // MyOTNotifyProc() handles asynch. functionality of this routine
  678. Boolean cancel = false;
  679. do 
  680. {
  681. cancel = Mac_net::CheckForCancel();
  682. }
  683. while (!myOTInfo.complete && !cancel);
  684. // Save the IP address
  685. Boolean bFound;
  686. if (myOTInfo.hostInfo.addrs && *myOTInfo.hostInfo.addrs)
  687. {
  688. bFound = true;
  689. mLastError = HXR_OK;
  690.  
  691. struct in_addr addr;  
  692. memcpy(&addr, myOTInfo.hostInfo.addrs, sizeof(struct in_addr));
  693. mHostIPValid = TRUE;
  694. mHostIPAddr = *(ULONG32 *) &addr;
  695. conn::add_to_cache((char *) host, mHostIPAddr);
  696. }
  697. else
  698. {
  699. bFound = false;
  700. mLastError = HX_INVALID_HOST;
  701. }
  702. ::OTRemoveNotifier(myOTInfo.inetSvcRef);
  703. ::OTCloseProvider (myOTInfo.inetSvcRef);
  704. if (mCallBack)  
  705. {
  706.     mCallBack->Func(DNS_NOTIFICATION, bFound);
  707. }
  708. return(mLastError);
  709. }
  710. return FALSE;
  711. }
  712. pascal void OT_net::MyOTNotifyProc
  713. (
  714. void*  contextPtr, 
  715. OTEventCode  code,
  716. OTResult  result, 
  717. void*  cookie
  718. )
  719. {
  720. MyOTInfo* myOTInfoPtr = (MyOTInfo *) contextPtr;
  721. switch (code) 
  722. {
  723. case T_OPENCOMPLETE:
  724. myOTInfoPtr->inetSvcRef = (InetSvcRef)cookie;
  725. ::OTInetStringToAddress(myOTInfoPtr->inetSvcRef, (char*)myOTInfoPtr->hostName, &myOTInfoPtr->hostInfo);
  726. break;
  727. case T_DNRSTRINGTOADDRCOMPLETE:
  728. case T_DNRADDRTONAMECOMPLETE:
  729. myOTInfoPtr->complete = true;
  730. break;
  731. }
  732. }
  733. BOOL OT_net::dns_ip_addr_found(BOOL * valid, ULONG32 *addr)
  734. {
  735. if (mDNSDone)
  736. {
  737. *valid = mHostIPValid;
  738. *addr  = mHostIPAddr;
  739. return TRUE;
  740. }
  741. else
  742. return FALSE;
  743. return FALSE;
  744. }
  745. /***********Common code for OT_UDP/OT_TCP*************************/
  746. pascal void OT_net::UDPTCPNotifyProc (
  747.  void *stream, 
  748.  OTEventCode code,
  749.  OTResult result, 
  750.  void *cookie )
  751.  
  752. {
  753. HXMM_INTERRUPTON();
  754. OT_net* s =  (OT_net*) stream;
  755. #ifdef _USE_OT_DEFER
  756.         if (s->m_OTDeferredCookie != 0)
  757. #else
  758. if (s->m_DeferredTaskStruct.dtAddr != NULL)
  759. #endif
  760. {
  761.     OTCallbackInfo* pOTCallbackInfo = new OTCallbackInfo(code, result, cookie); 
  762.     
  763.     s->AddToThePendingList((void*) pOTCallbackInfo);
  764.     
  765.     if (!s->m_bDeferredTaskPending)
  766.     {
  767.         if ( !s->m_bIsQuitting )
  768.         {
  769.         s->m_bDeferredTaskPending = TRUE;
  770. #ifdef _USE_OT_DEFER
  771. OTScheduleDeferredTask(s->m_OTDeferredCookie);
  772. #else
  773.         DTInstall(&s->m_DeferredTaskStruct);
  774. #endif
  775.         }
  776.     }
  777. }
  778.     
  779.     HXMM_INTERRUPTOFF();
  780. }
  781. #ifdef _USE_OT_DEFER
  782. pascal void OT_net::DeferredTaskProc(void* inParam)
  783. #else
  784. pascal void OT_net::DeferredTaskProc(long inParam)
  785. #endif
  786. {
  787.     HXMM_INTERRUPTON();
  788.     OT_net* s =  (OT_net*) inParam;
  789.     if(s)
  790.     {
  791. if ( !s->m_bIsQuitting )
  792. {
  793.     s->ProcessPendingCallbacks();
  794. }
  795.         s->m_bDeferredTaskPending = FALSE;
  796.     }
  797.     
  798.     HXMM_INTERRUPTOFF();
  799. }
  800. void OT_net::AddToThePendingList(void* pNode)
  801. {
  802.     /* Atleast one of the list MUST be free to operate on */
  803.     HX_ASSERT(!m_bUsingListOne || !m_bUsingListTwo);
  804.     if (!m_bUsingListOne)
  805.     {
  806.         if (!m_pPendingCallbackListOne)
  807.         {
  808.             m_pPendingCallbackListOne = new CHXSimpleList;
  809.         }
  810.         
  811.         m_pPendingCallbackListOne->AddTail(pNode);
  812.     }
  813.     else if (!m_bUsingListTwo)
  814.     {
  815.         if (!m_pPendingCallbackListTwo)
  816.         {
  817.             m_pPendingCallbackListTwo = new CHXSimpleList;
  818.         }
  819.         
  820.         m_pPendingCallbackListTwo->AddTail(pNode);
  821.     }    
  822. }
  823. void OT_net::ProcessPendingCallbacks()
  824. {
  825. start:
  826.     m_bUsingListOne = TRUE;
  827.     while (m_pPendingCallbackListOne && 
  828.           !m_pPendingCallbackListOne->IsEmpty())
  829.     {
  830. OTCallbackInfo* cmd = (OTCallbackInfo*) m_pPendingCallbackListOne->RemoveHead();
  831. /* Send time sync for ONLY the last pending audio callback */
  832. ProcessCmd(cmd->m_Code, cmd->m_Result, cmd->m_Cookie);
  833.       delete cmd;
  834.     }
  835.     m_bUsingListOne = FALSE;
  836.     m_bUsingListTwo = TRUE;
  837.     while (m_pPendingCallbackListTwo && 
  838.           !m_pPendingCallbackListTwo->IsEmpty())
  839.     {
  840. OTCallbackInfo* cmd = (OTCallbackInfo*) m_pPendingCallbackListTwo->RemoveHead();
  841. /* Send time sync for ONLY the last pending audio callback */
  842. ProcessCmd(cmd->m_Code, cmd->m_Result, cmd->m_Cookie);
  843.      delete cmd;
  844.     }
  845.     m_bUsingListTwo = FALSE;
  846.     
  847.     /* Do we still have more pending callbacks to process? */
  848.     if ((m_pPendingCallbackListOne && m_pPendingCallbackListOne->GetCount() > 0) ||
  849.         (m_pPendingCallbackListTwo && m_pPendingCallbackListTwo->GetCount() > 0))
  850.     {
  851.         goto start;
  852.     }    
  853. }        
  854. void OT_net::CleanupPendingLists()
  855. {
  856.     m_bUsingListOne = TRUE;
  857.     while(m_pPendingCallbackListOne && !m_pPendingCallbackListOne->IsEmpty())
  858.     {
  859.         SndCommand* cmd = (SndCommand*)m_pPendingCallbackListOne->RemoveHead();
  860.         delete cmd;
  861.     }
  862.     m_bUsingListOne = FALSE;
  863.     m_bUsingListTwo = TRUE;
  864.     while(m_pPendingCallbackListTwo && !m_pPendingCallbackListTwo->IsEmpty())
  865.     {
  866.         SndCommand* cmd = (SndCommand*)m_pPendingCallbackListTwo->RemoveHead();
  867.         delete cmd;
  868.     }
  869.     m_bUsingListTwo = FALSE;
  870. }
  871. OTResult OT_net::GetFourByteOption(EndpointRef ep,
  872.                            OTXTILevel level,
  873.                            OTXTIName  name,
  874.                            UInt32   *value)
  875. {
  876.    OTResult err;
  877.    TOption  option;
  878.    TOptMgmt request;
  879.    TOptMgmt result;
  880.    
  881.    /* Set up the option buffer */
  882.    option.len  = kOTFourByteOptionSize;
  883.    option.level= level;
  884.    option.name = name;
  885.    option.status = 0;
  886.    option.value[0] = 0;// Ignored because we're getting the value.
  887.    /* Set up the request parameter for OTOptionManagement to point
  888.     to the option buffer we just filled out */
  889.    request.opt.buf= (UInt8 *) &option;
  890.    request.opt.len= sizeof(option);
  891.    request.flags= T_CURRENT;
  892.    /* Set up the reply parameter for OTOptionManagement. */
  893.    result.opt.buf  = (UInt8 *) &option;
  894.    result.opt.maxlen = sizeof(option);
  895.    
  896.    err = OTOptionManagement(ep, &request, &result);
  897.    if (err == noErr) {
  898.       switch (option.status) 
  899.       {
  900.          case T_SUCCESS:
  901.          case T_READONLY:
  902.             *value = option.value[0];
  903.             break;
  904.          default:
  905.             err = option.status;
  906.             break;
  907.       }
  908.    }
  909.             
  910.    return (err);
  911. }
  912. OTResult OT_net::SetFourByteOption(EndpointRef ep,
  913.                            OTXTILevel level,
  914.                            OTXTIName  name,
  915.                            UInt32     value)
  916. {
  917.    OTResult err;
  918.    TOption  option;
  919.    TOptMgmt request;
  920.    TOptMgmt result;
  921.    
  922.    /* Set up the option buffer */
  923.    option.len  = kOTFourByteOptionSize;
  924.    option.level= level;
  925.    option.name = name;
  926.    option.status = 0;
  927.    option.value[0] = value; // set the value here
  928.    /* Set up the request parameter for OTOptionManagement to point
  929.     to the option buffer we just filled out */
  930.    request.opt.buf= (UInt8 *) &option;
  931.    request.opt.len= sizeof(option);
  932.    request.flags= T_NEGOTIATE;
  933.    /* Set up the reply parameter for OTOptionManagement. */
  934.    result.opt.buf  = (UInt8 *) &option;
  935.    result.opt.maxlen = sizeof(option);
  936.    
  937.    err = OTOptionManagement(ep, &request, &result);
  938.    if (err == noErr) {
  939.       switch (option.status) 
  940.       {
  941.          case T_SUCCESS:
  942.          case T_READONLY:
  943.             value = option.value[0];
  944.             break;
  945.          default:
  946.             err = option.status;
  947.             break;
  948.       }
  949.    }
  950.             
  951.    return (err);
  952. }