⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfcomm.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
// 
//      Bluetooth RFCOMM Layer
// 
// 
// Module Name:
// 
//      rfcomm.cxx
// 
// Abstract:
// 
//      This file implements Bluetooth RFCOMM Layer
// 
// 
//------------------------------------------------------------------------------
#include <windows.h>
#include <svsutil.hxx>

#if ! defined (UNDER_CE)
#include <stddef.h>
#include <malloc.h>
#else
#include <stdlib.h>
#endif

#include <bt_debug.h>
#include <bt_os.h>
#include <bt_buffer.h>
#include <bt_hcip.h>
#include <bt_ddi.h>

#define RFCOMM_T1		60
#define RFCOMM_T2		60
#define RFCOMM_T3		5
#define RFCOMM_N1		127

#define RFCOMM_MAX_CH	31

#define RFCOMM_SCALE	10

//	link stages (phys & log)
#define	DORMANT			0x00
#define CONNECTING		0x01
#define CONNECTED		0x02
#define CONFIG_REQ_DONE 0x04	// L2CAP Only
#define CONFIG_IND_DONE 0x08	// L2CAP Only
#define L2CAPUP         0x0e	// L2CAP Only
#define SABM0UA			0x10	// L2CAP Only
#define UP              0x1e

#define CALL_L2CAP_LINK_SETUP		0x01
#define CALL_L2CAP_LINK_CONFIG		0x02
#define CALL_RFCOMM_SABM0			0x03
#define CALL_RFCOMM_SABMN			0x04
#define CALL_RFCOMM_DISCN			0x05
#define CALL_RFCOMM_USERDATA		0x06
#define CALL_RFCOMM_SIGNALDATA		0x07

#define RFCOMM_SIGNAL_ASYNC			0x1
#define RFCOMM_SIGNAL_RESPONSE   	0x2
#define RFCOMM_SIGNAL_NONE			0x3


//
//	Protocol settings are loosely derived from Whistler RFCOMM protocol.h (by stana)
//
struct TS_FRAME_HEADER {
    unsigned char   ucAddress;
    unsigned char   ucControl;
    unsigned char   ucLength;
};

struct TS_FRAME_HEADER_X {
    unsigned char   ucAddress;
    unsigned char   ucControl;
    unsigned char   ucLength;
    unsigned char   ucExtLength;
	unsigned char	ucCredits;
};

struct TS_FRAME_FOOTER {
    unsigned char   ucFcs;
};

struct TS_FRAME {
	TS_FRAME_HEADER	h;
	TS_FRAME_FOOTER	f;
};

#define EA_BIT				0x01
#define CR_BIT				0x02
#define DLCI_DIRECTION_BIT  0x04

#define CHANNEL_MASK		0x1f
#define DLCI_MASK			0x2f

#define DLCI_FROM_CHANNEL(c, i)  ((((c)&CHANNEL_MASK)<<1) + ((i) ? 0 : 1))
#define DLCI_FROM_ADDRESS(a)     (((a)>>2)&DLCI_MASK)
#define CHANNEL_FROM_ADDRESS(a)  (((a)>>3)&CHANNEL_MASK)


#define CTL_SABM    0x2f
#define CTL_UA      0x63
#define CTL_DM      0x0f
#define CTL_DISC    0x43
#define CTL_UIH     0xef

#define CTL_PF      0x10

inline int TS_LENGTH(unsigned char *p) {
	return (p[0] & EA_BIT ? p[0] : p[0] | (p[1] << 8)) >> 1;
}

#define TS_SIZEOFLENGTH(p)  (((*(unsigned char *)(p))&EA_BIT) ? 1 : 2)
#define TS_SIZEOFHEADER(h)  (sizeof(TS_FRAME_HEADER)+TS_SIZEOFLENGTH(&(h)->Length))

// TEST is an RFCOMM ping.  N bytes of data are sent, and must be echoed back
// exactly to complete the test.
#pragma warning (push)
#pragma warning (disable : 4200)
struct MUX_MSG_TEST {
    unsigned char       Command;
    unsigned char       Length;
    unsigned char       Data[0];
};
#pragma warning (pop)
#define MSG_TEST    0x08

// Turn on aggregate flow control
struct MUX_MSG_FCON {
    unsigned char       Command;
    unsigned char       Length;                 // always 0
};
#define MSG_FCON    0x28

// Turn off aggregate flow control
struct MUX_MSG_FCOFF {
    unsigned char       Command;
    unsigned char       Length;                 // always 0
};
#define MSG_FCOFF   0x18

// Modem status command
struct MUX_MSG_MSC {
    unsigned char       Command;
    unsigned char       Length;                 // 2 or 3
    unsigned char       Address;
    unsigned char       Signals;
    unsigned char       Break;
};
#define MSG_MSC     0x38

