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 __l2cap_h
00147 #define __l2cap_h
00148
00149 #include <assert.h>
00150
00151 #include <list>
00152 #include <iostream>
00153 #include "bluetus.h"
00154 #include "baseband.h"
00155 #include "bnep.h"
00156
00157
00158 #define SIGNAL_CHANNEL 0x0001
00159
00160 #define CONNLESS_CHANNEL 0x0002
00161
00162
00163 #define REASON_NOTUNDERSTAND 0x0000
00164 #define REASON_MTUEXCEED 0x0001
00165 #define REASON_INVALIDCID 0x0002
00166
00167
00168 #define SDP 0x0001
00169 #define RFCOMM 0x0003
00170 #define TCS_BIN 0x0005
00171 #define TCS_BIN_CORDLESS 0x0007
00172 #define BNEP 0x000F
00173 #define HID_CONTROL 0x0011
00174 #define HID_INTERRUPT 0x0013
00175 #define UPNP 0x0015
00176 #define AVCTP 0x0017
00177 #define AVDTP 0x0019
00178 #define UDI_C_PLANE 0x001D
00179
00180
00181
00182 #define COMMAND_RESERVED 0x00
00183 #define COMMAND_REJECT 0x01
00184 #define COMMAND_CONN_REQ 0x02
00185 #define COMMAND_CONN_RESP 0x03
00186 #define COMMAND_CFG_REQ 0x04
00187 #define COMMAND_CFG_RESP 0x05
00188 #define COMMAND_DISCONN_REQ 0x06
00189 #define COMMAND_DISCONN_RESP 0x07
00190 #define COMMAND_ECHO_REQ 0x08
00191 #define COMMAND_ECHO_RESP 0x09
00192 #define COMMAND_INFO_REQ 0x0A
00193 #define COMMAND_INFO_RESP 0x0B
00194
00195
00196
00197
00198
00199
00200
00201 #define TIMEOUT_VALUE 10 //10 seconds.
00202 #define MAX_TRY 5
00203
00204 using namespace std;
00205
00206 typedef enum {CLOSED, W4_L2CAP_CONNECT_RSP, W4_L2CA_CONNECT_RSP, CONFIG,
00207 OPEN, W4_L2CAP_DISCONNECT_RSP, W4_L2CA_DISCONNECT_RSP
00208 } L2CAP_state;
00209
00210
00211
00212
00213 struct L2CAPPacket {
00214 uShort usLength;
00215 uShort usChannelID;
00216 uChar ucPayload[1];
00217
00218 int HdrSize() {
00219 return 2*sizeof(uShort);
00220 }
00221 };
00222
00223
00224 struct CommandPacket {
00225 uChar ucCode;
00226 uChar ucID;
00227 uShort usLength;
00228 uChar ucData[1];
00229
00230 int HdrSize(){
00231 return 2*sizeof(uChar) + sizeof(uShort);
00232 }
00233 };
00234
00235 struct CmdReject {
00236 uShort usReason;
00237
00238 };
00239
00240
00241
00242
00243
00244
00245
00246
00247 struct CmdConnReq {
00248 uShort usPSM;
00249 uShort usSrcCID;
00250 };
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 struct CmdConnResp {
00262 uShort usDstCID;
00263 uShort usSrcCID;
00264 uShort usResult;
00265 uShort usStatus;
00266 };
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 struct CmdCfgReq {
00286 uShort usDstCID;
00287 uShort usFlags;
00288
00289 };
00290
00291 struct CfgParamOpt {
00292 uChar ucType;
00293 uChar ucLength;
00294 };
00295 #define TYPE_MTU 0x01
00296 #define TYPE_FLUSHTIMEO 0x02
00297 #define TYPE_QOS 0x03
00298
00299 struct QosOpt {
00300 uChar ucFlags;
00301 uChar ucServiceType;
00302
00303 uLong ulTokenRate;
00304 uLong ulTokenBucketSize;
00305 uLong ulPeakBandw;
00306 uLong ulLatency;
00307 uLong ulDelayVar;
00308 };
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 struct CmdCfgResp {
00326 uShort usSrcCID;
00327 uShort usFlags;
00328 uShort usResult;
00329 uShort usConfig;
00330 };
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 struct CmdDisconnReq {
00345 uShort usDstCID;
00346 uShort usSrcCID;
00347 };
00348
00349
00350
00351
00352
00353
00354
00355 struct CmdDisconnResp {
00356 uShort usDstCID;
00357 uShort usSrcCID;
00358 };
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 struct CmdInfoReq {
00372 uShort usInfoType;
00373 };
00374
00375
00376
00377
00378
00379 struct CmdInfoResp {
00380 uShort usInfoType;
00381 uShort usResult;
00382
00383 };
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 #define MAX_QUEUE_LEN 128
00394
00395
00396
00397 class L2CAPTimerEvent : public TimerEvent {
00398 public:
00399
00400 typedef enum {CONNREQ_TIMEOUT, CFGREQ_TIMEOUT, DISCONNREQ_TIMEOUT
00401 } L2CAPTimerEvent_t;
00402 public:
00403 L2CAPTimerEvent(Event_t ev, uChar ucId)
00404 : TimerEvent(ev) {
00405 ucRequestId = ucId;
00406 }
00407 virtual ~L2CAPTimerEvent() {}
00408
00409 uChar ucRequestId;
00410 };
00411
00412 typedef std::list<L2CAPPacket *> L2CAPPacketList;
00413
00414 class L2capQueue {
00415 public:
00416 L2capQueue(){ usQueLen = 0;}
00417 bool Enque(L2CAPPacket *pPacket);
00418 bool DeQue(L2CAPPacket *pPacket);
00419 ~L2capQueue() {
00420 }
00421 private:
00422 uShort usQueLen;
00423 L2CAPPacketList L2capPktList;
00424 };
00425
00426
00427
00428 class L2capChannel {
00429 public:
00430 L2capChannel(uShort usRemoteChannelID = 0x0000,
00431 uShort usLocalChannelID = 0x0000) {
00432 pRxQueue = NULL;
00433 this->usRemoteChannelID = usRemoteChannelID;
00434 this->usLocalChannelID = usLocalChannelID;
00435 pLocalAddr = NULL;
00436 pRemoteAddr = NULL;
00437 }
00438
00439 virtual ~L2capChannel() {
00440 delete pLocalAddr;
00441 delete pRemoteAddr;
00442 if(pRxQueue)
00443 delete pRxQueue;
00444 }
00445
00446 virtual uShort DataIndication(L2CAPPacket *pPacket) = 0;
00447
00448 void SetLocalChannelID(uShort usLocalChannelID) {
00449 this->usLocalChannelID = usLocalChannelID;
00450 return;
00451 }
00452
00453 uShort GetLocalChannelID() {
00454 return usLocalChannelID;
00455 }
00456 void SetRemoteChannelID(uShort usRemoteChannelID) {
00457 this->usRemoteChannelID = usRemoteChannelID;
00458 return;
00459 }
00460 uShort GetRemoteChannelID() {
00461 return usRemoteChannelID;
00462 }
00463
00464 BdAddr * GetRemoteAddr() {
00465 assert(pRemoteAddr!=NULL);
00466 return pRemoteAddr;
00467 }
00468 void SetRemoteAddr(BdAddr addr) {
00469 if(pRemoteAddr)
00470 delete pRemoteAddr;
00471 pRemoteAddr = new BdAddr;
00472 memcpy(pRemoteAddr, &addr, sizeof(BdAddr));
00473 return ;
00474 }
00475
00476 BdAddr * GetLocalAddr() {
00477 assert(pLocalAddr!=NULL);
00478 return pLocalAddr;
00479 }
00480 void SetLocalAddr(BdAddr addr) {
00481 if(pLocalAddr)
00482 delete pLocalAddr;
00483 pLocalAddr = new BdAddr;
00484 memcpy(pLocalAddr, &addr, sizeof(BdAddr));
00485 return ;
00486 }
00487
00488 virtual uShort GetMTU() {
00489 return 0;
00490 }
00491 public:
00492 uShort usOutMTU;
00493 uShort usInFlushTO;
00494
00495 private:
00496 uChar ucChannelType;
00497
00498 BdAddr *pLocalAddr;
00499 BdAddr *pRemoteAddr;
00500
00501 L2capQueue *pRxQueue;
00502
00503
00504 uShort usRemoteChannelID;
00505 uShort usLocalChannelID;
00506
00507 };
00508
00509
00510 struct L2capCmdId {
00511 uChar ucIdentifier;
00512
00513
00514 double dExpire;
00515 };
00516
00517 typedef std::list<L2capCmdId> L2capCmdIdList;
00518
00519 struct ConfigPara {
00520 uShort usCID;
00521 uShort usInMTU;
00522 void *pOutFlow;
00523 uShort usOutFlushTO;
00524 uShort usLinkTO;
00525 uShort *pInMTU_O;
00526 void *pOutFlow_O;
00527 uShort *pOutFlushTO_O;
00528 };
00529
00530
00531
00532
00533 class L2cap;
00534 class L2capConnChannel;
00535
00536 class L2capSignalChannel: public L2capChannel{
00537
00538 public:
00539
00540 L2capSignalChannel(L2cap *pL2CAP = NULL);
00541
00542 ~L2capSignalChannel();
00543
00544
00545 virtual uShort DataIndication(L2CAPPacket *pPacket) {return 0x0000;};
00546
00547 uShort DataIndication(L2CAPPacket *pPacket, L2capConnChannel *pChannel);
00548
00549
00550 uShort DataRequest(void *pData);
00551
00552
00553 bool CmdIdRemove(L2capConnChannel *pChannel, uChar ucId);
00554 void CmdIdPurge(L2capConnChannel *pChannel);
00555 bool CmdIdLookup(L2capConnChannel *pChannel, uChar ucId);
00556 L2capCmdId CmdIdAlloc(L2capConnChannel *pChannel);
00557 bool CmdIdInsert(L2capConnChannel *pChannel, uChar ucID);
00558
00559 virtual uShort GetMTU() {
00560 return usMTU;
00561 }
00562
00563 uShort BuildCmd(uChar code, uChar identifier,
00564 uShort length, void *data, void *commandBuf);
00565
00566 uShort L2CA_ConnectReq(uShort PSM, BdAddr BD_Addr, uShort *pLCID,
00567 uChar ucId, uShort *pStatus,
00568 L2capConnChannel *pChannel);
00569 uShort L2CA_ConnectRsp(BdAddr BD_Addr,uChar ucIdentifier,uShort
00570 LCID, uShort response, uShort status);
00571 uShort L2CA_ConfigReq(uShort CID, uShort InMTU,void *pOutFlow,
00572 uShort OutFlushTO, uShort LinkTO,uShort *pInMTU_O,
00573 void *pOutFlow_O,uShort *pOutFlushTO_O,uChar ucId,
00574 L2capConnChannel *pChannel);
00575 uShort L2CA_ConfigRsp(uShort LCID, uShort OutMTU,uChar ucIdentifier,
00576 uShort Result, void *pInFlow,
00577 L2capConnChannel *pChannel);
00578 uShort L2CA_DisconnectReq(uShort usLocalCID, uChar ucId);
00579 uShort L2CA_DisconnectRsp(uShort usLocalCID, uChar ucIdentifier);
00580
00581 uShort Dispatch(CommandPacket *pCommand, L2capConnChannel *pChannel);
00582
00583 uShort RecvReject(CommandPacket *pCommand);
00584 uShort RecvConnReq(CommandPacket *pCommand);
00585 uShort RecvConnResp(CommandPacket *pCommand);
00586 uShort RecvCfgReq(CommandPacket *pCommand);
00587 uShort RecvCfgResp(CommandPacket *pCommand,L2capConnChannel *pChannel);
00588 uShort RecvDisconnReq(CommandPacket *pCommand);
00589 uShort RecvDisconnResp(CommandPacket *pCommand);
00590
00591 void SaveCfgPara(uShort CID, uShort InMTU, void *pOutFlow,
00592 uShort OutFlushTO, uShort LinkTO, uShort *pInMTU_O,
00593 void *pOutFlow_O, uShort *pOutFlushTO_O) {
00594 CfgParameter.usCID = CID;
00595 CfgParameter.usInMTU = InMTU;
00596 CfgParameter.pOutFlow = pOutFlow;
00597 CfgParameter.usOutFlushTO = OutFlushTO;
00598 CfgParameter.usLinkTO = LinkTO;
00599 CfgParameter.pInMTU_O = pInMTU_O;
00600 CfgParameter.pOutFlow_O = pOutFlow_O;
00601 CfgParameter.pOutFlushTO_O = pOutFlushTO_O;
00602 return;
00603 }
00604
00605 ConfigPara GetCfgPara() {
00606 return CfgParameter;
00607 }
00608
00609 private:
00610 L2cap *pL2CAP;
00611 uShort usMTU;
00612
00613 ConfigPara CfgParameter;
00614 L2capQueue *pTxQueue;
00615 };
00616
00617
00618
00619
00620 class L2capConnChannel: public L2capChannel , public TimerHandler {
00621
00622 public:
00623 #define DEFAULT_MTU 672
00624 #define DEFAULT_TIMEO 0xFFFF //msec
00625
00626 L2capConnChannel(uShort usPSM = 0x0000,uShort usOutMTU = DEFAULT_MTU,
00627 uShort usInFlushTO = DEFAULT_TIMEO,
00628 uShort usInMTU = DEFAULT_MTU,
00629 uShort usOutFlushTO = DEFAULT_TIMEO);
00630
00631 ~L2capConnChannel();
00632
00633
00634 int Demultiplxr(L2CAPPacket *pPacket);
00635
00636
00637 virtual uShort DataIndication(L2CAPPacket *pPacket);
00638
00639 virtual uShort GetMTU() {
00640 return usInMTU;
00641 }
00642
00643 uShort DataRequest(uShort usLength, void *pData);
00644
00645 L2CAP_state usState;
00646 uShort usCfgState;
00647
00648 L2cap *pL2CAP ;
00649 L2capSignalChannel *pSignalChannel;
00650
00651 #define ILLEGAL_COMMAND_ID 0x00
00652 uChar ucPendingCmdId;
00653
00654 L2capCmdIdList CmdIdList;
00655
00656 public:
00657 Timer timer;
00658
00659 L2CAPTimerEvent *pConnReqTimeout;
00660 L2CAPTimerEvent *pCfgReqTimeout;
00661 L2CAPTimerEvent *pDisconnReqTimeout;
00662
00663
00664 virtual void Timeout(TimerEvent*);
00665
00666 void ScheduleTimer(Event_t, uChar, L2CAPTimerEvent*&, Time_t);
00667 void CancelTimer(L2CAPTimerEvent*&, bool delTimer = false);
00668 void CancelAllTimers();
00669
00670 public:
00671
00672
00673 uChar ucMaxRetryReq;
00674
00675 private:
00676 L2capQueue *pTxQueue;
00677
00678 uShort usPSM;
00679
00680
00681
00682 uShort usInMTU;
00683 uShort usOutFlushTO;
00684
00685
00686
00687 QosOpt RequestQoS;
00688 QosOpt RequiredQoS;
00689
00690 };
00691
00692 struct AssembleBuf {
00693 uShort usTotalLen;
00694 uShort usOccupied;
00695 uShort usChannelID;
00696 uChar *pBuf;
00697 };
00698
00699 typedef std::list<L2capConnChannel *> L2capChannelList;
00700
00701 class BaseBand;
00702 class Bnep;
00703
00704
00705 class L2cap {
00706 public:
00707 L2cap();
00708
00709 ~L2cap();
00710
00711 public:
00712
00713 uShort DataIndication(uChar ucLogicChannel, uChar ucFlow,
00714 uShort usLen, uChar *pData);
00715
00716 void Segmentation(uShort usLen, uChar *pData);
00717 void Reassembly();
00718
00719 void DataRequest(L2CAPPacket *pPacket);
00720 uShort DataRequest(uShort usLen, uShort usLocalCID, void *pData);
00721
00722
00723
00724
00725 uShort SendL2CAPPacket(uShort usLength, uShort usChannelID,
00726 void * payload, L2capConnChannel *pChannel);
00727
00728
00729 uShort GetMTU(uShort usChannelID) {
00730 L2capConnChannel *pChannel;
00731 pChannel = ChannelLookupByLocalCID(usChannelID);
00732 return pChannel->usOutMTU;
00733 }
00734 uShort GetFlushTimeout(uShort usChannelID) {
00735 L2capConnChannel *pChannel;
00736 pChannel = ChannelLookupByLocalCID(usChannelID);
00737 return pChannel->usInFlushTO;
00738 }
00739
00740 uShort AllocateChannelID();
00741 bool ChannelInsert(L2capConnChannel *pChannel);
00742 L2capConnChannel * ChannelLookupByLocalCID(uShort usLocalChannelID);
00743 L2capConnChannel * ChannelLookupByRemoteCID(uShort usRemoteChannelID);
00744 bool ChannelClose(uShort usChannelID);
00745
00746 uShort L2CA_ConnectReq(uShort PSM, BdAddr BD_Addr,
00747 uShort *pLCID, uShort *pStatus);
00748 uShort L2CA_ConnectRsp(BdAddr BD_Addr,uChar ucIdentifier,
00749 uShort LCID, uShort response, uShort status);
00750
00751 uShort L2CA_ConfigReq(uShort CID, uShort InMTU, void *pOutFlow,
00752 uShort OutFlushTO, uShort LinkTO, uShort *pInMTU_O,
00753 void *pOutFlow_O, uShort *pOutFlushTO_O);
00754 uShort L2CA_ConfigRsp(uShort LCID, uShort OutMTU, uChar ucId, void *pInFlow,
00755 uShort result);
00756 uShort L2CA_DisconnectReq(uShort CID);
00757 uShort L2CA_DisconnectRsp(uShort usLocalCID, uChar ucIdentifier);
00758
00759 void L2CA_DataWriteReq(uShort usCID, uShort usLength,
00760 void *OutBuffer);
00761
00762 uShort L2CA_DataWriteCfm(uLong *size );
00763 uShort L2CA_DataRead(uLong CID, uLong length, void *pInBuffer, uLong *pN);
00764 uShort L2CA_GroupCreate(uLong PSM);
00765 uShort L2CA_GroupClose(uLong CID);
00766 uShort L2CA_GroupAddMember(uLong CID, BdAddr BD_Addr);
00767 uShort L2CA_GroupRemoveMember(uLong CID, BdAddr BD_Addr);
00768 uShort L2CA_GroupMembership(uLong CID, uLong *pN,
00769 void *BD_Addr_List);
00770 uShort L2CA_Ping(BdAddr BD_ADDR, uLong length,void *pEchoData,
00771 uLong size);
00772 uShort L2CA_DisableCLT(uLong PSM);
00773 uShort L2CA_EnableCLT(uLong PSM);
00774
00775 void AttachLMP(LMP *pLMPStack) {
00776 if((pLMP==NULL)&&(pLMPStack!=NULL))
00777 pLMP = pLMPStack;
00778 else
00779 cout<<"LMP already attached or parameter invalid."<<endl;
00780 }
00781 #define UPPER_PROTOCOL Bnep
00782 #define LOWER_PROTOCOL BaseBand
00783 Bnep * pUpperProtocol;
00784 BaseBand * pLowerProtocol;
00785 LMP *pLMP;
00786
00787
00788
00789
00790
00791
00792
00793
00794 private:
00795
00796 AssembleBuf assembleBuf;
00797 Node * pNode;
00798 BdAddr localAddr;
00799
00800
00801 int EventIndication(Event_t);
00802
00803
00804
00805 L2capSignalChannel *pSignalChannel;
00806
00807 L2capChannelList ChannelList;
00808 };
00809
00810 #endif