Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1709 lines
53 KiB

  1. /*****************************************************************************
  2. *
  3. * Copyright (c) 1998-1999 Microsoft Corporation
  4. *
  5. * TAPI.C - TAPI handling functions
  6. *
  7. * Author: Stan Adermann (stana)
  8. *
  9. * Created: 9/17/1998
  10. *
  11. *****************************************************************************/
  12. #include "raspptp.h"
  13. NDIS_STATUS
  14. TapiAnswer(
  15. IN PPPTP_ADAPTER pAdapter,
  16. IN PNDIS_TAPI_ANSWER pRequest
  17. )
  18. {
  19. PCALL_SESSION pCall = NULL;
  20. PCONTROL_TUNNEL pCtl;
  21. BOOLEAN LockHeld = FALSE;
  22. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  23. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiAnswer\n")));
  24. if ( pRequest == NULL || pAdapter == NULL )
  25. {
  26. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiAnswer NDIS_STATUS_TAPI_INVALPARAM\n")));
  27. return NDIS_STATUS_TAPI_INVALPARAM;
  28. }
  29. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  30. // Verify the ID
  31. if (!pCall)
  32. {
  33. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiAnswer NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  34. Status = NDIS_STATUS_TAPI_INVALCALLHANDLE;
  35. goto taDone;
  36. }
  37. NdisAcquireSpinLock(&pCall->Lock);
  38. LockHeld = TRUE;
  39. pCtl = pCall->pCtl;
  40. if (!pCtl)
  41. {
  42. DEBUGMSG(DBG_WARN, (DTEXT("No control tunnel in TapiAnswer\n")));
  43. Status = NDIS_STATUS_FAILURE;
  44. }
  45. else if (pCall->State==STATE_CALL_OFFERING)
  46. {
  47. USHORT NewCallId;
  48. PPTP_CALL_OUT_REPLY_PACKET *pReply = CtlAllocPacket(pCtl, CALL_OUT_REPLY);
  49. CallAssignSerialNumber(pCall);
  50. NewCallId = (USHORT)((pCall->SerialNumber << CALL_ID_INDEX_BITS) + pCall->DeviceId);
  51. if (pCall->Packet.CallId == NewCallId)
  52. {
  53. // Don't allow a line to have the same CallId twice in a row.
  54. NewCallId += (1<<CALL_ID_INDEX_BITS);
  55. }
  56. pCall->Packet.CallId = NewCallId;
  57. if (!pReply)
  58. {
  59. Status = NDIS_STATUS_RESOURCES;
  60. }
  61. else
  62. {
  63. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|
  64. CALL_CLOSE_DROP_COMPLETE|
  65. CALL_CLOSE_CLEANUP_STATE|
  66. CALL_CLOSE_CLOSE_CALL);
  67. CallSetState(pCall, STATE_CALL_ESTABLISHED, 0, LOCKED);
  68. pCall->Speed = pCtl->Speed;
  69. // pCtl is safe to touch because it can't be released from the call
  70. // without the call spinlock.
  71. NdisReleaseSpinLock(&pCall->Lock);
  72. LockHeld = FALSE;
  73. pReply->PeerCallId = htons(pCall->Remote.CallId);
  74. pReply->CallId = htons(pCall->Packet.CallId);
  75. pReply->ResultCode = RESULT_CALL_OUT_CONNECTED;
  76. pReply->RecvWindowSize = PPTP_RECV_WINDOW;
  77. pReply->ConnectSpeed = pCall->Speed;
  78. pReply->ProcessingDelay = 0;
  79. pReply->PhysicalChannelId = 0;
  80. Status = CtlSend(pCtl, pReply);
  81. if (Status!=NDIS_STATUS_SUCCESS)
  82. {
  83. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, UNLOCKED);
  84. CallCleanup(pCall, UNLOCKED);
  85. }
  86. }
  87. }
  88. else if (pCall->State==STATE_CALL_PAC_OFFERING)
  89. {
  90. USHORT NewCallId;
  91. PPTP_CALL_OUT_REPLY_PACKET *pReply = CtlAllocPacket(pCtl, CALL_IN_REPLY);
  92. CallAssignSerialNumber(pCall);
  93. NewCallId = (USHORT)((pCall->SerialNumber << CALL_ID_INDEX_BITS) + pCall->DeviceId);
  94. if (pCall->Packet.CallId == NewCallId)
  95. {
  96. // Don't allow a line to have the same CallId twice in a row.
  97. NewCallId += (1<<CALL_ID_INDEX_BITS);
  98. }
  99. pCall->Packet.CallId = NewCallId;
  100. if (!pReply)
  101. {
  102. Status = NDIS_STATUS_RESOURCES;
  103. }
  104. else
  105. {
  106. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|
  107. CALL_CLOSE_DROP_COMPLETE|
  108. CALL_CLOSE_CLEANUP_STATE|
  109. CALL_CLOSE_CLOSE_CALL);
  110. CallSetState(pCall, STATE_CALL_PAC_WAIT, 0, LOCKED);
  111. NdisReleaseSpinLock(&pCall->Lock);
  112. LockHeld = FALSE;
  113. //TapiLineUp(pCall);
  114. pReply->PeerCallId = htons(pCall->Remote.CallId);
  115. pReply->CallId = htons(pCall->Packet.CallId);
  116. pReply->ResultCode = RESULT_CALL_IN_CONNECTED;
  117. pReply->RecvWindowSize = PPTP_RECV_WINDOW;
  118. pReply->ProcessingDelay = 0;
  119. Status = CtlSend(pCtl, pReply);
  120. if (Status!=NDIS_STATUS_SUCCESS)
  121. {
  122. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, UNLOCKED);
  123. CallCleanup(pCall, UNLOCKED);
  124. }
  125. }
  126. }
  127. else
  128. {
  129. DEBUGMSG(DBG_WARN, (DTEXT("Wrong state for TapiAnswer %d\n"), pCall->State));
  130. Status = NDIS_STATUS_FAILURE;
  131. }
  132. taDone:
  133. if (LockHeld)
  134. {
  135. NdisReleaseSpinLock(&pCall->Lock);
  136. }
  137. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiAnswer %08x\n"), Status));
  138. return Status;
  139. }
  140. NDIS_STATUS
  141. TapiClose(
  142. IN PPPTP_ADAPTER pAdapter,
  143. IN PNDIS_TAPI_CLOSE pRequest
  144. )
  145. {
  146. PCALL_SESSION pCall;
  147. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  148. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiClose\n")));
  149. if ( pRequest == NULL || pAdapter == NULL )
  150. {
  151. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiClose NDIS_STATUS_TAPI_INVALPARAM\n")));
  152. return NDIS_STATUS_TAPI_INVALPARAM;
  153. }
  154. #if SINGLE_LINE
  155. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  156. {
  157. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiClose NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  158. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  159. }
  160. NdisAcquireSpinLock(&pAdapter->Lock);
  161. pAdapter->Tapi.Open = FALSE;
  162. pAdapter->Tapi.hTapiLine = 0;
  163. NdisReleaseSpinLock(&pAdapter->Lock);
  164. if (pAdapter->hCtdiListen)
  165. {
  166. // We have to pend this request until the listen endpoint is closed
  167. CtdiSetRequestPending(pAdapter->hCtdiListen);
  168. CtdiClose(pAdapter->hCtdiListen);
  169. pAdapter->hCtdiListen = NULL;
  170. Status = NDIS_STATUS_PENDING;
  171. }
  172. #else
  173. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  174. if (!pCall)
  175. {
  176. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiClose NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  177. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  178. }
  179. NdisAcquireSpinLock(&pCall->Lock);
  180. pCall->Close.Checklist |= CALL_CLOSE_CLOSE_LINE;
  181. if (!(pCall->Close.Checklist&CALL_CLOSE_DROP))
  182. {
  183. pCall->Close.Checklist |= (CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE);
  184. }
  185. pCall->Open = FALSE;
  186. pCall->hTapiLine = 0;
  187. //pCall->DeviceId = 0;
  188. CallDetachFromAdapter(pCall);
  189. CallCleanup(pCall, LOCKED);
  190. NdisReleaseSpinLock(&pCall->Lock);
  191. #endif
  192. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiClose\n")));
  193. return Status;
  194. }
  195. NDIS_STATUS
  196. TapiCloseCall(
  197. IN PPPTP_ADAPTER pAdapter,
  198. IN PNDIS_TAPI_CLOSE_CALL pRequest
  199. )
  200. {
  201. PCALL_SESSION pCall;
  202. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiCloseCall\n")));
  203. if ( pRequest == NULL || pAdapter == NULL )
  204. {
  205. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiCloseCall NDIS_STATUS_TAPI_INVALPARAM\n")));
  206. return NDIS_STATUS_TAPI_INVALPARAM;
  207. }
  208. // Verify the ID
  209. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  210. if (!pCall)
  211. {
  212. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiAnswer NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  213. goto tccDone;
  214. }
  215. NdisAcquireSpinLock(&pCall->Lock);
  216. pCall->Close.Checklist |= CALL_CLOSE_CLOSE_CALL;
  217. pCall->hTapiCall = 0;
  218. CallCleanup(pCall, LOCKED);
  219. NdisReleaseSpinLock(&pCall->Lock);
  220. tccDone:
  221. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiCloseCall\n")));
  222. return NDIS_STATUS_SUCCESS;
  223. }
  224. NDIS_STATUS
  225. TapiDrop(
  226. IN PPPTP_ADAPTER pAdapter,
  227. IN PNDIS_TAPI_DROP pRequest
  228. )
  229. {
  230. PCALL_SESSION pCall;
  231. PCONTROL_TUNNEL pCtl;
  232. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  233. BOOLEAN CleanupNow = FALSE;
  234. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiDrop\n")));
  235. if ( pRequest == NULL || pAdapter == NULL )
  236. {
  237. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiDrop NDIS_STATUS_TAPI_INVALPARAM\n")));
  238. return NDIS_STATUS_TAPI_INVALPARAM;
  239. }
  240. // Verify the ID
  241. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  242. if (!pCall)
  243. {
  244. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiDrop NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  245. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  246. }
  247. LOGMSG(FLL_DETAILED, (DTEXT(LOGHDRS"TapiDrop:%d\n"),
  248. LOGHDR(27, pCall->Remote.Address.Address[0].Address[0].in_addr),
  249. pCall->DeviceId));
  250. NdisAcquireSpinLock(&pCall->Lock);
  251. //ASSERT(!(pCall->Close.Checklist&CALL_CLOSE_DROP));
  252. pCtl = pCall->pCtl;
  253. if (pCall->State==STATE_CALL_ESTABLISHED)
  254. {
  255. PPPTP_CALL_CLEAR_REQUEST_PACKET pPacket = CtlAllocPacket(pCtl, CALL_CLEAR_REQUEST);
  256. if (!pPacket)
  257. {
  258. Status = NDIS_STATUS_RESOURCES;
  259. }
  260. else
  261. {
  262. CallSetState(pCall, STATE_CALL_WAIT_DISCONNECT, 0, LOCKED);
  263. pPacket->CallId = htons(pCall->Packet.CallId);
  264. NdisReleaseSpinLock(&pCall->Lock);
  265. Status = CtlSend(pCtl, pPacket);
  266. if (Status==NDIS_STATUS_SUCCESS)
  267. {
  268. Status = NDIS_STATUS_PENDING;
  269. }
  270. if (Status==NDIS_STATUS_PENDING)
  271. {
  272. NdisMSetTimer(&pCall->Close.Timer, PPTP_CLOSE_TIMEOUT);
  273. }
  274. NdisAcquireSpinLock(&pCall->Lock);
  275. }
  276. }
  277. else if (pCall->State!=STATE_CALL_CLEANUP)
  278. {
  279. CallSetState(pCall, STATE_CALL_CLEANUP, 0, LOCKED);
  280. CleanupNow = TRUE;
  281. }
  282. pCall->Close.Checklist |= CALL_CLOSE_DROP;
  283. if (Status==NDIS_STATUS_PENDING)
  284. {
  285. pCall->Close.Checklist &= ~CALL_CLOSE_DROP_COMPLETE;
  286. }
  287. else
  288. {
  289. pCall->Close.Checklist |= CALL_CLOSE_DROP_COMPLETE;
  290. }
  291. if (CleanupNow)
  292. {
  293. CallCleanup(pCall, LOCKED);
  294. }
  295. NdisReleaseSpinLock(&pCall->Lock);
  296. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiDrop %08x\n"), Status));
  297. return Status;
  298. }
  299. NDIS_STATUS
  300. TapiGetAddressCaps(
  301. IN PPPTP_ADAPTER pAdapter,
  302. IN OUT PNDIS_TAPI_GET_ADDRESS_CAPS pRequest
  303. )
  304. {
  305. BOOLEAN ValidCall;
  306. CHAR LineAddress[TAPI_MAX_LINE_ADDRESS_LENGTH];
  307. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetAddressCaps\n")));
  308. if ( pRequest == NULL || pAdapter == NULL )
  309. {
  310. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INVALPARAM\n")));
  311. return NDIS_STATUS_TAPI_INVALPARAM;
  312. }
  313. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  314. if (!ValidCall)
  315. {
  316. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_NODRIVER\n")));
  317. return NDIS_STATUS_TAPI_NODRIVER;
  318. }
  319. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  320. {
  321. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  322. return NDIS_STATUS_TAPI_INVALADDRESSID;
  323. }
  324. if (pRequest->ulExtVersion!=0 &&
  325. pRequest->ulExtVersion!=TAPI_EXT_VERSION)
  326. {
  327. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION\n")));
  328. return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;
  329. }
  330. pRequest->LineAddressCaps.ulDialToneModes = LINEDIALTONEMODE_NORMAL;
  331. pRequest->LineAddressCaps.ulSpecialInfo = LINESPECIALINFO_UNAVAIL;
  332. pRequest->LineAddressCaps.ulDisconnectModes = LINEDISCONNECTMODE_NORMAL |
  333. LINEDISCONNECTMODE_UNKNOWN |
  334. LINEDISCONNECTMODE_BUSY |
  335. LINEDISCONNECTMODE_NOANSWER;
  336. #if SINGLE_LINE
  337. pRequest->LineAddressCaps.ulMaxNumActiveCalls = pAdapter->Info.Endpoints;
  338. #else
  339. pRequest->LineAddressCaps.ulMaxNumActiveCalls = 1;
  340. #endif
  341. pRequest->LineAddressCaps.ulMaxNumTransConf = 1;
  342. pRequest->LineAddressCaps.ulAddrCapFlags = LINEADDRCAPFLAGS_DIALED;
  343. pRequest->LineAddressCaps.ulCallFeatures = LINECALLFEATURE_ACCEPT |
  344. LINECALLFEATURE_ANSWER |
  345. LINECALLFEATURE_COMPLETECALL |
  346. LINECALLFEATURE_DIAL |
  347. LINECALLFEATURE_DROP;
  348. pRequest->LineAddressCaps.ulLineDeviceID = pRequest->ulDeviceID;
  349. pRequest->LineAddressCaps.ulAddressSharing = LINEADDRESSSHARING_PRIVATE;
  350. pRequest->LineAddressCaps.ulAddressStates = 0;
  351. // List of all possible call states.
  352. pRequest->LineAddressCaps.ulCallStates = LINECALLSTATE_IDLE |
  353. LINECALLSTATE_OFFERING |
  354. LINECALLSTATE_DIALING |
  355. LINECALLSTATE_PROCEEDING |
  356. LINECALLSTATE_CONNECTED |
  357. LINECALLSTATE_DISCONNECTED;
  358. OsGetTapiLineAddress(DeviceIdToIndex(pAdapter, pRequest->ulDeviceID),
  359. LineAddress,
  360. sizeof(LineAddress));
  361. pRequest->LineAddressCaps.ulNeededSize = sizeof(pRequest->LineAddressCaps) +
  362. strlen(LineAddress) + 1;
  363. if (pRequest->LineAddressCaps.ulTotalSize<pRequest->LineAddressCaps.ulNeededSize)
  364. {
  365. pRequest->LineAddressCaps.ulUsedSize = 0;
  366. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressCaps NDIS_STATUS_INVALID_LENGTH\n")));
  367. return NDIS_STATUS_INVALID_LENGTH;
  368. }
  369. pRequest->LineAddressCaps.ulAddressSize = strlen(LineAddress) + 1;
  370. pRequest->LineAddressCaps.ulAddressOffset = sizeof(pRequest->LineAddressCaps);
  371. strcpy((PUCHAR)((&pRequest->LineAddressCaps) + 1), LineAddress);
  372. pRequest->LineAddressCaps.ulUsedSize = pRequest->LineAddressCaps.ulNeededSize;
  373. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetAddressCaps\n")));
  374. return NDIS_STATUS_SUCCESS;
  375. }
  376. NDIS_STATUS
  377. TapiGetAddressStatus(
  378. IN PPPTP_ADAPTER pAdapter,
  379. IN OUT PNDIS_TAPI_GET_ADDRESS_STATUS pRequest
  380. )
  381. {
  382. PCALL_SESSION pCall = NULL;
  383. BOOLEAN fReady;
  384. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetAddressStatus\n")));
  385. if ( pRequest == NULL || pAdapter == NULL )
  386. {
  387. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALPARAM\n")));
  388. return NDIS_STATUS_TAPI_INVALPARAM;
  389. }
  390. DEBUGMSG(DBG_TAPI, (DTEXT("TapiGetAddressStatus: hdLine=%Xh, ulAddressID=%d\n"),
  391. pRequest->hdLine, pRequest->ulAddressID));
  392. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  393. {
  394. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  395. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  396. }
  397. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  398. {
  399. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetAddressStatus NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  400. return NDIS_STATUS_TAPI_INVALADDRESSID;
  401. }
  402. #if SINGLE_LINE
  403. pCall = CallGetCall(pAdapter, 0);
  404. #else
  405. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  406. #endif
  407. if( pCall==NULL || (pCall->State == STATE_CALL_IDLE) ){
  408. fReady = TRUE;
  409. }else{
  410. fReady = FALSE;
  411. }
  412. pRequest->LineAddressStatus.ulNeededSize =
  413. pRequest->LineAddressStatus.ulUsedSize = sizeof(pRequest->LineAddressStatus);
  414. pRequest->LineAddressStatus.ulNumInUse = fReady ? 0 : 1;
  415. pRequest->LineAddressStatus.ulNumActiveCalls = fReady ? 0 : 1;
  416. pRequest->LineAddressStatus.ulAddressFeatures = fReady ? LINEADDRFEATURE_MAKECALL : 0;
  417. pRequest->LineAddressStatus.ulNumRingsNoAnswer = 999;
  418. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetAddressStatus\n")));
  419. return NDIS_STATUS_SUCCESS;
  420. }
  421. NDIS_STATUS
  422. TapiGetCallInfo(
  423. IN PPPTP_ADAPTER pAdapter,
  424. IN OUT PNDIS_TAPI_GET_CALL_INFO pRequest,
  425. IN OUT PULONG pRequiredLength
  426. )
  427. {
  428. PCALL_SESSION pCall;
  429. LINE_CALL_INFO *pLineCallInfo = NULL;
  430. ULONG CallerIdLength;
  431. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetCallInfo\n")));
  432. if ( pRequest == NULL || pAdapter == NULL )
  433. {
  434. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_TAPI_INVALPARAM\n")));
  435. return NDIS_STATUS_TAPI_INVALPARAM;
  436. }
  437. pLineCallInfo = &pRequest->LineCallInfo;
  438. // Verify the ID
  439. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  440. if (!pCall)
  441. {
  442. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  443. DEBUGMSG(DBG_FUNC | DBG_WARN, (DTEXT("-TapiGetCallInfo NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  444. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  445. }
  446. CallerIdLength = strlen(pCall->CallerId);
  447. if( CallerIdLength ){
  448. CallerIdLength += 1; // Add one for null terminator
  449. }
  450. if( pRequiredLength ){
  451. // Note: This returns NDIS struct size not LineCallInfo Size
  452. *pRequiredLength = sizeof(NDIS_TAPI_GET_CALL_INFO) + CallerIdLength;
  453. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_SUCCESS - Returning Length Only Len=0x%X\n"), *pRequiredLength));
  454. return NDIS_STATUS_SUCCESS;
  455. }
  456. pLineCallInfo->ulNeededSize = sizeof(pRequest->LineCallInfo) + CallerIdLength;
  457. if( pLineCallInfo->ulTotalSize < sizeof(pRequest->LineCallInfo) ){
  458. pLineCallInfo->ulUsedSize = 0;
  459. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo NDIS_STATUS_INVALID_LENGTH\n")));
  460. return NDIS_STATUS_INVALID_LENGTH;
  461. }
  462. pLineCallInfo->ulUsedSize = sizeof(pRequest->LineCallInfo);
  463. pLineCallInfo->hLine = (ULONG)pCall->DeviceId;
  464. pLineCallInfo->ulLineDeviceID = (ULONG)pCall->DeviceId;
  465. pLineCallInfo->ulAddressID = TAPI_ADDRESSID;
  466. pLineCallInfo->ulBearerMode = LINEBEARERMODE_DATA;
  467. pLineCallInfo->ulRate = pCall->Speed;
  468. pLineCallInfo->ulMediaMode = pCall->MediaModeMask;
  469. pLineCallInfo->ulCallParamFlags = LINECALLPARAMFLAGS_IDLE;
  470. pLineCallInfo->ulCallStates = CALL_STATES_MASK;
  471. pLineCallInfo->ulCallerIDFlags = LINECALLPARTYID_UNAVAIL;
  472. pLineCallInfo->ulCallerIDSize = 0;
  473. pLineCallInfo->ulCalledIDOffset = 0;
  474. pLineCallInfo->ulCalledIDFlags = LINECALLPARTYID_UNAVAIL;
  475. pLineCallInfo->ulCalledIDSize = 0;
  476. if( CallerIdLength ){
  477. if (pLineCallInfo->ulTotalSize >= pLineCallInfo->ulNeededSize)
  478. {
  479. PUCHAR pCallerId = (PUCHAR)(pLineCallInfo + 1);
  480. strcpy(pCallerId, pCall->CallerId);
  481. if (pCall->Inbound)
  482. {
  483. pLineCallInfo->ulCallerIDFlags = LINECALLPARTYID_ADDRESS;
  484. pLineCallInfo->ulCallerIDSize = CallerIdLength;
  485. pLineCallInfo->ulCallerIDOffset = sizeof(LINE_CALL_INFO);
  486. }
  487. else
  488. {
  489. pLineCallInfo->ulCalledIDFlags = LINECALLPARTYID_ADDRESS;
  490. pLineCallInfo->ulCalledIDSize = CallerIdLength;
  491. pLineCallInfo->ulCalledIDOffset = sizeof(LINE_CALL_INFO);
  492. }
  493. pLineCallInfo->ulUsedSize = pLineCallInfo->ulNeededSize;
  494. }else{
  495. DEBUGMSG(DBG_FUNC|DBG_WARN, (DTEXT("-TapiGetCallInfo NDIS_STATUS_SUCCESS without CallerID string\n")));
  496. return NDIS_STATUS_SUCCESS;
  497. }
  498. }
  499. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallInfo\n")));
  500. return NDIS_STATUS_SUCCESS;
  501. }
  502. NDIS_STATUS
  503. TapiGetCallStatus(
  504. IN PPPTP_ADAPTER pAdapter,
  505. IN OUT PNDIS_TAPI_GET_CALL_STATUS pRequest
  506. )
  507. {
  508. PCALL_SESSION pCall;
  509. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetCallStatus\n")));
  510. if ( pRequest == NULL || pAdapter == NULL )
  511. {
  512. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetCallStatus NDIS_STATUS_TAPI_INVALPARAM\n")));
  513. return NDIS_STATUS_TAPI_INVALPARAM;
  514. }
  515. // Verify the ID
  516. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  517. if (!pCall)
  518. {
  519. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallStatus NDIS_STATUS_TAPI_INVALCALLHANDLE\n")));
  520. return NDIS_STATUS_TAPI_INVALCALLHANDLE;
  521. }
  522. pRequest->LineCallStatus.ulNeededSize =
  523. pRequest->LineCallStatus.ulUsedSize = sizeof(LINE_CALL_STATUS);
  524. pRequest->LineCallStatus.ulCallFeatures = LINECALLFEATURE_ANSWER | LINECALLFEATURE_DROP;
  525. pRequest->LineCallStatus.ulCallPrivilege = LINECALLPRIVILEGE_OWNER;
  526. pRequest->LineCallStatus.ulCallState = CallGetLineCallState(pCall->State);
  527. DBG_X(DBG_TAPI, pRequest->LineCallStatus.ulCallState);
  528. switch (pRequest->LineCallStatus.ulCallState)
  529. {
  530. case LINECALLSTATE_DIALTONE:
  531. pRequest->LineCallStatus.ulCallStateMode = LINEDIALTONEMODE_NORMAL;
  532. break;
  533. case LINECALLSTATE_BUSY:
  534. pRequest->LineCallStatus.ulCallStateMode = LINEBUSYMODE_STATION;
  535. break;
  536. case LINECALLSTATE_DISCONNECTED:
  537. pRequest->LineCallStatus.ulCallStateMode = LINEDISCONNECTMODE_UNKNOWN;
  538. break;
  539. default:
  540. break;
  541. }
  542. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetCallStatus\n")));
  543. return NDIS_STATUS_SUCCESS;
  544. }
  545. NDIS_STATUS
  546. TapiGetDevCaps(
  547. IN PPPTP_ADAPTER pAdapter,
  548. IN OUT PNDIS_TAPI_GET_DEV_CAPS pRequest
  549. )
  550. {
  551. BOOLEAN ValidCall;
  552. NDIS_STATUS Status;
  553. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetDevCaps\n")));
  554. if ( pRequest == NULL || pAdapter == NULL )
  555. {
  556. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetDevCaps NDIS_STATUS_TAPI_INVALPARAM\n")));
  557. return NDIS_STATUS_TAPI_INVALPARAM;
  558. }
  559. // Verify the ID
  560. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  561. if (!ValidCall)
  562. {
  563. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetDevCaps NDIS_STATUS_TAPI_NODRIVER\n")));
  564. return NDIS_STATUS_TAPI_NODRIVER;
  565. }
  566. if (pRequest->LineDevCaps.ulTotalSize<sizeof(pRequest->LineDevCaps))
  567. {
  568. pRequest->LineDevCaps.ulUsedSize = 0;
  569. DEBUGMSG(DBG_FUNC|DBG_ERROR, (DTEXT("-TapiGetDevCaps NDIS_STATUS_INVALID_LENGTH\n")));
  570. return NDIS_STATUS_INVALID_LENGTH;
  571. }
  572. pRequest->LineDevCaps.ulUsedSize = sizeof(pRequest->LineDevCaps);
  573. pRequest->LineDevCaps.ulAddressModes = LINEADDRESSMODE_ADDRESSID |
  574. LINEADDRESSMODE_DIALABLEADDR;
  575. pRequest->LineDevCaps.ulNumAddresses = 1;
  576. pRequest->LineDevCaps.ulBearerModes = LINEBEARERMODE_DATA;
  577. pRequest->LineDevCaps.ulDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP;
  578. #if SINGLE_LINE
  579. pRequest->LineDevCaps.ulMaxNumActiveCalls = pAdapter->Info.Endpoints;
  580. #else
  581. pRequest->LineDevCaps.ulMaxNumActiveCalls = 1;
  582. #endif
  583. pRequest->LineDevCaps.ulAnswerMode = LINEANSWERMODE_DROP;
  584. pRequest->LineDevCaps.ulRingModes = 1;
  585. pRequest->LineDevCaps.ulPermanentLineID = pRequest->ulDeviceID + 1;
  586. pRequest->LineDevCaps.ulMaxRate = 0;
  587. pRequest->LineDevCaps.ulMediaModes = LINEMEDIAMODE_DIGITALDATA;
  588. Status = OsSpecificTapiGetDevCaps( pRequest->ulDeviceID, pRequest );
  589. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetDevCaps\n")));
  590. return Status;
  591. }
  592. NDIS_STATUS
  593. TapiGetExtensionId(
  594. IN PPPTP_ADAPTER pAdapter,
  595. IN OUT PNDIS_TAPI_GET_EXTENSION_ID pRequest
  596. )
  597. {
  598. BOOLEAN ValidCall;
  599. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetExtensionId\n")));
  600. if ( pRequest == NULL || pAdapter == NULL )
  601. {
  602. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetExtensionId NDIS_STATUS_TAPI_INVALPARAM\n")));
  603. return NDIS_STATUS_TAPI_INVALPARAM;
  604. }
  605. // Verify the ID
  606. ValidCall = CallIsValidCall(pAdapter, pRequest->ulDeviceID);
  607. if (!ValidCall)
  608. {
  609. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetExtensionId NDIS_STATUS_TAPI_NODRIVER\n")));
  610. return NDIS_STATUS_TAPI_NODRIVER;
  611. }
  612. // No extensions supported.
  613. pRequest->LineExtensionID.ulExtensionID0 = 0;
  614. pRequest->LineExtensionID.ulExtensionID1 = 0;
  615. pRequest->LineExtensionID.ulExtensionID2 = 0;
  616. pRequest->LineExtensionID.ulExtensionID3 = 0;
  617. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetExtensionId\n")));
  618. return NDIS_STATUS_SUCCESS;
  619. }
  620. #define PPTP_DEVICE_TYPE_STR "PPTP"
  621. NDIS_STATUS
  622. TapiGetId(
  623. IN PPPTP_ADAPTER pAdapter,
  624. IN OUT PNDIS_TAPI_GET_ID pRequest
  625. )
  626. {
  627. PCALL_SESSION pCall;
  628. ULONG_PTR DeviceID;
  629. BOOLEAN IsNdisClass = FALSE;
  630. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiGetId\n")));
  631. if ( pRequest == NULL || pAdapter == NULL )
  632. {
  633. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALPARAM\n")));
  634. return NDIS_STATUS_TAPI_INVALPARAM;
  635. }
  636. // Make sure this is a tapi or ndis request.
  637. if (_strnicmp((PCHAR) pRequest + pRequest->ulDeviceClassOffset,
  638. NDIS_DEVICECLASS_NAME, pRequest->ulDeviceClassSize) == 0)
  639. {
  640. IsNdisClass = TRUE;
  641. }
  642. else if (_strnicmp((PCHAR) pRequest + pRequest->ulDeviceClassOffset,
  643. TAPI_DEVICECLASS_NAME, pRequest->ulDeviceClassSize) != 0)
  644. {
  645. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALDEVICECLASS\n")));
  646. return NDIS_STATUS_TAPI_INVALDEVICECLASS;
  647. }
  648. DBG_D(DBG_TAPI, pRequest->ulSelect);
  649. #if DBG
  650. if(pRequest->ulDeviceClassSize != 0)
  651. {
  652. DBG_S(DBG_TAPI, (PCHAR) pRequest + pRequest->ulDeviceClassOffset);
  653. }
  654. #endif
  655. switch (pRequest->ulSelect) {
  656. case LINECALLSELECT_LINE:
  657. #if SINGLE_LINE
  658. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  659. {
  660. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  661. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  662. }
  663. DeviceID = 0;
  664. #else
  665. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  666. if (pCall == NULL)
  667. {
  668. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  669. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  670. }
  671. DeviceID = pCall->DeviceId;
  672. #endif
  673. break;
  674. case LINECALLSELECT_ADDRESS:
  675. #if SINGLE_LINE
  676. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  677. {
  678. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  679. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  680. }
  681. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  682. {
  683. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  684. return NDIS_STATUS_TAPI_INVALADDRESSID;
  685. }
  686. DeviceID = 0;
  687. #else
  688. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  689. if (pCall == NULL)
  690. {
  691. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  692. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  693. }
  694. if (pRequest->ulAddressID >= TAPI_ADDR_PER_LINE)
  695. {
  696. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALADDRESSID\n")));
  697. return NDIS_STATUS_TAPI_INVALADDRESSID;
  698. }
  699. DeviceID = pCall->DeviceId;
  700. #endif
  701. break;
  702. case LINECALLSELECT_CALL:
  703. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  704. if (pCall == NULL)
  705. {
  706. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  707. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  708. }
  709. TapiLineUp(pCall);
  710. DeviceID = (ULONG_PTR)pCall->NdisLinkContext;
  711. break;
  712. default:
  713. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetId NDIS_STATUS_FAILURE ulSelect=%d\n"), pRequest->ulSelect));
  714. return (NDIS_STATUS_FAILURE);
  715. }
  716. // Default to the minimum amount of data we will return.
  717. pRequest->DeviceID.ulUsedSize = sizeof(VAR_STRING);
  718. if( IsNdisClass ){
  719. // The format of the DeviceID for the "ndis" class is:
  720. struct _NDIS_CLASS {
  721. ULONG_PTR hDevice;
  722. CHAR szDeviceType[1];
  723. } *pNDISClass;
  724. pRequest->DeviceID.ulNeededSize =sizeof(VAR_STRING) + sizeof(PVOID) +
  725. sizeof(DeviceID) + sizeof(PPTP_DEVICE_TYPE_STR);
  726. if (pRequest->DeviceID.ulTotalSize >= pRequest->DeviceID.ulNeededSize)
  727. {
  728. pRequest->DeviceID.ulUsedSize = pRequest->DeviceID.ulNeededSize;
  729. pRequest->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  730. pRequest->DeviceID.ulStringSize = sizeof(DeviceID) + sizeof(PPTP_DEVICE_TYPE_STR);
  731. pNDISClass = (struct _NDIS_CLASS *)
  732. ((PUCHAR)((&pRequest->DeviceID) + 1) + sizeof(PVOID));
  733. (ULONG_PTR)pNDISClass &=
  734. ~((ULONG_PTR)sizeof(PVOID) - 1);
  735. pRequest->DeviceID.ulStringOffset = (ULONG)
  736. ((PUCHAR)pNDISClass - (PUCHAR)(&pRequest->DeviceID));
  737. pNDISClass->hDevice = DeviceID;
  738. DBG_X(DBG_TAPI, pNDISClass->hDevice);
  739. NdisMoveMemory(pNDISClass->szDeviceType, PPTP_DEVICE_TYPE_STR, sizeof(PPTP_DEVICE_TYPE_STR));
  740. }
  741. }else{
  742. // Now we need to adjust the variable field to place the device ID.
  743. pRequest->DeviceID.ulNeededSize = sizeof(VAR_STRING) + sizeof(DeviceID);
  744. if (pRequest->DeviceID.ulTotalSize >= pRequest->DeviceID.ulNeededSize)
  745. {
  746. pRequest->DeviceID.ulUsedSize = pRequest->DeviceID.ulNeededSize;
  747. pRequest->DeviceID.ulStringFormat = STRINGFORMAT_BINARY;
  748. pRequest->DeviceID.ulStringSize = sizeof(DeviceID);
  749. pRequest->DeviceID.ulStringOffset = sizeof(VAR_STRING);
  750. *(PULONG_PTR)((&pRequest->DeviceID) + 1) = DeviceID;
  751. }
  752. }
  753. //DEBUGMEM(DBG_TAPI, &pRequest->DeviceID, pRequest->DeviceID.ulUsedSize, 1);
  754. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiGetId\n")));
  755. return NDIS_STATUS_SUCCESS;
  756. }
  757. VOID
  758. TapiLineDown(
  759. PCALL_SESSION pCall
  760. )
  761. {
  762. NDIS_MAC_LINE_DOWN LineDownInfo;
  763. DEBUGMSG(DBG_FUNC|DBG_CALL|DBG_TAPI, (DTEXT("+TapiLineDown %08x\n"), pCall->NdisLinkContext));
  764. if (pCall->NdisLinkContext)
  765. {
  766. LineDownInfo.NdisLinkContext = pCall->NdisLinkContext;
  767. LOGMSG(FLL_DETAILED, (DTEXT(LOGHDRS"TapiLineDown:%d\n"),
  768. LOGHDR(28, pCall->Remote.Address.Address[0].Address[0].in_addr),
  769. pCall->DeviceId));
  770. /*
  771. * Indicate the event to the WAN wrapper.
  772. */
  773. NdisMIndicateStatus(pCall->pAdapter->hMiniportAdapter,
  774. NDIS_STATUS_WAN_LINE_DOWN,
  775. &LineDownInfo,
  776. sizeof(LineDownInfo));
  777. pCall->NdisLinkContext = NULL;
  778. }
  779. else
  780. {
  781. LOGMSG(FLL_DETAILED, (DTEXT(LOGHDRS"TapiLineDown:%d - No NdisLinkContext\n"),
  782. LOGHDR(28, pCall->Remote.Address.Address[0].Address[0].in_addr),
  783. pCall->DeviceId));
  784. }
  785. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiLineDown\n")));
  786. }
  787. VOID
  788. TapiLineUp(
  789. PCALL_SESSION pCall
  790. )
  791. {
  792. NDIS_MAC_LINE_UP LineUpInfo;
  793. DEBUGMSG(DBG_FUNC|DBG_CALL|DBG_TAPI, (DTEXT("+TapiLineUp %08x\n"), pCall));
  794. NdisAcquireSpinLock(&pCall->Lock);
  795. pCall->Close.Checklist &= ~CALL_CLOSE_LINE_DOWN;
  796. NdisReleaseSpinLock(&pCall->Lock);
  797. /*
  798. * Initialize the LINE_UP event packet.
  799. */
  800. LineUpInfo.LinkSpeed = pCall->Speed / 100;
  801. LineUpInfo.Quality = NdisWanErrorControl;
  802. LineUpInfo.SendWindow = 0;
  803. // Jeff says Win98 needs the DeviceID as the connection wrapper ID, but
  804. // TonyBe says NT needs an absolutely unique ID, which hTapiCall is.
  805. // hTapiCall is probably more correct according to Tapi rules, but we make
  806. // allowances.
  807. LineUpInfo.ConnectionWrapperID = OS_CONNECTION_WRAPPER_ID;
  808. LineUpInfo.NdisLinkHandle = (NDIS_HANDLE) DeviceIdToLinkHandle(pCall->DeviceId);
  809. LineUpInfo.NdisLinkContext = pCall->NdisLinkContext;
  810. LOGMSG(FLL_DETAILED, (DTEXT(LOGHDRS"TapiLineUp:%d\n"),
  811. LOGHDR(27, pCall->Remote.Address.Address[0].Address[0].in_addr),
  812. pCall->DeviceId));
  813. /*
  814. * Indicate the event to the WAN wrapper.
  815. */
  816. NdisMIndicateStatus(pCall->pAdapter->hMiniportAdapter,
  817. NDIS_STATUS_WAN_LINE_UP,
  818. &LineUpInfo,
  819. sizeof(LineUpInfo));
  820. NdisAcquireSpinLock(&pCall->Lock);
  821. pCall->NdisLinkContext = LineUpInfo.NdisLinkContext;
  822. NdisReleaseSpinLock(&pCall->Lock);
  823. DBG_X(DBG_TAPI, LineUpInfo.NdisLinkContext);
  824. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiLineUp\n")));
  825. }
  826. typedef struct {
  827. TA_IP_ADDRESS TargetAddress[MAX_TARGET_ADDRESSES];
  828. ULONG NumAddresses;
  829. ULONG CurrentAddress;
  830. } MAKE_CALL_CONTEXT, *PMAKE_CALL_CONTEXT;
  831. VOID
  832. TapipParseIpAddresses(
  833. IN OUT PUCHAR *ppAddressList,
  834. IN ULONG ListLength,
  835. IN OUT PTA_IP_ADDRESS TargetAddress,
  836. IN OUT PULONG pulCountAddresses
  837. )
  838. {
  839. BOOLEAN ValidAddress;
  840. ULONG NumTargetAddresses = 0;
  841. PUCHAR pAddressList, pEndAddressList;
  842. ULONG MaxTargetAddresses = *pulCountAddresses;
  843. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipParseAddresses\n")));
  844. // TAPI gives us an address of the following forms:
  845. //
  846. // [ IP Address ... IP Address ] [ Phone Number ]
  847. //
  848. // It begins with a list of addresses to try, and an optional phone number
  849. // if the remote device is an access concentrator.
  850. NdisZeroMemory(TargetAddress, sizeof(TargetAddress));
  851. pAddressList = *ppAddressList;
  852. pEndAddressList = pAddressList + ListLength;
  853. // ToDo: we expect NULL terminated. Is ok?
  854. // On Win98 an error may be passed rather than an address
  855. // In which cast the form is "E=XXXXXXX" where XXXXXXXX is a hexidecimal error code
  856. if( *pAddressList == 'E' && *(pAddressList+1) == '=' ){
  857. ULONG Err;
  858. // An Error code has been passed down to us from name resolution rather
  859. // than an IP address. Parse the error code and pass it along.
  860. if( !axtol( pAddressList + 2, &Err )){ // Get the error code from the string
  861. Err = (ULONG)-1L;
  862. }
  863. NumTargetAddresses = 1;
  864. TargetAddress->TAAddressCount = 0xffffffff; // Magic cookie to indicate error code
  865. TargetAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
  866. TargetAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
  867. TargetAddress->Address[0].Address[0].sin_port = 0;
  868. TargetAddress->Address[0].Address[0].in_addr = Err;
  869. pAddressList = pAddressList + strlen(pAddressList);
  870. LOGMSG( FLL_USER,(DTEXT("An error occured while resolving the VPN name and an\n")));
  871. LOGMSG( FLL_USER,(DTEXT(" error number was passed to PPTP instead of an address\n")));
  872. LOGMSG( FLL_USER,(DTEXT(" The error number passed is %u(0x%x)\n"), Err, Err ));
  873. DEBUGMSG( DBG_ERROR,(DTEXT("TapiMakeCall was passed error 0x%x\n"), Err ));
  874. // Reason = PptpTapiMapError(Err); // &&&&
  875. // DBG_ERROR( "Reporting disconnect for reason 0x%X\n", Reason );
  876. }else{
  877. ValidAddress = TRUE;
  878. while (ValidAddress && pAddressList<pEndAddressList)
  879. {
  880. pAddressList = StringToIpAddress(pAddressList,
  881. &TargetAddress[NumTargetAddresses],
  882. &ValidAddress);
  883. if (ValidAddress)
  884. {
  885. if (++NumTargetAddresses==MaxTargetAddresses)
  886. {
  887. // We've hit the limit of what we'll take. Throw the rest.
  888. while (ValidAddress && pAddressList<pEndAddressList)
  889. {
  890. TA_IP_ADDRESS ThrowAway;
  891. pAddressList = StringToIpAddress(pAddressList,
  892. &ThrowAway,
  893. &ValidAddress);
  894. }
  895. }
  896. }
  897. }
  898. }
  899. *pulCountAddresses = NumTargetAddresses;
  900. *ppAddressList = pAddressList;
  901. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipParseAddresses\n")));
  902. }
  903. VOID
  904. TapipMakeCallCallback(
  905. PPPTP_WORK_ITEM pWorkItem
  906. )
  907. {
  908. PCALL_SESSION pCall;
  909. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  910. PNDIS_TAPI_MAKE_CALL pRequest = pWorkItem->pBuffer;
  911. NDIS_STATUS Status;
  912. PUCHAR pAddressList;
  913. ULONG NumAddresses;
  914. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipMakeCallCallback\n")));
  915. #if SINGLE_LINE
  916. pCall = CallGetCall(pAdapter, pRequest->hdCall);
  917. if (!pCall)
  918. {
  919. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapipMakeCallCallback NDIS_STATUS_TAPI_INUSE\n")));
  920. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_TAPI_INUSE);
  921. return;
  922. }
  923. #else
  924. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  925. if (!pCall)
  926. {
  927. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapipMakeCallCallback NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  928. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_TAPI_INVALLINEHANDLE);
  929. return;
  930. }
  931. #endif
  932. DEBUGMEM(DBG_TAPI,
  933. (PUCHAR)pRequest + pRequest->ulDestAddressOffset,
  934. pRequest->ulDestAddressSize,
  935. 1);
  936. NdisAcquireSpinLock(&pCall->Lock);
  937. CallSetState(pCall, STATE_CALL_DIALING, 0, LOCKED);
  938. NdisMSetTimer(&pCall->DialTimer, 60*1000);
  939. pCall->UseUdp = (PptpTunnelConfig&CONFIG_INITIATE_UDP) ? TRUE : FALSE;
  940. pAddressList = (PUCHAR)pRequest + pRequest->ulDestAddressOffset;
  941. NumAddresses = 1;
  942. TapipParseIpAddresses(&pAddressList,
  943. pRequest->ulDestAddressSize,
  944. &pCall->Remote.Address,
  945. &NumAddresses);
  946. // We've got the addresses. Now nab the phone #
  947. {
  948. ULONG Digits = 0;
  949. while (*pAddressList && (*pAddressList==' ' || *pAddressList=='\t'))
  950. {
  951. pAddressList++;
  952. }
  953. while (*pAddressList &&
  954. Digits<MAX_PHONE_NUMBER_LENGTH-1)
  955. {
  956. pCall->CallerId[Digits++] = *pAddressList++;
  957. }
  958. pCall->CallerId[Digits] = '\0';
  959. #if 0
  960. // This apparently breaks Alcatel
  961. if (!Digits)
  962. {
  963. IpAddressToString(htonl(pCall->Remote.Address.Address[0].Address[0].in_addr), pCall->CallerId);
  964. }
  965. #endif
  966. DEBUGMSG(DBG_CALL, (DTEXT("Dialing %hs\n"), pCall->CallerId));
  967. }
  968. // ToDo: try all of the addresses.
  969. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  970. pCall->Close.Checklist &= ~(CALL_CLOSE_DISCONNECT|CALL_CLOSE_CLEANUP_STATE);
  971. NdisReleaseSpinLock(&pCall->Lock);
  972. Status = CtlConnectCall(pAdapter, pCall, &pCall->Remote.Address);
  973. NdisAcquireSpinLock(&pCall->Lock);
  974. if (Status==NDIS_STATUS_PENDING)
  975. {
  976. Status = NDIS_STATUS_SUCCESS;
  977. }
  978. else if (Status!=NDIS_STATUS_SUCCESS)
  979. {
  980. // We weren't successful, so we won't be getting these calls from tapi
  981. pCall->Close.Checklist |= (CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  982. }
  983. pCall->Remote.Address.Address[0].Address[0].sin_port = htons(PptpUdpPort);
  984. NdisReleaseSpinLock(&pCall->Lock);
  985. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, Status);
  986. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipMakeCallCallback\n")));
  987. }
  988. NDIS_STATUS
  989. TapiMakeCall(
  990. IN PPPTP_ADAPTER pAdapter,
  991. IN OUT PNDIS_TAPI_MAKE_CALL pRequest
  992. )
  993. {
  994. PCALL_SESSION pCall;
  995. NDIS_STATUS Status;
  996. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiMakeCall\n")));
  997. if ( pRequest == NULL || pAdapter == NULL )
  998. {
  999. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INVALPARAM\n")));
  1000. return NDIS_STATUS_TAPI_INVALPARAM;
  1001. }
  1002. #if SINGLE_LINE
  1003. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1004. {
  1005. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1006. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1007. }
  1008. pCall = CallFindAndLock(pAdapter, STATE_CALL_IDLE, FIND_OUTGOING);
  1009. if (!pCall)
  1010. {
  1011. DEBUGMSG(DBG_ERROR, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INUSE\n")));
  1012. return NDIS_STATUS_TAPI_INUSE;
  1013. }
  1014. #else
  1015. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  1016. if (!pCall)
  1017. {
  1018. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1019. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1020. }
  1021. NdisAcquireSpinLock(&pCall->Lock);
  1022. #endif
  1023. if (pCall->State != STATE_CALL_IDLE)
  1024. {
  1025. NdisReleaseSpinLock(&pCall->Lock);
  1026. DEBUGMSG(DBG_ERROR, (DTEXT("-TapiMakeCall NDIS_STATUS_TAPI_INUSE\n")));
  1027. return NDIS_STATUS_TAPI_INUSE;
  1028. }
  1029. // Save the handle tapi provides
  1030. pCall->hTapiCall = pRequest->htCall;
  1031. // our handle for tapi to this call is the device id
  1032. pRequest->hdCall = pCall->DeviceId;
  1033. CallSetState(pCall, STATE_CALL_OFFHOOK, 0, LOCKED);
  1034. NdisReleaseSpinLock(&pCall->Lock);
  1035. if (pRequest->ulDestAddressSize)
  1036. {
  1037. // Schedule a work item so we can issue a CtlCreateCall at passive level.
  1038. Status = ScheduleWorkItem(TapipMakeCallCallback,
  1039. pAdapter,
  1040. pRequest,
  1041. 0);
  1042. if (Status==NDIS_STATUS_SUCCESS)
  1043. {
  1044. // Keep the pRequest around until the callback.
  1045. Status = NDIS_STATUS_PENDING;
  1046. }
  1047. else
  1048. {
  1049. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_UNKNOWN, UNLOCKED);
  1050. CallCleanup(pCall, UNLOCKED);
  1051. }
  1052. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiMakeCall %08x\n"), Status));
  1053. return Status;
  1054. }
  1055. pCall->Close.Checklist &= ~(CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  1056. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiMakeCall\n")));
  1057. return NDIS_STATUS_SUCCESS;
  1058. }
  1059. NDIS_STATUS
  1060. TapiNegotiateExtVersion(
  1061. IN PPPTP_ADAPTER pAdapter,
  1062. IN OUT PNDIS_TAPI_NEGOTIATE_EXT_VERSION pRequest
  1063. )
  1064. {
  1065. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiNegotiateExtVersion Low=%08x Hi=%08x\n"),
  1066. pRequest ? pRequest->ulLowVersion : 0, pRequest ? pRequest->ulHighVersion : 0));
  1067. if ( pRequest == NULL || pAdapter == NULL )
  1068. {
  1069. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiNegotiateExtVersion NDIS_STATUS_TAPI_INVALPARAM\n")));
  1070. return NDIS_STATUS_TAPI_INVALPARAM;
  1071. }
  1072. if (pRequest->ulLowVersion < TAPI_EXT_VERSION ||
  1073. pRequest->ulHighVersion > TAPI_EXT_VERSION)
  1074. {
  1075. return NDIS_STATUS_TAPI_INCOMPATIBLEEXTVERSION;
  1076. }
  1077. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiNegotiateExtVersion\n")));
  1078. return NDIS_STATUS_SUCCESS;
  1079. }
  1080. VOID
  1081. TapipPassiveOpen(
  1082. PPPTP_WORK_ITEM pWorkItem
  1083. )
  1084. {
  1085. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1086. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipPassiveOpen\n")));
  1087. // We only come here if PptpInitialized = FALSE;
  1088. // It's a mechanism to defer opening tcp handles until tcp is
  1089. // actually available, as it may not always be during startup/setup
  1090. PptpInitialize(pAdapter);
  1091. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1092. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveOpen\n")));
  1093. }
  1094. NDIS_STATUS
  1095. TapiOpen(
  1096. IN PPPTP_ADAPTER pAdapter,
  1097. IN OUT PNDIS_TAPI_OPEN pRequest
  1098. )
  1099. {
  1100. PCALL_SESSION pCall;
  1101. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiOpen\n")));
  1102. if ( pRequest == NULL || pAdapter == NULL )
  1103. {
  1104. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiOpen NDIS_STATUS_TAPI_INVALPARAM\n")));
  1105. return NDIS_STATUS_TAPI_INVALPARAM;
  1106. }
  1107. if (!CallIsValidCall(pAdapter, pRequest->ulDeviceID))
  1108. {
  1109. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiGetDevCaps NDIS_STATUS_TAPI_NODRIVER\n")));
  1110. return NDIS_STATUS_TAPI_NODRIVER;
  1111. }
  1112. #if SINGLE_LINE
  1113. NdisAcquireSpinLock(&pAdapter->Lock);
  1114. if (pAdapter->Tapi.Open)
  1115. {
  1116. NdisReleaseSpinLock(&pAdapter->Lock);
  1117. return NDIS_STATUS_TAPI_ALLOCATED;
  1118. }
  1119. pAdapter->Tapi.Open = TRUE;
  1120. pAdapter->Tapi.hTapiLine = pRequest->htLine;
  1121. pRequest->hdLine = TapiIdToLineHandle(pRequest->ulDeviceID);
  1122. NdisReleaseSpinLock(&pAdapter->Lock);
  1123. #else
  1124. NdisAcquireSpinLock(&pAdapter->Lock);
  1125. if (pAdapter->pCallArray[DeviceIdToIndex(pAdapter, pRequest->ulDeviceID)]==NULL)
  1126. {
  1127. pAdapter->pCallArray[DeviceIdToIndex(pAdapter, pRequest->ulDeviceID)] = pCall = CallAlloc(pAdapter);
  1128. }
  1129. NdisReleaseSpinLock(&pAdapter->Lock);
  1130. if (!pCall)
  1131. {
  1132. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen NDIS_STATUS_RESOURCES\n")));
  1133. return NDIS_STATUS_RESOURCES;
  1134. }
  1135. NdisAcquireSpinLock(&pCall->Lock);
  1136. if (pCall->State!=STATE_CALL_CLOSED)
  1137. {
  1138. NdisReleaseSpinLock(&pCall->Lock);
  1139. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen NDIS_STATUS_TAPI_ALLOCATED\n")));
  1140. return NDIS_STATUS_TAPI_ALLOCATED;
  1141. }
  1142. pCall->hTapiLine = pRequest->htLine;
  1143. pCall->DeviceId = pRequest->ulDeviceID;
  1144. pRequest->hdLine = TapiIdToLineHandle(pRequest->ulDeviceID);
  1145. pCall->Open = TRUE;
  1146. CallSetState(pCall, STATE_CALL_IDLE, 0, LOCKED);
  1147. NdisReleaseSpinLock(&pCall->Lock);
  1148. #endif
  1149. if (!PptpInitialized)
  1150. {
  1151. if (ScheduleWorkItem(TapipPassiveOpen, pAdapter, NULL, 0)==NDIS_STATUS_SUCCESS)
  1152. {
  1153. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen PENDING\n")));
  1154. return NDIS_STATUS_PENDING;
  1155. }
  1156. }
  1157. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiOpen\n")));
  1158. return NDIS_STATUS_SUCCESS;
  1159. }
  1160. VOID
  1161. TapipPassiveProviderInitialize(
  1162. PPPTP_WORK_ITEM pWorkItem
  1163. )
  1164. {
  1165. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1166. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipPassiveProviderInitialize\n")));
  1167. // We initialize this here because TCP may not be available in MiniportInitialize
  1168. // We don't uninit until MiniportHalt. CtdiInitialize will just return quietly
  1169. // if it's already initialized, so we can come through here several times
  1170. // safely.
  1171. PptpInitialize(pAdapter); // Ignore the return status.
  1172. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1173. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveProviderInitialize\n")));
  1174. }
  1175. NDIS_STATUS
  1176. TapiProviderInitialize(
  1177. IN PPPTP_ADAPTER pAdapter,
  1178. IN OUT PNDIS_TAPI_PROVIDER_INITIALIZE pRequest
  1179. )
  1180. {
  1181. NDIS_STATUS Status;
  1182. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiProviderInitialize\n")));
  1183. if ( pRequest == NULL || pAdapter == NULL )
  1184. {
  1185. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiProviderInitialize NDIS_STATUS_TAPI_INVALPARAM\n")));
  1186. return NDIS_STATUS_TAPI_INVALPARAM;
  1187. }
  1188. pAdapter->Tapi.DeviceIdBase = pRequest->ulDeviceIDBase;
  1189. #if SINGLE_LINE
  1190. pRequest->ulNumLineDevs = 1;
  1191. #else
  1192. pRequest->ulNumLineDevs = pAdapter->Info.Endpoints;
  1193. #endif
  1194. DEBUGMSG(DBG_TAPI, (DTEXT("TapiProviderInitialize: ulNumLineDevices=%d\n"), pRequest->ulNumLineDevs));
  1195. pRequest->ulProviderID = (ULONG_PTR)pAdapter;
  1196. Status = ScheduleWorkItem(TapipPassiveProviderInitialize, pAdapter, NULL, 0);
  1197. if (Status==NDIS_STATUS_SUCCESS)
  1198. {
  1199. // Keep the pRequest around until the callback.
  1200. Status = NDIS_STATUS_PENDING;
  1201. }
  1202. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiProviderInitialize %08x\n"), Status));
  1203. return Status;
  1204. }
  1205. VOID
  1206. TapipPassiveProviderShutdown(
  1207. PPPTP_WORK_ITEM pWorkItem
  1208. )
  1209. {
  1210. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1211. ULONG i;
  1212. DEBUGMSG(DBG_FUNC|DBG_TAPI, (DTEXT("+TapipPassiveProviderShutdown\n")));
  1213. #if SINGLE_LINE
  1214. NdisAcquireSpinLock(&pAdapter->Lock);
  1215. pAdapter->Tapi.Open = FALSE;
  1216. pAdapter->Tapi.hTapiLine = 0;
  1217. NdisReleaseSpinLock(&pAdapter->Lock);
  1218. #endif
  1219. for (i=0; i<pAdapter->Info.Endpoints; i++)
  1220. {
  1221. // PCALL_SESSION pCall = CallGetCall(pAdapter, i);
  1222. PCALL_SESSION pCall = pAdapter->pCallArray[i];
  1223. if (IS_CALL(pCall))
  1224. {
  1225. NdisAcquireSpinLock(&pCall->Lock);
  1226. if (IS_CALL(pCall) && pCall->State>STATE_CALL_IDLE && pCall->State<STATE_CALL_CLEANUP)
  1227. {
  1228. pCall->Open = FALSE;
  1229. pCall->hTapiLine = 0;
  1230. CallSetState(pCall, STATE_CALL_CLEANUP, LINEDISCONNECTMODE_NORMAL, LOCKED);
  1231. CallDetachFromAdapter(pCall);
  1232. pCall->Close.Checklist |= (CALL_CLOSE_DROP|CALL_CLOSE_DROP_COMPLETE|CALL_CLOSE_CLOSE_CALL);
  1233. CallCleanup(pCall, LOCKED);
  1234. }
  1235. NdisReleaseSpinLock(&pCall->Lock);
  1236. }
  1237. }
  1238. if (pAdapter->hCtdiDg)
  1239. {
  1240. CtdiClose(pAdapter->hCtdiDg);
  1241. pAdapter->hCtdiDg = NULL;
  1242. }
  1243. if (pAdapter->hCtdiUdp)
  1244. {
  1245. CtdiClose(pAdapter->hCtdiUdp);
  1246. pAdapter->hCtdiUdp = NULL;
  1247. }
  1248. if (pAdapter->hCtdiListen)
  1249. {
  1250. CtdiClose(pAdapter->hCtdiListen);
  1251. pAdapter->hCtdiListen = NULL;
  1252. }
  1253. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, NDIS_STATUS_SUCCESS);
  1254. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipPassiveProviderShutdown\n")));
  1255. }
  1256. NDIS_STATUS
  1257. TapiProviderShutdown(
  1258. IN PPPTP_ADAPTER pAdapter,
  1259. IN OUT PNDIS_TAPI_PROVIDER_SHUTDOWN pRequest
  1260. )
  1261. {
  1262. NDIS_STATUS Status;
  1263. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiProviderShutdown\n")));
  1264. if ( pRequest == NULL || pAdapter == NULL )
  1265. {
  1266. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiProviderShutdown NDIS_STATUS_TAPI_INVALPARAM\n")));
  1267. return NDIS_STATUS_TAPI_INVALPARAM;
  1268. }
  1269. Status = ScheduleWorkItem(TapipPassiveProviderShutdown, pAdapter, NULL, 0);
  1270. if (Status==NDIS_STATUS_SUCCESS)
  1271. {
  1272. Status = NDIS_STATUS_PENDING;
  1273. }
  1274. DEBUGMSG(DBG_FUNC|DBG_ERR(Status), (DTEXT("-TapiProviderShutdown %08x\n"), Status));
  1275. return Status;
  1276. }
  1277. VOID
  1278. TapipSetDefaultMediaDetectionCallback(
  1279. PPPTP_WORK_ITEM pWorkItem
  1280. )
  1281. {
  1282. PPPTP_ADAPTER pAdapter = pWorkItem->Context;
  1283. PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION pRequest = pWorkItem->pBuffer;
  1284. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1285. DEBUGMSG(DBG_FUNC, (DTEXT("+TapipSetDefaultMediaDetectionCallback\n")));
  1286. if (pRequest->ulMediaModes&LINEMEDIAMODE_DIGITALDATA)
  1287. {
  1288. Status = CtlListen(pAdapter);
  1289. }
  1290. else if (pAdapter->hCtdiListen)
  1291. {
  1292. CtdiClose(pAdapter->hCtdiListen);
  1293. pAdapter->hCtdiListen = NULL;
  1294. }
  1295. NdisMSetInformationComplete(pAdapter->hMiniportAdapter, Status);
  1296. DEBUGMSG(DBG_FUNC, (DTEXT("-TapipSetDefaultMediaDetectionCallback\n")));
  1297. }
  1298. NDIS_STATUS
  1299. TapiSetDefaultMediaDetection(
  1300. IN PPPTP_ADAPTER pAdapter,
  1301. IN OUT PNDIS_TAPI_SET_DEFAULT_MEDIA_DETECTION pRequest
  1302. )
  1303. {
  1304. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1305. PCALL_SESSION pCall;
  1306. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiSetDefaultMediaDetection\n")));
  1307. if ( pRequest == NULL || pAdapter == NULL )
  1308. {
  1309. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALPARAM\n")));
  1310. return NDIS_STATUS_TAPI_INVALPARAM;
  1311. }
  1312. // Verify the ID
  1313. #if SINGLE_LINE
  1314. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1315. {
  1316. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1317. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1318. }
  1319. #else
  1320. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  1321. if (!pCall)
  1322. {
  1323. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_NODRIVER\n")));
  1324. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1325. }
  1326. #endif
  1327. // This is the OID to make us start accepting calls.
  1328. DEBUGMSG(DBG_TAPI, (DTEXT("MediaModes: %x\n"), pRequest->ulMediaModes));
  1329. // Schedule a work item so we can issue a CtlListen at passive level.
  1330. Status = ScheduleWorkItem(TapipSetDefaultMediaDetectionCallback,
  1331. pAdapter,
  1332. pRequest,
  1333. 0);
  1334. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection %08x\n"), Status));
  1335. return NDIS_STATUS_PENDING;
  1336. }
  1337. NDIS_STATUS
  1338. TapiSetStatusMessages(
  1339. IN PPPTP_ADAPTER pAdapter,
  1340. IN OUT PNDIS_TAPI_SET_STATUS_MESSAGES pRequest
  1341. )
  1342. {
  1343. PCALL_SESSION pCall;
  1344. DEBUGMSG(DBG_FUNC, (DTEXT("+TapiSetStatusMessages\n")));
  1345. if ( pRequest == NULL || pAdapter == NULL )
  1346. {
  1347. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetStatusMessages NDIS_STATUS_TAPI_INVALPARAM\n")));
  1348. return NDIS_STATUS_TAPI_INVALPARAM;
  1349. }
  1350. #if SINGLE_LINE
  1351. if (!CallIsValidCall(pAdapter, TapiLineHandleToId(pRequest->hdLine)))
  1352. {
  1353. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetDefaultMediaDetection NDIS_STATUS_TAPI_INVALLINEHANDLE\n")));
  1354. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1355. }
  1356. pAdapter->Tapi.LineStateMask = pRequest->ulLineStates;
  1357. #else
  1358. // Verify the ID
  1359. pCall = CallGetCall(pAdapter, TapiLineHandleToId(pRequest->hdLine));
  1360. if (!pCall)
  1361. {
  1362. DEBUGMSG(DBG_ERROR|DBG_FUNC, (DTEXT("-TapiSetStatusMessages NDIS_STATUS_TAPI_NODRIVER\n")));
  1363. return NDIS_STATUS_TAPI_INVALLINEHANDLE;
  1364. }
  1365. // This OID tells which status messages TAPI is interested in.
  1366. NdisAcquireSpinLock(&pCall->Lock);
  1367. pCall->LineStateMask = pRequest->ulLineStates;
  1368. NdisReleaseSpinLock(&pCall->Lock);
  1369. #endif
  1370. DEBUGMSG(DBG_FUNC, (DTEXT("-TapiSetStatusMessages\n")));
  1371. return NDIS_STATUS_SUCCESS;
  1372. }
  1373. // Converts a hexedicimal string to an unsigned long
  1374. // How many times to I have to write this function in my life time?
  1375. // Returns TRUE if valid hexidecimal string
  1376. // Returns FALSE otherwise
  1377. // *pResult contains the result
  1378. int axtol( LPSTR psz, ULONG *pResult )
  1379. {
  1380. ULONG l;
  1381. int i;
  1382. char *p;
  1383. char ch;
  1384. *pResult = 0xFFFFFFFF;
  1385. l = 0;
  1386. i = 0;
  1387. for( p = psz; *p != '\0'; p++){
  1388. i++; // Count the digits
  1389. l = l << 4;
  1390. ch = *p;
  1391. if( ch >= '0' && ch <= '9' ){
  1392. l = l + (ch - '0');
  1393. }else if( ch >= 'a' && ch <= 'f'){
  1394. l = l + (ch - 'a' + 10 );
  1395. }else if( ch >= 'A' && *p <= 'F'){
  1396. l = l + (ch - 'A' + 10 );
  1397. }else{
  1398. return( FALSE );
  1399. }
  1400. }
  1401. if(i > 8){ // Error on too long a string
  1402. return( FALSE );
  1403. }
  1404. *pResult = l;
  1405. return( TRUE );
  1406. }