#define MSC_EA_BIT      EA_BIT
#define MSC_FC_BIT      BIT(1)      // Flow control, clear if we can receive
#define MSC_RTC_BIT     BIT(2)      // Ready to communicate, set when ready
#define MSC_RTR_BIT     BIT(3)      // Ready to receive, set when ready
#define MSC_IC_BIT      BIT(6)      // Incoming call
#define MSC_DV_BIT      BIT(7)      // Data valid

#define MSC_BREAK_BIT   BIT(1)      // Set if sending break
#define MSC_SET_BREAK_LENGTH(b, l)  ((b) = ((b)&0x3) | (((l)&0xf) << 4))

/* Alignment & packing
struct MUX_MSG_RPN {
    unsigned char       Command;
    unsigned char       Length;                 // 1 or 8
    unsigned char       Address;
    unsigned    Baud                : 8;

    unsigned    DataBits            : 2;
    unsigned    StopBits            : 1;
    unsigned    ParityEnabled       : 1;
    unsigned    ParityType          : 2;
    unsigned    Reserved0           : 2;

    unsigned    XonXoffInput        : 1;
    unsigned    XonXoffOutput       : 1;
    unsigned    RTRInput            : 1;
    unsigned    RTROutput           : 1;
    unsigned    RTCInput            : 1;
    unsigned    RTCOutput           : 1;
    unsigned    Reserved1           : 2;

    unsigned    XonChar             : 8;
    unsigned    XoffChar            : 8;
    union {
        struct {
            unsigned    Baud            : 1;
            unsigned    Data            : 1;
            unsigned    Stop            : 1;
            unsigned    Parity          : 1;
            unsigned    ParityType      : 1;
            unsigned    XonChar         : 1;
            unsigned    XofChar         : 1;
            unsigned    Reserved        : 1;

            unsigned    XonXoffInput    : 1;
            unsigned    XonXoffOutput   : 1;
            unsigned    RTRInput        : 1;
            unsigned    RTROutput       : 1;
            unsigned    RTCInput        : 1;
            unsigned    RTCOutput       : 1;
            unsigned    Reserved1       : 2;
        };
        USHORT          Mask;
    } Change;
}; */

#define MSG_RPN     0x24

#define RPN_BAUD_2400       0
#define RPN_BAUD_4800       1
#define RPN_BAUD_7200       2
#define RPN_BAUD_9600       3
#define RPN_BAUD_19200      4
#define RPN_BAUD_38400      5
#define RPN_BAUD_57600      6
#define RPN_BAUD_115200     7
#define RPN_BAUD_230400     8

#define RPN_DATA_5          0
#define RPN_DATA_6          1
#define RPN_DATA_7          2
#define RPN_DATA_8          3

#define RPN_PARITY_ODD      0
#define RPN_PARITY_EVEN     1
#define RPN_PARITY_MARK     2
#define RPN_PARITY_SPACE    3

// Remote line status
/* Alignment & packing
struct MUX_MSG_RLS {
    unsigned char       Command;
    unsigned char       Length;                     // Always 2
    unsigned char       Address;
    struct  {
        unsigned    Error           : 1;    // An error has occurred

        unsigned    OverrunError    : 1;    //
        unsigned    ParityError     : 1;    // Type of error
        unsigned    FramingError    : 1;    //
    } LineStatus;
}; */
#define MSG_RLS     0x14

// Parameter negotiation
/* Alignment & packing
struct MUX_MSG_PN {
    unsigned char       Command;
    unsigned char       Length;
    unsigned    IType               : 4;    // Always 0, (UIH frames)
    unsigned    ConvergenceLayer    : 4;
    unsigned    Priority            : 6;
    unsigned    Fill0               : 2;
    unsigned    AckTimer            : 8;    // Hundredths of a second
    unsigned    MaxFrameSize        : 16;
    unsigned    MaxRetransmissions  : 8;
    unsigned    WindowSize          : 3;
    unsigned    Fill1               : 5;
}; */
#define MSG_PN  0x20

struct MUX_MSG_NSC {
    unsigned char       Command;
    unsigned char       Length;                     // Always 1
    unsigned char       CommandNotSupported;
};
#define MSG_NSC 0x04

#define MSG_PSC	0x10
#define MSG_CLD	0x30
#define MSG_SNC	0x34

struct DLCI;
struct Task;
struct Session;
struct RFCOMM_CONTEXT;

struct DLCI {
	DLCI			*pNext;			// Next channel

	Session			*pSess;			// Physical session

	RFCOMM_CONTEXT	*pOwner;		// Owner context
	unsigned int	channel    : 5;	// server channel id
	unsigned int	fLocal     : 1;	// Channel is local?
	unsigned int	fStage     : 8;	// Lifestage of a channel
	unsigned int	fFCA       : 1;	// 1 = sent FC signal already

