www.pudn.com > WINCEOS.zip > hidpkt.cxx
// // 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. // #include#include #if defined (DEBUG) || defined (_DEBUG) #undef DEBUGCHK #define DEBUGCHK SVSUTIL_ASSERT #endif #include "bthidpriv.h" #include "hidpkt.h" static CRITICAL_SECTION gAllocator; static FixedMemDescr *pfmdAllocator; int BthPktInitAllocator (void) { InitializeCriticalSection (&gAllocator); pfmdAllocator = svsutil_AllocFixedMemDescr (sizeof(BTHHIDPacket), 10); return pfmdAllocator != NULL; } int BthPktFreeAllocator (void) { if (pfmdAllocator) svsutil_ReleaseFixedNonEmpty (pfmdAllocator); pfmdAllocator = NULL; DeleteCriticalSection (&gAllocator); return TRUE; } void *BTHHIDPacket::operator new (size_t iSize) { SVSUTIL_ASSERT (iSize == sizeof(BTHHIDPacket)); if (! pfmdAllocator) return NULL; EnterCriticalSection (&gAllocator); void *pRes = svsutil_GetFixed (pfmdAllocator); LeaveCriticalSection (&gAllocator); return pRes; } void BTHHIDPacket::operator delete(void *ptr) { EnterCriticalSection (&gAllocator); if (pfmdAllocator) svsutil_FreeFixed (ptr, pfmdAllocator); LeaveCriticalSection (&gAllocator); } BTHHIDPacket::BTHHIDPacket() : m_bHeader(0), m_pbPayload(NULL), m_cbPayload(0), m_cbRemaining(0), m_iMTU(0), m_iReportType(BTHID_REPORT_OTHER) { } BTHHIDPacket::BTHHIDPacket(BYTE* pPayload, int cbBuffer) : m_bHeader(0), m_pbPayload(pPayload), m_cbPayload(cbBuffer), m_cbRemaining(cbBuffer), m_iMTU(0), m_iReportType(BTHID_REPORT_OTHER) { } /* BTHHIDPacket::BTHHIDPacket(const BTHHIDPacket& packet) { if (this != &packet) { m_bHeader = packet.m_bHeader; m_cbRemaining = packet.m_cbRemaining; m_iMTU = packet.m_iMTU; m_iReportType = packet.m_iReportType; m_cbPayload = packet.m_cbPayload; if (m_cbPayload > 0) { m_pbPayload = new BYTE[m_cbPayload]; memcpy(m_pbPayload, packet.m_pbPayload, m_cbPayload); } else { m_pbPayload = NULL; } } } */ BTHHIDPacket::~BTHHIDPacket() { } void BTHHIDPacket::ReleasePayload() { if (m_pbPayload != m_ucBuffer) delete[] m_pbPayload; m_cbPayload = 0; m_pbPayload = NULL; } void BTHHIDPacket::SetReportType(E_BTHID_REPORT_TYPES iReportType) { m_iReportType = iReportType; } void BTHHIDPacket::SetHeader(BYTE bHeader) { m_bHeader = bHeader; } void BTHHIDPacket::SetPayload(BYTE* pbPayload, int cbPayload) { m_pbPayload = pbPayload; m_cbPayload = cbPayload; m_cbRemaining = cbPayload; } void BTHHIDPacket::SetMTU(int iMTU) { m_iMTU = iMTU; } void BTHHIDPacket::SetOwner(void *pOwner) { m_pOwner = pOwner; } E_BTHID_REPORT_TYPES BTHHIDPacket::GetReportType() const { return m_iReportType; } BYTE BTHHIDPacket::GetHeader() const { return m_bHeader; } int BTHHIDPacket::GetMTU() const { return m_iMTU; } void *BTHHIDPacket::GetOwner() const { return m_pOwner; } void BTHHIDPacket::GetPayload(BYTE** ppbPayload, int* pcbPayload) const { if (!IsBadWritePtr(ppbPayload, sizeof(*ppbPayload)) && !IsBadWritePtr(pcbPayload, sizeof(*pcbPayload))) { *ppbPayload = m_pbPayload; *pcbPayload = m_cbPayload; } } BOOL BTHHIDPacket::AddPayloadChunk(BYTE* pbPayload, int cbPayload) { // DEBUGCHK(!IsBadReadPtr(pbPayload, cbPayload)); // The payload contains the BTHID header. Store it. if (m_bHeader == 0) { m_bHeader = *pbPayload; m_iReportType = (E_BTHID_REPORT_TYPES) (m_bHeader & 0x03); } ++pbPayload; --cbPayload; if (cbPayload > 0) { // Regrow internal array int cNew = m_cbPayload + cbPayload; BYTE* pNew = cNew > sizeof(m_ucBuffer) ? new BYTE[cNew] : m_ucBuffer; if (pNew) { // Copy old data if ((m_cbPayload > 0) && (pNew != m_pbPayload)) { memcpy(pNew, m_pbPayload, m_cbPayload); if (m_pbPayload != m_ucBuffer) delete[] m_pbPayload; } m_pbPayload = pNew; // Add the new chunk memcpy(m_pbPayload + m_cbPayload, pbPayload, cbPayload); m_cbPayload += cbPayload; m_cbRemaining = m_cbPayload; } } // If this chunk is equal to the MTU size, we need to recv more data so // we return true. Otherwise, we return false to indicate that the // packet is complete and can be indicated up. return (cbPayload + 1) == m_iMTU; } BOOL BTHHIDPacket::GetPayloadChunk(BYTE* pbPayload, int cbPayload, int* pcbTransfered) { // DEBUGCHK(!IsBadWritePtr(pcbTransfered, sizeof(*pcbTransfered))); int c = (m_iMTU - 1) < m_cbRemaining ? (m_iMTU-1) : m_cbRemaining; if (cbPayload == 0) { *pcbTransfered = c + 1; return TRUE; } DEBUGCHK(cbPayload >= c); if (m_cbRemaining == m_cbPayload) *pbPayload = m_bHeader; else { BTHID_Header_Parameter headerDATC; headerDATC.bRawHeader = 0; headerDATC.datc_p.bReportType = m_iReportType; *pbPayload = (BTHID_DATC << 4) | headerDATC.bRawHeader; } if (c > 0) { memcpy(pbPayload + 1, (m_cbPayload - m_cbRemaining) + m_pbPayload, c); m_cbRemaining -= c; } // Transfered c payload bytes plus the header *pcbTransfered = c + 1; return (m_cbRemaining > 0) || (c == m_iMTU-1); }