ot_net.cp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:27k
源码类别:

Symbian

开发平台:

C/C++

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