00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #ifndef __baseband_h__
00147 #define __baseband_h__
00148
00149 #include <assert.h>
00150
00151 #include "packet.h"
00152 #include "timer.h"
00153 #include "link-real.h"
00154 #include "bluetus.h"
00155
00156
00157 #include "node-blue.h"
00158 #include "node-blue-impl.h"
00159
00160 #include <assert.h>
00161
00162
00163
00164 const double Msec = 1e-3;
00165 const double Usec = 1e-6;
00166 const double PropDelay = 5 * Usec;
00167 const double SLOTTIME = 625.0 * Usec;
00168 const double CLOCKTICK = 312.5 * Usec;
00169 const double NEWCONNECTIONTIMEOUT= 32 * SLOTTIME;
00170 const double PAGETIMEOUT = 8192 * CLOCKTICK;
00171 const double PAGERSPTIMEOUT = 36 * CLOCKTICK;
00172 const double INQUIRYTIMEOUT = 5.0;
00173 const double TwPageScan = 36 * CLOCKTICK;
00174 const double TPageScan = 4096 * CLOCKTICK;
00175 const int Npage = 128;
00176 const int Ninq = 256;
00177
00178 const double TXRXPOWER = 37.6;
00179 const double RXACERRPOWER = 24.2;
00180 const double ACTIVENOPOWER = 20.0;
00181 const double HOLDPOWER = 0.06;
00182 const double IDPOWER = 23.3;
00183 const double POLLNULLPOWER = 26.0;
00184
00185 #define BT_MAXRANGE 10 //meter
00186
00187 #define NULL_PKT 0x00
00188 #define POLL_PKT 0x01
00189 #define FHS_PKT 0x02
00190 #define DM1_PKT 0x03
00191 #define DH1_PKT 0x04 //for ACL only
00192 #define HV1_PKT 0x05 //for SCO only
00193 #define HV2_PKT 0x06 //for SCO only
00194 #define HV3_PKT 0x07 //for SCO only
00195 #define DV_PKT 0x08 //for SCO only
00196 #define AUX1_PKT 0x09 //for ACL only
00197 #define DM3_PKT 0x0A //for ACL only
00198 #define DH3_PKT 0x0B //for ACL only
00199
00200
00201 #define DM5_PKT 0x0E //for ACL only
00202 #define DH5_PKT 0x0F //for ACL only
00203
00204
00205
00206
00207 const int LAP_GIAC = 0x9e8b33;
00208 const int LAP_IACLow = 0x9e8b00;
00209 const int LAP_IACHigh = 0x9e8b3F;
00210
00211 class AccessCode72 {
00212 public:
00213 AccessCode72() {
00214 ucPreamble = ucTrailer = 0x00;
00215 ucSynWord[0] = ucSynWord[1] = ucSynWord[2] = ucSynWord[3]
00216 = ucSynWord[4] = ucSynWord[5] = ucSynWord[6] = ucSynWord[7]
00217 =0x00;
00218 }
00219
00220 AccessCode72(uChar *pSynWord) {
00221 assert(pSynWord!=NULL);
00222
00223 uChar ucTemp = 0;
00224 ucTemp = *pSynWord;
00225 if((ucTemp & 0x01))
00226 ucPreamble = 0x05;
00227 else
00228 ucPreamble = 0x0A;
00229
00230 ucTemp = *(pSynWord+7);
00231 if(ucTemp>>7)
00232 ucTrailer = 0x0A;
00233 else
00234 ucTrailer = 0x05;
00235 memcpy(&ucSynWord,pSynWord, 8);
00236 }
00237
00238 AccessCode72(const AccessCode72& orig) {
00239 ucPreamble = orig.ucPreamble;
00240 memcpy(&ucSynWord, &(orig.ucSynWord),8);
00241 ucTrailer = orig.ucTrailer;
00242 }
00243
00244 ~AccessCode72() {}
00245
00246 uChar * GetSynWord() {
00247 return (uChar *)&ucSynWord;
00248 }
00249
00250 private:
00251 uChar ucPreamble:4 ;
00252 uChar ucSynWord[8] ;
00253 uChar ucTrailer:4 ;
00254 };
00255
00256 class AccessCode68 {
00257 public:
00258 AccessCode68() {
00259 ucPreamble = 0x00;
00260 ucSynWord[0] = ucSynWord[1] = ucSynWord[2] = ucSynWord[3]
00261 = ucSynWord[4] = ucSynWord[5] = ucSynWord[6] = ucSynWord[7]
00262 =0x00;
00263 }
00264
00265 AccessCode68(uChar *pSynWord) {
00266 assert(pSynWord!=NULL);
00267
00268 uChar ucTemp = 0;
00269 ucTemp = *pSynWord ;
00270 if((ucTemp&0x01))
00271 ucPreamble = 0x05;
00272 else
00273 ucPreamble = 0x0A;
00274
00275 memcpy(&ucSynWord,pSynWord, 8);
00276 }
00277
00278 AccessCode68(const AccessCode68& orig) {
00279 ucPreamble = orig.ucPreamble;
00280 memcpy(&ucSynWord, &(orig.ucSynWord),8);
00281 }
00282
00283 ~AccessCode68() {}
00284
00285 uChar * GetSynWord() {
00286 return (uChar *)&ucSynWord;
00287 }
00288 private:
00289 uChar ucPreamble:4 ;
00290 uChar ucSynWord[8] ;
00291 };
00292
00293
00294 struct Header {
00295 uChar ucAMAddr:3;
00296 uChar ucType:4;
00297 uChar ucFlow:1;
00298 uChar ucArqn:1;
00299 uChar ucSeqn:1;
00300 uChar ucHec;
00301 };
00302
00303
00304 #define LM_CH 0x03
00305 #define L2CAP_CH 0x02 //start L2CAP msg or no fragmentation
00306 #define L2CAP_CON_CH 0x01 //continue fragment of an L2CAP msg
00307
00308
00309 #define STOPFLOW 0x00 // 1 bit used
00310 #define GOFLOW 0x01 // 1 bit used.
00311
00312
00313 #define NAK 0x00
00314 #define ACK 0x01
00315
00316 class PayloadHdr {
00317 public:
00318 PayloadHdr(uChar ucL_CH, uChar ucFlag, uChar ucLen,
00319 uChar *pData) {
00320 ucLogicChannel = ucL_CH;
00321 ucFlow = ucFlag;
00322 ucLength = ucLen;
00323 this->pData = pData;
00324 }
00325
00326 PayloadHdr(const PayloadHdr& hdr) {
00327 ucLogicChannel = hdr.ucLogicChannel;
00328 ucFlow = hdr.ucFlow;
00329 ucLength = hdr.ucLength;
00330 pData = hdr.pData;
00331 }
00332 ~PayloadHdr() {
00333
00334 }
00335
00336 public:
00337 uChar ucLogicChannel:2;
00338 uChar ucFlow:1;
00339 uChar ucLength:5;
00340 uChar *pData;
00341 };
00342
00343
00344 class PayloadHdrMultiSlot {
00345 public:
00346 PayloadHdrMultiSlot(uChar ucL_CH, uChar ucFlag, uShort usLen,
00347 uChar *pData) {
00348 ucLogicChannel = ucL_CH;
00349 ucFlow = ucFlag;
00350 ucLengthL = (uChar) (usLen & 0x001F);
00351 ucLengthH = (uChar) (usLen & 0x01E0) >>5 ;
00352 ucUnused = 0;
00353 this->pData = pData;
00354 }
00355 public:
00356 uChar ucLogicChannel:2;
00357 uChar ucFlow:1;
00358 uChar ucLengthL:5;
00359 uChar ucLengthH:4;
00360 uChar ucUnused:4;
00361 uChar *pData;
00362
00363 };
00364
00365 #define R0 0x00
00366 #define R1 0x01
00367 #define R2 0x02
00368
00369 #define P0 0x00
00370 #define P1 0x01
00371 #define P2 0x02
00372
00373 #define MANDATORY_MODE 0x00
00374 #define OPTIONAL_MODE1 0x01
00375 #define OPTIONAL_MODE2 0x02
00376 #define OPTIONAL_MODE3 0x03
00377
00378
00379 #define TRAINSIZE 16
00380
00381
00382 struct FHSPayload {
00383 uLong ulParityBits;
00384 uChar ucCon2Bits:2;
00385 uLong ulLAP:24;
00386 uChar ucUndef:2;
00387 uChar ucSR:2;
00388 uChar ucSP:2;
00389 uChar ucUAP;
00390 uShort usNAP;
00391 uLong ulClassService:24;
00392 uChar ucAMAddr:3;
00393 uLong ulClk27_2:26;
00394 uChar ucPageScanMode:3;
00395 };
00396
00397
00398
00399
00400 class CommonHdr : public PDU {
00401 public:
00402 CommonHdr() {
00403 }
00404 CommonHdr(uChar ucFreq, uShort usLen) {
00405 this->ucFreq = ucFreq;
00406 this->usLen = usLen;
00407
00408 }
00409 virtual Size_t Size() const = 0;
00410 public:
00411 uChar ucFreq;
00412 uShort usLen;
00413
00414 };
00415
00416 class IDPacket : public CommonHdr {
00417 public:
00418 IDPacket():CommonHdr(0, 0) {
00419 }
00420 IDPacket(const IDPacket &pkt) {
00421 this->accessCode68 = pkt.accessCode68;
00422 }
00423 IDPacket *
00424 Copy() const {
00425 IDPacket *pTemp = new IDPacket;
00426 pTemp->ucFreq = this->ucFreq;
00427 pTemp->usLen = this->usLen;
00428 pTemp->accessCode68 = this->accessCode68;
00429 return pTemp;
00430 }
00431 Size_t Size() const {
00432 return sizeof(ucFreq) + sizeof(usLen) + sizeof(accessCode68);
00433 }
00434
00435
00436 ~IDPacket() {
00437 }
00438
00439
00440
00441
00442
00443 public:
00444 AccessCode68 accessCode68;
00445 };
00446
00447 class BaseBandPacket : public CommonHdr {
00448 public:
00449
00450 BaseBandPacket(uChar freq, uShort len,
00451 AccessCode72 code72, Header hdr,
00452 uChar *ucPayload) : CommonHdr(freq, len) {
00453 ucFreq = freq;
00454 usLen = len;
00455 accessCode72 = code72;
00456 Hdr = hdr;
00457 pPayload = ucPayload;
00458 }
00459
00460
00461 BaseBandPacket(const BaseBandPacket &pkt) {
00462 this->ucFreq = pkt.ucFreq;
00463 this->usLen = pkt.usLen;
00464 this->accessCode72 = pkt.accessCode72;
00465 this->Hdr = pkt.Hdr;
00466 uShort usTempLen = this->usLen -
00467 sizeof(accessCode72) - sizeof(Hdr);
00468 this->pPayload = new uChar[usTempLen];
00469 assert(this->pPayload!=NULL);
00470
00471 memcpy(this->pPayload, pkt.pPayload,
00472 usTempLen);
00473 }
00474
00475 ~BaseBandPacket() {
00476 if(pPayload !=NULL)
00477 delete []pPayload;
00478 }
00479
00480 public:
00481 BaseBandPacket *
00482 Copy() const {
00483 BaseBandPacket *pTemp = new BaseBandPacket(
00484 this->ucFreq,
00485 this->usLen,
00486 this->accessCode72,
00487 this->Hdr,
00488 this->pPayload);
00489 uShort usTempLen = this->usLen -
00490 sizeof(accessCode72) - sizeof(Hdr);
00491 pTemp->pPayload = new uChar[usTempLen];
00492 memcpy(pTemp->pPayload, this->pPayload, usTempLen);
00493 return pTemp;
00494 }
00495
00496 Size_t Size() const {
00497 return sizeof(ucFreq) + sizeof(usLen) + sizeof(accessCode72)
00498 + sizeof(Hdr) + usLen;
00499 }
00500
00501 public:
00502 AccessCode72 accessCode72;
00503 Header Hdr;
00504 uChar *pPayload;
00505 };
00506
00507 typedef enum { STANDBY, PAGE, PAGE_SCAN, INQUIRY, INQUIRY_SCAN,
00508 MASTER_RSP, SLAVE_RSP, INQUIRY_RSP, CONNECTION } StateType;
00509
00510 typedef enum {PAGE_HOPPING, MASTER_PAGE_RSP_HOPPING, SLAVE_PAGE_RSP_HOPPING,
00511 INQUIRY_HOPPING, INQUIRY_RSP_HOPPING, PAGE_SCAN_HOPPING, INQUIRY_SCAN_HOPPING,
00512 CHANNEL_HOPPING } HoppingSeqType;
00513
00514 struct FIFOBuf {
00515 BaseBandPacket *pCurrent;
00516 BaseBandPacket *pNext;
00517 };
00518
00519 struct TXBuf {
00520 BdAddr addr;
00521 FIFOBuf *pTXBuf;
00522 };
00523
00524 typedef std::list<TXBuf *> TXBufList;
00525
00526 struct PktStruct {
00527 Time_t TimeStamp;
00528 BaseBandPacket *pPacket;
00529 };
00530 typedef std::list<PktStruct> PktQueue;
00531
00532
00533 class BaseBandEvent : public TimerEvent {
00534 public:
00535
00536 typedef enum {CLOCK_TICK, NEW_CONNECTION_TO,
00537 PAGE_TO, PAGE_RSP_TO, INQUIRY_TO,
00538 START_RUN, STOP_RUN
00539 } BaseBandTimeout_t;
00540 public:
00541 BaseBandEvent(Event_t ev) : TimerEvent(ev) { };
00542 virtual ~BaseBandEvent() {};
00543 };
00544
00545
00546
00547
00548 class L2cap;
00549 class LMP;
00550
00551
00552
00553 struct Context {
00554
00555 uChar ucAMAddr;
00556 BdAddr SlaveAddr;
00557
00558 uChar ucFlow;
00559 uChar ucArqn;
00560 uChar ucSeqn;
00561
00562 uChar ucSeqnOld;
00563 uChar ucAcked;
00564 uChar ucFlowRevert;
00565
00566 uChar ucRecvFreq;
00567
00568 uShort usN;
00569 uChar ucIdNo;
00570 uShort usTrainSent;
00571 uChar ucTrainType;
00572 uChar ucKoffsetStar;
00573
00574 BaseBandEvent* CLOCKTICKTimeout;
00575 BaseBandEvent* NewConnectionTimeout;
00576 BaseBandEvent* PageTimeout;
00577 BaseBandEvent* PageRspTimeout;
00578 BaseBandEvent* InquiryTimeout;
00579
00580 RoleType role;
00581 };
00582
00583 typedef std::vector<Context> ContextVec_t;
00584
00585
00586
00587 struct PiconetContext {
00588
00589 uLong ulClk;
00590 BdAddr MasterAddr;
00591
00592 StateType State;
00593
00594
00595 FIFOBuf *pRXBuf;
00596 TXBufList TxBufferList;
00597
00598 uLong ulClkN;
00599 uLong ulClkF;
00600 uLong ulClkE;
00601
00602 Context MyContext;
00603 char cActiveList[7];
00604 BdAddr ActiveAddr[7];
00605
00606 ContextVec_t SlaveContexts;
00607 };
00608
00609 typedef std::vector<PiconetContext> PiconetContextVec_t;
00610
00611 class BaseBand : public Handler, public TimerHandler {
00612 public:
00613 BaseBand();
00614 ~BaseBand() {
00615 }
00616 public:
00617 void Start(RoleType myRole, double t);
00618 void Stop(double t);
00619 void Reset();
00620 RoleType GetRole() {
00621 return role;
00622 }
00623
00624 void TestFreq();
00625
00626 BdAddr GetMyAddr() {
00627 return pNode->GetBdAddr();
00628 }
00629 BdAddr GetPeerAddr() {
00630 if(role == MASTER)
00631 return SlaveAddr;
00632 else
00633 return MasterAddr;
00634 }
00635 bool CheckAccessCode(uChar *DstCode, uLong ulLAP);
00636 void AttachNode(BlueNode *pNodeAttached) {
00637 if(pNode==NULL)
00638 pNode = pNodeAttached;
00639 return;
00640 }
00641 void InstallLMP(LMP *pLMPStack);
00642 void InstallL2CAP(L2cap *pL2CAPStack);
00643 L2cap* GetL2CAP() {return pL2CAP;}
00644 LMP* GetLMP() {return pLMP;}
00645
00646 void Initialize(StateType currentState = STANDBY,
00647 RoleType myRole = SLAVE);
00648 void Inquiry();
00649 void PageDevice(BdAddr slave);
00650 void PageDevices();
00651 void DataIndication(BaseBandPacket *pBaseBandPkt);
00652 void DataIndication(IDPacket *pIDPacket);
00653 void DataRequest(uChar ucLogicChannel, uShort usLen,
00654 uChar *ucPayload, BdAddr DstAddr);
00655 void SendPacket(uChar ucL_CH, uShort usLen, uChar *ucPayload,
00656 BdAddr DstAddr,
00657 uChar ucSlot = 1 );
00658 void Send(AccessCode72 *pAccessCode72, Header *pPktHdr,
00659 uChar *pPayload, double dTime, uChar ucFreq);
00660 void SendIDPacket(uLong ulLAP, uChar ucFreq, double dTime=0.0);
00661 void SendPollPacket(uChar ucAMAddr);
00662 void SendNullPacket(AccessCode72 *pAccessCode72,
00663 Header *pPktHdr, uChar ucFreq);
00664
00665 public:
00666 void SynWordConstruct(uLong ulLAP, uChar *pSynWord);
00667 void SynWordConstruct(BdAddr addr, uChar *pSynWord);
00668
00669 public:
00670 bool isWithinRange(double dX, double dY);
00671 bool isWithinRange(BlueNode *pNode);
00672
00673 public:
00674 Timer timer;
00675 bool useTimerBuckets;
00676 bool bStartPoll;
00677
00678 virtual void Timeout(TimerEvent*);
00679 void ScheduleTimer(Event_t e, BaseBandEvent*& ev, Time_t t);
00680 void CancelTimer(BaseBandEvent*& ev, bool delTimer);
00681
00682
00683 void Handle(Event*, Time_t);
00684
00685 public:
00686 uChar Freq();
00687
00688 public:
00689 void SwitchPiconet();
00690 bool SwitchContext(uChar ucAddrToSave, uChar ucAddrToActive);
00691 void SaveContext(uChar ucActiveAddr);
00692 bool RemoveContext(uChar ucAddr);
00693 void UpdateNeighborClockE();
00694
00695 uLong GetClk() {
00696 return ulClk;
00697 }
00698
00699 void CheckPiconetSetup();
00700 void LMPReadyIndication(void);
00701
00702
00703 double StatTxPower() {return TxPower;}
00704 double StatRxPower() {return RxPower;}
00705 double StatRxAcErrPower() {return RxAcErrPower;}
00706 double StatActiveNoPower() {return ActiveNoPower;}
00707 double StatHoldPower() {return HoldPower;}
00708
00709 private:
00710 char AllocAmAddr();
00711 uChar DetermineARQN(BaseBandPacket *pBaseBandPkt);
00712 uChar RetransmitFilter(uChar ucPktType);
00713 void DetermineFlowFlag();
00714
00715 void Trigger(Packet *pPacket);
00716 void UpdateRecvFreq();
00717 void Transmit(IDPacket *pIDPacket, double dTime);
00718 void Transmit(BaseBandPacket *pPacket, double dTime);
00719
00720 void ScheduleRx(LinkEvent *e, Time_t t);
00721 void ScheduleTx(LinkEvent *e, Time_t t);
00722 void UpdateInqPageParameter();
00723 void InitInqPageParameter();
00724
00725
00726 uChar HopSelection(uLong ulClkFrozen,
00727 HoppingSeqType hopSeqType, BdAddr addr);
00728 void ButterFly(uChar ucCtrl, uChar& ucVar1, uChar& ucVar2);
00729 uChar Perm5(uChar ucZ, uChar ucCY1, uShort usD);
00730 uShort GetBits(uShort usVar, uChar ucStartBit,
00731 uChar ucHowmany, uChar ucLeftShift = 0);
00732
00733 void CRC16(uShort& usCrc, uChar *ucData, uShort usLen);
00734 uChar Hec(uChar ucCrc, uChar *ucData, uChar ucLen);
00735 void Fec23(uChar *ucData, uShort usLen);
00736 void Fec13(uChar *ucData, uShort usLen);
00737
00738 private:
00739 BlueNode *pNode;
00740 L2cap *pL2CAP;
00741 LMP *pLMP;
00742
00743
00744
00745
00746 StateType State;
00747
00748
00749 FIFOBuf *pRXBuf;
00750 TXBufList TxBufferList;
00751
00752 PktQueue LmpPktSlaveQueue;
00753 PktQueue L2capPktSlaveQueue;
00754 PktQueue LmpPktMasterQueue[7];
00755 PktQueue L2capPktMasterQueue[7];
00756 PktQueue PollNullPktQueue;
00757
00758 BdAddr MasterAddr;
00759
00760
00761 uLong ulClkN;
00762 uLong ulClkF;
00763 uLong ulClkE;
00764 uLong ulClk;
00765
00766 StateType PreviousState;
00767 uShort InquiryBackoff;
00768
00769 BdAddr SlaveAddr;
00770 uChar ucFlow;
00771 uChar ucArqn;
00772 uChar ucSeqn;
00773 uChar ucAMAddr;
00774
00775 uChar ucSeqnOld;
00776 uChar ucAcked;
00777 uChar ucFlowRevert;
00778
00779 uChar ucRecvFreq;
00780
00781 uShort usN;
00782 uChar ucIdNo;
00783 uShort usTrainSent;
00784 uChar ucTrainType;
00785 uChar ucKoffsetStar;
00786
00787
00788 BaseBandEvent* CLOCKTICKTimeout;
00789 BaseBandEvent* NewConnectionTimeout;
00790 BaseBandEvent* PageTimeout;
00791 BaseBandEvent* PageRspTimeout;
00792 BaseBandEvent* InquiryTimeout;
00793
00794 RoleType role;
00795 char cActiveList[7];
00796 BdAddr ActiveAddr[7];
00797 bool bPiconetSetupDone;
00798 char cLMPConnected[7];
00799
00800
00801 AccessCode72 channelAC;
00802 AccessCode72 DeviceAC;
00803
00804 Time_t dTotalDelay;
00805 uLong ulPktCount;
00806 ContextVec_t SlaveContexts;
00807 uChar ucRRQueue;
00808 bool bMyTurn;
00809 uShort usTpoll[7];
00810 uShort usTpollCount[7];
00811
00812 double TxPower;
00813 double RxPower;
00814 double RxAcErrPower;
00815 double ActiveNoPower;
00816 double HoldPower;
00817 };
00818
00819 #endif