BluetoothUART.Mod 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. MODULE BluetoothUART; (** AUTHOR "be"; PURPOSE "HCI UART transport layer"; *)
  2. IMPORT
  3. KernelLog, Streams, Bluetooth, Objects;
  4. (* HCI command packet format (RS-232)
  5. | 01X | opcode (2bytes) | total parameter length | par0 | ... | parN |; and opcode = OGF (6bit) || OCF (10bit)
  6. HCI ACL data packet format (RS-232)
  7. | 02X |
  8. HCI SCO data packet format (RS-232)
  9. | 03X |
  10. HCI event packet format (RS-232)
  11. | 04X | Event Code | total parameter length | par0 | ... | parN |
  12. Error message packed format (RS-232)
  13. | 05X |
  14. Negotiation packet format (RS-232)
  15. | 06X |
  16. *)
  17. CONST
  18. (*
  19. TraceSend = FALSE;
  20. TraceReceive = FALSE;
  21. *)
  22. ModuleName = "[BTUART]";
  23. uartCommand = 01X;
  24. uartACLData = 02X;
  25. uartSCOData = 03X;
  26. uartEvent = 04X;
  27. TYPE
  28. TransportLayer* = OBJECT(Bluetooth.TransportLayer)
  29. VAR
  30. TraceReceive*, TraceSend*: BOOLEAN;
  31. dead-: BOOLEAN;
  32. PROCEDURE &Init*(name: ARRAY OF CHAR; sender: Streams.Sender; receiver: Streams.Receiver);
  33. BEGIN
  34. Init^(name, sender, receiver);
  35. NEW(out, sender, 512); NEW(in, receiver, 512);
  36. dead := FALSE;
  37. TraceReceive := FALSE; TraceSend := FALSE;
  38. END Init;
  39. PROCEDURE Close*;
  40. BEGIN {EXCLUSIVE}
  41. dead := TRUE
  42. END Close;
  43. PROCEDURE IsOpen*() :BOOLEAN;
  44. BEGIN {EXCLUSIVE}
  45. RETURN ~dead;
  46. END IsOpen;
  47. PROCEDURE ReadACLPacket() : Bluetooth.Packet;
  48. VAR acl: Bluetooth.ACLPacket; i : LONGINT;
  49. BEGIN
  50. NEW(acl);
  51. i := ORD(in.Get()) + ORD(in.Get())*100H;
  52. acl.handle := i MOD 1000H;
  53. acl.PB := (i DIV 1000H) MOD 4;
  54. acl.BC := (i DIV 4000H) MOD 4;
  55. acl.len := ORD(in.Get()) + ORD(in.Get())*100H;
  56. (*ASSERT(acl.len <= Bluetooth.MaxACLDataLen);*)
  57. IF (acl.len > Bluetooth.MaxACLDataLen) THEN
  58. KernelLog.String(ModuleName);
  59. KernelLog.String("TransportLayer.ReadACLPacket: acl.len > Bluetooth.MaxACLDataLen");
  60. KernelLog.Ln;
  61. KernelLog.String("acl.len= "); KernelLog.Int(acl.len, 0);
  62. KernelLog.String("; BluetoothMaxACLDataLen= "); KernelLog.Int(Bluetooth.MaxACLDataLen, 0);
  63. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  64. KernelLog.Ln;
  65. RETURN NIL;
  66. END;
  67. FOR i := 0 TO acl.len-1 DO
  68. acl.data[i] := in.Get();
  69. END;
  70. IF (in.res # 0) THEN
  71. KernelLog.String(ModuleName);
  72. KernelLog.String("TransportLayer.ReadACLPacket: UART failure; in.res= 0x"); KernelLog.Hex(in.res, -2);
  73. KernelLog.Ln;
  74. RETURN NIL;
  75. END;
  76. IF TraceReceive THEN
  77. KernelLog.String(ModuleName);
  78. KernelLog.String("TransportLayer.ReadACLPacket: reading ACL data");
  79. KernelLog.Ln;
  80. KernelLog.String("handle= 0x");KernelLog.Hex(acl.handle,-2);
  81. KernelLog.String("; packet boundary= 0x");KernelLog.Hex(acl.PB,-2);
  82. KernelLog.String("; broadcast= 0x"); KernelLog.Hex(acl.BC,-2);
  83. KernelLog.String("; payload length= 0x"); KernelLog.Int(acl.len,0);
  84. KernelLog.String("; acl.data= ");
  85. FOR i := 0 TO acl.len-1 DO
  86. KernelLog.String(" 0x"); KernelLog.Hex(ORD(acl.data[i]),-2);
  87. END;
  88. KernelLog.Ln;
  89. END;
  90. RETURN acl;
  91. END ReadACLPacket;
  92. PROCEDURE ReadSCOPacket() : Bluetooth.Packet;
  93. VAR sco: Bluetooth.SCOPacket; i : LONGINT;
  94. BEGIN
  95. KernelLog.String(ModuleName);
  96. KernelLog.String("TransportLayer.ReadSCOPacket: uartSCOData received!! continue ....");
  97. KernelLog.Ln;
  98. NEW(sco);
  99. i := ORD(in.Get()) + ORD(in.Get())*100H;
  100. sco.handle := i MOD 1000H;
  101. sco.len := ORD(in.Get());
  102. (*ASSERT(sco.len <= Bluetooth.MaxSCODataLen);*)
  103. IF (sco.len > Bluetooth.MaxSCODataLen) THEN
  104. KernelLog.String(ModuleName);
  105. KernelLog.String("TransportLayer.ReadSCOPacket: sco.len > Bluetooth.MaxSCODataLen");
  106. KernelLog.Ln;
  107. KernelLog.String("sco.len= "); KernelLog.Int(sco.len, 0);
  108. KernelLog.String("; BluetoothMaxACLDataLen= "); KernelLog.Int(Bluetooth.MaxSCODataLen, 0);
  109. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  110. KernelLog.Ln;
  111. RETURN NIL;
  112. END;
  113. FOR i := 0 TO sco.len-1 DO
  114. sco.data[i] := in.Get();
  115. END;
  116. IF (in.res # 0) THEN
  117. KernelLog.String(ModuleName);
  118. KernelLog.String("TransportLayer.ReadSCOPacket: UART failure; in.res= 0x"); KernelLog.Hex(in.res, -2);
  119. KernelLog.Ln;
  120. RETURN NIL;
  121. END;
  122. IF TraceReceive THEN
  123. KernelLog.String(ModuleName);
  124. KernelLog.String("TransportLayer.ReadSCOPacket: reading SCO data");
  125. KernelLog.Ln;
  126. KernelLog.String("handle= 0x");KernelLog.Hex(sco.handle,-2);
  127. KernelLog.String(" payload length= 0x"); KernelLog.Int(sco.len,0);
  128. KernelLog.String("; sco.data= ");
  129. FOR i := 0 TO sco.len-1 DO
  130. KernelLog.String(" 0x"); KernelLog.Hex(ORD(sco.data[i]),-2);
  131. END;
  132. KernelLog.Ln;
  133. END;
  134. RETURN sco;
  135. END ReadSCOPacket;
  136. PROCEDURE ReadEventPacket() : Bluetooth.Packet;
  137. VAR event: Bluetooth.EventPacket; i : LONGINT;
  138. BEGIN
  139. NEW(event);
  140. event.code :=in. Get();
  141. event.paramLen := ORD(in.Get());
  142. (*ASSERT(event.paramLen < Bluetooth.MaxEventParamLen);*)
  143. IF (event.paramLen > Bluetooth.MaxEventParamLen) THEN
  144. KernelLog.String(ModuleName);
  145. KernelLog.String("TransportLayer.ReadEventPacket: paramLen > MaxParamLen");
  146. KernelLog.Ln;
  147. KernelLog.String("paramLen= "); KernelLog.Int(event.paramLen, 0);
  148. KernelLog.String("; MaxParamLen= "); KernelLog.Int(Bluetooth.MaxEventParamLen, 0);
  149. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  150. KernelLog.Ln;
  151. END;
  152. FOR i := 0 TO event.paramLen-1 DO
  153. event.params[i] := in.Get();
  154. END;
  155. IF (in.res # 0) THEN
  156. KernelLog.String(ModuleName);
  157. KernelLog.String("TransportLayer.ReadEventPacket: UART failure; in.res= 0x"); KernelLog.Hex(in.res, -2);
  158. KernelLog.Ln;
  159. RETURN NIL;
  160. END;
  161. IF TraceReceive THEN
  162. KernelLog.String(ModuleName);
  163. KernelLog.String("TransportLayer.ReadEventPacket: reading event Data");
  164. KernelLog.Ln;
  165. KernelLog.String("event.code = 0x"); KernelLog.Hex(ORD(event.code),-2);
  166. KernelLog.String("; event.paramLen= "); KernelLog.Int(event.paramLen,0);
  167. KernelLog.String("; event.params= ");
  168. FOR i := 0 TO event.paramLen-1 DO
  169. KernelLog.String(" 0x"); KernelLog.Hex(ORD(event.params[i]),-2);
  170. END;
  171. KernelLog.Ln;
  172. END;
  173. RETURN event;
  174. END ReadEventPacket;
  175. PROCEDURE ReadUnknownPacket() : Bluetooth.Packet;
  176. VAR unknown: Bluetooth.UnknownPacket; ch : CHAR;
  177. BEGIN
  178. KernelLog.String(ModuleName);
  179. KernelLog.String("TransportLayer.ReadUnknownPacket: unknown/invalid packet ch= 0x"); KernelLog.Hex(ORD(ch),-2);
  180. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  181. KernelLog.String("; in.Available()= "); KernelLog.Int(in.Available(), 0);
  182. KernelLog.Ln;
  183. NEW(unknown);
  184. unknown.len := 0;
  185. WHILE ((in.Available() > 0) & (in.res = 0)) DO
  186. IF(unknown.len < Bluetooth.MaxUnknownDataLen) THEN
  187. unknown.data[unknown.len] := in.Get();
  188. KernelLog.String("unknown.data["); KernelLog.Int(unknown.len,0); KernelLog.String("]= 0x");
  189. KernelLog.Hex(ORD(unknown.data[unknown.len]),-2);
  190. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  191. KernelLog.Ln;
  192. INC(unknown.len);
  193. ELSE
  194. ch := in.Get();
  195. KernelLog.String("discard ch= 0x"); KernelLog.Hex(ORD(ch),-2);
  196. KernelLog.String("; in.res= 0x"); KernelLog.Hex(in.res, -2);
  197. KernelLog.Ln;
  198. END;
  199. END;
  200. RETURN unknown;
  201. END ReadUnknownPacket;
  202. PROCEDURE Read;
  203. VAR
  204. ch: CHAR;
  205. queue: Bluetooth.Queue;
  206. packet: Bluetooth.Packet;
  207. BEGIN
  208. ch := in.Get();
  209. IF (in.res # 0) THEN
  210. KernelLog.String(ModuleName);
  211. KernelLog.String("TransportLayer.Read: UART failure in.res= 0x"); KernelLog.Hex(in.res, -2);
  212. KernelLog.String("; closing layer");
  213. KernelLog.Ln;
  214. Close;
  215. RETURN;
  216. END;
  217. IF (ch = uartCommand) THEN (* HCI command packet *)
  218. (*HALT(100) (* not sent by host controller *)*)
  219. KernelLog.String(ModuleName);
  220. KernelLog.String("TransportLayer.Read: uartCommand received! closing layer");
  221. KernelLog.Ln;
  222. Close;
  223. RETURN;
  224. ELSIF (ch = uartACLData) THEN (* HCI ACL data packet *)
  225. packet := ReadACLPacket();
  226. queue := sink[Bluetooth.ACL];
  227. ELSIF (ch = uartSCOData) THEN (* HCI SCO data packet *)
  228. packet := ReadSCOPacket();
  229. queue := sink[Bluetooth.SCO];
  230. ELSIF (ch = uartEvent) THEN (* HCI event packet *)
  231. packet := ReadEventPacket();
  232. queue := sink[Bluetooth.Event];
  233. ELSE (* unknown/invalid packet *)
  234. packet := ReadUnknownPacket();
  235. queue := sink[Bluetooth.Default];
  236. END;
  237. IF (packet = NIL) THEN
  238. KernelLog.String(ModuleName);
  239. KernelLog.String("TransportLayer.Read: error while reading packet; ch= "); KernelLog.Char(ch);
  240. KernelLog.String("; in.res= "); KernelLog.Int(in.res, 0);
  241. KernelLog.String("; closing layer");
  242. KernelLog.Ln;
  243. Close;
  244. RETURN;
  245. ELSE
  246. queue.Add(packet);
  247. END;
  248. IF TraceReceive THEN
  249. KernelLog.String(ModuleName);
  250. KernelLog.String("TransportLayer.Read done.");
  251. KernelLog.String(" in.Available()= "); KernelLog.Int(in.Available(), 0);
  252. KernelLog.Ln;
  253. END;
  254. END Read;
  255. PROCEDURE GetPacketType(type: LONGINT; VAR c: CHAR): BOOLEAN;
  256. VAR res: BOOLEAN;
  257. BEGIN
  258. res := TRUE;
  259. CASE type OF
  260. | Bluetooth.Command: c := uartCommand
  261. | Bluetooth.ACL: c := uartACLData
  262. | Bluetooth.SCO: c := uartSCOData
  263. ELSE res := FALSE
  264. END;
  265. RETURN res
  266. END GetPacketType;
  267. PROCEDURE Send*(type: LONGINT; VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR res: WORD);
  268. VAR pt: CHAR; i: LONGINT;
  269. BEGIN {EXCLUSIVE}
  270. IF ~GetPacketType(type, pt) THEN
  271. KernelLog.String(ModuleName);
  272. KernelLog.String("TransportLayer.Send: wrong packet type= 0x"); KernelLog.Hex(type,-2);
  273. KernelLog.Ln;
  274. res := Bluetooth.ErrInvalidParameters;
  275. RETURN
  276. END;
  277. IF TraceSend THEN
  278. KernelLog.String(ModuleName);
  279. KernelLog.String("TransportLayer.Send: packet type= 0x"); KernelLog.Hex(ORD(pt), -2);
  280. FOR i := 0 TO len-1 DO
  281. KernelLog.Char(" ");
  282. KernelLog.Hex(ORD(data[ofs+i]), -2);
  283. END;
  284. KernelLog.Ln
  285. END;
  286. out.Char(pt); out.Bytes(data, ofs, len); out.Update;
  287. res := out.res
  288. END Send;
  289. PROCEDURE Send1H*(type: LONGINT; VAR hdr: ARRAY OF CHAR; hdrlen: LONGINT; VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR res: WORD);
  290. VAR pt: CHAR; i: LONGINT;
  291. BEGIN
  292. IF ~GetPacketType(type, pt) THEN
  293. KernelLog.String(ModuleName);
  294. KernelLog.String("TransportLayer.Send1H: wrong packet type= 0x"); KernelLog.Hex(type,-2);
  295. KernelLog.Ln;
  296. res := Bluetooth.ErrInvalidParameters;
  297. RETURN
  298. END;
  299. IF TraceSend THEN
  300. KernelLog.String(ModuleName);
  301. KernelLog.String("TransportLayer.Send1H: packet type= 0x"); KernelLog.Hex(ORD(pt), -2);
  302. FOR i := 0 TO hdrlen-1 DO
  303. KernelLog.Char(" "); KernelLog.Hex(ORD(hdr[i]), -2);
  304. END;
  305. FOR i := 0 TO len-1 DO
  306. KernelLog.Char(" "); KernelLog.Hex(ORD(data[ofs+i]), -2);
  307. END;
  308. KernelLog.Ln
  309. END;
  310. out.Char(pt); out.Bytes(hdr, 0, hdrlen); out.Bytes(data, ofs, len); out.Update;
  311. res := out.res
  312. END Send1H;
  313. PROCEDURE Send2H*(type: LONGINT; VAR hdr1: ARRAY OF CHAR; hdr1len: LONGINT;
  314. VAR hdr2: ARRAY OF CHAR; hdr2len: LONGINT;
  315. VAR data: ARRAY OF CHAR; ofs, len: LONGINT; VAR res: WORD);
  316. VAR pt: CHAR; i: LONGINT;
  317. BEGIN
  318. IF ~GetPacketType(type, pt) THEN
  319. KernelLog.String(ModuleName);
  320. KernelLog.String("TransportLayer.Send2H: wrong packet type= 0x"); KernelLog.Hex(type,-2);
  321. KernelLog.Ln;
  322. res := Bluetooth.ErrInvalidParameters;
  323. RETURN
  324. END;
  325. IF TraceSend THEN
  326. KernelLog.String(ModuleName);
  327. KernelLog.String("TransportLayer.Send2H: packet type= 0x"); KernelLog.Hex(ORD(pt), -2);
  328. FOR i := 0 TO hdr1len-1 DO
  329. KernelLog.Char(" "); KernelLog.Hex(ORD(hdr1[i]), -2);
  330. END;
  331. FOR i := 0 TO hdr2len-1 DO
  332. KernelLog.Char(" "); KernelLog.Hex(ORD(hdr2[ofs+i]), -2);
  333. END;
  334. FOR i := 0 TO len-1 DO
  335. KernelLog.Char(" "); KernelLog.Hex(ORD(data[ofs+i]), -2);
  336. END;
  337. KernelLog.Ln
  338. END;
  339. out.Char(pt); out.Bytes(hdr1, 0, hdr1len); out.Bytes(hdr2, 0, hdr2len); out.Bytes(data, ofs, len); out.Update;
  340. res := out.res
  341. END Send2H;
  342. BEGIN {ACTIVE}
  343. Objects.SetPriority(3);
  344. REPEAT
  345. Read;
  346. UNTIL dead
  347. END TransportLayer;
  348. END BluetoothUART.