	DLCI (Session *a_pSess, unsigned char a_ch, int a_fLocal, RFCOMM_CONTEXT *a_pOwner) {
		memset (this, 0, sizeof(*this));

		pSess  = a_pSess;
		pOwner = a_pOwner;
		channel= a_ch;
		fLocal = a_fLocal ? TRUE : FALSE;
	}

	void *operator new (size_t iSize);
	void operator delete (void *ptr);
};

struct Task {
	Task			*pNext;			// Next task
	RFCOMM_CONTEXT	*pOwner;		// Owner context
	void			*pContext;		// Call context

	unsigned int	fWhat			: 8;	// Call type
	unsigned int	channel			: 5;	// Channel server id
	unsigned int	fLocal			: 1;	// Channel is local
	unsigned int	fPF				: 1;	// Does this block the line?
	unsigned int	fData			: 1;	// Is this data or signal
	unsigned int	fUnused         : 2;	// pad
	unsigned int    eType			: 6;	// Signal type

	unsigned char   signal_length      : 4;	// Signal packet waiting for session to open
	unsigned char	signal_dlci_offset : 4;	// offset to be filled with DLCI

	unsigned char   signal_body[10];

	Session			*pPhysLink;

	Task (int a_fWhat, RFCOMM_CONTEXT *a_pOwner, Session *a_pSess) {
		memset (this, 0, sizeof(*this));

		pOwner    = a_pOwner;
		fWhat     = a_fWhat;
		pPhysLink = a_pSess;

		if ((fWhat == CALL_RFCOMM_USERDATA) || (fWhat == CALL_RFCOMM_SIGNALDATA))
			fData = TRUE;
	}

	Task (RFCOMM_CONTEXT *a_pOwner, Session *a_pSess, void *a_pContext, unsigned char a_cType) {
		memset (this, 0, sizeof(*this));

		pOwner    = a_pOwner;
		pContext  = a_pContext;
		fWhat     = CALL_RFCOMM_SIGNALDATA;
		fData     = TRUE;
		eType     = a_cType;
		pPhysLink = a_pSess;
	}

	void *operator new (size_t iSize);
	void operator delete (void *ptr);
};

struct Session {
	Session			*pNext;			// Next session
	DLCI			*pLogLinks;		// List of logical channels

	BD_ADDR			b;				// Bluetooth address
	unsigned short	cid;			// L2CAP cid

	unsigned int	fStage    : 8;	// Lifestage
	unsigned int	fIncoming : 1;	// DLCI DIRECTION BIT = ! fIncoming
	unsigned int	fBusy     : 1;	// Has PF command outstanding
	unsigned int    fWaitAck  : 1;  // PF command was removed, but UA/DM is needed

	unsigned short	inMTU;			// L2CAP MTU in
	unsigned short	outMTU;			// L2CAP MTU out

	SVSCookie		kTimeoutCookie;	// Timer handle

	int				iErr;			// Number of physical errors

	Session (BD_ADDR *pba) {
		memset (this, 0, sizeof(*this));

		b         = *pba;
		fStage	  = DORMANT;
	}

	void *operator new (size_t iSize);
	void operator delete (void *ptr);

#if defined (DEBUG) || defined (_DEBUG)
	unsigned char   ucDbgBusyChannel;
#endif
};

struct ServerChannel {
	ServerChannel	*pNext;
	unsigned int	channel : 5;

	void *operator new (size_t iSize);
	void operator delete (void *ptr);
};

struct RFCOMM_CONTEXT : public SVSAllocClass, public SVSRefObj {
	RFCOMM_CONTEXT			*pNext;	// Next context

	RFCOMM_EVENT_INDICATION	ei;		// Event indicators vtable
	RFCOMM_CALLBACKS		c;		// Callbacks vtable

	void			        *pUserContext;	// User context

	ServerChannel			*pReservedChannels;

	unsigned int			fDefaultServer;	// Channel to restrict incoming connections to.

	RFCOMM_CONTEXT (void) {
		pNext = NULL;
		memset (&ei, 0, sizeof(ei));
		memset (&c, 0, sizeof(c));

		pUserContext      = NULL;
		pReservedChannels = NULL;
		fDefaultServer    = FALSE;
	}

};

class RFCOMM : public SVSSynch, public SVSRefObj, public SVSAllocClass {
public:
	RFCOMM_CONTEXT	*pContexts;		// List of contexts
	Session			*pPhysLinks;	// List of sessions
	Task			*pCalls;		// List of calls

	FixedMemDescr	*pfmdSessions;	// FMD for sessions
	FixedMemDescr	*pfmdChannels;	// FMD for channels
	FixedMemDescr	*pfmdCalls;		// FMD for calls
	FixedMemDescr	*pfmdSC;		// FMD for server channels

	HANDLE			hL2CAP;			// L2CAP handle
	L2CAP_INTERFACE	l2cap_if;		// L2CAP interface table

	int				cDataHeaders;	// Size of headers at the lower layer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -