port_api.c 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 1999-2012 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * this file contains the Serial Port API code
  21. *
  22. ******************************************************************************/
  23. #include <string.h>
  24. #include "common/bt_target.h"
  25. #include "stack/rfcdefs.h"
  26. #include "stack/port_api.h"
  27. #include "port_int.h"
  28. #include "btm_int.h"
  29. #include "stack/btm_api.h"
  30. #include "rfc_int.h"
  31. #include "stack/l2c_api.h"
  32. #include "stack/sdp_api.h"
  33. #include "osi/allocator.h"
  34. #include "osi/mutex.h"
  35. #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
  36. /* duration of break in 200ms units */
  37. #define PORT_BREAK_DURATION 1
  38. /* Mapping from PORT_* result codes to human readable strings. */
  39. static const char *result_code_strings[] = {
  40. "Success",
  41. "Unknown error",
  42. "Already opened",
  43. "Command pending",
  44. "App not registered",
  45. "No memory",
  46. "No resources",
  47. "Bad BD address",
  48. "Unspecified error",
  49. "Bad handle",
  50. "Not opened",
  51. "Line error",
  52. "Start failed",
  53. "Parameter negotiation failed",
  54. "Port negotiation failed",
  55. "Sec failed",
  56. "Peer connection failed",
  57. "Peer failed",
  58. "Peer timeout",
  59. "Closed",
  60. "TX full",
  61. "Local closed",
  62. "Local timeout",
  63. "TX queue disabled",
  64. "Page timeout",
  65. "Invalid SCN",
  66. "Unknown result code"
  67. };
  68. /*******************************************************************************
  69. **
  70. ** Function RFCOMM_CreateConnection
  71. **
  72. ** Description RFCOMM_CreateConnection function is used from the application
  73. ** to establish serial port connection to the peer device,
  74. ** or allow RFCOMM to accept a connection from the peer
  75. ** application.
  76. **
  77. ** Parameters: scn - Service Channel Number as registered with
  78. ** the SDP (server) or obtained using SDP from
  79. ** the peer device (client).
  80. ** is_server - TRUE if requesting application is a server
  81. ** mtu - Maximum frame size the application can accept
  82. ** bd_addr - BD_ADDR of the peer (client)
  83. ** mask - specifies events to be enabled. A value
  84. ** of zero disables all events.
  85. ** p_handle - OUT pointer to the handle.
  86. ** p_mgmt_cb - pointer to callback function to receive
  87. ** connection up/down events.
  88. ** Notes:
  89. **
  90. ** Server can call this function with the same scn parameter multiple times if
  91. ** it is ready to accept multiple simulteneous connections.
  92. **
  93. ** DLCI for the connection is (scn * 2 + 1) if client originates connection on
  94. ** existing none initiator multiplexer channel. Otherwise it is (scn * 2).
  95. ** For the server DLCI can be changed later if client will be calling it using
  96. ** (scn * 2 + 1) dlci.
  97. **
  98. *******************************************************************************/
  99. int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
  100. UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle,
  101. tPORT_MGMT_CALLBACK *p_mgmt_cb)
  102. {
  103. tPORT *p_port;
  104. int i;
  105. UINT8 dlci;
  106. tRFC_MCB *p_mcb = port_find_mcb (bd_addr);
  107. UINT16 rfcomm_mtu;
  108. RFCOMM_TRACE_API ("RFCOMM_CreateConnection() BDA: %02x-%02x-%02x-%02x-%02x-%02x",
  109. bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
  110. *p_handle = 0;
  111. if (( scn == 0 ) || (scn >= PORT_MAX_RFC_PORTS )) {
  112. /* Server Channel Number(SCN) should be in range 1...30 */
  113. RFCOMM_TRACE_ERROR ("RFCOMM_CreateConnection - invalid SCN");
  114. return (PORT_INVALID_SCN);
  115. }
  116. /* For client that originate connection on the existing none initiator */
  117. /* multiplexer channel DLCI should be odd */
  118. if (p_mcb && !p_mcb->is_initiator && !is_server) {
  119. dlci = (scn << 1) + 1;
  120. } else {
  121. dlci = (scn << 1);
  122. }
  123. RFCOMM_TRACE_API("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p",
  124. scn, dlci, is_server, mtu, p_mcb);
  125. /* For the server side always allocate a new port. On the client side */
  126. /* do not allow the same (dlci, bd_addr) to be opened twice by application */
  127. if (!is_server && ((p_port = port_find_port (dlci, bd_addr)) != NULL)) {
  128. /* if existing port is also a client port */
  129. if (p_port->is_server == FALSE) {
  130. RFCOMM_TRACE_ERROR ("RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, MCB state:%d",
  131. p_port->state, p_port->rfc.state, p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0);
  132. return (PORT_ALREADY_OPENED);
  133. }
  134. }
  135. if ((p_port = port_allocate_port (dlci, bd_addr)) == NULL) {
  136. RFCOMM_TRACE_WARNING ("RFCOMM_CreateConnection - no resources");
  137. return (PORT_NO_RESOURCES);
  138. }
  139. RFCOMM_TRACE_API("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p, p_port:%p",
  140. scn, dlci, is_server, mtu, p_mcb, p_port);
  141. p_port->default_signal_state = (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
  142. switch (uuid) {
  143. case UUID_PROTOCOL_OBEX:
  144. p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
  145. break;
  146. case UUID_SERVCLASS_SERIAL_PORT:
  147. p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
  148. break;
  149. case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
  150. p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
  151. break;
  152. case UUID_SERVCLASS_DIALUP_NETWORKING:
  153. case UUID_SERVCLASS_FAX:
  154. p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
  155. break;
  156. }
  157. RFCOMM_TRACE_EVENT ("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci, p_port->default_signal_state);
  158. *p_handle = p_port->inx;
  159. p_port->state = PORT_STATE_OPENING;
  160. p_port->uuid = uuid;
  161. p_port->is_server = is_server;
  162. p_port->scn = scn;
  163. p_port->ev_mask = 0;
  164. /* If the MTU is not specified (0), keep MTU decision until the
  165. * PN frame has to be send
  166. * at that time connection should be established and we
  167. * will know for sure our prefered MTU
  168. */
  169. rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
  170. if (mtu) {
  171. p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
  172. } else {
  173. p_port->mtu = rfcomm_mtu;
  174. }
  175. /* server doesn't need to release port when closing */
  176. if ( is_server ) {
  177. p_port->keep_port_handle = TRUE;
  178. /* keep mtu that user asked, p_port->mtu could be updated during param negotiation */
  179. p_port->keep_mtu = p_port->mtu;
  180. }
  181. p_port->local_ctrl.modem_signal = p_port->default_signal_state;
  182. p_port->local_ctrl.fc = FALSE;
  183. p_port->p_mgmt_callback = p_mgmt_cb;
  184. for (i = 0; i < BD_ADDR_LEN; i++) {
  185. p_port->bd_addr[i] = bd_addr[i];
  186. }
  187. /* If this is not initiator of the connection need to just wait */
  188. if (p_port->is_server) {
  189. return (PORT_SUCCESS);
  190. }
  191. /* Open will be continued after security checks are passed */
  192. return port_open_continue (p_port);
  193. }
  194. /*******************************************************************************
  195. **
  196. ** Function RFCOMM_RemoveConnection
  197. **
  198. ** Description This function is called to close the specified connection.
  199. **
  200. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  201. **
  202. *******************************************************************************/
  203. int RFCOMM_RemoveConnection (UINT16 handle)
  204. {
  205. tPORT *p_port;
  206. RFCOMM_TRACE_API ("RFCOMM_RemoveConnection() handle:%d", handle);
  207. /* Check if handle is valid to avoid crashing */
  208. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  209. RFCOMM_TRACE_ERROR ("RFCOMM_RemoveConnection() BAD handle:%d", handle);
  210. return (PORT_BAD_HANDLE);
  211. }
  212. p_port = &rfc_cb.port.port[handle - 1];
  213. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  214. RFCOMM_TRACE_EVENT ("RFCOMM_RemoveConnection() Not opened:%d", handle);
  215. return (PORT_SUCCESS);
  216. }
  217. p_port->state = PORT_STATE_CLOSING;
  218. port_start_close (p_port);
  219. return (PORT_SUCCESS);
  220. }
  221. /*******************************************************************************
  222. **
  223. ** Function RFCOMM_RemoveServer
  224. **
  225. ** Description This function is called to close the server port.
  226. **
  227. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  228. **
  229. *******************************************************************************/
  230. int RFCOMM_RemoveServer (UINT16 handle)
  231. {
  232. tPORT *p_port;
  233. RFCOMM_TRACE_API ("RFCOMM_RemoveServer() handle:%d", handle);
  234. /* Check if handle is valid to avoid crashing */
  235. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  236. RFCOMM_TRACE_ERROR ("RFCOMM_RemoveServer() BAD handle:%d", handle);
  237. return (PORT_BAD_HANDLE);
  238. }
  239. p_port = &rfc_cb.port.port[handle - 1];
  240. /* Do not report any events to the client any more. */
  241. p_port->p_mgmt_callback = NULL;
  242. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  243. RFCOMM_TRACE_EVENT ("RFCOMM_RemoveServer() Not opened:%d", handle);
  244. return (PORT_SUCCESS);
  245. }
  246. /* this port will be deallocated after closing */
  247. p_port->keep_port_handle = FALSE;
  248. p_port->state = PORT_STATE_CLOSING;
  249. port_start_close (p_port);
  250. return (PORT_SUCCESS);
  251. }
  252. /*******************************************************************************
  253. **
  254. ** Function PORT_SetEventCallback
  255. **
  256. ** Description This function is called to provide an address of the
  257. ** function which will be called when one of the events
  258. ** specified in the mask occures.
  259. **
  260. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  261. ** p_callback - address of the callback function which should
  262. ** be called from the RFCOMM when an event
  263. ** specified in the mask occures.
  264. **
  265. **
  266. *******************************************************************************/
  267. int PORT_SetEventCallback (UINT16 port_handle, tPORT_CALLBACK *p_port_cb)
  268. {
  269. tPORT *p_port;
  270. /* Check if handle is valid to avoid crashing */
  271. if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
  272. return (PORT_BAD_HANDLE);
  273. }
  274. p_port = &rfc_cb.port.port[port_handle - 1];
  275. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  276. return (PORT_NOT_OPENED);
  277. }
  278. RFCOMM_TRACE_API ("PORT_SetEventCallback() handle:%d", port_handle);
  279. p_port->p_callback = p_port_cb;
  280. return (PORT_SUCCESS);
  281. }
  282. /*******************************************************************************
  283. **
  284. ** Function PORT_ClearKeepHandleFlag
  285. **
  286. ** Description This function is called to clear the keep handle flag
  287. ** which will cause not to keep the port handle open when closed
  288. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  289. **
  290. *******************************************************************************/
  291. int PORT_ClearKeepHandleFlag (UINT16 port_handle)
  292. {
  293. tPORT *p_port;
  294. /* Check if handle is valid to avoid crashing */
  295. if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
  296. return (PORT_BAD_HANDLE);
  297. }
  298. p_port = &rfc_cb.port.port[port_handle - 1];
  299. p_port->keep_port_handle = 0;
  300. return (PORT_SUCCESS);
  301. }
  302. /*******************************************************************************
  303. **
  304. ** Function PORT_SetDataCallback
  305. **
  306. ** Description This function is when a data packet is received
  307. **
  308. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  309. ** p_callback - address of the callback function which should
  310. ** be called from the RFCOMM when data packet
  311. ** is received.
  312. **
  313. **
  314. *******************************************************************************/
  315. int PORT_SetDataCallback (UINT16 port_handle, tPORT_DATA_CALLBACK *p_port_cb)
  316. {
  317. tPORT *p_port;
  318. // RFCOMM_TRACE_API ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
  319. /* Check if handle is valid to avoid crashing */
  320. if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
  321. return (PORT_BAD_HANDLE);
  322. }
  323. p_port = &rfc_cb.port.port[port_handle - 1];
  324. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  325. return (PORT_NOT_OPENED);
  326. }
  327. p_port->p_data_callback = p_port_cb;
  328. return (PORT_SUCCESS);
  329. }
  330. /*******************************************************************************
  331. **
  332. ** Function PORT_SetCODataCallback
  333. **
  334. ** Description This function is when a data packet is received
  335. **
  336. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  337. ** p_callback - address of the callback function which should
  338. ** be called from the RFCOMM when data packet
  339. ** is received.
  340. **
  341. **
  342. *******************************************************************************/
  343. int PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_cb)
  344. {
  345. tPORT *p_port;
  346. // RFCOMM_TRACE_API ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
  347. /* Check if handle is valid to avoid crashing */
  348. if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
  349. return (PORT_BAD_HANDLE);
  350. }
  351. p_port = &rfc_cb.port.port[port_handle - 1];
  352. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  353. return (PORT_NOT_OPENED);
  354. }
  355. p_port->p_data_co_callback = p_port_cb;
  356. return (PORT_SUCCESS);
  357. }
  358. /*******************************************************************************
  359. **
  360. ** Function PORT_SetEventMask
  361. **
  362. ** Description This function is called to close the specified connection.
  363. **
  364. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  365. ** mask - Bitmask of the events the host is interested in
  366. **
  367. *******************************************************************************/
  368. int PORT_SetEventMask (UINT16 port_handle, UINT32 mask)
  369. {
  370. tPORT *p_port;
  371. RFCOMM_TRACE_API ("PORT_SetEventMask() handle:%d mask:0x%x", port_handle, mask);
  372. /* Check if handle is valid to avoid crashing */
  373. if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
  374. return (PORT_BAD_HANDLE);
  375. }
  376. p_port = &rfc_cb.port.port[port_handle - 1];
  377. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  378. return (PORT_NOT_OPENED);
  379. }
  380. p_port->ev_mask = mask;
  381. return (PORT_SUCCESS);
  382. }
  383. /*******************************************************************************
  384. **
  385. ** Function PORT_CheckConnection
  386. **
  387. ** Description This function returns PORT_SUCCESS if connection referenced
  388. ** by handle is up and running
  389. **
  390. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  391. ** ignore_rfc_state - If need to ignore rfc state
  392. ** bd_addr - OUT bd_addr of the peer
  393. ** p_lcid - OUT L2CAP's LCID
  394. **
  395. *******************************************************************************/
  396. int PORT_CheckConnection(UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid)
  397. {
  398. tPORT *p_port;
  399. RFCOMM_TRACE_API ("PORT_CheckConnection() handle:%d", handle);
  400. /* Check if handle is valid to avoid crashing */
  401. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  402. return (PORT_BAD_HANDLE);
  403. }
  404. p_port = &rfc_cb.port.port[handle - 1];
  405. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  406. return (PORT_NOT_OPENED);
  407. }
  408. if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
  409. (!ignore_rfc_state ? (p_port->rfc.state != RFC_STATE_OPENED) : false)) {
  410. return (PORT_LINE_ERR);
  411. }
  412. memcpy (bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN);
  413. if (p_lcid) {
  414. *p_lcid = p_port->rfc.p_mcb->lcid;
  415. }
  416. return (PORT_SUCCESS);
  417. }
  418. /*******************************************************************************
  419. **
  420. ** Function PORT_IsOpening
  421. **
  422. ** Description This function returns TRUE if there is any RFCOMM connection
  423. ** opening in process.
  424. **
  425. ** Parameters: TRUE if any connection opening is found
  426. ** bd_addr - bd_addr of the peer
  427. **
  428. *******************************************************************************/
  429. BOOLEAN PORT_IsOpening (BD_ADDR bd_addr)
  430. {
  431. UINT8 xx, yy;
  432. tRFC_MCB *p_mcb = NULL;
  433. tPORT *p_port;
  434. BOOLEAN found_port;
  435. /* Check for any rfc_mcb which is in the middle of opening. */
  436. for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++) {
  437. if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
  438. (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED)) {
  439. memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
  440. return TRUE;
  441. }
  442. if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED) {
  443. found_port = FALSE;
  444. p_mcb = &rfc_cb.port.rfc_mcb[xx];
  445. p_port = &rfc_cb.port.port[0];
  446. for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++) {
  447. if (p_port->rfc.p_mcb == p_mcb) {
  448. found_port = TRUE;
  449. break;
  450. }
  451. }
  452. if ((!found_port) ||
  453. (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
  454. /* Port is not established yet. */
  455. memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
  456. return TRUE;
  457. }
  458. }
  459. }
  460. return FALSE;
  461. }
  462. /*******************************************************************************
  463. **
  464. ** Function PORT_SetState
  465. **
  466. ** Description This function configures connection according to the
  467. ** specifications in the tPORT_STATE structure.
  468. **
  469. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  470. ** p_settings - Pointer to a tPORT_STATE structure containing
  471. ** configuration information for the connection.
  472. **
  473. **
  474. *******************************************************************************/
  475. int PORT_SetState (UINT16 handle, tPORT_STATE *p_settings)
  476. {
  477. tPORT *p_port;
  478. UINT8 baud_rate;
  479. RFCOMM_TRACE_API ("PORT_SetState() handle:%d", handle);
  480. /* Check if handle is valid to avoid crashing */
  481. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  482. return (PORT_BAD_HANDLE);
  483. }
  484. p_port = &rfc_cb.port.port[handle - 1];
  485. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  486. return (PORT_NOT_OPENED);
  487. }
  488. if (p_port->line_status) {
  489. return (PORT_LINE_ERR);
  490. }
  491. RFCOMM_TRACE_API ("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
  492. p_settings->fc_type);
  493. baud_rate = p_port->user_port_pars.baud_rate;
  494. p_port->user_port_pars = *p_settings;
  495. /* for now we've been asked to pass only baud rate */
  496. if (baud_rate != p_settings->baud_rate) {
  497. port_start_par_neg (p_port);
  498. }
  499. return (PORT_SUCCESS);
  500. }
  501. /*******************************************************************************
  502. **
  503. ** Function PORT_GetRxQueueCnt
  504. **
  505. ** Description This function return number of buffers on the rx queue.
  506. **
  507. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  508. ** p_rx_queue_count - Pointer to return queue count in.
  509. **
  510. *******************************************************************************/
  511. int PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count)
  512. {
  513. tPORT *p_port;
  514. RFCOMM_TRACE_API ("PORT_GetRxQueueCnt() handle:%d", handle);
  515. /* Check if handle is valid to avoid crashing */
  516. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  517. return (PORT_BAD_HANDLE);
  518. }
  519. p_port = &rfc_cb.port.port[handle - 1];
  520. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  521. return (PORT_NOT_OPENED);
  522. }
  523. if (p_port->line_status) {
  524. return (PORT_LINE_ERR);
  525. }
  526. *p_rx_queue_count = p_port->rx.queue_size;
  527. RFCOMM_TRACE_API ("PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
  528. *p_rx_queue_count, p_port->rx.queue_size);
  529. return (PORT_SUCCESS);
  530. }
  531. /*******************************************************************************
  532. **
  533. ** Function PORT_GetState
  534. **
  535. ** Description This function is called to fill tPORT_STATE structure
  536. ** with the curremt control settings for the port
  537. **
  538. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  539. ** p_settings - Pointer to a tPORT_STATE structure in which
  540. ** configuration information is returned.
  541. **
  542. *******************************************************************************/
  543. int PORT_GetState (UINT16 handle, tPORT_STATE *p_settings)
  544. {
  545. tPORT *p_port;
  546. RFCOMM_TRACE_API ("PORT_GetState() handle:%d", handle);
  547. /* Check if handle is valid to avoid crashing */
  548. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  549. return (PORT_BAD_HANDLE);
  550. }
  551. p_port = &rfc_cb.port.port[handle - 1];
  552. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  553. return (PORT_NOT_OPENED);
  554. }
  555. if (p_port->line_status) {
  556. return (PORT_LINE_ERR);
  557. }
  558. *p_settings = p_port->user_port_pars;
  559. return (PORT_SUCCESS);
  560. }
  561. /*******************************************************************************
  562. **
  563. ** Function PORT_Control
  564. **
  565. ** Description This function directs a specified connection to pass control
  566. ** control information to the peer device.
  567. **
  568. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  569. ** signal = specify the function to be passed
  570. **
  571. *******************************************************************************/
  572. int PORT_Control (UINT16 handle, UINT8 signal)
  573. {
  574. tPORT *p_port;
  575. UINT8 old_modem_signal;
  576. RFCOMM_TRACE_API ("PORT_Control() handle:%d signal:0x%x", handle, signal);
  577. /* Check if handle is valid to avoid crashing */
  578. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  579. return (PORT_BAD_HANDLE);
  580. }
  581. p_port = &rfc_cb.port.port[handle - 1];
  582. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  583. return (PORT_NOT_OPENED);
  584. }
  585. old_modem_signal = p_port->local_ctrl.modem_signal;
  586. p_port->local_ctrl.break_signal = 0;
  587. switch (signal) {
  588. case PORT_SET_CTSRTS:
  589. p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
  590. break;
  591. case PORT_CLR_CTSRTS:
  592. p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
  593. break;
  594. case PORT_SET_DTRDSR:
  595. p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
  596. break;
  597. case PORT_CLR_DTRDSR:
  598. p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
  599. break;
  600. case PORT_SET_RI:
  601. p_port->local_ctrl.modem_signal |= PORT_RING_ON;
  602. break;
  603. case PORT_CLR_RI:
  604. p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
  605. break;
  606. case PORT_SET_DCD:
  607. p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
  608. break;
  609. case PORT_CLR_DCD:
  610. p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
  611. break;
  612. }
  613. if (signal == PORT_BREAK) {
  614. p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
  615. } else if (p_port->local_ctrl.modem_signal == old_modem_signal) {
  616. return (PORT_SUCCESS);
  617. }
  618. port_start_control (p_port);
  619. RFCOMM_TRACE_EVENT ("PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
  620. ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
  621. ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
  622. ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
  623. ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
  624. return (PORT_SUCCESS);
  625. }
  626. /*******************************************************************************
  627. **
  628. ** Function PORT_FlowControl
  629. **
  630. ** Description This function directs a specified connection to pass
  631. ** flow control message to the peer device. Enable flag passed
  632. ** shows if port can accept more data.
  633. **
  634. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  635. ** enable - enables data flow
  636. **
  637. *******************************************************************************/
  638. int PORT_FlowControl (UINT16 handle, BOOLEAN enable)
  639. {
  640. tPORT *p_port;
  641. BOOLEAN old_fc;
  642. UINT32 events;
  643. RFCOMM_TRACE_API ("PORT_FlowControl() handle:%d enable: %d", handle, enable);
  644. /* Check if handle is valid to avoid crashing */
  645. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  646. return (PORT_BAD_HANDLE);
  647. }
  648. p_port = &rfc_cb.port.port[handle - 1];
  649. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  650. return (PORT_NOT_OPENED);
  651. }
  652. if (!p_port->rfc.p_mcb) {
  653. return (PORT_NOT_OPENED);
  654. }
  655. p_port->rx.user_fc = !enable;
  656. if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
  657. if (!p_port->rx.user_fc) {
  658. port_flow_control_peer(p_port, TRUE, 0);
  659. }
  660. } else {
  661. old_fc = p_port->local_ctrl.fc;
  662. /* FC is set if user is set or peer is set */
  663. p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
  664. if (p_port->local_ctrl.fc != old_fc) {
  665. port_start_control (p_port);
  666. }
  667. }
  668. /* Need to take care of the case when we could not deliver events */
  669. /* to the application because we were flow controlled */
  670. if (enable && (p_port->rx.queue_size != 0)) {
  671. events = PORT_EV_RXCHAR;
  672. if (p_port->rx_flag_ev_pending) {
  673. p_port->rx_flag_ev_pending = FALSE;
  674. events |= PORT_EV_RXFLAG;
  675. }
  676. events &= p_port->ev_mask;
  677. if (p_port->p_callback && events) {
  678. p_port->p_callback (events, p_port->inx);
  679. }
  680. }
  681. return (PORT_SUCCESS);
  682. }
  683. #if 0 //Unused
  684. /*******************************************************************************
  685. **
  686. ** Function PORT_FlowControl_MaxCredit
  687. **
  688. ** Description This function directs a specified connection to pass
  689. ** flow control message to the peer device. Enable flag passed
  690. ** shows if port can accept more data. It also sends max credit
  691. ** when data flow enabled
  692. **
  693. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  694. ** enable - enables data flow
  695. **
  696. *******************************************************************************/
  697. int PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
  698. {
  699. tPORT *p_port;
  700. BOOLEAN old_fc;
  701. UINT32 events;
  702. RFCOMM_TRACE_API ("PORT_FlowControl() handle:%d enable: %d", handle, enable);
  703. /* Check if handle is valid to avoid crashing */
  704. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  705. return (PORT_BAD_HANDLE);
  706. }
  707. p_port = &rfc_cb.port.port[handle - 1];
  708. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  709. return (PORT_NOT_OPENED);
  710. }
  711. if (!p_port->rfc.p_mcb) {
  712. return (PORT_NOT_OPENED);
  713. }
  714. p_port->rx.user_fc = !enable;
  715. if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
  716. if (!p_port->rx.user_fc) {
  717. port_flow_control_peer(p_port, TRUE, p_port->credit_rx);
  718. }
  719. } else {
  720. old_fc = p_port->local_ctrl.fc;
  721. /* FC is set if user is set or peer is set */
  722. p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
  723. if (p_port->local_ctrl.fc != old_fc) {
  724. port_start_control (p_port);
  725. }
  726. }
  727. /* Need to take care of the case when we could not deliver events */
  728. /* to the application because we were flow controlled */
  729. if (enable && (p_port->rx.queue_size != 0)) {
  730. events = PORT_EV_RXCHAR;
  731. if (p_port->rx_flag_ev_pending) {
  732. p_port->rx_flag_ev_pending = FALSE;
  733. events |= PORT_EV_RXFLAG;
  734. }
  735. events &= p_port->ev_mask;
  736. if (p_port->p_callback && events) {
  737. p_port->p_callback (events, p_port->inx);
  738. }
  739. }
  740. return (PORT_SUCCESS);
  741. }
  742. #endif
  743. /*******************************************************************************
  744. **
  745. ** Function PORT_FlowControl_GiveCredit
  746. **
  747. ** Description This function gives specified credits to the peer
  748. **
  749. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  750. ** enable - enables data flow
  751. ** credits_given - credits to give
  752. **
  753. *******************************************************************************/
  754. int PORT_FlowControl_GiveCredit (UINT16 handle, BOOLEAN enable, UINT16 credits_given)
  755. {
  756. tPORT *p_port;
  757. BOOLEAN old_fc;
  758. UINT32 events;
  759. RFCOMM_TRACE_DEBUG("%s handle:%d enable: %d, cred %d", __func__, handle, enable, credits_given);
  760. /* Check if handle is valid to avoid crashing */
  761. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  762. return (PORT_BAD_HANDLE);
  763. }
  764. p_port = &rfc_cb.port.port[handle - 1];
  765. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  766. return (PORT_NOT_OPENED);
  767. }
  768. if (!p_port->rfc.p_mcb) {
  769. return (PORT_NOT_OPENED);
  770. }
  771. p_port->rx.user_fc = !enable;
  772. if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
  773. if (!p_port->rx.user_fc) {
  774. port_flow_control_peer(p_port, TRUE, credits_given);
  775. }
  776. } else {
  777. assert(0); // karl: temporarily not allowed
  778. old_fc = p_port->local_ctrl.fc;
  779. /* FC is set if user is set or peer is set */
  780. p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
  781. if (p_port->local_ctrl.fc != old_fc) {
  782. port_start_control (p_port);
  783. }
  784. }
  785. /* Need to take care of the case when we could not deliver events */
  786. /* to the application because we were flow controlled */
  787. if (enable && (p_port->rx.queue_size != 0)) {
  788. assert(0); // karl: temporarily not allowed
  789. events = PORT_EV_RXCHAR;
  790. if (p_port->rx_flag_ev_pending) {
  791. p_port->rx_flag_ev_pending = FALSE;
  792. events |= PORT_EV_RXFLAG;
  793. }
  794. events &= p_port->ev_mask;
  795. if (p_port->p_callback && events) {
  796. p_port->p_callback (events, p_port->inx);
  797. }
  798. }
  799. return (PORT_SUCCESS);
  800. }
  801. /*******************************************************************************
  802. **
  803. ** Function PORT_GetModemStatus
  804. **
  805. ** Description This function retrieves modem control signals. Normally
  806. ** application will call this function after a callback
  807. ** function is called with notification that one of signals
  808. ** has been changed.
  809. **
  810. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  811. ** p_signal - specify the pointer to control signals info
  812. **
  813. *******************************************************************************/
  814. int PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal)
  815. {
  816. tPORT *p_port;
  817. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  818. return (PORT_BAD_HANDLE);
  819. }
  820. p_port = &rfc_cb.port.port[handle - 1];
  821. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  822. return (PORT_NOT_OPENED);
  823. }
  824. *p_signal = p_port->peer_ctrl.modem_signal;
  825. RFCOMM_TRACE_API ("PORT_GetModemStatus() handle:%d signal:%x", handle, *p_signal);
  826. return (PORT_SUCCESS);
  827. }
  828. /*******************************************************************************
  829. **
  830. ** Function PORT_ClearError
  831. **
  832. ** Description This function retreives information about a communications
  833. ** error and reports current status of a connection. The
  834. ** function should be called when an error occures to clear
  835. ** the connection error flag and to enable additional read
  836. ** and write operations.
  837. **
  838. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  839. ** p_errors - pointer of the variable to receive error codes
  840. ** p_status - pointer to the tPORT_STATUS structur to receive
  841. ** connection status
  842. **
  843. *******************************************************************************/
  844. int PORT_ClearError (UINT16 handle, UINT16 *p_errors, tPORT_STATUS *p_status)
  845. {
  846. tPORT *p_port;
  847. RFCOMM_TRACE_API ("PORT_ClearError() handle:%d", handle);
  848. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  849. return (PORT_BAD_HANDLE);
  850. }
  851. p_port = &rfc_cb.port.port[handle - 1];
  852. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  853. return (PORT_NOT_OPENED);
  854. }
  855. *p_errors = p_port->line_status;
  856. /* This is the only call to clear error status. We can not clear */
  857. /* connection failed status. To clean it port should be closed and reopened */
  858. p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);
  859. PORT_GetQueueStatus (handle, p_status);
  860. return (PORT_SUCCESS);
  861. }
  862. /*******************************************************************************
  863. **
  864. ** Function PORT_SendError
  865. **
  866. ** Description This function send a communications error to the peer device
  867. **
  868. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  869. ** errors - receive error codes
  870. **
  871. *******************************************************************************/
  872. int PORT_SendError (UINT16 handle, UINT8 errors)
  873. {
  874. tPORT *p_port;
  875. RFCOMM_TRACE_API ("PORT_SendError() handle:%d errors:0x%x", handle, errors);
  876. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  877. return (PORT_BAD_HANDLE);
  878. }
  879. p_port = &rfc_cb.port.port[handle - 1];
  880. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  881. return (PORT_NOT_OPENED);
  882. }
  883. if (!p_port->rfc.p_mcb) {
  884. return (PORT_NOT_OPENED);
  885. }
  886. RFCOMM_LineStatusReq (p_port->rfc.p_mcb, p_port->dlci, errors);
  887. return (PORT_SUCCESS);
  888. }
  889. /*******************************************************************************
  890. **
  891. ** Function PORT_GetQueueStatus
  892. **
  893. ** Description This function reports current status of a connection.
  894. **
  895. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  896. ** p_status - pointer to the tPORT_STATUS structur to receive
  897. ** connection status
  898. **
  899. *******************************************************************************/
  900. int PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status)
  901. {
  902. tPORT *p_port;
  903. /* RFCOMM_TRACE_API ("PORT_GetQueueStatus() handle:%d", handle); */
  904. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  905. return (PORT_BAD_HANDLE);
  906. }
  907. p_port = &rfc_cb.port.port[handle - 1];
  908. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  909. return (PORT_NOT_OPENED);
  910. }
  911. p_status->in_queue_size = (UINT16) p_port->rx.queue_size;
  912. p_status->out_queue_size = (UINT16) p_port->tx.queue_size;
  913. p_status->mtu_size = (UINT16) p_port->peer_mtu;
  914. p_status->flags = 0;
  915. if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON)) {
  916. p_status->flags |= PORT_FLAG_CTS_HOLD;
  917. }
  918. if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON)) {
  919. p_status->flags |= PORT_FLAG_DSR_HOLD;
  920. }
  921. if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON)) {
  922. p_status->flags |= PORT_FLAG_RLSD_HOLD;
  923. }
  924. return (PORT_SUCCESS);
  925. }
  926. /*******************************************************************************
  927. **
  928. ** Function PORT_Purge
  929. **
  930. ** Description This function discards all the data from the output or
  931. ** input queues of the specified connection.
  932. **
  933. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  934. ** purge_flags - specify the action to take.
  935. **
  936. *******************************************************************************/
  937. int PORT_Purge (UINT16 handle, UINT8 purge_flags)
  938. {
  939. tPORT *p_port;
  940. BT_HDR *p_buf;
  941. UINT16 count;
  942. UINT32 events;
  943. RFCOMM_TRACE_API ("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);
  944. /* Check if handle is valid to avoid crashing */
  945. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  946. return (PORT_BAD_HANDLE);
  947. }
  948. p_port = &rfc_cb.port.port[handle - 1];
  949. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  950. return (PORT_NOT_OPENED);
  951. }
  952. if (purge_flags & PORT_PURGE_RXCLEAR) {
  953. osi_mutex_global_lock(); /* to prevent missing credit */
  954. count = fixed_queue_length(p_port->rx.queue);
  955. while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_port->rx.queue, 0)) != NULL) {
  956. osi_free (p_buf);
  957. }
  958. p_port->rx.queue_size = 0;
  959. osi_mutex_global_unlock();
  960. /* If we flowed controlled peer based on rx_queue size enable data again */
  961. if (count) {
  962. port_flow_control_peer (p_port, TRUE, count);
  963. }
  964. }
  965. if (purge_flags & PORT_PURGE_TXCLEAR) {
  966. osi_mutex_global_lock(); /* to prevent tx.queue_size from being negative */
  967. while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_port->tx.queue, 0)) != NULL) {
  968. osi_free (p_buf);
  969. }
  970. p_port->tx.queue_size = 0;
  971. osi_mutex_global_unlock();
  972. events = PORT_EV_TXEMPTY;
  973. events |= port_flow_control_user (p_port);
  974. events &= p_port->ev_mask;
  975. if ((p_port->p_callback != NULL) && events) {
  976. (p_port->p_callback)(events, p_port->inx);
  977. }
  978. }
  979. return (PORT_SUCCESS);
  980. }
  981. /*******************************************************************************
  982. **
  983. ** Function PORT_ReadData
  984. **
  985. ** Description Normally not GKI aware application will call this function
  986. ** after receiving PORT_EV_RXCHAR event.
  987. **
  988. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  989. ** p_data - Data area
  990. ** max_len - Byte count requested
  991. ** p_len - Byte count received
  992. **
  993. *******************************************************************************/
  994. int PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
  995. {
  996. tPORT *p_port;
  997. BT_HDR *p_buf;
  998. UINT16 count;
  999. RFCOMM_TRACE_API ("PORT_ReadData() handle:%d max_len:%d", handle, max_len);
  1000. /* Initialize this in case of an error */
  1001. *p_len = 0;
  1002. /* Check if handle is valid to avoid crashing */
  1003. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1004. return (PORT_BAD_HANDLE);
  1005. }
  1006. p_port = &rfc_cb.port.port[handle - 1];
  1007. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1008. return (PORT_NOT_OPENED);
  1009. }
  1010. if (p_port->line_status) {
  1011. return (PORT_LINE_ERR);
  1012. }
  1013. if (fixed_queue_is_empty(p_port->rx.queue)){
  1014. return (PORT_SUCCESS);
  1015. }
  1016. count = 0;
  1017. while (max_len)
  1018. {
  1019. p_buf = (BT_HDR *)fixed_queue_try_peek_first(p_port->rx.queue);
  1020. if (p_buf == NULL){
  1021. break;
  1022. }
  1023. if (p_buf->len > max_len) {
  1024. memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, max_len);
  1025. p_buf->offset += max_len;
  1026. p_buf->len -= max_len;
  1027. *p_len += max_len;
  1028. osi_mutex_global_lock();
  1029. p_port->rx.queue_size -= max_len;
  1030. osi_mutex_global_unlock();
  1031. break;
  1032. } else {
  1033. memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
  1034. *p_len += p_buf->len;
  1035. max_len -= p_buf->len;
  1036. osi_mutex_global_lock();
  1037. p_port->rx.queue_size -= p_buf->len;
  1038. if (max_len) {
  1039. p_data += p_buf->len;
  1040. }
  1041. osi_free(fixed_queue_dequeue(p_port->rx.queue, 0));
  1042. osi_mutex_global_unlock();
  1043. count++;
  1044. }
  1045. }
  1046. if (*p_len == 1) {
  1047. RFCOMM_TRACE_EVENT ("PORT_ReadData queue:%d returned:%d %x", p_port->rx.queue_size, *p_len, (p_data[0]));
  1048. } else {
  1049. RFCOMM_TRACE_EVENT ("PORT_ReadData queue:%d returned:%d", p_port->rx.queue_size, *p_len);
  1050. }
  1051. /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
  1052. /* check if it can be resumed now */
  1053. port_flow_control_peer (p_port, TRUE, count);
  1054. return (PORT_SUCCESS);
  1055. }
  1056. /*******************************************************************************
  1057. **
  1058. ** Function PORT_Read
  1059. **
  1060. ** Description Normally application will call this function after receiving
  1061. ** PORT_EV_RXCHAR event.
  1062. **
  1063. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  1064. ** pp_buf - pointer to address of buffer with data,
  1065. **
  1066. *******************************************************************************/
  1067. int PORT_Read (UINT16 handle, BT_HDR **pp_buf)
  1068. {
  1069. tPORT *p_port;
  1070. BT_HDR *p_buf;
  1071. RFCOMM_TRACE_API ("PORT_Read() handle:%d", handle);
  1072. /* Check if handle is valid to avoid crashing */
  1073. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1074. return (PORT_BAD_HANDLE);
  1075. }
  1076. p_port = &rfc_cb.port.port[handle - 1];
  1077. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1078. return (PORT_NOT_OPENED);
  1079. }
  1080. if (p_port->line_status) {
  1081. return (PORT_LINE_ERR);
  1082. }
  1083. osi_mutex_global_lock();
  1084. p_buf = (BT_HDR *)fixed_queue_dequeue(p_port->rx.queue, 0);
  1085. if (p_buf) {
  1086. p_port->rx.queue_size -= p_buf->len;
  1087. osi_mutex_global_unlock();
  1088. /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
  1089. /* check if it can be resumed now */
  1090. port_flow_control_peer (p_port, TRUE, 1);
  1091. } else {
  1092. osi_mutex_global_unlock();
  1093. }
  1094. *pp_buf = p_buf;
  1095. return (PORT_SUCCESS);
  1096. }
  1097. /*******************************************************************************
  1098. **
  1099. ** Function port_write
  1100. **
  1101. ** Description This function when a data packet is received from the apper
  1102. ** layer task.
  1103. **
  1104. ** Parameters: p_port - pointer to address of port control block
  1105. ** p_buf - pointer to address of buffer with data,
  1106. **
  1107. *******************************************************************************/
  1108. static int port_write (tPORT *p_port, BT_HDR *p_buf)
  1109. {
  1110. /* We should not allow to write data in to server port when connection is not opened */
  1111. if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) {
  1112. osi_free (p_buf);
  1113. return (PORT_CLOSED);
  1114. }
  1115. /* Keep the data in pending queue if peer does not allow data, or */
  1116. /* Peer is not ready or Port is not yet opened or initial port control */
  1117. /* command has not been sent */
  1118. if (p_port->tx.peer_fc
  1119. || !p_port->rfc.p_mcb
  1120. || !p_port->rfc.p_mcb->peer_ready
  1121. || (p_port->rfc.state != RFC_STATE_OPENED)
  1122. || ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
  1123. (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
  1124. if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM)
  1125. || (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)){
  1126. RFCOMM_TRACE_WARNING ("PORT_Write: Queue size: %d",
  1127. p_port->tx.queue_size);
  1128. osi_free (p_buf);
  1129. if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR)) {
  1130. p_port->p_callback (PORT_EV_ERR, p_port->inx);
  1131. }
  1132. return (PORT_TX_FULL);
  1133. }
  1134. RFCOMM_TRACE_EVENT ("PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d ctrl_state %x",
  1135. p_port->tx.peer_fc,
  1136. (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready),
  1137. p_port->rfc.state,
  1138. p_port->port_ctrl);
  1139. fixed_queue_enqueue(p_port->tx.queue, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
  1140. p_port->tx.queue_size += p_buf->len;
  1141. return (PORT_CMD_PENDING);
  1142. } else {
  1143. RFCOMM_TRACE_EVENT ("PORT_Write : Data is being sent");
  1144. RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf);
  1145. return (PORT_SUCCESS);
  1146. }
  1147. }
  1148. /*******************************************************************************
  1149. **
  1150. ** Function PORT_Write
  1151. **
  1152. ** Description This function when a data packet is received from the apper
  1153. ** layer task.
  1154. **
  1155. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  1156. ** pp_buf - pointer to address of buffer with data,
  1157. **
  1158. *******************************************************************************/
  1159. int PORT_Write (UINT16 handle, BT_HDR *p_buf)
  1160. {
  1161. tPORT *p_port;
  1162. UINT32 event = 0;
  1163. int rc;
  1164. RFCOMM_TRACE_API ("PORT_Write() handle:%d", handle);
  1165. /* Check if handle is valid to avoid crashing */
  1166. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1167. osi_free (p_buf);
  1168. return (PORT_BAD_HANDLE);
  1169. }
  1170. p_port = &rfc_cb.port.port[handle - 1];
  1171. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1172. osi_free (p_buf);
  1173. return (PORT_NOT_OPENED);
  1174. }
  1175. if (p_port->line_status) {
  1176. RFCOMM_TRACE_WARNING ("PORT_Write: Data dropped line_status:0x%x",
  1177. p_port->line_status);
  1178. osi_free (p_buf);
  1179. return (PORT_LINE_ERR);
  1180. }
  1181. rc = port_write (p_port, p_buf);
  1182. event |= port_flow_control_user (p_port);
  1183. switch (rc) {
  1184. case PORT_TX_FULL:
  1185. event |= PORT_EV_ERR;
  1186. break;
  1187. case PORT_SUCCESS:
  1188. event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
  1189. break;
  1190. }
  1191. /* Mask out all events that are not of interest to user */
  1192. event &= p_port->ev_mask;
  1193. /* Send event to the application */
  1194. if (p_port->p_callback && event) {
  1195. (p_port->p_callback)(event, p_port->inx);
  1196. }
  1197. return (PORT_SUCCESS);
  1198. }
  1199. /*******************************************************************************
  1200. **
  1201. ** Function PORT_WriteDataCO
  1202. **
  1203. ** Description Normally not GKI aware application will call this function
  1204. ** to send data to the port by callout functions
  1205. **
  1206. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  1207. ** fd - socket fd
  1208. ** p_len - Byte count returned
  1209. **
  1210. *******************************************************************************/
  1211. int PORT_WriteDataCO (UINT16 handle, int *p_len, int len, UINT8 *p_data)
  1212. {
  1213. tPORT *p_port;
  1214. BT_HDR *p_buf;
  1215. UINT32 event = 0;
  1216. int rc = 0;
  1217. UINT16 length;
  1218. RFCOMM_TRACE_API ("PORT_WriteDataCO() handle:%d", handle);
  1219. *p_len = 0;
  1220. /* Check if handle is valid to avoid crashing */
  1221. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1222. return (PORT_BAD_HANDLE);
  1223. }
  1224. p_port = &rfc_cb.port.port[handle - 1];
  1225. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1226. RFCOMM_TRACE_WARNING ("PORT_WriteDataByFd() no port state:%d", p_port->state);
  1227. return (PORT_NOT_OPENED);
  1228. }
  1229. if (!p_port->peer_mtu) {
  1230. RFCOMM_TRACE_ERROR ("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
  1231. return (PORT_UNKNOWN_ERROR);
  1232. }
  1233. int available = 0;
  1234. available = len;
  1235. if (available == 0) {
  1236. return PORT_SUCCESS;
  1237. }
  1238. /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
  1239. length = RFCOMM_DATA_BUF_SIZE -
  1240. (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
  1241. while (available) {
  1242. /* if we're over buffer high water mark, we're done */
  1243. if ((p_port->tx.queue_size > PORT_TX_HIGH_WM)
  1244. || (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
  1245. port_flow_control_user(p_port);
  1246. event |= PORT_EV_FC;
  1247. RFCOMM_TRACE_EVENT ("tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
  1248. p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue), available);
  1249. break;
  1250. }
  1251. /* continue with rfcomm data write */
  1252. if (p_port->peer_mtu < length) {
  1253. length = p_port->peer_mtu;
  1254. }
  1255. if (available < (int)length) {
  1256. length = (UINT16)available;
  1257. }
  1258. UINT16 alloc_size = (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD
  1259. + length + L2CAP_FCS_LEN);
  1260. p_buf = (BT_HDR *)osi_malloc(alloc_size);
  1261. if (!p_buf) {
  1262. RFCOMM_TRACE_EVENT ("PORT_WriteDataCO: out of heap.");
  1263. break;
  1264. }
  1265. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
  1266. p_buf->layer_specific = handle;
  1267. p_buf->len = length;
  1268. p_buf->event = BT_EVT_TO_BTU_SP_DATA;
  1269. memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
  1270. RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);
  1271. rc = port_write (p_port, p_buf);
  1272. /* If queue went below the threshold need to send flow control */
  1273. event |= port_flow_control_user (p_port);
  1274. if (rc == PORT_SUCCESS) {
  1275. event |= PORT_EV_TXCHAR;
  1276. }
  1277. if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) {
  1278. break;
  1279. }
  1280. *p_len += length;
  1281. available -= (int)length;
  1282. p_data += length;
  1283. }
  1284. if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) {
  1285. event |= PORT_EV_TXEMPTY;
  1286. }
  1287. /* Mask out all events that are not of interest to user */
  1288. event &= p_port->ev_mask;
  1289. /* Send event to the application */
  1290. if (p_port->p_callback && event) {
  1291. (p_port->p_callback)(event, p_port->inx);
  1292. }
  1293. return (PORT_SUCCESS);
  1294. }
  1295. /*******************************************************************************
  1296. **
  1297. ** Function PORT_WriteData
  1298. **
  1299. ** Description Normally not GKI aware application will call this function
  1300. ** to send data to the port.
  1301. **
  1302. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  1303. ** p_data - Data area
  1304. ** max_len - Byte count requested
  1305. ** p_len - Byte count received
  1306. **
  1307. *******************************************************************************/
  1308. int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
  1309. {
  1310. tPORT *p_port;
  1311. BT_HDR *p_buf;
  1312. UINT32 event = 0;
  1313. int rc = 0;
  1314. UINT16 length;
  1315. RFCOMM_TRACE_API ("PORT_WriteData() max_len:%d", max_len);
  1316. *p_len = 0;
  1317. /* Check if handle is valid to avoid crashing */
  1318. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1319. return (PORT_BAD_HANDLE);
  1320. }
  1321. p_port = &rfc_cb.port.port[handle - 1];
  1322. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1323. RFCOMM_TRACE_WARNING ("PORT_WriteData() no port state:%d", p_port->state);
  1324. return (PORT_NOT_OPENED);
  1325. }
  1326. if (!max_len || !p_port->peer_mtu) {
  1327. RFCOMM_TRACE_ERROR ("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
  1328. return (PORT_UNKNOWN_ERROR);
  1329. }
  1330. /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
  1331. length = RFCOMM_DATA_BUF_SIZE -
  1332. (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
  1333. /* If there are buffers scheduled for transmission check if requested */
  1334. /* data fits into the end of the queue */
  1335. osi_mutex_global_lock();
  1336. if (((p_buf = (BT_HDR *)fixed_queue_try_peek_last(p_port->tx.queue)) != NULL)
  1337. && ((p_buf->len + max_len) <= p_port->peer_mtu)
  1338. && ((p_buf->len + max_len) <= length)) {
  1339. memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
  1340. p_port->tx.queue_size += max_len;
  1341. *p_len = max_len;
  1342. p_buf->len += max_len;
  1343. osi_mutex_global_unlock();
  1344. return (PORT_SUCCESS);
  1345. }
  1346. osi_mutex_global_unlock();
  1347. while (max_len) {
  1348. /* if we're over buffer high water mark, we're done */
  1349. if ((p_port->tx.queue_size > PORT_TX_HIGH_WM)
  1350. || (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
  1351. break;
  1352. }
  1353. /* continue with rfcomm data write */
  1354. p_buf = (BT_HDR *)osi_malloc(RFCOMM_DATA_BUF_SIZE);
  1355. if (!p_buf) {
  1356. break;
  1357. }
  1358. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
  1359. p_buf->layer_specific = handle;
  1360. if (p_port->peer_mtu < length) {
  1361. length = p_port->peer_mtu;
  1362. }
  1363. if (max_len < length) {
  1364. length = max_len;
  1365. }
  1366. p_buf->len = length;
  1367. p_buf->event = BT_EVT_TO_BTU_SP_DATA;
  1368. memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
  1369. RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);
  1370. rc = port_write (p_port, p_buf);
  1371. /* If queue went below the threashold need to send flow control */
  1372. event |= port_flow_control_user (p_port);
  1373. if (rc == PORT_SUCCESS) {
  1374. event |= PORT_EV_TXCHAR;
  1375. }
  1376. if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) {
  1377. break;
  1378. }
  1379. *p_len += length;
  1380. max_len -= length;
  1381. p_data += length;
  1382. }
  1383. if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) {
  1384. event |= PORT_EV_TXEMPTY;
  1385. }
  1386. /* Mask out all events that are not of interest to user */
  1387. event &= p_port->ev_mask;
  1388. /* Send event to the application */
  1389. if (p_port->p_callback && event) {
  1390. (p_port->p_callback)(event, p_port->inx);
  1391. }
  1392. return (PORT_SUCCESS);
  1393. }
  1394. /*******************************************************************************
  1395. **
  1396. ** Function PORT_Test
  1397. **
  1398. ** Description Application can call this function to send RFCOMM Test frame
  1399. **
  1400. ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
  1401. ** p_data - Data area
  1402. ** max_len - Byte count requested
  1403. **
  1404. *******************************************************************************/
  1405. int PORT_Test (UINT16 handle, UINT8 *p_data, UINT16 len)
  1406. {
  1407. BT_HDR *p_buf;
  1408. tPORT *p_port;
  1409. RFCOMM_TRACE_API ("PORT_Test() len:%d", len);
  1410. if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
  1411. return (PORT_BAD_HANDLE);
  1412. }
  1413. p_port = &rfc_cb.port.port[handle - 1];
  1414. if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
  1415. return (PORT_NOT_OPENED);
  1416. }
  1417. if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu)) {
  1418. return (PORT_UNKNOWN_ERROR);
  1419. }
  1420. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) != NULL) {
  1421. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
  1422. p_buf->len = len;
  1423. memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
  1424. rfc_send_test (p_port->rfc.p_mcb, TRUE, p_buf);
  1425. return (PORT_SUCCESS);
  1426. } else {
  1427. return (PORT_NO_MEM);
  1428. }
  1429. }
  1430. /*******************************************************************************
  1431. **
  1432. ** Function RFCOMM_Init
  1433. **
  1434. ** Description This function is called to initialize RFCOMM layer
  1435. **
  1436. ** Returns status
  1437. **
  1438. *******************************************************************************/
  1439. bt_status_t RFCOMM_Init (void)
  1440. {
  1441. #if RFC_DYNAMIC_MEMORY == TRUE
  1442. rfc_cb_ptr = (tRFC_CB *)osi_malloc(sizeof(tRFC_CB));
  1443. if (rfc_cb_ptr == NULL) {
  1444. return BT_STATUS_NOMEM;
  1445. }
  1446. #endif /* #if (RFC_DYNAMIC_MEMORY) */
  1447. memset (&rfc_cb, 0, sizeof (tRFC_CB)); /* Init RFCOMM control block */
  1448. rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
  1449. #if defined(RFCOMM_INITIAL_TRACE_LEVEL)
  1450. rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
  1451. #else
  1452. rfc_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  1453. #endif
  1454. rfcomm_l2cap_if_init ();
  1455. return BT_STATUS_SUCCESS;
  1456. }
  1457. /*******************************************************************************
  1458. **
  1459. ** Function RFCOMM_Deinit
  1460. **
  1461. ** Description This function is called to deinitialize the control block
  1462. ** for this layer.
  1463. **
  1464. ** Returns void
  1465. **
  1466. *******************************************************************************/
  1467. void RFCOMM_Deinit(void)
  1468. {
  1469. #if RFC_DYNAMIC_MEMORY == TRUE
  1470. if (rfc_cb_ptr){
  1471. osi_free(rfc_cb_ptr);
  1472. rfc_cb_ptr = NULL;
  1473. }
  1474. #endif
  1475. }
  1476. /*******************************************************************************
  1477. **
  1478. ** Function PORT_SetTraceLevel
  1479. **
  1480. ** Description This function sets the trace level for RFCOMM. If called with
  1481. ** a value of 0xFF, it simply reads the current trace level.
  1482. **
  1483. ** Returns the new (current) trace level
  1484. **
  1485. *******************************************************************************/
  1486. UINT8 PORT_SetTraceLevel (UINT8 new_level)
  1487. {
  1488. if (new_level != 0xFF) {
  1489. rfc_cb.trace_level = new_level;
  1490. }
  1491. return (rfc_cb.trace_level);
  1492. }
  1493. /*******************************************************************************
  1494. **
  1495. ** Function PORT_GetResultString
  1496. **
  1497. ** Description This function returns the human-readable string for a given
  1498. ** result code.
  1499. **
  1500. ** Returns a pointer to the human-readable string for the given result.
  1501. **
  1502. *******************************************************************************/
  1503. const char *PORT_GetResultString (const uint8_t result_code)
  1504. {
  1505. if (result_code > PORT_ERR_MAX) {
  1506. return result_code_strings[PORT_ERR_MAX];
  1507. }
  1508. return result_code_strings[result_code];
  1509. }
  1510. /*******************************************************************************
  1511. **
  1512. ** Function PORT_SetL2capErtm
  1513. **
  1514. ** Description This function sets whether RFCOMM uses L2CAP ERTM.
  1515. **
  1516. ** Returns void
  1517. **
  1518. *******************************************************************************/
  1519. void PORT_SetL2capErtm (BOOLEAN enable_l2cap_ertm)
  1520. {
  1521. rfc_cb.port.enable_l2cap_ertm = enable_l2cap_ertm;
  1522. }
  1523. #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)