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.

629 lines
21 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. termcaps.c
  5. Abstract:
  6. Routines for handling terminal capabilities.
  7. Environment:
  8. User Mode - Win32
  9. --*/
  10. ///////////////////////////////////////////////////////////////////////////////
  11. // //
  12. // Include files //
  13. // //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. #include "globals.h"
  16. #include "termcaps.h"
  17. #include "call.h"
  18. ///////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // Global variables //
  21. // //
  22. ///////////////////////////////////////////////////////////////////////////////
  23. H245_TOTCAP_T g_TermCapG723;
  24. H245_TOTCAP_T g_TermCapG711ULaw64;
  25. H245_TOTCAP_T g_TermCapG711ALaw64;
  26. H245_TOTCAP_T g_TermCapH261;
  27. H245_TOTCAP_T g_TermCapT120;
  28. H245_TOTCAP_T g_TermCapH263_28800;
  29. H245_TOTCAP_T g_TermCapH263_35000;
  30. H245_TOTCAP_T g_TermCapH263_42000;
  31. H245_TOTCAP_T g_TermCapH263_49000;
  32. H245_TOTCAP_T g_TermCapH263_56000;
  33. H245_TOTCAP_T g_TermCapH263_ISDN;
  34. H245_TOTCAP_T g_TermCapH263_LAN;
  35. PCC_TERMCAP g_TermCapArray_14400[] = {
  36. &g_TermCapG723
  37. };
  38. PCC_TERMCAP g_TermCapArray_28800[] = {
  39. &g_TermCapG723,
  40. &g_TermCapH263_28800,
  41. &g_TermCapT120
  42. };
  43. PCC_TERMCAP g_TermCapArray_35000[] = {
  44. &g_TermCapG723,
  45. &g_TermCapH263_35000,
  46. &g_TermCapT120
  47. };
  48. PCC_TERMCAP g_TermCapArray_42000[] = {
  49. &g_TermCapG723,
  50. &g_TermCapH263_42000,
  51. &g_TermCapT120
  52. };
  53. PCC_TERMCAP g_TermCapArray_49000[] = {
  54. &g_TermCapG723,
  55. &g_TermCapH263_49000,
  56. &g_TermCapT120
  57. };
  58. PCC_TERMCAP g_TermCapArray_56000[] = {
  59. &g_TermCapG723,
  60. &g_TermCapH263_56000,
  61. &g_TermCapT120
  62. };
  63. PCC_TERMCAP g_TermCapArray_ISDN[] = {
  64. &g_TermCapG723,
  65. &g_TermCapH263_ISDN,
  66. &g_TermCapT120
  67. };
  68. PCC_TERMCAP g_TermCapArray_LAN[] = {
  69. &g_TermCapG723,
  70. &g_TermCapH263_LAN,
  71. &g_TermCapG711ULaw64,
  72. &g_TermCapG711ALaw64,
  73. &g_TermCapH261,
  74. &g_TermCapT120
  75. };
  76. // these must match the arrays above...
  77. H245_TOTCAPDESC_T g_TermCapDescriptor_14400;
  78. H245_TOTCAPDESC_T g_TermCapDescriptor_28800;
  79. H245_TOTCAPDESC_T g_TermCapDescriptor_LAN;
  80. H245_TOTCAPDESC_T * g_TermCapDArray_14400[] = {
  81. &g_TermCapDescriptor_14400
  82. };
  83. H245_TOTCAPDESC_T * g_TermCapDArray_28800[] = {
  84. &g_TermCapDescriptor_28800
  85. };
  86. // re-use g.723.1 and h.263 descriptors
  87. H245_TOTCAPDESC_T * g_TermCapDArray_35000[] = {
  88. &g_TermCapDescriptor_28800
  89. };
  90. // re-use g.723.1 and h.263 descriptors
  91. H245_TOTCAPDESC_T * g_TermCapDArray_42000[] = {
  92. &g_TermCapDescriptor_28800
  93. };
  94. // re-use g.723.1 and h.263 descriptors
  95. H245_TOTCAPDESC_T * g_TermCapDArray_49000[] = {
  96. &g_TermCapDescriptor_28800
  97. };
  98. // re-use g.723.1 and h.263 descriptors
  99. H245_TOTCAPDESC_T * g_TermCapDArray_56000[] = {
  100. &g_TermCapDescriptor_28800
  101. };
  102. // re-use g.723.1 and h.263 descriptors
  103. H245_TOTCAPDESC_T * g_TermCapDArray_ISDN[] = {
  104. &g_TermCapDescriptor_28800
  105. };
  106. H245_TOTCAPDESC_T * g_TermCapDArray_LAN[] = {
  107. &g_TermCapDescriptor_LAN
  108. };
  109. CC_OCTETSTRING g_ProductID = {
  110. H323_PRODUCT_ID,
  111. sizeof(H323_PRODUCT_ID)
  112. };
  113. CC_OCTETSTRING g_ProductVersion = {
  114. H323_PRODUCT_VERSION,
  115. sizeof(H323_PRODUCT_VERSION)
  116. };
  117. CC_VENDORINFO g_VendorInfo = DEFINE_VENDORINFO(g_ProductID,g_ProductVersion);
  118. // T.120 related data.
  119. BOOL g_fAdvertiseT120 = FALSE;
  120. DWORD g_dwIPT120 = INADDR_ANY;
  121. WORD g_wPortT120 = 0;
  122. // the enum H245_CAPABILITY is used as the index into this array,
  123. DWORD g_CapabilityWeights[MAX_CAPS] = {100, 100, 100, 100};
  124. ///////////////////////////////////////////////////////////////////////////////
  125. // //
  126. // Private procedures //
  127. // //
  128. ///////////////////////////////////////////////////////////////////////////////
  129. BOOL
  130. UpdateSimultaneousCapabilities(
  131. )
  132. /*++
  133. Routine Description:
  134. This function is called when the capabilities are changed by the app. The
  135. array of caps and simcaps are updated based on the new status.
  136. Arguments:
  137. None.
  138. Return Values:
  139. Returns true if successful.
  140. --*/
  141. {
  142. unsigned short ulNumArrays;
  143. // initialize 14.4 descriptors
  144. g_TermCapDescriptor_14400.CapDescId = 0;
  145. ulNumArrays = 0;
  146. if (g_CapabilityWeights[HC_G723] > 0)
  147. {
  148. g_TermCapDescriptor_14400.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  149. g_TermCapDescriptor_14400.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G723;
  150. ulNumArrays ++;
  151. }
  152. if (g_fAdvertiseT120)
  153. {
  154. g_TermCapDescriptor_14400.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  155. g_TermCapDescriptor_14400.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_T120;
  156. ulNumArrays ++;
  157. }
  158. g_TermCapDescriptor_14400.CapDesc.Length = ulNumArrays;
  159. // initialize 28.8 descriptors
  160. g_TermCapDescriptor_28800.CapDescId = 0;
  161. ulNumArrays = 0;
  162. if (g_CapabilityWeights[HC_G723] > 0)
  163. {
  164. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  165. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G723;
  166. ulNumArrays ++;
  167. }
  168. if (g_CapabilityWeights[HC_H263QCIF] > 0)
  169. {
  170. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  171. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_H263;
  172. ulNumArrays ++;
  173. }
  174. if (g_fAdvertiseT120)
  175. {
  176. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  177. g_TermCapDescriptor_28800.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_T120;
  178. ulNumArrays ++;
  179. }
  180. g_TermCapDescriptor_28800.CapDesc.Length = ulNumArrays;
  181. // initialize LAN descriptors
  182. g_TermCapDescriptor_LAN.CapDescId = 0;
  183. ulNumArrays = 0;
  184. if ((g_CapabilityWeights[HC_G723] > 0) && (g_CapabilityWeights[HC_G711] > 0))
  185. {
  186. // both G723 and G711 are selected.
  187. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 3;
  188. // decide witch one is prefered.
  189. if (g_CapabilityWeights[HC_G723] >= g_CapabilityWeights[HC_G711])
  190. {
  191. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G723;
  192. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[1] = H245_TERMCAPID_G711_ULAW64;
  193. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[2] = H245_TERMCAPID_G711_ALAW64;
  194. }
  195. else
  196. {
  197. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G711_ULAW64;
  198. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[1] = H245_TERMCAPID_G711_ALAW64;
  199. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[2] = H245_TERMCAPID_G723;
  200. }
  201. ulNumArrays ++;
  202. }
  203. else if (g_CapabilityWeights[HC_G723] > 0)
  204. {
  205. // only G723 is selected.
  206. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  207. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G723;
  208. ulNumArrays ++;
  209. }
  210. else if (g_CapabilityWeights[HC_G711] > 0)
  211. {
  212. // only G711 is selected.
  213. g_TermCapDescriptor_LAN.CapDesc.Length ++;
  214. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 2;
  215. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_G711_ULAW64;
  216. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[1] = H245_TERMCAPID_G711_ALAW64;
  217. ulNumArrays ++;
  218. }
  219. if ((g_CapabilityWeights[HC_H263QCIF] > 0) && (g_CapabilityWeights[HC_H261QCIF] > 0))
  220. {
  221. // both H261 and H263 are selected.
  222. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 2;
  223. // decide witch one is prefered.
  224. if (g_CapabilityWeights[HC_H263QCIF] >= g_CapabilityWeights[HC_H261QCIF] > 0)
  225. {
  226. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_H263;
  227. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[1] = H245_TERMCAPID_H261;
  228. }
  229. else
  230. {
  231. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_H261;
  232. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[1] = H245_TERMCAPID_H263;
  233. }
  234. ulNumArrays ++;
  235. }
  236. else if (g_CapabilityWeights[HC_H263QCIF] > 0)
  237. {
  238. // Only H263 is selected.
  239. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  240. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_H263;
  241. ulNumArrays ++;
  242. }
  243. else if (g_CapabilityWeights[HC_H261QCIF] > 0)
  244. {
  245. // Only H263 is selected.
  246. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  247. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_H261;
  248. ulNumArrays ++;
  249. }
  250. if (g_fAdvertiseT120)
  251. {
  252. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].Length = 1;
  253. g_TermCapDescriptor_LAN.CapDesc.SimCapArray[ulNumArrays].AltCaps[0] = H245_TERMCAPID_T120;
  254. ulNumArrays ++;
  255. }
  256. g_TermCapDescriptor_LAN.CapDesc.Length = ulNumArrays;
  257. // success
  258. return TRUE;
  259. }
  260. ///////////////////////////////////////////////////////////////////////////////
  261. // //
  262. // Public procedures //
  263. // //
  264. ///////////////////////////////////////////////////////////////////////////////
  265. BOOL
  266. InitializeTermCaps(
  267. )
  268. /*++
  269. Routine Description:
  270. Initializes terminal capabilites list.
  271. Arguments:
  272. None.
  273. Return Values:
  274. Returns true if successful.
  275. --*/
  276. {
  277. g_TermCapT120.Dir = H245_CAPDIR_LCLRXTX;
  278. g_TermCapT120.DataType = H245_DATA_DATA;
  279. g_TermCapT120.ClientType = H245_CLIENT_DAT_T120;
  280. g_TermCapT120.CapId = H245_TERMCAPID_T120;
  281. g_TermCapT120.Cap.H245Dat_T120.application.choice =
  282. DACy_applctn_t120_chosen;
  283. g_TermCapT120.Cap.H245Dat_T120.application.u.DACy_applctn_t120.choice =
  284. separateLANStack_chosen;
  285. g_TermCapT120.Cap.H245Dat_T120.maxBitRate = 0; // updated later.
  286. // initialize g723 capabilities
  287. g_TermCapG723.Dir = H245_CAPDIR_LCLRX;
  288. g_TermCapG723.DataType = H245_DATA_AUDIO;
  289. g_TermCapG723.ClientType = H245_CLIENT_AUD_G723;
  290. g_TermCapG723.CapId = H245_TERMCAPID_G723;
  291. g_TermCapG723.Cap.H245Aud_G723.silenceSuppression = FALSE;
  292. g_TermCapG723.Cap.H245Aud_G723.maxAl_sduAudioFrames =
  293. G723_FRAMES_PER_PACKET(
  294. G723_MAXIMUM_MILLISECONDS_PER_PACKET
  295. );
  296. // initialize g711 capabilities
  297. g_TermCapG711ULaw64.Dir = H245_CAPDIR_LCLRX;
  298. g_TermCapG711ULaw64.DataType = H245_DATA_AUDIO;
  299. g_TermCapG711ULaw64.ClientType = H245_CLIENT_AUD_G711_ULAW64;
  300. g_TermCapG711ULaw64.CapId = H245_TERMCAPID_G711_ULAW64;
  301. g_TermCapG711ULaw64.Cap.H245Aud_G711_ULAW64 =
  302. G711_FRAMES_PER_PACKET(
  303. G711_MAXIMUM_MILLISECONDS_PER_PACKET
  304. );
  305. // initialize g711 capabilities
  306. g_TermCapG711ALaw64.Dir = H245_CAPDIR_LCLRX;
  307. g_TermCapG711ALaw64.DataType = H245_DATA_AUDIO;
  308. g_TermCapG711ALaw64.ClientType = H245_CLIENT_AUD_G711_ALAW64;
  309. g_TermCapG711ALaw64.CapId = H245_TERMCAPID_G711_ALAW64;
  310. g_TermCapG711ALaw64.Cap.H245Aud_G711_ALAW64 =
  311. G711_FRAMES_PER_PACKET(
  312. G711_MAXIMUM_MILLISECONDS_PER_PACKET
  313. );
  314. // initialize h261 capabilities
  315. g_TermCapH261.Dir = H245_CAPDIR_LCLRX;
  316. g_TermCapH261.DataType = H245_DATA_VIDEO;
  317. g_TermCapH261.ClientType = H245_CLIENT_VID_H261;
  318. g_TermCapH261.CapId = H245_TERMCAPID_H261;
  319. g_TermCapH261.Cap.H245Vid_H261.bit_mask = H261VdCpblty_qcifMPI_present;
  320. g_TermCapH261.Cap.H245Vid_H261.H261VdCpblty_qcifMPI = H261_QCIF_MPI;
  321. g_TermCapH261.Cap.H245Vid_H261.maxBitRate = MAXIMUM_BITRATE_H26x_QCIF;
  322. g_TermCapH261.Cap.H245Vid_H261.tmprlSptlTrdOffCpblty = FALSE;
  323. g_TermCapH261.Cap.H245Vid_H261.stillImageTransmission = FALSE;
  324. // initialize h263 capabilities
  325. g_TermCapH263_LAN.Dir = H245_CAPDIR_LCLRX;
  326. g_TermCapH263_LAN.DataType = H245_DATA_VIDEO;
  327. g_TermCapH263_LAN.ClientType = H245_CLIENT_VID_H263;
  328. g_TermCapH263_LAN.CapId = H245_TERMCAPID_H263;
  329. g_TermCapH263_LAN.Cap.H245Vid_H263.bit_mask = H263VdCpblty_qcifMPI_present;
  330. g_TermCapH263_LAN.Cap.H245Vid_H263.H263VdCpblty_qcifMPI = H263_QCIF_MPI;
  331. g_TermCapH263_LAN.Cap.H245Vid_H263.unrestrictedVector = FALSE;
  332. g_TermCapH263_LAN.Cap.H245Vid_H263.arithmeticCoding = FALSE;
  333. g_TermCapH263_LAN.Cap.H245Vid_H263.advancedPrediction = FALSE;
  334. g_TermCapH263_LAN.Cap.H245Vid_H263.pbFrames = FALSE;
  335. g_TermCapH263_LAN.Cap.H245Vid_H263.tmprlSptlTrdOffCpblty = FALSE;
  336. // make copies of termcaps
  337. g_TermCapH263_28800 = g_TermCapH263_LAN;
  338. g_TermCapH263_35000 = g_TermCapH263_LAN;
  339. g_TermCapH263_42000 = g_TermCapH263_LAN;
  340. g_TermCapH263_49000 = g_TermCapH263_LAN;
  341. g_TermCapH263_56000 = g_TermCapH263_LAN;
  342. g_TermCapH263_ISDN = g_TermCapH263_LAN;
  343. // modify bitrate for speed of each link
  344. g_TermCapH263_28800.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_28800;
  345. g_TermCapH263_35000.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_35000;
  346. g_TermCapH263_42000.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_42000;
  347. g_TermCapH263_49000.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_49000;
  348. g_TermCapH263_56000.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_56000;
  349. g_TermCapH263_ISDN.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_ISDN;
  350. g_TermCapH263_LAN.Cap.H245Vid_H263.maxBitRate = MAXIMUM_BITRATE_H26x_QCIF;
  351. UpdateSimultaneousCapabilities();
  352. // success
  353. return TRUE;
  354. }
  355. BOOL
  356. H323GetTermCapList(
  357. PH323_CALL pCall,
  358. PCC_TERMCAPLIST pTermCapList,
  359. PCC_TERMCAPDESCRIPTORS pTermCapDescriptors
  360. )
  361. /*++
  362. Routine Description:
  363. Initializes terminal capabilities list.
  364. Arguments:
  365. None.
  366. Return Values:
  367. Returns true if successful.
  368. --*/
  369. {
  370. H323DBG((
  371. DEBUG_LEVEL_TRACE,
  372. "H323GetTermCapList, g_fAdvertiseT120:%d\n",
  373. g_fAdvertiseT120
  374. ));
  375. if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_28800 * 100)) {
  376. // determine number of elements and save pointer to array
  377. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_14400);
  378. pTermCapList->pTermCapArray = g_TermCapArray_14400;
  379. // determine number of elements and save pointer to array
  380. pTermCapDescriptors->wLength = 1;
  381. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_14400;
  382. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_35000 * 100)) {
  383. // determine number of elements and save pointer to array
  384. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_28800);
  385. pTermCapList->pTermCapArray = g_TermCapArray_28800;
  386. // do not publish the T120 cap at the end of the array.
  387. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  388. // determine number of elements and save pointer to array
  389. pTermCapDescriptors->wLength = 1;
  390. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_28800;
  391. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_42000 * 100)) {
  392. // determine number of elements and save pointer to array
  393. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_35000);
  394. pTermCapList->pTermCapArray = g_TermCapArray_35000;
  395. // do not publish the T120 cap at the end of the array.
  396. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  397. // determine number of elements and save pointer to array
  398. pTermCapDescriptors->wLength = 1;
  399. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_35000;
  400. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_49000 * 100)) {
  401. // determine number of elements and save pointer to array
  402. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_42000);
  403. pTermCapList->pTermCapArray = g_TermCapArray_42000;
  404. // do not publish the T120 cap at the end of the array.
  405. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  406. // determine number of elements and save pointer to array
  407. pTermCapDescriptors->wLength = 1;
  408. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_42000;
  409. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_56000 * 100)) {
  410. // determine number of elements and save pointer to array
  411. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_49000);
  412. pTermCapList->pTermCapArray = g_TermCapArray_49000;
  413. // do not publish the T120 cap at the end of the array.
  414. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  415. // determine number of elements and save pointer to array
  416. pTermCapDescriptors->wLength = 1;
  417. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_49000;
  418. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_63000 * 100)) {
  419. // determine number of elements and save pointer to array
  420. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_56000);
  421. pTermCapList->pTermCapArray = g_TermCapArray_56000;
  422. // do not publish the T120 cap at the end of the array.
  423. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  424. // determine number of elements and save pointer to array
  425. pTermCapDescriptors->wLength = 1;
  426. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_56000;
  427. } else if (pCall->dwLinkSpeed < (MAXIMUM_BITRATE_ISDN * 100)) {
  428. // determine number of elements and save pointer to array
  429. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_ISDN);
  430. pTermCapList->pTermCapArray = g_TermCapArray_ISDN;
  431. // do not publish the T120 cap at the end of the array.
  432. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  433. // determine number of elements and save pointer to array
  434. pTermCapDescriptors->wLength = 1;
  435. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_ISDN;
  436. } else {
  437. // determine number of elements and save pointer to array
  438. pTermCapList->wLength = SIZEOF_TERMCAPLIST(g_TermCapArray_LAN);
  439. pTermCapList->pTermCapArray = g_TermCapArray_LAN;
  440. // do not publish the T120 cap at the end of the array.
  441. if (!g_fAdvertiseT120) pTermCapList->wLength --;
  442. // determine number of elements and save pointer to array
  443. pTermCapDescriptors->wLength = 1;
  444. pTermCapDescriptors->pTermCapDescriptorArray = g_TermCapDArray_LAN;
  445. }
  446. // This is a hack to put the right T120 bitrate into the PDU.
  447. g_TermCapT120.Cap.H245Dat_T120.maxBitRate = pCall->dwLinkSpeed;
  448. // success
  449. return TRUE;
  450. }
  451. BOOL
  452. H323ProcessConfigT120Command(
  453. PH323MSG_CONFIG_T120_COMMAND pCommand
  454. )
  455. {
  456. H323DBG((
  457. DEBUG_LEVEL_TRACE,
  458. "H323ProcessConfigT120Command. IP:%x, port:%d\n",
  459. pCommand->dwIP, pCommand->wPort
  460. ));
  461. // update the T120 information.
  462. g_fAdvertiseT120 = pCommand->fEnable;
  463. g_dwIPT120 = pCommand->dwIP;
  464. g_wPortT120 = pCommand->wPort;
  465. UpdateSimultaneousCapabilities();
  466. return TRUE;
  467. }
  468. BOOL
  469. H323ProcessConfigCapabilityCommand(
  470. PH323MSG_CONFIG_CAPABILITY_COMMAND pCommand
  471. )
  472. {
  473. DWORD dw;
  474. ASSERT(pCommand->dwNumCaps <= MAX_CAPS);
  475. // update the weight table
  476. for (dw = 0; dw < pCommand->dwNumCaps; dw ++)
  477. {
  478. H245_CAPABILITY cap = pCommand->pCapabilities[dw];
  479. g_CapabilityWeights[cap] = pCommand->pdwWeights[dw];
  480. }
  481. UpdateSimultaneousCapabilities();
  482. return TRUE;
  483. }