12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202 |
- MODULE BluetoothHCI; (** AUTHOR "be"; PURPOSE "Bluetooth HCI driver"; *)
- IMPORT KernelLog, Bluetooth;
- CONST
- Trace = FALSE;
- TraceReceive = FALSE;
- TraceSend = FALSE;
- ModuleName = "[BTHCI]";
- TraceHCI = FALSE;
- TraceLink = FALSE;
- (* Timeouts (in ms) *)
- Timeout = 1000;
- ConnectionTimeout = 10000;
- (**--- HCI Command Packets OGF and OCF ---*)
- (** Link Control Commands *)
- ogfLinkControl* = 01H; (** OGF, OCFs follow *)
- ocfInquiry* = 0001H;
- ocfInquiryCancel* = 0002H;
- ocfPeriodicInquiryMode* = 0003H;
- ocfExitPeriodicInquiryMode* = 0004H;
- ocfCreateConnection* = 0005H;
- ocfDisconnect* = 0006H;
- ocfAddSCOConnection* = 0007H;
- ocfAcceptConnectionRequest* = 0009H;
- ocfRejectConnectionRequest* = 000AH;
- ocfLinkKeyRequestReply* = 000BH;
- ocfLinkKeyRequestNegativeReply* = 000CH;
- ocfPINCodeRequestReply* = 000DH;
- ocfPINCodeRequestNegativeReply* = 000EH;
- ocfChangeConnectionPacketType* = 000FH;
- ocfAuthenticationRequested* = 0011H;
- ocfSetConnectionEncryption* = 0013H;
- ocfChangeConnectionLinkKey* = 0015H;
- ocfMasterLinkKey* = 0017H;
- ocfRemoteNameRequest* = 0019H;
- ocfReadRemoteSupportedFeatures* = 001BH;
- ocfReadRemoteVersionInformation* = 001DH;
- ocfReadClockOffset* = 001FH;
- (** Link Policy Commands *)
- ogfLinkPolicy* = 02H; (** OGF, OCFs follow *)
- ocfHoldMode* = 0001H;
- ocfSniffMode* = 0003H;
- ocfExitSniffMode* = 0004H;
- ocfParkMode* = 0005H;
- ocfExitParkMode* = 0006H;
- ocfQoSSetup* = 0007H;
- ocfRoleDiscovery* = 0009H;
- ocfSwitchRole* = 000BH;
- ocfReadLinkPolicySettings* = 000CH;
- ocfWriteLinkPolicySettings* = 000DH;
- (** Host Controller & Baseband Commands *)
- ogfControl* = 03H; (** OGF, OCFs follow *)
- ocfSetEventMask* = 0001H;
- ocfReset* = 0003H;
- ocfSetEventFilter* = 0005H;
- ocfFlush* = 0008H;
- ocfReadPINType* = 0009H;
- ocfWritePINType* = 000AH;
- ocfCreateNewUnitKey* = 000BH;
- ocfReadStoredLinkKey* = 000DH;
- ocfWriteStoredLinkKey* = 0011H;
- ocfDeleteStoredLinkKey* = 0012H;
- ocfChangeLocalName* = 0013H;
- ocfReadLocalName* = 0014H;
- ocfReadConnectionAcceptTimeout* = 0015H;
- ocfWriteConnectionAcceptTimeout* = 0016H;
- ocfReadPageTimeout* = 0017H;
- ocfWritePageTimeout* = 0018H;
- ocfReadScanEnable* = 0019H;
- ocfWriteScanEnable* = 001AH;
- ocfReadPageScanActivity* = 001BH;
- ocfWritePageScanActivity* = 001CH;
- ocfReadInquiryScanActivity* = 001DH;
- ocfWriteInquiryScanActivity* = 001EH;
- ocfReadAuthenticationEnable* = 001FH;
- ocfWriteAuthenticationEnable* = 0020H;
- ocfReadEncryptionMode* = 0021H;
- ocfWriteEncryptionMode* = 0022H;
- ocfReadClassOfDevice* = 0023H;
- ocfWriteClassOfDevice* = 0024H;
- ocfReadVoiceSetting* = 0025H;
- ocfWriteVoiceSetting* = 0026H;
- ocfReadAutomaticFlushTimeout* = 0027H;
- ocfWriteAutomaticFlushTimeout* = 0028H;
- ocfReadNumBroadcastRetrans* = 0029H;
- ocfWriteNumBroadcastRetrans* = 002AH;
- ocfReadHoldModeActivity* = 002BH;
- ocfWriteHoldModeActivity* = 002CH;
- ocfReadTransmitPowerLevel* = 002DH;
- ocfReadSCOFlowControlEnable* = 002EH;
- ocfWriteSCOFlowControlEnable* = 002FH;
- ocfSetHostCtrlToHostFlowCtrl* = 0031H;
- ocfHostBufferSize* = 0033H;
- ocfHostNumberOfCompletedPackets* = 0035H;
- ocfReadLinkSupervisionTimeout* = 0036H;
- ocfWriteLinkSupervisionTimeout* = 0037H;
- ocfReadNumberOfSupportedIAC* = 0038H;
- ocfReadCurrentIACLAP* = 0039H;
- ocfWriteCurrentIACLAP* = 003AH;
- ocfReadPageScanPeriodMode* = 003BH;
- ocfWritePageScanPeriodMode* = 003CH;
- ocfReadPageScanMode* = 003DH;
- ocfWritePageScanMode* = 003EH;
- (** Informational Parameters *)
- ogfInformational* = 04H; (** OGF, OCFs follow *)
- ocfReadLocalVersionInformation* = 0001H;
- ocfReadLocalSupportedFeatures* = 0003H;
- ocfReadBufferSize* = 0005H;
- ocfReadCountryCode* = 0007H;
- ocfReadBDAddr* = 0009H;
- (** Status Parameters *)
- ogfStatus* = 05H; (** OGF, OCFs follow *)
- ocfReadFailedContactCounter* = 0001H;
- ocfResetFailedContactCounter* = 0002H;
- ocfGetLinkQuality* = 0003H;
- ocfHCIReadRSSI* = 0005H;
- (** Ericsson Parameters *)
- ogfEricsson* = 03FH;
- ocfSetUARTBaudRate* = 0009H;
- (**--- ACL flags (see spec chapter 4.4.3) ---*)
- (** Packet Boundary Flag (PBF) *)
- pbfFirst* = 2; (** first packet of higher layer message *)
- pbfContinuing* = 1; (** continuing fragment packet of higher layer message *)
- (** Broadcast Flag (BF) *)
- bfPointToPoint* = 0; (** point to point *)
- bfActive* = 1; (** active broadcast *)
- bfPiconet* = 2; (** piconet broadcast *)
- (** HCI Events *)
- EInquiryComplete* = 01X; (** params: Status *)
- EInquiryResult* = 02X; (** params: see spec chapter 5.2.2, p. 728 *)
- EConnectionComplete* = 03X; (** params: Status, Connection_Handle (2 bytes), BD_Addr (6 bytes), Link_Type, Encryption_Mode *)
- EDisconnectionComplete* = 05X; (** params: Status, Connection_Handle (2 bytes), Reason *)
- EReadRemoteVersionInfoComplete* = 0CX;
- ECmdComplete* = 0EX; (** params: Num_HCI_Commands, Command_Opcode (2 bytes), Return_Parameters *)
- ECmdStatus* = 0FX; (** params: Status, Num_HCI_Commands, Command-Opcode (2 bytes) *)
- ENofCompletedPackets* = 13X;
- EMaxSlotsChange* = 1BX;
- EPageScanRepModeChange* = 20X;
- CONST
- (** WriteScanEnable *)
- SENoScan* = 00X;
- SEInquiry* = 01X;
- SEPage* = 02X;
- SEInquiryPage* = 03X;
- (** SetEventFilter *)
- (** filter types *)
- EFClear* = 00X;
- EFInquiryResult* = 01X;
- EFConnectionSetup* = 02X;
- (** connection types for EFInquiryResult *)
- EFIRNewDevice* = 00X; (** requires no condition *)
- EFIRClass* = 01X; (** requires 'class of device' (3 bytes) and 'class of device mask' (3 bytes) *)
- EFIRAddr* = 02X; (** requires 'bd_addr' (6 bytes) *)
- (** connection types for EFConnectionSetup *)
- EFCSAll* = 00X; (** requires 'auto accept flag' (1 byte) *)
- EFCSClass* = 01X; (** requires 'class of device' (3 bytes), 'class of device mask' (3 bytes) and 'auto accept flag' (1 byte) *)
- EFCSAddr* = 02X; (** requires 'bd_addr' (6 bytes) and 'auto accept flag' (1 byte) *)
- (** 'auto accept flag' for EFConnectionSetup *)
- EFCSAAOff* = 01X; (** auto accept is off *)
- EFCSAAOn* = 02X; (** auto accept is on, role switch is off *)
- EFCSAAOnRoleSwitch* = 03X; (** auto accept is on, role switch is on *)
- CONST
- (** link states *)
- lsUp* = 0;
- lsDown* = 1;
- TYPE
- Link* = OBJECT (** HCI link *)
- VAR
- next: Link;
- hci : HCI;
- state*: LONGINT; (** link state *)
- remote*: Bluetooth.BDAddr; (** remote device *)
- handle-: LONGINT; (** connection handle *)
- type*: LONGINT; (** connection type *)
- encryption*: LONGINT; (** encryption mode *)
- reason*: LONGINT; (** error code (depends on state) *)
- nofPackets-: LONGINT; (** number of completed (transmitted or flushed) packets *)
- OnReceiveACLData*: ReceiveACLDataEvent;
- PROCEDURE &Init*(hci : HCI; remote: Bluetooth.BDAddr; handle: LONGINT);
- BEGIN
- ASSERT((0000H <= handle) & (handle <= 0EFFH));
- SELF.hci := hci; SELF.remote := remote; SELF.handle := handle;
- IF TraceLink THEN
- KernelLog.String(ModuleName);
- KernelLog.String("Link.Init: handle = "); KernelLog.Int(handle,0);
- KernelLog.Ln;
- END;
- END Init;
- (** send ACL data.
- PBF: packet boundary flag
- BF: broadcast flag
- *)
- PROCEDURE SendACL*(PBF, BF: LONGINT; VAR data: ARRAY OF CHAR; ofs, len: LONGINT): WORD;
- VAR v: LONGINT; res: WORD; aclhdr: ARRAY 4 OF CHAR;
- BEGIN
- ASSERT((pbfContinuing <= PBF) & (PBF <= pbfFirst));
- ASSERT((bfPointToPoint <= BF) & (BF <= bfPiconet));
- ASSERT((0 < len) & (len < 10000H));
- v := handle + PBF*1000H + BF*4000H;
- aclhdr[0] := CHR(v MOD 100H); aclhdr[1] := CHR(v DIV 100H);
- aclhdr[2] := CHR(len MOD 100H); aclhdr[3] := CHR(len DIV 100H);
- hci.tl.Send1H(Bluetooth.ACL, aclhdr, 4, data, ofs, len, res);
- IF TraceLink THEN
- KernelLog.String(ModuleName);
- KernelLog.String("Link.SendACL: handle = "); KernelLog.Int(handle,0);
- KernelLog.Ln;
- END;
- RETURN res
- END SendACL;
- PROCEDURE SendACLH*(PBF, BF: LONGINT; VAR hdr: ARRAY OF CHAR; hdrlen: LONGINT; VAR data: ARRAY OF CHAR; ofs, len: LONGINT): WORD;
- VAR v, totlen: LONGINT; res: WORD; aclhdr: ARRAY 4 OF CHAR;
- BEGIN
- totlen := len + hdrlen;
- ASSERT((pbfContinuing <= PBF) & (PBF <= pbfFirst));
- ASSERT((bfPointToPoint <= BF) & (BF <= bfPiconet));
- ASSERT((0 < totlen) & (totlen < 10000H));
- v := handle + PBF*1000H + BF*4000H;
- aclhdr[0] := CHR(v MOD 100H); aclhdr[1] := CHR(v DIV 100H);
- aclhdr[2] := CHR(totlen MOD 100H); aclhdr[3] := CHR(totlen DIV 100H);
- hci.tl.Send2H(Bluetooth.ACL, aclhdr, 4, hdr, hdrlen, data, ofs, len, res);
- IF TraceLink THEN
- KernelLog.String(ModuleName);
- KernelLog.String("Link.SendACLH: handle = "); KernelLog.Int(handle,0);
- KernelLog.Ln;
- END;
- RETURN res
- END SendACLH;
- PROCEDURE ACLDataReceived(acl: Bluetooth.ACLPacket);
- BEGIN
- IF TraceLink THEN
- KernelLog.String(ModuleName);
- KernelLog.String("Link.ACLDataReceived: handle = "); KernelLog.Int(handle,0);
- KernelLog.Ln;
- END;
- IF (OnReceiveACLData # NIL) THEN OnReceiveACLData(SELF, acl) END
- END ACLDataReceived;
- END Link;
- (* stupid Paco does not allow this definition before 'Link' *)
- ReceiveACLDataEvent* = PROCEDURE {DELEGATE} (sender: Link; acl: Bluetooth.ACLPacket);
- LinkEnumPar = POINTER TO RECORD
- handle: LONGINT;
- remote: Bluetooth.BDAddr;
- link: Link
- END;
- LinkEnumerator* = PROCEDURE {DELEGATE} (l: Link; par: ANY): BOOLEAN; (** return TRUE if the enumeration should be continued *)
- LinkManager = OBJECT
- VAR
- links: Link;
- numLinks: LONGINT;
- PROCEDURE &Init*;
- BEGIN
- NEW(links, NIL,"", 0); (* dummy head *)
- links.handle := -1;
- numLinks := 0
- END Init;
- PROCEDURE Reset;
- BEGIN
- links.next := NIL;
- numLinks := 0
- END Reset;
- PROCEDURE AddLink*(l: Link);
- BEGIN {EXCLUSIVE}
- l.next := links.next; links.next := l; INC(numLinks)
- END AddLink;
- PROCEDURE RemoveLink*(l: Link);
- VAR p,q: Link;
- BEGIN {EXCLUSIVE}
- p := links.next; q := links;
- WHILE (p # NIL) & (p # l) DO q := p; p := p.next END;
- IF (p # NIL) THEN q.next := p.next; DEC(numLinks) END
- END RemoveLink;
- PROCEDURE FindLink*(handle: LONGINT): Link;
- VAR l: Link;
- BEGIN {EXCLUSIVE}
- l := links.next;
- WHILE (l # NIL) & (l.handle # handle) DO l := l.next END;
- RETURN l
- END FindLink;
- PROCEDURE Enumerate(callback: LinkEnumerator; par: ANY);
- VAR l: Link; la: POINTER TO ARRAY OF Link; i: LONGINT;
- BEGIN
- NEW(la, numLinks);
- BEGIN {EXCLUSIVE}
- l := links.next;
- FOR i := 0 TO numLinks-1 DO la[i] := l; l := l.next END
- END;
- i := 0;
- WHILE (i < numLinks) & (callback(la[i], par)) DO
- INC(i)
- END
- END Enumerate;
- END LinkManager;
- HCI* = OBJECT
- VAR
- tl: Bluetooth.TransportLayer;
- aclQueue, eventQueue-: Bluetooth.Queue;
- linkManager*: LinkManager;
- (** info *)
- bdAddr-: Bluetooth.BDAddr; (* device address *)
- aclMTU-, scoMTU-, aclNumPackets-, scoNumPackets-: LONGINT; (* MTUs and max. # of packets for ACL/SCO connections *)
- (** events *)
- OnConnectionComplete* : ConnectionComplete;
- OnDisconnectionComplete* : DisconnectionComplete;
- OnInquiryComplete* : InquiryComplete;
- OnConnect*: ConnectionEvent;
- OnDisconnect*: ConnectionEvent;
- OnInquiry*: InquiryEvent;
- OnEvent*: GeneralEvent;
- OnError*: ErrorEvent;
- PROCEDURE &Init*(transportLayer: Bluetooth.TransportLayer);
- VAR q: Bluetooth.Queue;
- BEGIN
- tl := transportLayer;
- NEW(linkManager);
- NEW(eventQueue); tl.SetSink(Bluetooth.Event, eventQueue);
- eventQueue.RegisterPacketFilter(EricssonFilter, EricssonHandler);
- eventQueue.RegisterPacketFilter(EventFilter, EventHandler);
- NEW(aclQueue); tl.SetSink(Bluetooth.ACL, aclQueue);
- aclQueue.RegisterPacketFilter(ACLFilter, ACLHandler);
- q := tl.GetSink(Bluetooth.Default);
- q.RegisterPacketFilter(ErrorFilter, ErrorHandler);
- END Init;
- PROCEDURE Close*;
- BEGIN {EXCLUSIVE}
- IF TraceHCI THEN
- KernelLog.String(ModuleName); KernelLog.String("HCI.Close: ...");
- KernelLog.Ln;
- END;
- tl.Close;
- eventQueue.Close; aclQueue.Close;
- IF TraceHCI THEN
- KernelLog.String(ModuleName); KernelLog.String("HCI.Close: done.");
- KernelLog.Ln;
- END;
- END Close;
- (** initialize the module, get BDADDR, MTUs, etc *)
- PROCEDURE Initialize*(): WORD;
- VAR res: WORD;
- BEGIN
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Initialize: ...");
- KernelLog.Ln;
- END;
- res := Reset();
- IF (res # 0) THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Initialize: Reset failed. res = 0x"); KernelLog.Hex(res,-2);
- KernelLog.Ln;
- RETURN res
- END;
- res := ReadBDAddr(bdAddr);
- IF (res # 0) THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Initialize: ReadBDaddr failed. res = 0x"); KernelLog.Hex(res,-2);
- KernelLog.Ln;
- RETURN res
- END;
- res := ReadBufferSize(aclMTU, scoMTU, aclNumPackets, scoNumPackets);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Initialize: done. ReadBufferSize res = "); KernelLog.Int(res,0);
- KernelLog.Ln;
- END;
- RETURN res;
- END Initialize;
- (** enumerate all active links. par is passed back to the callback procedure *)
- PROCEDURE EnumerateLinks*(enumCallback: LinkEnumerator; par: ANY);
- BEGIN
- linkManager.Enumerate(enumCallback, par)
- END EnumerateLinks;
- (** find a link. If 'handle'=-1, the first link to 'remote' is returned *)
- PROCEDURE FindLinkCallback(l: Link; par: ANY): BOOLEAN;
- BEGIN
- WITH par: LinkEnumPar DO
- IF (par.handle # -1) THEN
- IF (par.handle = l.handle) THEN par.link := l END
- ELSE
- IF (par.remote = l.remote) THEN par.link := l END
- END;
- RETURN par.link = NIL
- END
- END FindLinkCallback;
- PROCEDURE FindLink*(handle: LONGINT; remote: Bluetooth.BDAddr): Link;
- VAR lep: LinkEnumPar;
- BEGIN
- NEW(lep); lep.handle := handle; lep.remote := remote; lep.link := NIL;
- linkManager.Enumerate(FindLinkCallback, lep);
- RETURN lep.link
- END FindLink;
- (** send a HCI command. Return values:
- res: result code
- pending: TRUE if the command is pending
- packet: reply packet from BT host (may be NIL)
- *)
- PROCEDURE SendCommand*(OGF, OCF: LONGINT; params: ARRAY OF CHAR; len: LONGINT;
- VAR packet: Bluetooth.EventPacket;
- VAR pending: BOOLEAN;
- VAR res: WORD);
- BEGIN {EXCLUSIVE}
- InSendCommand(OGF, OCF, params, len, packet, pending, res)
- END SendCommand;
- PROCEDURE InSendCommand(OGF, OCF: LONGINT; params: ARRAY OF CHAR; len: LONGINT;
- VAR packet: Bluetooth.EventPacket;
- VAR pending: BOOLEAN;
- VAR res: WORD);
- VAR
- cmd: POINTER TO ARRAY OF CHAR; i: LONGINT;
- BEGIN (* EXCLUSIVE *)
- NEW(cmd,3+len);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: OGF= 0x"); KernelLog.Hex(OGF,-2);
- KernelLog.String(" OCF= 0x"); KernelLog.Hex(OCF,-2);
- KernelLog.String(" params= ");
- FOR i := 0 TO len-1 DO
- KernelLog.String("0x"); KernelLog.Hex(ORD(params[i]), -2);
- END;
- KernelLog.String(" ..."); KernelLog.Ln;
- END;
- pending := FALSE;
- ComposeCommandHeader(OGF, OCF, len, cmd^);
- FOR i := 0 TO len-1 DO cmd[3+i] := params[i] END;
- tl.Send(Bluetooth.Command, cmd^, 0, 3+len, res);
- IF (res = 0) THEN
- GetEvent(Timeout,packet,res);
- IF (res = 0) THEN
- IF (packet.code = ECmdComplete) & (packet.paramLen >= 3) &
- (packet.params[1] = cmd[0]) & (packet.params[2] = cmd[1]) THEN
- (* in BT V1.1 all commands that return a command complete event have 'status' (0 = ok)
- as the first parameter. *)
- res := ORD(packet.params[3]);
- (* hack... *)
- IF (OGF = ogfControl) & (OCF = ocfReset) & (res = 0) THEN
- linkManager.Reset
- END;
- ELSIF (packet.code = ECmdStatus) & (packet.paramLen >= 3) &
- (packet.params[2] = cmd[0]) & (packet.params[3] = cmd[1]) THEN
- res := ORD(packet.params[0]);
- pending := TRUE;
- ELSE
- res := Bluetooth.ErrInvalidEvent;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: invalid event received:"); KernelLog.Ln;
- KernelLog.String(" event code: "); KernelLog.Hex(ORD(packet.code), -2); KernelLog.Ln;
- KernelLog.String(" parameters: ");
- FOR i := 0 TO packet.paramLen-1 DO
- KernelLog.Hex(ORD(packet.params[i]), -2); KernelLog.Char(" ")
- END;
- KernelLog.Ln;
- END;
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: event received. event code = 0x"); KernelLog.Hex(ORD(packet.code), -2);
- KernelLog.String(" result = 0x"); KernelLog.Hex(res,-2);
- KernelLog.String(" pending = "); IF pending THEN KernelLog.String("TRUE"); ELSE KernelLog.String("FALSE"); END;
- KernelLog.Ln;
- END;
- ELSE
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: GetEvent failed. res = 0x"); KernelLog.Hex(res,-2);
- KernelLog.Ln;
- END;
- ELSE
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: tl.Send failed. res = 0x"); KernelLog.Hex(res,-2);
- KernelLog.Ln;
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.InSendCommand: done.");
- KernelLog.Ln;
- END;
- END InSendCommand;
- PROCEDURE GetEvent*(timeout: LONGINT; VAR event: Bluetooth.EventPacket; VAR res: WORD);
- VAR p: Bluetooth.Packet;
- BEGIN
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.GetEvent: ...");
- KernelLog.Ln;
- END;
- eventQueue.Get(p, timeout, res);
- IF (res = 0) THEN
- IF (p IS Bluetooth.EventPacket) THEN
- event := p(Bluetooth.EventPacket);
- ELSE
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.GetEvent: wrong packet received");
- KernelLog.Ln;
- END;
- res := Bluetooth.ErrInvalidPacket;
- END
- ELSE
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.GetEvent: eventQueue.Get failed. res = 0x"); KernelLog.Hex(res,-2);
- KernelLog.Ln;
- END;
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.GetEvent: done.");
- KernelLog.Ln;
- END;
- END GetEvent;
- (**--- often used HCI commands ---*)
- (* ------- link controller commands -------- *)
- PROCEDURE Inquiry*(lap : LONGINT;inquiryLength : LONGINT; numResponses : LONGINT) : WORD;
- VAR
- par: ARRAY 5 OF CHAR;
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- res: WORD;
- BEGIN
- par[0] := CHR(lap MOD 100H);
- par[1] := CHR((lap DIV 100H) MOD 100H);
- par[2] := CHR(lap DIV 10000H);
- par[3] := CHR(inquiryLength);
- par[4] := CHR(numResponses);
- InSendCommand(ogfLinkControl,ocfInquiry,par,5,event,pending,res);
- RETURN res;
- END Inquiry;
- PROCEDURE CreateConnection*(bdAddr: Bluetooth.BDAddr; clkofs: LONGINT): WORD;
- (* TODO: parameters!!! *)
- VAR
- par: ARRAY 13 OF CHAR;
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- i: LONGINT; res: WORD;
- BEGIN
- FOR i := 0 TO Bluetooth.BDAddrLen-1 DO par[i] := bdAddr[i] END;
- par[6] := 08X; par[7] := 00X; (* packet type: DM1 only *)
- par[8] := 00X; (* page scan repetition mode: R0 *)
- par[9] := 00X; (* page scan mode: mandatory page scan mode *)
- par[10] := CHR(clkofs MOD 100H); par[11] := CHR(clkofs DIV 100H MOD 100H); (* clock offset *)
- par[12] := 00X; (* allow role switch: local device master, no role switch *)
- InSendCommand(ogfLinkControl, ocfCreateConnection, par, 13, event, pending, res);
- RETURN res
- END CreateConnection;
- PROCEDURE Disconnect*(linkHandle,reason : LONGINT) : WORD;
- VAR
- par: ARRAY 3 OF CHAR;
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- res: WORD;
- BEGIN
- par[0] := CHR(linkHandle MOD 100H);
- par[1] := CHR(linkHandle DIV 100H);
- par[2] := CHR(reason);
- InSendCommand(ogfLinkControl,ocfDisconnect,par,3,event,pending, res);
- RETURN res;
- END Disconnect;
- (* ------- host controller & bas band commands -------- *)
- PROCEDURE SetEventMask*(eventMask : LONGINT) : WORD;
- VAR
- par : ARRAY 8 OF CHAR;
- res: WORD;
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- BEGIN
- (* TO DO *)
- par[0] := CHR(eventMask MOD 100H); eventMask := eventMask DIV 100H;
- par[1] := CHR(eventMask MOD 100H); eventMask := eventMask DIV 100H;
- par[2] := CHR(eventMask MOD 100H); eventMask := eventMask DIV 100H;
- par[3] := CHR(eventMask);
- InSendCommand(ogfControl, ocfSetEventMask, par, 8, event, pending, res);
- RETURN res;
- END SetEventMask;
- PROCEDURE Reset*(): WORD;
- VAR
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res: WORD;
- BEGIN
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Reset: ..."); KernelLog.Ln;
- END;
- eventQueue.Clear;
- InSendCommand(ogfControl, ocfReset, "", 0, event, pending, res);
- IF pending & (res = 0) THEN res := Bluetooth.Error END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.Reset: done. res = "); KernelLog.Int(res,0); KernelLog.Ln;
- END;
- RETURN res
- END Reset;
- PROCEDURE SetEventFilter*(type, conditionType: CHAR; condition: ARRAY OF CHAR): WORD;
- VAR
- par: ARRAY 9 OF CHAR;
- i, len: LONGINT; res: WORD;
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- BEGIN
- res := Bluetooth.ErrInvalidParameters;
- CASE type OF
- | EFClear: len := 1
- | EFInquiryResult:
- CASE conditionType OF
- | EFIRNewDevice: len := 2
- | EFIRClass: len := 8
- | EFIRAddr: len := 8
- ELSE RETURN res
- END
- | EFConnectionSetup:
- CASE conditionType OF
- | EFCSAll: len := 3
- | EFCSClass: len := 9
- | EFCSAddr: len := 9
- ELSE RETURN res
- END
- ELSE RETURN res
- END;
- par[0] := type;
- par[1] := conditionType;
- FOR i := 0 TO len-3 DO par[2+i] := condition[i] END;
- InSendCommand(ogfControl, ocfSetEventFilter, par, len, event, pending, res);
- IF pending & (res = 0) THEN res := Bluetooth.Error END;
- RETURN res
- END SetEventFilter;
- PROCEDURE WriteScanEnable*(mode: CHAR): WORD;
- VAR
- par: ARRAY 1 OF CHAR;
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res: WORD;
- BEGIN
- par[0] := mode;
- InSendCommand(ogfControl, ocfWriteScanEnable, par, 1, event, pending, res);
- IF pending & (res = 0) THEN res := Bluetooth.Error END;
- RETURN res
- END WriteScanEnable;
- PROCEDURE ReadScanEnable*(VAR scanEnable : CHAR) : WORD;
- VAR
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res : WORD;
- BEGIN
- InSendCommand(ogfControl,ocfReadScanEnable,"",0,event,pending,res);
- scanEnable := event.params[4];
- IF pending & (res = 0) THEN res := Bluetooth.Error END;
- RETURN res;
- END ReadScanEnable;
- PROCEDURE WriteLinkSupervisionTimeout*(inHandle, linkTimeout : LONGINT) : WORD;
- VAR
- par: ARRAY 4 OF CHAR;
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res : WORD;
- outHandle : LONGINT;
- BEGIN
- par[0] := CHR(inHandle MOD 100H);
- par[1] := CHR(inHandle DIV 100H);
- par[2] := CHR(linkTimeout MOD 100H);
- par[3] := CHR(linkTimeout DIV 100H);
- InSendCommand(ogfControl,ocfWriteLinkSupervisionTimeout,par,4,event,pending,res);
- IF pending THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.WriteLinkSupervisonTimout: pending! - res = "); KernelLog.Int(res,0);
- KernelLog.Ln;
- res := Bluetooth.ErrInvalidEvent;
- ELSIF (res = 0) THEN
- outHandle := (ORD(event.params[4]) + ORD(event.params[5]) * 100H) MOD 1000H;
- IF(outHandle # inHandle) THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.WriteLinkSupervisonTimout: error ?! - outHandle = "); KernelLog.Int(outHandle,0);
- KernelLog.String("; inHandle = "); KernelLog.Int(inHandle,0);
- KernelLog.Ln;
- END;
- END;
- RETURN res;
- END WriteLinkSupervisionTimeout;
- PROCEDURE ReadLinkSupervisionTimeout*(inHandle : LONGINT; VAR linkTimeout : LONGINT) : WORD;
- VAR
- par: ARRAY 2 OF CHAR;
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res : WORD;
- outHandle : LONGINT;
- BEGIN
- par[0] := CHR(inHandle MOD 100H);
- par[1] := CHR(inHandle DIV 100H);
- InSendCommand(ogfControl,ocfReadLinkSupervisionTimeout,par,2,event,pending,res);
- IF pending THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ReadLinkSupervisonTimout: pending! - res = "); KernelLog.Int(res,0);
- KernelLog.Ln;
- res := Bluetooth.ErrInvalidEvent;
- ELSIF (res = 0) THEN
- outHandle := (ORD(event.params[4]) + ORD(event.params[5]) * 100H) MOD 1000H;
- IF(outHandle # inHandle) THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ReadLinkSupervisonTimout: error ?! - outHandle = "); KernelLog.Int(outHandle,0);
- KernelLog.String("; inHandle = "); KernelLog.Int(inHandle,0);
- KernelLog.Ln;
- ELSE
- linkTimeout := ORD(event.params[6]) + ORD(event.params[7]) * 100H;
- END;
- END;
- RETURN res;
- END ReadLinkSupervisionTimeout;
- (* ------- Erricsson paramters -------- *)
- PROCEDURE EricssonSetUARTBaudRate*(baudRate : CHAR):WORD;
- VAR
- par: ARRAY 1 OF CHAR;
- pending: BOOLEAN;
- event: Bluetooth.EventPacket;
- res : WORD;
- BEGIN
- par[0] := baudRate;
- InSendCommand(ogfEricsson,ocfSetUARTBaudRate,par,LEN(par),event,pending,res);
- IF pending THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EricssonSetUARTBaudRate: pending! - res = "); KernelLog.Int(res,0);
- KernelLog.Ln;
- END;
- IF pending & (res = 0) THEN res := Bluetooth.Error END;
- RETURN res;
- END EricssonSetUARTBaudRate;
- (* ------- Informational paramters -------- *)
- PROCEDURE ReadBDAddr*(VAR bdAddr: Bluetooth.BDAddr): WORD;
- VAR
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- res: WORD; i: LONGINT;
- BEGIN
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ReadBDAddr: ...");
- KernelLog.Ln;
- END;
- InSendCommand(ogfInformational, ocfReadBDAddr, "", 0, event, pending, res);
- IF pending THEN res := Bluetooth.ErrInvalidEvent
- ELSIF (res = 0) THEN
- FOR i := 0 TO Bluetooth.BDAddrLen-1 DO bdAddr[i] := event.params[4+i] END;
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ReadBDAddr: done. res = "); KernelLog.Int(res,0);
- KernelLog.Ln;
- END;
- RETURN res
- END ReadBDAddr;
- PROCEDURE ReadBufferSize*(VAR aclMaxLen, scoMaxLen, aclNumPackets, scoNumPackets: LONGINT): WORD;
- VAR
- event: Bluetooth.EventPacket;
- pending: BOOLEAN;
- res: WORD;
- BEGIN
- InSendCommand(ogfInformational, ocfReadBufferSize, "", 0, event, pending, res);
- IF pending THEN res := Bluetooth.ErrInvalidEvent
- ELSIF (res = 0) THEN
- aclMaxLen := ORD(event.params[5])*100H+ORD(event.params[4]);
- scoMaxLen := ORD(event.params[6]);
- aclNumPackets := ORD(event.params[8])*100H+ORD(event.params[7]);
- scoNumPackets := ORD(event.params[10])*100H+ORD(event.params[9])
- END;
- RETURN res
- END ReadBufferSize;
- (*--- HCI event handling ---*)
- PROCEDURE EventFilter(packet: Bluetooth.Packet): BOOLEAN;
- VAR event: Bluetooth.EventPacket; ec: CHAR;
- BEGIN
- event := packet(Bluetooth.EventPacket); ec := event.code;
- RETURN
- (ec = EConnectionComplete)
- OR (ec = EDisconnectionComplete)
- OR (ec = EInquiryResult)
- OR (ec = EInquiryComplete)
- OR (ec = ENofCompletedPackets)
- OR (ec = EMaxSlotsChange)
- OR (ec = EPageScanRepModeChange)
- OR (* status event to indicate host is ready *)
- ((ec = ECmdStatus) & (event.params[0] = 0X) & (event.params[2] = 0X) & (event.params[3] = 0X))
- OR (* command event to indicate host is ready *)
- ((ec = ECmdComplete) & (event.params[1] = 0X) & (event.params[2] = 0X))
- END EventFilter;
- PROCEDURE EventHandler(packet: Bluetooth.Packet);
- VAR
- event: Bluetooth.EventPacket;
- i : LONGINT;
- BEGIN
- event := packet(Bluetooth.EventPacket);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventHandler: event.code = 0x"); KernelLog.Hex(ORD(event.code),-2);
- KernelLog.String(" ..."); KernelLog.Ln;
- END;
- IF (event.code = EConnectionComplete) THEN
- EventConnectionCompleteOLD(event);
- ELSIF (event.code = EDisconnectionComplete) THEN
- EventDisconnectionCompleteOLD(event);
- ELSIF (event.code = EInquiryResult) THEN
- EventInquiryResult(event);
- ELSIF (event.code = ENofCompletedPackets) THEN
- EventNumOfCompletedPackets(event);
- ELSIF (event.code = EInquiryComplete) THEN
- EventInquiryComplete(event);
- ELSIF (event.code = EMaxSlotsChange) THEN
- EventMaxSlotsChange(event);
- ELSIF (event.code = EPageScanRepModeChange) THEN
- EventPageScanRepModeChange(event);
- ELSIF ((event.code = ECmdStatus) OR (event.code = ECmdComplete)) THEN
- (* ignore - indicates that the host is ready *)
- ELSE
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventHandler: unhandled event ! event.code = 0x");
- KernelLog.Hex(ORD(event.code),-2); KernelLog.String(" params:"); KernelLog.Ln;
- FOR i:= 0 TO event.paramLen-1 DO
- KernelLog.Hex(ORD(event.params[i]),-2); KernelLog.String(" ");
- END;
- KernelLog.Ln;
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventHandler: done."); KernelLog.Ln;
- END;
- END EventHandler;
- PROCEDURE EventInquiryComplete(event: Bluetooth.EventPacket);
- VAR
- status : LONGINT;
- BEGIN
- status := ORD(event.params[0]);
- IF (OnInquiryComplete # NIL) THEN
- OnInquiryComplete(SELF,status);
- END;
- END EventInquiryComplete;
- PROCEDURE EventInquiryResult(event: Bluetooth.EventPacket);
- VAR
- nr,psrm, pspm, psm, co: LONGINT;
- bdAddr : Bluetooth.BDAddr;
- class : Bluetooth.DeviceClass;
- i,k,ofs : LONGINT;
- BEGIN
- IF (OnInquiry # NIL) THEN
- i := 0; nr := ORD(event.params[0]);
- WHILE (i < nr) DO
- ofs := 1 + i*14;
- FOR k := 0 TO Bluetooth.BDAddrLen-1 DO
- bdAddr[k] := event.params[ofs+k]
- END;
- psrm := ORD(event.params[ofs+6]);
- pspm := ORD(event.params[ofs+7]);
- psm := ORD(event.params[ofs+8]);
- FOR k := 0 TO Bluetooth.DeviceClassLen-1 DO
- class[k] := event.params[ofs+9+k]
- END;
- co := ORD(event.params[ofs+12])+LONG(ORD(event.params[ofs+13]))*100H;
- OnInquiry(SELF,bdAddr,class,psrm,pspm,psm,co);
- INC(i);
- END;
- END;
- END EventInquiryResult;
- PROCEDURE EventConnectionComplete(event: Bluetooth.EventPacket);
- VAR
- status,handle : LONGINT;
- bdAddr : Bluetooth.BDAddr;
- linkType ,encryMode: LONGINT;
- i : LONGINT;
- BEGIN
- status := ORD(event.params[0]);
- handle := (ORD(event.params[2])*100H + ORD(event.params[1])) MOD 1000H;
- FOR i := 0 TO Bluetooth.BDAddrLen-1 DO
- bdAddr[i] := event.params[3+i]
- END;
- linkType := ORD(event.params[9]);
- encryMode := ORD(event.params[10]);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventConnectionComplete: status = 0x"); KernelLog.Hex(status,-2);
- KernelLog.String("; handle = "); KernelLog.Int(handle,0); KernelLog.String("; bdAddr = ");
- FOR i:= 0 TO Bluetooth.BDAddrLen-1 DO
- KernelLog.Hex(ORD(bdAddr[i]),-2);
- END;
- KernelLog.String("; linkType = "); KernelLog.Int(linkType,0);
- KernelLog.String("; encryptionMode = "); KernelLog.Int(encryMode,0);
- KernelLog.Ln;
- END;
- IF (OnConnectionComplete # NIL) THEN
- OnConnectionComplete(SELF,status,handle,bdAddr,linkType,encryMode);
- END;
- END EventConnectionComplete;
- PROCEDURE EventDisconnectionComplete(event: Bluetooth.EventPacket);
- VAR
- status,handle,reason : LONGINT;
- BEGIN
- status := ORD(event.params[0]);
- handle := (ORD(event.params[2])*100H + ORD(event.params[1])) MOD 1000H;
- reason := ORD(event.params[3]);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventDisconnectionComplete: status = 0x"); KernelLog.Hex(status,-2);
- KernelLog.String("; handle = "); KernelLog.Int(handle,0);
- KernelLog.String("; reason = 0x"); KernelLog.Hex(reason,-2);
- KernelLog.Ln;
- END;
- IF (OnDisconnectionComplete # NIL) THEN
- OnDisconnectionComplete(SELF,status,handle,reason);
- END;
- END EventDisconnectionComplete;
- PROCEDURE EventConnectionCompleteOLD(event: Bluetooth.EventPacket);
- VAR
- status,handle,i : LONGINT;
- bdAddr : Bluetooth.BDAddr;
- link : Link;
- BEGIN
- status := ORD(event.params[0]);
- IF (status = 0) THEN
- handle := (ORD(event.params[2])*100H + ORD(event.params[1])) MOD 1000H;
- FOR i := 0 TO Bluetooth.BDAddrLen-1 DO
- bdAddr[i] := event.params[3+i]
- END;
- link := linkManager.FindLink(handle);
- IF (link = NIL) THEN
- NEW(link,SELF, bdAddr,handle);
- linkManager.AddLink(link);
- END;
- link.state := lsUp;
- link.type := ORD(event.params[9]);
- link.encryption := ORD(event.params[10]);
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventConnectionCompleteOLD: status = 0x"); KernelLog.Hex(status,-2);
- KernelLog.String("; handle = "); KernelLog.Int(link.handle,0); KernelLog.String("; bdAddr = ");
- FOR i:= 0 TO Bluetooth.BDAddrLen-1 DO
- KernelLog.Hex(ORD(bdAddr[i]),-2);
- END;
- KernelLog.String("; linkType = "); KernelLog.Int(link.type,0);
- KernelLog.String("; encryptionMode = "); KernelLog.Int(link.encryption,0);
- KernelLog.Ln;
- END;
- ELSE
- handle := -1; link := NIL;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventConnectionCompleteOLD: status = 0x"); KernelLog.Hex(status,-2);KernelLog.Ln;
- END;
- END;
- IF (OnConnect # NIL) THEN
- OnConnect(SELF,link,status)
- END;
- END EventConnectionCompleteOLD;
- PROCEDURE EventDisconnectionCompleteOLD(event: Bluetooth.EventPacket);
- VAR
- status,handle : LONGINT;
- link : Link;
- BEGIN
- status := ORD(event.params[0]);
- IF (status = 0) THEN
- handle := (ORD(event.params[2])*100H + ORD(event.params[1])) MOD 1000H;
- link := linkManager.FindLink(handle);
- IF (link # NIL) THEN
- link.state := lsDown;
- link.reason := ORD(event.params[3]);
- linkManager.RemoveLink(link);
- END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventDisconnectionCompleteOLD: status = 0x"); KernelLog.Hex(status,-2);
- KernelLog.String("; handle = "); KernelLog.Int(handle,0);
- KernelLog.String("; reason = 0x"); KernelLog.Hex(link.reason,-2);
- KernelLog.Ln;
- END;
- ELSE
- link := NIL;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.EventDisconnectionCompleteOLD: status = 0x"); KernelLog.Hex(status,-2);KernelLog.Ln;
- END;
- END;
- IF (OnDisconnect # NIL) THEN
- OnDisconnect(SELF,link,status)
- END;
- END EventDisconnectionCompleteOLD;
- PROCEDURE EventNumOfCompletedPackets(event: Bluetooth.EventPacket);
- VAR
- numOfHandles,handle,numOfCompletedPackets : LONGINT;
- link : Link;
- ofs,i : LONGINT;
- BEGIN
- i := 0; numOfHandles := ORD(event.params[0]);
- WHILE (i < numOfHandles) DO
- ofs := 1 + i*4;
- handle := (ORD(event.params[ofs])+LONG(ORD(event.params[ofs+1]))*100H) MOD 1000H;
- numOfCompletedPackets := ORD(event.params[ofs+2])+LONG(ORD(event.params[ofs+3]))*100H;
- link := linkManager.FindLink(handle);
- IF (link # NIL) THEN
- INC(link.nofPackets, numOfCompletedPackets);
- END;
- INC(i);
- END;
- END EventNumOfCompletedPackets;
- PROCEDURE EventMaxSlotsChange(event: Bluetooth.EventPacket);
- VAR
- handle,maxSlots : LONGINT;
- BEGIN
- handle := (ORD(event.params[1])*100H + ORD(event.params[0])) MOD 1000H;
- maxSlots := ORD(event.params[2]);
- KernelLog.String(ModuleName);
- KernelLog.String("EventMaxSlotsChange: handle = "); KernelLog.Int(handle,0);
- KernelLog.String(" max slots = "); KernelLog.Int(maxSlots,0);
- KernelLog.Ln
- END EventMaxSlotsChange;
- PROCEDURE EventPageScanRepModeChange(event: Bluetooth.EventPacket);
- VAR
- i : LONGINT;
- BEGIN
- KernelLog.String(ModuleName);
- KernelLog.String("EventPageScanRepititionModeChange: bdAddr = ");
- FOR i := 0 TO Bluetooth.BDAddrLen-1 DO
- KernelLog.Hex(ORD(event.params[i]),-2);
- END;
- KernelLog.String(" mode = R"); KernelLog.Int(ORD(event.params[Bluetooth.BDAddrLen]),0);
- KernelLog.Ln
- END EventPageScanRepModeChange;
- PROCEDURE EricssonFilter(packet: Bluetooth.Packet): BOOLEAN;
- BEGIN RETURN packet(Bluetooth.EventPacket).code = 0FFX
- END EricssonFilter;
- PROCEDURE EricssonHandler(packet: Bluetooth.Packet);
- VAR event: Bluetooth.EventPacket; i: LONGINT;
- BEGIN
- event := packet(Bluetooth.EventPacket);
- KernelLog.Enter;
- CASE event.params[0] OF
- | 01X: KernelLog.String("Ericsson OSE crash")
- | 04X: KernelLog.String("Ericsson OSE pool event")
- | 06X: KernelLog.String("Message from Ericsson module on TL '"); KernelLog.String(tl.name); KernelLog.String("': ");
- FOR i := 0 TO ORD(event.params[1])-1 DO KernelLog.Char(event.params[2+i]) END;
- ELSE KernelLog.String("unknown Ericsson event")
- END;
- KernelLog.Exit
- END EricssonHandler;
- PROCEDURE ACLFilter(packet: Bluetooth.Packet): BOOLEAN;
- BEGIN RETURN TRUE
- END ACLFilter;
- PROCEDURE ACLHandler(packet: Bluetooth.Packet);
- VAR acl: Bluetooth.ACLPacket; l: Link;
- BEGIN
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ACLHandler: ..."); KernelLog.Ln;
- END;
- acl := packet(Bluetooth.ACLPacket);
- l := linkManager.FindLink(acl.handle);
- IF (l # NIL) THEN l.ACLDataReceived(acl) END;
- IF TraceHCI THEN
- KernelLog.String(ModuleName);
- KernelLog.String("HCI.ACLHandler: done."); KernelLog.Ln;
- END;
- END ACLHandler;
- PROCEDURE ErrorFilter(packet: Bluetooth.Packet): BOOLEAN;
- BEGIN RETURN (packet IS Bluetooth.UnknownPacket)
- END ErrorFilter;
- PROCEDURE ErrorHandler(packet: Bluetooth.Packet);
- BEGIN
- IF (OnError # NIL) THEN
- OnError(packet)
- END
- END ErrorHandler;
- END HCI;
- ConnectionComplete* = PROCEDURE {DELEGATE} (sender: HCI; status, handle: LONGINT;
- bdAddr: Bluetooth.BDAddr; linkType, encryMode: LONGINT);
- DisconnectionComplete* = PROCEDURE {DELEGATE} (sender : HCI; status,handle,reason : LONGINT);
- InquiryComplete* = PROCEDURE {DELEGATE} (sender: HCI; status: LONGINT);
- ConnectionEvent* = PROCEDURE{DELEGATE} (sender: HCI; link: Link; res: WORD);
- (*OnReceiveACLDataEvent* = PROCEDURE{DELEGATE} (link: Link; acl: Bluetooth.ACLPacket); *)
- (*handle, PB, PC, len: LONGINT; VAR data: ARRAY OF CHAR);*)
- InquiryEvent* = PROCEDURE {DELEGATE} (sender: HCI; bdAddr: Bluetooth.BDAddr; deviceClass: Bluetooth.DeviceClass;
- psRepMode, psPeriodMode, psMode, clockOffset: LONGINT);
- GeneralEvent* = PROCEDURE {DELEGATE} (sender: HCI; event: Bluetooth.EventPacket);
- ErrorEvent* = PROCEDURE{DELEGATE} (packet: Bluetooth.Packet);
- (** composes a HCI command packet header *)
- PROCEDURE ComposeCommandHeader*(OGF, OCF, paramLen: LONGINT; VAR command: ARRAY OF CHAR);
- BEGIN
- ASSERT((0 <= OGF) & (OGF <= 03FH));
- ASSERT((0 <= OCF) & (OCF <= 03FFH));
- ASSERT((0 <= paramLen) & (paramLen <= 0FFH));
- command[0] := CHR(OCF MOD 100H);
- command[1] := CHR(OCF DIV 100H + OGF*4);
- command[2] := CHR(paramLen)
- END ComposeCommandHeader;
- END BluetoothHCI.
|