gobi-api: add GobiAPI_2012-09-12-0719
This commit is contained in:
parent
abab11c291
commit
aeddf3ef8a
|
@ -0,0 +1,647 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Comm.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Implementation of cComm class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cComm
|
||||
This class wraps low level port communications
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "Comm.h"
|
||||
#include "ProtocolServer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread commands
|
||||
#define START_READ_CMD 0
|
||||
#define STOP_READ_CMD 1
|
||||
#define EXIT_CMD 2
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
RxThread (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Thread for simulating asynchronous reads
|
||||
|
||||
PARAMETERS:
|
||||
pData [ I ] Asynchronous read object
|
||||
|
||||
RETURN VALUE:
|
||||
void * - thread exit value (always 0)
|
||||
===========================================================================*/
|
||||
void * RxThread( void * pData )
|
||||
{
|
||||
cComm * pComm = (cComm*)pData;
|
||||
if (pComm == NULL || pComm->IsValid() == false)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd_set inputSet, outputSet;
|
||||
FD_ZERO( &inputSet );
|
||||
FD_SET( pComm->mCommandPipe[READING], &inputSet );
|
||||
int largestFD = pComm->mCommandPipe[READING];
|
||||
|
||||
int status = 0;
|
||||
while (true)
|
||||
{
|
||||
// No FD_COPY() available
|
||||
memcpy( &outputSet, &inputSet, sizeof( fd_set ) );
|
||||
|
||||
status = select( largestFD + 1, &outputSet, NULL, NULL, NULL );
|
||||
if (status <= 0)
|
||||
{
|
||||
TRACE( "error %d in select, errno %d\n", status, errno );
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET( pComm->mCommandPipe[READING], &outputSet ) == true)
|
||||
{
|
||||
// Read from the pipe
|
||||
BYTE cmd;
|
||||
status = read( pComm->mCommandPipe[READING], &cmd, 1 );
|
||||
if (status != 1)
|
||||
{
|
||||
TRACE( "cmd error %d\n", status );
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd == START_READ_CMD)
|
||||
{
|
||||
FD_SET( pComm->mPort, &inputSet );
|
||||
largestFD = std::max( pComm->mPort,
|
||||
pComm->mCommandPipe[READING] );
|
||||
}
|
||||
else if (cmd == STOP_READ_CMD)
|
||||
{
|
||||
FD_CLR( pComm->mPort, &inputSet );
|
||||
largestFD = pComm->mCommandPipe[READING];
|
||||
}
|
||||
else
|
||||
{
|
||||
// EXIT_CMD or anything else
|
||||
pComm->mpRxCallback = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET( pComm->mPort, &outputSet ) == true)
|
||||
{
|
||||
// Stop watching for read data
|
||||
FD_CLR( pComm->mPort, &inputSet );
|
||||
largestFD = pComm->mCommandPipe[READING];
|
||||
|
||||
// Perform a read
|
||||
status = read( pComm->mPort,
|
||||
pComm->mpBuffer,
|
||||
pComm->mBuffSz );
|
||||
|
||||
cIOCallback * pCallback = pComm->mpRxCallback;
|
||||
pComm->mpRxCallback = 0;
|
||||
|
||||
if (pCallback == (cIOCallback *)1)
|
||||
{
|
||||
// We wanted to read, but not to be notified
|
||||
}
|
||||
else if (status >= 0)
|
||||
{
|
||||
pCallback->IOComplete( 0, status );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCallback->IOComplete( status, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// cComm Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cComm (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cComm::cComm()
|
||||
: mPortName( "" ),
|
||||
mPort( INVALID_HANDLE_VALUE ),
|
||||
mbCancelWrite( false ),
|
||||
mpBuffer( 0 ),
|
||||
mBuffSz( 0 ),
|
||||
mRxThreadID( 0 )
|
||||
{
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cComm (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cComm::~cComm()
|
||||
{
|
||||
// Disconnect from current port
|
||||
Disconnect();
|
||||
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsValid (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Is this object valid?
|
||||
|
||||
RETURN VALUE:
|
||||
Bool
|
||||
===========================================================================*/
|
||||
bool cComm::IsValid()
|
||||
{
|
||||
// Nothing to do, dependant on extended class functionality
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Connect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Connect to the specified port
|
||||
|
||||
PARAMETERS:
|
||||
pPort [ I ] - Name of port to open (IE: /dev/qcqmi0)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::Connect( LPCSTR pPort )
|
||||
{
|
||||
if (IsValid() == false || pPort == 0 || pPort[0] == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPort != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
// Initialize command pipe for read thread
|
||||
int nRet = pipe( mCommandPipe );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "cComm:Connect() pipe creation failed %d\n", nRet );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the read thread
|
||||
nRet = pthread_create( &mRxThreadID,
|
||||
0,
|
||||
RxThread,
|
||||
this );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "cComm::Connect() pthread_create = %d\n", nRet );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Opening the com port
|
||||
mPort = open( pPort, O_RDWR );
|
||||
if (mPort == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save port name
|
||||
mPortName = pPort;
|
||||
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
SendCtl (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Run an IOCTL on the open file handle
|
||||
|
||||
PARAMETERS:
|
||||
ioctlReq [ I ] - ioctl request value
|
||||
pData [I/O] - input or output specific to ioctl request value
|
||||
|
||||
RETURN VALUE:
|
||||
int - ioctl return value (0 for success)
|
||||
===========================================================================*/
|
||||
int cComm::SendCtl(
|
||||
UINT ioctlReq,
|
||||
void * pData )
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
TRACE( "Invalid file handle\n" );
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
return ioctl( mPort, ioctlReq, pData );
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Disconnect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Disconnect from the current port
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::Disconnect()
|
||||
{
|
||||
// Assume success
|
||||
bool bRC = true;
|
||||
|
||||
if (mCommandPipe[WRITING] != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (mRxThreadID != 0)
|
||||
{
|
||||
// Notify the thread to exit
|
||||
BYTE byte = EXIT_CMD;
|
||||
write( mCommandPipe[WRITING], &byte, 1 );
|
||||
|
||||
// And wait for it
|
||||
TRACE( "cComm::Disconnnect() joining thread %lu\n", mRxThreadID );
|
||||
int nRC = pthread_join( mRxThreadID, 0 );
|
||||
if (nRC != 0)
|
||||
{
|
||||
TRACE( "failed to join thread %d\n", nRC );
|
||||
bRC = false;
|
||||
}
|
||||
|
||||
mRxThreadID = 0;
|
||||
}
|
||||
|
||||
close( mCommandPipe[WRITING] );
|
||||
close( mCommandPipe[READING] );
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (mPort != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
close( mPort );
|
||||
mPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
// Double check
|
||||
mpRxCallback = 0;
|
||||
|
||||
mPortName.clear();
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ConfigureSettings (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Configure the port with the passed in parameters
|
||||
|
||||
PARAMETERS:
|
||||
pSettings [ I ] - Desired port settings
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::ConfigureSettings( termios * pSettings )
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE || pSettings == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tcflush( mPort, TCIOFLUSH );
|
||||
int nRC = tcsetattr( mPort, TCSANOW, pSettings );
|
||||
if (nRC == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetSettings (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return the current port settings
|
||||
|
||||
PARAMETERS:
|
||||
pSettings [ I ] - Current port settings
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::GetSettings( termios * pSettings )
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE || pSettings == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the COM port settings
|
||||
int nRC = tcgetattr( mPort, pSettings );
|
||||
if (nRC == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelIO (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress I/O
|
||||
|
||||
PARAMETERS:
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::CancelIO()
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bRxCancel = CancelRx();
|
||||
bool bTxCancel = CancelTx();
|
||||
|
||||
return (bRxCancel && bTxCancel);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelRx (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress receive operation
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::CancelRx()
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE
|
||||
|| mCommandPipe[WRITING] == INVALID_HANDLE_VALUE
|
||||
|| mpRxCallback == 0
|
||||
|| mRxThreadID == 0)
|
||||
{
|
||||
TRACE( "cannot cancel, thread not active\n" );
|
||||
mpRxCallback = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notify the thread to stop reading
|
||||
BYTE byte = STOP_READ_CMD;
|
||||
int nRC = write( mCommandPipe[WRITING], &byte, 1 );
|
||||
if (nRC != 1)
|
||||
{
|
||||
TRACE( "error %d canceling read\n", nRC );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the old callback
|
||||
mpRxCallback = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelTx (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress transmit operation
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::CancelTx()
|
||||
{
|
||||
if (mPort == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mbCancelWrite = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
RxData (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Receive data
|
||||
|
||||
PARAMETERS:
|
||||
pBuf [ I ] - Buffer to contain received data
|
||||
bufSz [ I ] - Amount of data to be received
|
||||
pCallback [ I ] - Callback object to be exercised when the
|
||||
operation completes
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::RxData(
|
||||
BYTE * pBuf,
|
||||
ULONG bufSz,
|
||||
cIOCallback * pCallback )
|
||||
{
|
||||
if (IsValid() == false || mpRxCallback != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pCallback == 0)
|
||||
{
|
||||
// Not interested in being notified, but we still need a value
|
||||
// for this so that only one outstanding I/O operation is active
|
||||
// at any given point in time
|
||||
mpRxCallback = (cIOCallback * )1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpRxCallback = pCallback;
|
||||
}
|
||||
|
||||
mpBuffer = pBuf;
|
||||
mBuffSz = bufSz;
|
||||
|
||||
// Notify the thread to stop reading
|
||||
BYTE byte = START_READ_CMD;
|
||||
int nRC = write( mCommandPipe[WRITING], &byte, 1 );
|
||||
if (nRC != 1)
|
||||
{
|
||||
TRACE( "error %d starting read\n", nRC );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
TxData (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Transmit data
|
||||
|
||||
PARAMETERS:
|
||||
pBuf [ I ] - Data to be transmitted
|
||||
bufSz [ I ] - Amount of data to be transmitted
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cComm::TxData(
|
||||
const BYTE * pBuf,
|
||||
ULONG bufSz )
|
||||
{
|
||||
if (IsValid() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
ULONGLONG nStart = GetTickCount();
|
||||
#endif
|
||||
|
||||
// Allow ourselves to be interupted
|
||||
mbCancelWrite = false;
|
||||
|
||||
// This seems a bit pointless, but we're still going verify
|
||||
// the device is ready for writing, and give it up to
|
||||
// (1000 + num bytes) MS to be ready (in 100 MS chunks)
|
||||
|
||||
struct timeval TimeOut;
|
||||
fd_set set;
|
||||
|
||||
int nReady = 0;
|
||||
int nCount = 0;
|
||||
|
||||
while ( nReady == 0 )
|
||||
{
|
||||
if (mbCancelWrite == true)
|
||||
{
|
||||
TRACE( "cComm::TxData() write canceled before device was ready\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nCount >= (1000 + bufSz) / 100)
|
||||
{
|
||||
// Timeout is expired
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO( &set );
|
||||
FD_SET( mPort, &set );
|
||||
TimeOut.tv_sec = 0;
|
||||
TimeOut.tv_usec = 100000;
|
||||
nReady = select( mPort + 1, NULL, &set, NULL, &TimeOut );
|
||||
|
||||
nCount++;
|
||||
}
|
||||
|
||||
if (nReady <= 0)
|
||||
{
|
||||
TRACE( "cComm::TxData() Unable to get device ready for"
|
||||
" Write, error %d: %s\n",
|
||||
nReady,
|
||||
strerror( nReady) );
|
||||
return false;
|
||||
}
|
||||
|
||||
int nRet = write( mPort, pBuf, bufSz );
|
||||
if (nRet != bufSz)
|
||||
{
|
||||
TRACE( "cComm::TxData() write returned %d instead of %lu\n",
|
||||
nRet,
|
||||
bufSz );
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
TRACE( "Write of %lu bytes took %llu miliseconds\n", bufSz, GetTickCount() - nStart );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Comm.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration of cComm class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cComm
|
||||
This class wraps low level port communications
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Event.h"
|
||||
#include "Connection.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cComm
|
||||
/*=========================================================================*/
|
||||
class cComm : public cConnection
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cComm();
|
||||
|
||||
// Destructor
|
||||
~cComm();
|
||||
|
||||
// Is this object valid?
|
||||
bool IsValid();
|
||||
|
||||
// Connect to the specified port
|
||||
bool Connect( LPCSTR pPort );
|
||||
|
||||
// Run an IOCTL on the open file handle
|
||||
int SendCtl(
|
||||
UINT ioctlReq,
|
||||
void * pData );
|
||||
|
||||
// Disconnect from the current port
|
||||
bool Disconnect();
|
||||
|
||||
// Configure the port with the passed in parameters
|
||||
bool ConfigureSettings( termios * pSettings );
|
||||
|
||||
// Return the current port settings
|
||||
bool GetSettings( termios * pSettings );
|
||||
|
||||
// Cancel any in-progress I/O
|
||||
bool CancelIO();
|
||||
|
||||
// Cancel any in-progress receive operation
|
||||
bool CancelRx();
|
||||
|
||||
// Cancel any in-progress transmit operation
|
||||
bool CancelTx();
|
||||
|
||||
// Receive data
|
||||
bool RxData(
|
||||
BYTE * pBuf,
|
||||
ULONG bufSz,
|
||||
cIOCallback * pCallback );
|
||||
|
||||
// Transmit data
|
||||
bool TxData(
|
||||
const BYTE * pBuf,
|
||||
ULONG bufSz );
|
||||
|
||||
// (Inline) Return current port name
|
||||
std::string GetPortName() const
|
||||
{
|
||||
return mPortName;
|
||||
};
|
||||
|
||||
// Are we currently connected to a port?
|
||||
bool IsConnected()
|
||||
{
|
||||
return (mPort != INVALID_HANDLE_VALUE);
|
||||
};
|
||||
|
||||
protected:
|
||||
/* Name of current port */
|
||||
std::string mPortName;
|
||||
|
||||
/* Handle to COM port */
|
||||
int mPort;
|
||||
|
||||
// Cancel the write request?
|
||||
bool mbCancelWrite;
|
||||
|
||||
/* Buffer */
|
||||
BYTE * mpBuffer;
|
||||
|
||||
/* Buffer size */
|
||||
ULONG mBuffSz;
|
||||
|
||||
/* Pipe for comunication with thread */
|
||||
int mCommandPipe[2];
|
||||
|
||||
/* Thread ID of Rx Thread. */
|
||||
pthread_t mRxThreadID;
|
||||
|
||||
// Rx thread is allowed complete access
|
||||
friend void * RxThread( void * pData );
|
||||
};
|
|
@ -0,0 +1,149 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Connection.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration of cConnection class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cComm
|
||||
This class defines a prototype for low level communications
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Event.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cIOCallback
|
||||
/*=========================================================================*/
|
||||
class cIOCallback
|
||||
{
|
||||
public:
|
||||
// (Inline) Constructor
|
||||
cIOCallback() { };
|
||||
|
||||
// (Inline) Destructor
|
||||
virtual ~cIOCallback() { };
|
||||
|
||||
// The I/O has been completed, process the results
|
||||
virtual void IOComplete(
|
||||
DWORD status,
|
||||
DWORD bytesTransferred ) = 0;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cConnection
|
||||
/*=========================================================================*/
|
||||
class cConnection
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cConnection()
|
||||
: mpRxCallback( 0 )
|
||||
{ };
|
||||
|
||||
// Is this object valid?
|
||||
virtual bool IsValid()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Connect to the specified interface
|
||||
virtual bool Connect( LPCSTR pPort )
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Send a control message
|
||||
virtual int SendCtl(
|
||||
UINT type,
|
||||
void * pData )
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Disconnect from the current port
|
||||
virtual bool Disconnect()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Cancel any in-progress I/O
|
||||
virtual bool CancelIO()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Cancel any in-progress receive operation
|
||||
virtual bool CancelRx()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Cancel any in-progress transmit operation
|
||||
virtual bool CancelTx()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Receive data
|
||||
virtual bool RxData(
|
||||
BYTE * pBuf,
|
||||
ULONG bufSz,
|
||||
cIOCallback * pCallback )
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Transmit data
|
||||
virtual bool TxData(
|
||||
const BYTE * pBuf,
|
||||
ULONG bufSz )
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// Are we currently connected to a port?
|
||||
virtual bool IsConnected()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
protected:
|
||||
/* Read callbacks */
|
||||
cIOCallback * mpRxCallback;
|
||||
};
|
|
@ -0,0 +1,437 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Event.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Implementation of cEvent class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
WaitOnMultipleEvents
|
||||
cEvent
|
||||
Functionality to mimic Windows events using UNIX pipes (enhanced
|
||||
somewhat to allow one to specify a DWORD value to pass through
|
||||
when signalling the event)
|
||||
|
||||
WARNING:
|
||||
This class is not designed to be thread safe
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "Event.h"
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
WaitOnMultipleEvents (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Wait for any of the events to be set and return the value
|
||||
|
||||
Note: If multiple events are set, only the event specified by
|
||||
eventIndex will be read from. Run this function again
|
||||
to get the next event.
|
||||
|
||||
PARAMETERS:
|
||||
events [ I ] - Vector of events which may be signaled
|
||||
timeoutMS [ I ] - Relative timeout length (in milliseconds)
|
||||
val [ O ] - Associated value upon success
|
||||
eventIndex [ O ] - Index of event which was signaled
|
||||
|
||||
RETURN VALUE:
|
||||
Return code
|
||||
positive for number of events set
|
||||
-ETIME on timeout
|
||||
negative errno value on failure
|
||||
===========================================================================*/
|
||||
int WaitOnMultipleEvents(
|
||||
std::vector <cEvent *> events,
|
||||
DWORD timeoutMS,
|
||||
DWORD & val,
|
||||
DWORD & eventIndex )
|
||||
{
|
||||
// Check internal pipes' status
|
||||
for (ULONG index = 0; index < events.size(); index++)
|
||||
{
|
||||
int error = events[index]->mError;
|
||||
if (error != 0)
|
||||
{
|
||||
TRACE( "cEvent %lu has error %d\n", index, error );
|
||||
return -error;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the FD set
|
||||
fd_set fds;
|
||||
FD_ZERO( &fds );
|
||||
|
||||
// Add each item to the FD set, keeping track of the largest,
|
||||
// which is used for select()
|
||||
int largestFD = 0;
|
||||
for (ULONG index = 0; index < events.size(); index++)
|
||||
{
|
||||
int pipe = events[index]->mPipes[READING];
|
||||
FD_SET( pipe, &fds );
|
||||
|
||||
largestFD = std::max( pipe, largestFD );
|
||||
}
|
||||
|
||||
struct timeval timeOut;
|
||||
|
||||
// Add avoiding an overflow on (long)usec
|
||||
timeOut.tv_sec = timeoutMS / 1000l;
|
||||
timeOut.tv_usec = ( timeoutMS % 1000l ) * 1000l;
|
||||
|
||||
// Wait for activity on the pipes for the specified amount of time
|
||||
int rc = select( largestFD + 1, &fds, 0, 0, &timeOut );
|
||||
if (rc == -1)
|
||||
{
|
||||
TRACE( "WaitOnMultipleEvents error %d\n", errno );
|
||||
return -errno;
|
||||
}
|
||||
else if (rc == 0)
|
||||
{
|
||||
// No activity on the pipes
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
int numSignaled = rc;
|
||||
|
||||
// Only read from first pipe which was signaled
|
||||
int signaled = -1;
|
||||
for (ULONG index = 0; index < events.size(); index++)
|
||||
{
|
||||
int pipe = events[index]->mPipes[READING];
|
||||
if (FD_ISSET( pipe, &fds ) != 0)
|
||||
{
|
||||
signaled = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (signaled == -1)
|
||||
{
|
||||
// Odd, no one was signaled
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
DWORD tempVal = 0;
|
||||
rc = events[signaled]->Read( tempVal );
|
||||
if (rc == 0)
|
||||
{
|
||||
// Success
|
||||
val = tempVal;
|
||||
eventIndex = signaled;
|
||||
return numSignaled;
|
||||
}
|
||||
else
|
||||
{
|
||||
// failure
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/*=========================================================================*/
|
||||
// cEvent Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cEvent (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cEvent::cEvent()
|
||||
: mError( 0 )
|
||||
{
|
||||
int rc = pipe( mPipes );
|
||||
if (rc != 0)
|
||||
{
|
||||
mError = errno;
|
||||
TRACE( "cEvent - Error %d creating pipe, %s\n",
|
||||
mError,
|
||||
strerror( mError ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cEvent (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cEvent::~cEvent()
|
||||
{
|
||||
// Check internal pipe status
|
||||
if (mError == 0)
|
||||
{
|
||||
Close();
|
||||
mError = EBADF;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Close (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Close pipe
|
||||
|
||||
RETURN VALUE:
|
||||
Return code
|
||||
0 on success
|
||||
errno value on failure
|
||||
===========================================================================*/
|
||||
int cEvent::Close()
|
||||
{
|
||||
int retCode = 0;
|
||||
|
||||
int rc = close( mPipes[READING] );
|
||||
mPipes[READING] = -1;
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
retCode = errno;
|
||||
TRACE( "cEvent - Error %d deleting pipe[READING], %s\n",
|
||||
retCode,
|
||||
strerror( retCode ) );
|
||||
}
|
||||
|
||||
rc = close( mPipes[WRITING] );
|
||||
mPipes[WRITING] = -1;
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
retCode = errno;
|
||||
TRACE( "cEvent - Error %d deleting pipe[WRITING], %s\n",
|
||||
retCode,
|
||||
strerror( retCode ) );
|
||||
}
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Set (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Set/signal the event with the specified value
|
||||
|
||||
PARAMETERS:
|
||||
val [ I ] - Value to pass through with signal
|
||||
|
||||
RETURN VALUE:
|
||||
Return code
|
||||
0 on success
|
||||
errno value on failure
|
||||
===========================================================================*/
|
||||
int cEvent::Set( DWORD val )
|
||||
{
|
||||
// Check internal pipe status
|
||||
if (mError != 0)
|
||||
{
|
||||
return mError;
|
||||
}
|
||||
|
||||
PBYTE pWrite = (PBYTE)&val;
|
||||
|
||||
int writeSize = sizeof( DWORD );
|
||||
while (writeSize > 0)
|
||||
{
|
||||
int bytesWritten = write( mPipes[WRITING], pWrite, writeSize );
|
||||
if (bytesWritten == -1)
|
||||
{
|
||||
// Store error from write
|
||||
int writeErr = errno;
|
||||
|
||||
// First error?
|
||||
if (mError == 0)
|
||||
{
|
||||
// Yes, save the error
|
||||
mError = writeErr;
|
||||
}
|
||||
|
||||
// We cannot recover from this error
|
||||
Close();
|
||||
return writeErr;
|
||||
}
|
||||
|
||||
pWrite += bytesWritten;
|
||||
writeSize -= bytesWritten;
|
||||
}
|
||||
|
||||
// Success
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Wait (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Wait for the event to be signalled and return the read in value
|
||||
|
||||
PARAMETERS:
|
||||
timeoutMS [ I ] - Relative timeout length (in milliseconds)
|
||||
val [ O ] - Associated value upon success
|
||||
|
||||
RETURN VALUE:
|
||||
Return code
|
||||
0 on success
|
||||
ETIME on timeout
|
||||
errno value on failure
|
||||
===========================================================================*/
|
||||
int cEvent::Wait(
|
||||
DWORD timeoutMS,
|
||||
DWORD & val )
|
||||
{
|
||||
// Check internal pipe status
|
||||
if (mError != 0)
|
||||
{
|
||||
return mError;
|
||||
}
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO( &fds );
|
||||
FD_SET( mPipes[READING], &fds );
|
||||
|
||||
struct timeval timeOut;
|
||||
|
||||
// Add avoiding an overflow on (long)usec
|
||||
timeOut.tv_sec = timeoutMS / 1000l;
|
||||
timeOut.tv_usec = ( timeoutMS % 1000l ) * 1000l;
|
||||
|
||||
// Wait for activity on the pipe for the specified amount of time
|
||||
int rc = select( mPipes[READING] + 1, &fds, 0, 0, &timeOut );
|
||||
if (rc == -1)
|
||||
{
|
||||
// Store error from select
|
||||
int selectErr = errno;
|
||||
|
||||
// First error?
|
||||
if (mError == 0)
|
||||
{
|
||||
// Yes, save the error
|
||||
mError = selectErr;
|
||||
}
|
||||
|
||||
// We cannot recover from this error
|
||||
Close();
|
||||
return selectErr;
|
||||
}
|
||||
else if (rc == 0)
|
||||
{
|
||||
// No activity on the pipe
|
||||
return ETIME;
|
||||
}
|
||||
|
||||
return Read( val );
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Clear (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Read and discard all values currently in the pipe
|
||||
===========================================================================*/
|
||||
void cEvent::Clear()
|
||||
{
|
||||
DWORD unusedVal;
|
||||
int rc = 0;
|
||||
while (rc == 0)
|
||||
{
|
||||
rc = Wait( (DWORD)0, unusedVal );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Read (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Read a DWORD from the pipe
|
||||
|
||||
RETURN VALUE:
|
||||
Return code
|
||||
0 on success
|
||||
errno value on failure
|
||||
===========================================================================*/
|
||||
int cEvent::Read( DWORD & val )
|
||||
{
|
||||
DWORD tempVal;
|
||||
PBYTE pRead = (PBYTE)&tempVal;
|
||||
|
||||
int readSize = sizeof( DWORD );
|
||||
while (readSize > 0)
|
||||
{
|
||||
int bytesRead = read( mPipes[READING], pRead, readSize );
|
||||
if (bytesRead <= 0)
|
||||
{
|
||||
// Store error from read
|
||||
int readErr = errno;
|
||||
if (readErr == 0)
|
||||
{
|
||||
// Hard error! This should NEVER happen for a pipe
|
||||
ASSERT( 0 );
|
||||
readErr = EBADF;
|
||||
}
|
||||
|
||||
// First error?
|
||||
if (mError == 0)
|
||||
{
|
||||
// Yes, store the error
|
||||
mError = readErr;
|
||||
}
|
||||
|
||||
// We cannot recover from this error
|
||||
Close();
|
||||
return readErr;
|
||||
}
|
||||
|
||||
pRead += bytesRead;
|
||||
readSize -= bytesRead;
|
||||
}
|
||||
|
||||
val = tempVal;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Event.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration of cEvent class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
WaitOnMultipleEvents
|
||||
cEvent
|
||||
Functionality to mimic Windows events using UNIX pipes (enhanced
|
||||
somewhat to allow one to specify a DWORD value to pass through
|
||||
when signalling the event)
|
||||
|
||||
WARNING:
|
||||
This class is not designed to be thread safe
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include <vector>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Prototype
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class cEvent;
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free methods
|
||||
/*=========================================================================*/
|
||||
|
||||
// Wait for any of the events to be set and return the value
|
||||
int WaitOnMultipleEvents(
|
||||
std::vector <cEvent *> events,
|
||||
DWORD timeoutMS,
|
||||
DWORD & val,
|
||||
DWORD & eventIndex );
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cEvent
|
||||
/*=========================================================================*/
|
||||
class cEvent
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cEvent();
|
||||
|
||||
// Destructor
|
||||
~cEvent();
|
||||
|
||||
// Set/signal the event with the specified value
|
||||
int Set( DWORD val );
|
||||
|
||||
// Wait for the event to be signalled and return the read in value
|
||||
int Wait(
|
||||
DWORD timeoutMS,
|
||||
DWORD & val );
|
||||
|
||||
// Read and discard all values currently in the pipe
|
||||
void Clear();
|
||||
|
||||
protected:
|
||||
// Close pipe (used in errors or normal exit)
|
||||
int Close();
|
||||
|
||||
// Read from the pipe
|
||||
int Read( DWORD & val );
|
||||
|
||||
/* Internal error status */
|
||||
int mError;
|
||||
|
||||
/* Internal pipes */
|
||||
int mPipes[2];
|
||||
|
||||
// WaitOnMultipleEvents gets full access
|
||||
friend int WaitOnMultipleEvents(
|
||||
std::vector <cEvent *> events,
|
||||
DWORD timeoutMS,
|
||||
DWORD & val,
|
||||
DWORD & eventIndex );
|
||||
};
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolBuffer.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolBuffer
|
||||
Simple struct to represent a protocol buffer using a reference counted
|
||||
(shared) buffer, this allows us to use in in several places without
|
||||
copying it once in each place. A few base services are provided
|
||||
but the main purpose is to provide a class to inherit off of for
|
||||
specific protocols
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "ProtocolBuffer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// sProtocolBuffer Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor (default)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolBuffer::sProtocolBuffer()
|
||||
: mpData( 0 ),
|
||||
mbValid( false )
|
||||
{
|
||||
// Object is currently invalid
|
||||
mTimestamp = EMPTY_TIME;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor (parameterized)
|
||||
|
||||
PARAMETERS:
|
||||
pBuffer [ I ] - Shareable buffer that contains the DIAG data
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolBuffer::sProtocolBuffer( sSharedBuffer * pBuffer )
|
||||
: mpData( 0 ),
|
||||
mbValid( false )
|
||||
{
|
||||
mTimestamp = EMPTY_TIME;
|
||||
|
||||
time_t rawtime;
|
||||
time( &rawtime );
|
||||
tm * timestamp = localtime( &rawtime );
|
||||
if (timestamp != 0)
|
||||
{
|
||||
mTimestamp = *timestamp;
|
||||
}
|
||||
|
||||
if (mpData != 0 && mpData->IsValid() == true)
|
||||
{
|
||||
mpData->Release();
|
||||
mpData = 0;
|
||||
}
|
||||
|
||||
mpData = pBuffer;
|
||||
if (mpData != 0 && mpData->IsValid() == true)
|
||||
{
|
||||
mpData->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
mpData = 0;
|
||||
}
|
||||
|
||||
// NOTE: Derived classes need to call their own validation method
|
||||
// in their constructors since the override might try to access
|
||||
// data that is not yet in place
|
||||
sProtocolBuffer::Validate();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Copy constructor
|
||||
|
||||
PARAMETERS:
|
||||
copyThis [ I ] - sProtocolBuffer to base the new one on
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolBuffer::sProtocolBuffer( const sProtocolBuffer & copyThis )
|
||||
: mpData( copyThis.mpData ),
|
||||
mTimestamp( copyThis.mTimestamp ),
|
||||
mbValid( copyThis.mbValid )
|
||||
{
|
||||
// Bump reference count for shared buffer
|
||||
if (mpData != 0 && mpData->IsValid() == true)
|
||||
{
|
||||
mpData->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
mpData = 0;
|
||||
mbValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
operator = (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Assignment operator
|
||||
|
||||
PARAMETERS:
|
||||
copyThis [ I ] - sProtocolBuffer to base the new one on
|
||||
|
||||
RETURN VALUE:
|
||||
sProtocolBuffer &
|
||||
===========================================================================*/
|
||||
sProtocolBuffer & sProtocolBuffer::operator = ( const sProtocolBuffer & copyThis )
|
||||
{
|
||||
// Do we already have data?
|
||||
if (mpData != 0)
|
||||
{
|
||||
// Is it different than what we are duplicating?
|
||||
if (mpData != copyThis.mpData)
|
||||
{
|
||||
// Yes, release our current buffer
|
||||
mpData->Release();
|
||||
}
|
||||
}
|
||||
|
||||
mpData = copyThis.mpData;
|
||||
mTimestamp = copyThis.mTimestamp;
|
||||
mbValid = copyThis.mbValid;
|
||||
|
||||
// Bump reference count for shared buffer
|
||||
if (mpData != 0 && mpData->IsValid() == true)
|
||||
{
|
||||
mpData->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
mpData = 0;
|
||||
mbValid = false;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~sProtocolBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolBuffer::~sProtocolBuffer()
|
||||
{
|
||||
if (mpData != 0 && mpData->IsValid() == true)
|
||||
{
|
||||
mpData->Release();
|
||||
mpData = 0;
|
||||
}
|
||||
else if (mpData != 0)
|
||||
{
|
||||
ASSERT( 0 );
|
||||
}
|
||||
|
||||
mbValid = false;
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolBuffer.h
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolBuffer
|
||||
Simple struct to represent a protocol buffer using a reference counted
|
||||
(shared) buffer, this allows us to use in in several places without
|
||||
copying it once in each place. A few base services are provided
|
||||
but the main purpose is to provide a class to inherit off of for
|
||||
specific protocols
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "SharedBuffer.h"
|
||||
#include "ProtocolEnum.h"
|
||||
|
||||
static const tm EMPTY_TIME = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sProtocolBuffer
|
||||
/*=========================================================================*/
|
||||
struct sProtocolBuffer
|
||||
{
|
||||
public:
|
||||
// Constructor (default)
|
||||
sProtocolBuffer();
|
||||
|
||||
// Constructor (parameterized)
|
||||
sProtocolBuffer( sSharedBuffer * pBuffer );
|
||||
|
||||
// Copy constructor
|
||||
sProtocolBuffer( const sProtocolBuffer & copyThis );
|
||||
|
||||
// Assignment operator
|
||||
sProtocolBuffer & operator = ( const sProtocolBuffer & copyThis );
|
||||
|
||||
// Destructor
|
||||
virtual ~sProtocolBuffer();
|
||||
|
||||
// (Inline) Get buffer
|
||||
const BYTE * GetBuffer() const
|
||||
{
|
||||
BYTE * pRet = 0;
|
||||
if (IsValid() == true)
|
||||
{
|
||||
pRet = (BYTE *)mpData->GetBuffer();
|
||||
}
|
||||
|
||||
return (const BYTE *)pRet;
|
||||
};
|
||||
|
||||
// (Inline) Get buffer size
|
||||
ULONG GetSize() const
|
||||
{
|
||||
ULONG size = 0;
|
||||
if (IsValid() == true)
|
||||
{
|
||||
size = mpData->GetSize();
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
// (Inline) Return the protocol type
|
||||
eProtocolType GetType() const
|
||||
{
|
||||
eProtocolType pt = ePROTOCOL_ENUM_BEGIN;
|
||||
if (IsValid() == true)
|
||||
{
|
||||
pt = (eProtocolType)mpData->GetType();
|
||||
}
|
||||
|
||||
return pt;
|
||||
};
|
||||
|
||||
// (Inline) Return the shared buffer
|
||||
sSharedBuffer * GetSharedBuffer() const
|
||||
{
|
||||
sSharedBuffer * pRet = 0;
|
||||
if (IsValid() == true)
|
||||
{
|
||||
pRet = mpData;
|
||||
}
|
||||
|
||||
return pRet;
|
||||
};
|
||||
|
||||
// (Inline) Return the timestamp
|
||||
tm GetTimestamp() const
|
||||
{
|
||||
tm ft = EMPTY_TIME;
|
||||
|
||||
if (IsValid() == true)
|
||||
{
|
||||
ft = mTimestamp;
|
||||
}
|
||||
|
||||
return ft;
|
||||
};
|
||||
|
||||
// (Inline) Is this buffer valid?
|
||||
virtual bool IsValid() const
|
||||
{
|
||||
return mbValid;
|
||||
};
|
||||
|
||||
protected:
|
||||
// (Inline) Validate buffer
|
||||
virtual bool Validate()
|
||||
{
|
||||
// Do we have a shared buffer and is it valid?
|
||||
mbValid = (mpData != 0 && mpData->IsValid());
|
||||
return mbValid;
|
||||
};
|
||||
|
||||
/* Our data buffer */
|
||||
sSharedBuffer * mpData;
|
||||
|
||||
/* Time buffer was created */
|
||||
tm mTimestamp;
|
||||
|
||||
/* Has this buffer been validated? (NOTE: *NOT* set in base) */
|
||||
bool mbValid;
|
||||
};
|
|
@ -0,0 +1,244 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolEnum.h
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol enumerations and related methods
|
||||
|
||||
PUBLIC ENUMERATIONS AND METHODS:
|
||||
eProtocolType
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// eProtocolType Enumeration
|
||||
//
|
||||
// NOTE: QMI protocol types need to be in the same order as eQMIService
|
||||
// with RX added first then TX
|
||||
/*=========================================================================*/
|
||||
enum eProtocolType
|
||||
{
|
||||
ePROTOCOL_ENUM_BEGIN = -1,
|
||||
|
||||
ePROTOCOL_COMMAND, // 000 Protocol server command
|
||||
ePROTOCOL_AT, // 001 AT command protocol
|
||||
ePROTOCOL_NMEA, // 002 NMEA (GPS) protocol
|
||||
ePROTOCOL_DIAG_RX, // 003 DIAG protocol (incoming)
|
||||
ePROTOCOL_DIAG_TX, // 004 DIAG protocol (outgoing)
|
||||
ePROTOCOL_DOWNLOAD_RX, // 005 Download protocol (incoming)
|
||||
ePROTOCOL_DOWNLOAD_TX, // 006 Download protocol (outgoing)
|
||||
ePROTOCOL_SDOWNLOAD_RX, // 007 Streaming download protocol (incoming)
|
||||
ePROTOCOL_SDOWNLOAD_TX, // 008 Streaming download protocol (outgoing)
|
||||
ePROTOCOL_QDL_RX, // 009 QDL streaming protocol (incoming)
|
||||
ePROTOCOL_QDL_TX, // 010 QDL streaming protocol (outgoing)
|
||||
|
||||
ePROTOCOL_QMI_CTL_RX = 60, // 060 QMI CTL protocol (incoming)
|
||||
ePROTOCOL_QMI_CTL_TX, // 061 QMI CTL protocol (outgoing)
|
||||
ePROTOCOL_QMI_WDS_RX, // 062 QMI WDS protocol (incoming)
|
||||
ePROTOCOL_QMI_WDS_TX, // 063 QMI WDS protocol (outgoing)
|
||||
ePROTOCOL_QMI_DMS_RX, // 064 QMI DMS protocol (incoming)
|
||||
ePROTOCOL_QMI_DMS_TX, // 065 QMI DMS protocol (outgoing)
|
||||
ePROTOCOL_QMI_NAS_RX, // 066 QMI NAS protocol (incoming)
|
||||
ePROTOCOL_QMI_NAS_TX, // 067 QMI NAS protocol (outgoing)
|
||||
ePROTOCOL_QMI_QOS_RX, // 068 QMI QOS protocol (incoming)
|
||||
ePROTOCOL_QMI_QOS_TX, // 069 QMI QOS protocol (outgoing)
|
||||
ePROTOCOL_QMI_WMS_RX, // 070 QMI WMS protocol (incoming)
|
||||
ePROTOCOL_QMI_WMS_TX, // 071 QMI WMS protocol (outgoing)
|
||||
ePROTOCOL_QMI_PDS_RX, // 072 QMI PDS protocol (incoming)
|
||||
ePROTOCOL_QMI_PDS_TX, // 073 QMI PDS protocol (outgoing)
|
||||
ePROTOCOL_QMI_AUTH_RX, // 074 QMI AUTH protocol (incoming)
|
||||
ePROTOCOL_QMI_AUTH_TX, // 075 QMI AUTH protocol (outgoing)
|
||||
ePROTOCOL_QMI_AT_RX, // 076 QMI AUTH protocol (incoming)
|
||||
ePROTOCOL_QMI_AT_TX, // 077 QMI AUTH protocol (outgoing)
|
||||
ePROTOCOL_QMI_VOICE_RX, // 078 QMI Voice protocol (incoming)
|
||||
ePROTOCOL_QMI_VOICE_TX, // 079 QMI Voice protocol (outgoing)
|
||||
ePROTOCOL_QMI_CAT2_RX, // 080 QMI CAT (new) protocol (incoming)
|
||||
ePROTOCOL_QMI_CAT2_TX, // 081 QMI CAT (new) protocol (outgoing)
|
||||
ePROTOCOL_QMI_UIM_RX, // 082 QMI UIM protocol (incoming)
|
||||
ePROTOCOL_QMI_UIM_TX, // 083 QMI UIM protocol (outgoing)
|
||||
ePROTOCOL_QMI_PBM_RX, // 084 QMI PBM protocol (incoming)
|
||||
ePROTOCOL_QMI_PBM_TX, // 085 QMI PBM protocol (outgoing)
|
||||
ePROTOCOL_QMI_13_RX, // 086 QMI service ID 13 protocol (incoming)
|
||||
ePROTOCOL_QMI_13_TX, // 087 QMI service ID 13 protocol (outgoing)
|
||||
ePROTOCOL_QMI_RMTFS_RX, // 088 QMI RMTFS protocol (incoming)
|
||||
ePROTOCOL_QMI_RMTFS_TX, // 089 QMI RMTFS protocol (outgoing)
|
||||
ePROTOCOL_QMI_15_RX, // 090 QMI service ID 15 protocol (incoming)
|
||||
ePROTOCOL_QMI_15_TX, // 091 QMI service ID 15 protocol (outgoing)
|
||||
ePROTOCOL_QMI_LOC_RX, // 092 QMI UIM protocol (incoming)
|
||||
ePROTOCOL_QMI_LOC_TX, // 093 QMI UIM protocol (outgoing)
|
||||
ePROTOCOL_QMI_SAR_RX, // 094 QMI PBM protocol (incoming)
|
||||
ePROTOCOL_QMI_SAR_TX, // 095 QMI PBM protocol (outgoing)
|
||||
ePROTOCOL_QMI_18_RX, // 096 QMI service ID 18 protocol (incoming)
|
||||
ePROTOCOL_QMI_18_TX, // 097 QMI service ID 18 protocol (outgoing)
|
||||
ePROTOCOL_QMI_19_RX, // 098 QMI service ID 19 protocol (incoming)
|
||||
ePROTOCOL_QMI_19_TX, // 099 QMI service ID 19 protocol (outgoing)
|
||||
ePROTOCOL_QMI_CSD_RX, // 100 QMI CSD protocol (incoming)
|
||||
ePROTOCOL_QMI_CSD_TX, // 101 QMI CSD protocol (outgoing)
|
||||
ePROTOCOL_QMI_EFS_RX, // 102 QMI EFS protocol (incoming)
|
||||
ePROTOCOL_QMI_EFS_TX, // 103 QMI EFS protocol (outgoing)
|
||||
ePROTOCOL_QMI_22_RX, // 104 QMI service ID 22 protocol (incoming)
|
||||
ePROTOCOL_QMI_22_TX, // 105 QMI service ID 22 protocol (outgoing)
|
||||
ePROTOCOL_QMI_TS_RX, // 106 QMI TS protocol (incoming)
|
||||
ePROTOCOL_QMI_TS_TX, // 107 QMI TS protocol (outgoing)
|
||||
ePROTOCOL_QMI_TMD_RX, // 108 QMI TMD protocol (incoming)
|
||||
ePROTOCOL_QMI_TMD_TX, // 109 QMI TMD protocol (outgoing)
|
||||
ePROTOCOL_QMI_25_RX, // 110 QMI service ID 25 protocol (incoming)
|
||||
ePROTOCOL_QMI_25_TX, // 111 QMI service ID 25 protocol (outgoing)
|
||||
ePROTOCOL_QMI_26_RX, // 112 QMI service ID 26 protocol (incoming)
|
||||
ePROTOCOL_QMI_26_TX, // 113 QMI service ID 26 protocol (outgoing)
|
||||
ePROTOCOL_QMI_27_RX, // 114 QMI service ID 27 protocol (incoming)
|
||||
ePROTOCOL_QMI_27_TX, // 115 QMI service ID 27 protocol (outgoing)
|
||||
ePROTOCOL_QMI_28_RX, // 116 QMI service ID 28 protocol (incoming)
|
||||
ePROTOCOL_QMI_28_TX, // 117 QMI service ID 28 protocol (outgoing)
|
||||
|
||||
ePROTOCOL_QMI_CAT_RX = 508, // 508 QMI CAT protocol (incoming)
|
||||
ePROTOCOL_QMI_CAT_TX, // 509 QMI CAT protocol (outgoing)
|
||||
ePROTOCOL_QMI_RMS_RX, // 510 QMI RMS protocol (incoming)
|
||||
ePROTOCOL_QMI_RMS_TX, // 511 QMI RMS protocol (outgoing)
|
||||
ePROTOCOL_QMI_OMA_RX, // 512 QMI OMA protocol (incoming)
|
||||
ePROTOCOL_QMI_OMA_TX, // 513 QMI OMA protocol (outgoing)
|
||||
|
||||
ePROTOCOL_ENUM_END
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsValid (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
eProtocolType validity check
|
||||
|
||||
PARAMETERS:
|
||||
pt [ I ] - Enum value being verified
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsValid( eProtocolType pt )
|
||||
{
|
||||
bool retVal = false;
|
||||
if ( (pt > ePROTOCOL_ENUM_BEGIN && pt <= ePROTOCOL_QDL_TX)
|
||||
|| (pt >= ePROTOCOL_QMI_CTL_RX && pt <= ePROTOCOL_QMI_28_TX)
|
||||
|| (pt >= ePROTOCOL_QMI_CAT_RX && pt < ePROTOCOL_ENUM_END) )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsQMIProtocol (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Does the passed in value represent a QMI protocol?
|
||||
|
||||
PARAMETERS:
|
||||
pt [ I ] - Enum value being checked
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsQMIProtocol( eProtocolType pt )
|
||||
{
|
||||
bool retVal = false;
|
||||
if ( (pt >= ePROTOCOL_QMI_CTL_RX && pt <= ePROTOCOL_QMI_28_TX)
|
||||
|| (pt >= ePROTOCOL_QMI_CAT_RX && pt < ePROTOCOL_ENUM_END) )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsQMIProtocolRX (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Does the passed in value represent a QMI protocol and if so in the
|
||||
incoming direction?
|
||||
|
||||
PARAMETERS:
|
||||
pt [ I ] - Enum value being checked
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsQMIProtocolRX( eProtocolType pt )
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
// QMI protocol values that are even are RX
|
||||
if ( (IsQMIProtocol( pt ) == true)
|
||||
&& ((DWORD)pt % 2 == 0) )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsQMIProtocolTX (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Does the passed in value represent a QMI protocol and if so in the
|
||||
outgoing direction?
|
||||
|
||||
PARAMETERS:
|
||||
pt [ I ] - Enum value being checked
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsQMIProtocolTX( eProtocolType pt )
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
// QMI protocol values that are odd are TX
|
||||
if ( (IsQMIProtocol( pt ) == true)
|
||||
&& ((DWORD)pt % 2 == 1) )
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
|
@ -0,0 +1,190 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolLog.h
|
||||
|
||||
DESCRIPTION:
|
||||
Simple protocol 'log' class definition
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cProtocolLog
|
||||
This class stores protocol buffers in to a flat array (actually a
|
||||
double-ended queue) so that they can be accessed by other objects
|
||||
during the flow of normal processing. Note that the storage is
|
||||
in-memory and therefore finite
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "ProtocolLog.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// The maximum number of in-memory buffers we allow
|
||||
const ULONG MAX_PROTOCOL_BUFFERS = 1024 * 16;
|
||||
|
||||
/*=========================================================================*/
|
||||
// cProtocolLog Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cProtocolLog (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
PARAMETERS:
|
||||
maxBuffers [ I ] - Maximum number of buffers to store in the log
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cProtocolLog::cProtocolLog( ULONG maxBuffers )
|
||||
: mLog( maxBuffers > MAX_PROTOCOL_BUFFERS ? MAX_PROTOCOL_BUFFERS : maxBuffers,
|
||||
true )
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cProtocolLog (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cProtocolLog::~cProtocolLog()
|
||||
{
|
||||
// Empty out the log
|
||||
Clear();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
AddBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Add an protocol buffer to the end of the log
|
||||
|
||||
PARAMETERS:
|
||||
buff [ I ] - Protocol buffer to add
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Index of newly added buffer (INVALID_LOG_INDEX upon failure)
|
||||
===========================================================================*/
|
||||
ULONG cProtocolLog::AddBuffer( sProtocolBuffer & buf )
|
||||
{
|
||||
ULONG idx = INVALID_LOG_INDEX;
|
||||
if (buf.IsValid() == false)
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool bRC = mLog.AddElement( buf, idx );
|
||||
if (bRC == false)
|
||||
{
|
||||
idx = INVALID_LOG_INDEX;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return the protocol buffer at the given index from the log
|
||||
|
||||
PARAMETERS:
|
||||
idx [ I ] - Index of protocol buffer to obtain
|
||||
|
||||
RETURN VALUE:
|
||||
sProtocolBuffer - Protocol buffer
|
||||
===========================================================================*/
|
||||
sProtocolBuffer cProtocolLog::GetBuffer( ULONG idx ) const
|
||||
{
|
||||
sProtocolBuffer buf;
|
||||
mLog.GetElement( idx, buf );
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetSignalEvent (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return the underlying signal event, which will be set when
|
||||
the log is updated.
|
||||
|
||||
RETURN VALUE:
|
||||
cEvent - Signal event
|
||||
===========================================================================*/
|
||||
cEvent & cProtocolLog::GetSignalEvent() const
|
||||
{
|
||||
return mLog.GetSignalEvent();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetCount (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return the total number of buffers added to the log
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG
|
||||
===========================================================================*/
|
||||
ULONG cProtocolLog::GetCount() const
|
||||
{
|
||||
return mLog.GetTotalCount();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Clear (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Clear the log
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void cProtocolLog::Clear()
|
||||
{
|
||||
mLog.EmptyQueue();
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolLog.h
|
||||
|
||||
DESCRIPTION:
|
||||
Simple protocol 'log' class declaration
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cProtocolLog
|
||||
This class stores protocol buffers in to a flat array (actually a
|
||||
double-ended queue) so that they can be accessed by other objects
|
||||
during the flow of normal processing. Note that the storage is
|
||||
in-memory and therefore finite
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "ProtocolBuffer.h"
|
||||
#include "SyncQueue.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
const ULONG INVALID_LOG_INDEX = ULONG_MAX;
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cProtocolLog
|
||||
/*=========================================================================*/
|
||||
class cProtocolLog
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cProtocolLog( ULONG maxBuffers );
|
||||
|
||||
// Destructor
|
||||
virtual ~cProtocolLog();
|
||||
|
||||
// Add an protocol buffer to the end of the log
|
||||
virtual ULONG AddBuffer( sProtocolBuffer & buf );
|
||||
|
||||
// Return the protocol buffer at the given index from the log
|
||||
virtual sProtocolBuffer GetBuffer( ULONG idx ) const;
|
||||
|
||||
// Return the underlying signal event
|
||||
virtual cEvent & GetSignalEvent() const;
|
||||
|
||||
// Return the total number of buffers added to the log
|
||||
virtual ULONG GetCount() const;
|
||||
|
||||
// Clear the log
|
||||
virtual void Clear();
|
||||
|
||||
protected:
|
||||
/* The underlying 'log' */
|
||||
cSyncQueue <sProtocolBuffer> mLog;
|
||||
};
|
|
@ -0,0 +1,171 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolNotification.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Implementation of cProtocolNotification base class and derivations
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolNotificationEvent
|
||||
Generic protocol event notification structure
|
||||
|
||||
cProtocolNotification
|
||||
This abstract base class provides notification of protocol server
|
||||
events sent from the protocol server to protocol server clients
|
||||
|
||||
cProtocolQueueNotification
|
||||
This class provides notification via a cSyncQueue object
|
||||
populated with sProtocolNotificationEvent objects
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "ProtocolNotification.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// cProtocolQueueNotification Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cProtocolQueueNotification (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
PARAMETERS:
|
||||
pSQ [ I ] - Sync queue to utilize
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cProtocolQueueNotification::cProtocolQueueNotification(
|
||||
cSyncQueue <sProtocolNotificationEvent> * pSQ )
|
||||
: mpSQ( pSQ )
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cProtocolQueueNotification (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Copy constructor
|
||||
|
||||
PARAMETERS:
|
||||
notifier [ I ] - Notifier to base the new one on
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cProtocolQueueNotification::cProtocolQueueNotification(
|
||||
const cProtocolQueueNotification & notifier )
|
||||
: mpSQ( notifier.mpSQ )
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cProtocolQueueNotification (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cProtocolQueueNotification::~cProtocolQueueNotification()
|
||||
{
|
||||
mpSQ = 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Clone (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return an allocated copy of this object downcasted to our base class
|
||||
|
||||
RETURN VALUE:
|
||||
cProtocolNotification * : Cloned object (0 on error)
|
||||
===========================================================================*/
|
||||
cProtocolNotification * cProtocolQueueNotification::Clone() const
|
||||
{
|
||||
cProtocolQueueNotification * pCopy = 0;
|
||||
|
||||
try
|
||||
{
|
||||
pCopy = new cProtocolQueueNotification( *this );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Simply return 0
|
||||
}
|
||||
|
||||
return ((cProtocolNotification *)pCopy);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Notify (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Notify view of a protocol event by adding notification structure to
|
||||
the underlying sync queue (which will provide the notification
|
||||
by signalling an event)
|
||||
|
||||
PARAMETERS:
|
||||
eventType [ I ] - Protocol event type
|
||||
param1 [ I ] - Event type specific argument (see header description)
|
||||
param2 [ I ] - Event type specific argument (see header description)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void cProtocolQueueNotification::Notify(
|
||||
eProtocolEventType eventType,
|
||||
DWORD param1,
|
||||
DWORD param2 ) const
|
||||
{
|
||||
sProtocolNotificationEvent evt( eventType, param1, param2 );
|
||||
if (evt.IsValid() == true && mpSQ != 0 && mpSQ->IsValid() == true)
|
||||
{
|
||||
sProtocolNotificationEvent elem( eventType, param1, param2 );
|
||||
mpSQ->AddElement( elem );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolNotification.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration of cProtocolNotification base class and derivations
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolNotificationEvent
|
||||
Generic protocol event notification structure
|
||||
|
||||
cProtocolNotification
|
||||
This abstract base class provides notification of protocol server
|
||||
events sent from the protocol server to protocol server clients
|
||||
|
||||
cProtocolQueueNotification
|
||||
This class provides notification via a cSyncQueue object
|
||||
populated with sProtocolNotificationEvent objects
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "SyncQueue.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
enum eProtocolEventType
|
||||
{
|
||||
ePROTOCOL_EVT_BEGIN = -1,
|
||||
|
||||
ePROTOCOL_EVT_REQ_ERR, // There was an error sending the request
|
||||
ePROTOCOL_EVT_REQ_SENT, // The request has been sent
|
||||
|
||||
ePROTOCOL_EVT_RSP_ERR, // There was an error receiving the response
|
||||
ePROTOCOL_EVT_RSP_RECV, // The response has been received
|
||||
|
||||
ePROTOCOL_EVT_AUX_TU_SENT, // Auxiliary data transmission unit sent
|
||||
|
||||
ePROTOCOL_EVT_END
|
||||
};
|
||||
|
||||
// NOTE: The arguments for each event are currently as follows:
|
||||
//
|
||||
// ePROTOCOL_EVT_REQ_ERR
|
||||
// param1: Request ID
|
||||
// param2: Error code
|
||||
//
|
||||
// ePROTOCOL_EVT_REQ_SENT
|
||||
// param1: Request ID
|
||||
// param2: Index of request buffer in associated protocol log
|
||||
|
||||
// ePROTOCOL_EVT_RSP_ERR
|
||||
// param1: Request ID
|
||||
// param2: Error code
|
||||
//
|
||||
// ePROTOCOL_EVT_RSP_RECV
|
||||
// param1: Request ID
|
||||
// param2: Index of response buffer in associated protocol log
|
||||
//
|
||||
// ePROTOCOL_EVT_AUX_TU_SENT
|
||||
// param1: Request ID
|
||||
// param2: Size of transmission unit
|
||||
|
||||
// NOTE: To handle protoocl events using the Windows notifier add the following
|
||||
// prototype to your Window class header file:
|
||||
//
|
||||
// afx_msg LRESULT OnProtocolEvent(
|
||||
// WPARAM wParam,
|
||||
// LPARAM lParam );
|
||||
//
|
||||
// Then add an entry to the message map in your Window class source file:
|
||||
//
|
||||
// BEGIN_MESSAGE_MAP( CView, CChildView )
|
||||
// ON_MESSAGE( PROTOCOL_WM_BASE + (ULONG)ePROTOCOL_EVT_XXX, OnProtocolEvent )
|
||||
// END_MESSAGE_MAP()
|
||||
//
|
||||
// Finally write the handler itself:
|
||||
//
|
||||
// LRESULT CView::OnProtocolEvent(
|
||||
// WPARAM wParam,
|
||||
// LPARAM lParam )
|
||||
// {
|
||||
// Do something
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsValid (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
eProtocolEventType validity check
|
||||
|
||||
PARAMETERS:
|
||||
evtType [ I ] - Enum value being verified
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsValid( eProtocolEventType evtType )
|
||||
{
|
||||
bool bRC = false;
|
||||
if (evtType > ePROTOCOL_EVT_BEGIN && evtType < ePROTOCOL_EVT_END)
|
||||
{
|
||||
bRC = true;
|
||||
}
|
||||
|
||||
return bRC;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sProtocolNotificationEvent
|
||||
/*=========================================================================*/
|
||||
struct sProtocolNotificationEvent
|
||||
{
|
||||
public:
|
||||
// (Inline) Default constructor (results in invalid object)
|
||||
sProtocolNotificationEvent()
|
||||
: mEventType( ePROTOCOL_EVT_BEGIN ),
|
||||
mParam1( 0 ),
|
||||
mParam2( 0 )
|
||||
{
|
||||
// Nothing to do
|
||||
};
|
||||
|
||||
// (Inline) Parameter constructor
|
||||
sProtocolNotificationEvent(
|
||||
eProtocolEventType eventType,
|
||||
DWORD param1,
|
||||
DWORD param2 )
|
||||
: mEventType( eventType ),
|
||||
mParam1( param1 ),
|
||||
mParam2( param2 )
|
||||
{
|
||||
// Nothing to do
|
||||
};
|
||||
|
||||
// (Inline) Is this object valid?
|
||||
bool IsValid()
|
||||
{
|
||||
return ::IsValid( mEventType );
|
||||
}
|
||||
|
||||
/* Event type */
|
||||
eProtocolEventType mEventType;
|
||||
|
||||
/* First parameter (see above) */
|
||||
DWORD mParam1;
|
||||
|
||||
/* Second parameter (see above) */
|
||||
DWORD mParam2;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cProtocolNotification
|
||||
//
|
||||
// This abstract base class provides notification of protocol server
|
||||
// events sent from the protocol server to protocol server clients
|
||||
/*=========================================================================*/
|
||||
class cProtocolNotification
|
||||
{
|
||||
public:
|
||||
// Return an allocated copy of this object
|
||||
virtual cProtocolNotification * Clone() const = 0;
|
||||
|
||||
// Notify view of a protocol event
|
||||
virtual void Notify(
|
||||
eProtocolEventType eventType,
|
||||
DWORD param1,
|
||||
DWORD param2 ) const = 0;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cProtocolQueueNotification
|
||||
//
|
||||
// This class provides notification via a cSyncQueue object
|
||||
// populated with sProtocolNotificationEvent objects
|
||||
/*=========================================================================*/
|
||||
class cProtocolQueueNotification : public cProtocolNotification
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cProtocolQueueNotification( cSyncQueue <sProtocolNotificationEvent> * pSQ );
|
||||
|
||||
// Copy constructor
|
||||
cProtocolQueueNotification( const cProtocolQueueNotification & notifier );
|
||||
|
||||
// Destructor
|
||||
virtual ~cProtocolQueueNotification();
|
||||
|
||||
// Return a copy of this object
|
||||
virtual cProtocolNotification * Clone() const;
|
||||
|
||||
// Notify view of a MIS event
|
||||
virtual void Notify(
|
||||
eProtocolEventType eventType,
|
||||
DWORD param1,
|
||||
DWORD param2 ) const;
|
||||
|
||||
protected:
|
||||
/* Event notification queue */
|
||||
mutable cSyncQueue <sProtocolNotificationEvent> * mpSQ;
|
||||
};
|
|
@ -0,0 +1,254 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolRequest.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol request/command related structures and
|
||||
affliated methods, these structures are used by clients of
|
||||
the protocol server to specify outgoing requests
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolRequest
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ProtocolRequest.h"
|
||||
#include "ProtocolNotification.h"
|
||||
#include "ProtocolServer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Default protocol request timeout
|
||||
const ULONG DEFAULT_REQ_TIMEOUT = 1000;
|
||||
|
||||
// Minimum and maximum allowable timeout values (in milliseconds)
|
||||
const ULONG MIN_REQ_TIMEOUT = 100;
|
||||
const ULONG MAX_REQ_TIMEOUT = 300000;
|
||||
|
||||
// Minimum number of attempts a request can be scheduled for
|
||||
const ULONG MIN_REQ_ATTEMPTS = 1;
|
||||
|
||||
// Value to indicate that a request is to be sent out indefinately
|
||||
const ULONG INFINITE_REQS = 0xFFFFFFFF;
|
||||
|
||||
// Minimum/default amount of time between repeated requests (in milliseconds)
|
||||
const ULONG MIN_REQ_FREQUENCY = 10;
|
||||
const ULONG DEFAULT_REQ_FREQUENCY = 100;
|
||||
|
||||
/*=========================================================================*/
|
||||
// sProtocolRequest Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolRequest
|
||||
|
||||
DESCRIPTION:
|
||||
Parameterized constructor
|
||||
|
||||
PARAMETERS:
|
||||
pBuffer [ I ] - Shareable buffer representing the request (must be
|
||||
valid)
|
||||
|
||||
schedule [ I ] - When (from now, in milliseconds) to send the first
|
||||
request, this isn't a hard value as the request is
|
||||
only guaranteed to go out after this time elapses
|
||||
|
||||
timeout [ I ] - Milliseconds to wait for a response to an individual
|
||||
request before declaring a timeout. Regardless of
|
||||
what is passed in the timeout value used will be
|
||||
between MIN/MAX_REQ_TIMEOUT
|
||||
|
||||
requests [ I ] - Number of request attempts to make, this isn't a
|
||||
retry count rather this value is used to specify
|
||||
repeating requests. Regardless of what is passed in
|
||||
the requests value used will be at least
|
||||
MIN_REQ_ATTEMPTS
|
||||
|
||||
frequency [ I ] - If the 'requests' value is greater than the
|
||||
MIN_REQ_ATTEMPTS than this represents the amount of
|
||||
time to wait between requests (from the completion of
|
||||
the last request attempt, in milliseconds), again this
|
||||
isn't a hard value. Regardless of what is passed in
|
||||
the frequency value used will be at least
|
||||
MIN_REQ_FREQUENCY
|
||||
|
||||
pNotifier [ I ] - Status notification mechanism (may be 0)
|
||||
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolRequest::sProtocolRequest(
|
||||
sSharedBuffer * pBuffer,
|
||||
ULONG schedule,
|
||||
ULONG timeout,
|
||||
ULONG requests,
|
||||
ULONG frequency,
|
||||
cProtocolNotification * pNotifier )
|
||||
: sProtocolBuffer( pBuffer ),
|
||||
mSchedule( schedule ),
|
||||
mTimeout( DEFAULT_REQ_TIMEOUT ),
|
||||
mRequests( MIN_REQ_ATTEMPTS ),
|
||||
mFrequency( DEFAULT_REQ_FREQUENCY ),
|
||||
mpNotifier( 0 ),
|
||||
mpAuxData( 0 ),
|
||||
mAuxDataSize( 0 ),
|
||||
mbTXOnly( false )
|
||||
{
|
||||
// Constrain requested timeout to allowable range
|
||||
if (timeout < MIN_REQ_TIMEOUT)
|
||||
{
|
||||
timeout = MIN_REQ_TIMEOUT;
|
||||
}
|
||||
|
||||
if (timeout > MAX_REQ_TIMEOUT)
|
||||
{
|
||||
timeout = MAX_REQ_TIMEOUT;
|
||||
}
|
||||
|
||||
mTimeout = timeout;
|
||||
|
||||
// Constrain request attempts
|
||||
if (requests >= MIN_REQ_ATTEMPTS)
|
||||
{
|
||||
mRequests = requests;
|
||||
}
|
||||
|
||||
// Constrain frequency
|
||||
if (frequency >= MIN_REQ_FREQUENCY)
|
||||
{
|
||||
mFrequency = frequency;
|
||||
}
|
||||
|
||||
// Clone notifier?
|
||||
if (pNotifier != 0)
|
||||
{
|
||||
mpNotifier = pNotifier->Clone();
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolRequest
|
||||
|
||||
DESCRIPTION:
|
||||
Parameterized constructor (notification with defaults)
|
||||
|
||||
PARAMETERS:
|
||||
pBuffer [ I ] - Shareable buffer representing the request (must be
|
||||
valid)
|
||||
|
||||
pNotifier [ I ] - Status notification mechanism (may be 0)
|
||||
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolRequest::sProtocolRequest(
|
||||
sSharedBuffer * pBuffer,
|
||||
cProtocolNotification * pNotifier )
|
||||
: sProtocolBuffer( pBuffer ),
|
||||
mSchedule( 0 ),
|
||||
mTimeout( DEFAULT_REQ_TIMEOUT ),
|
||||
mRequests( MIN_REQ_ATTEMPTS ),
|
||||
mFrequency( DEFAULT_REQ_FREQUENCY ),
|
||||
mpNotifier( pNotifier ),
|
||||
mpAuxData( 0 ),
|
||||
mAuxDataSize( 0 ),
|
||||
mbTXOnly( false )
|
||||
{
|
||||
// Clone notifier?
|
||||
if (pNotifier != 0)
|
||||
{
|
||||
mpNotifier = pNotifier->Clone();
|
||||
}
|
||||
|
||||
Validate();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sProtocolRequest
|
||||
|
||||
DESCRIPTION:
|
||||
Copy constructor
|
||||
|
||||
PARAMETERS:
|
||||
req [ I ] - Request to copy
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolRequest::sProtocolRequest( const sProtocolRequest & req )
|
||||
: sProtocolBuffer( req ),
|
||||
mSchedule( req.mSchedule ),
|
||||
mTimeout( req.mTimeout ),
|
||||
mRequests( req.mRequests ),
|
||||
mFrequency( req.mFrequency ),
|
||||
mpNotifier( 0 ),
|
||||
mpAuxData( req.mpAuxData ),
|
||||
mAuxDataSize( req.mAuxDataSize ),
|
||||
mbTXOnly( req.mbTXOnly )
|
||||
{
|
||||
// Clone notifier?
|
||||
if (req.mpNotifier != 0)
|
||||
{
|
||||
mpNotifier = req.mpNotifier->Clone();
|
||||
}
|
||||
|
||||
Validate();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~sProtocolRequest
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sProtocolRequest::~sProtocolRequest()
|
||||
{
|
||||
// Delete cloned notifier?
|
||||
if (mpNotifier != 0)
|
||||
{
|
||||
delete mpNotifier;
|
||||
mpNotifier = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolRequest.h
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol request/command related structures and
|
||||
affliated methods, these structures are used by clients of
|
||||
the protocol server to specify outgoing protocol requests
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sProtocolRequest
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "ProtocolBuffer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Forward Declarations
|
||||
//---------------------------------------------------------------------------
|
||||
class cProtocolNotification;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Default protocol request timeout
|
||||
extern const ULONG DEFAULT_REQ_TIMEOUT;
|
||||
|
||||
// Minimum and maximum allowable timeout values (in milliseconds)
|
||||
extern const ULONG MIN_REQ_TIMEOUT;
|
||||
extern const ULONG MAX_REQ_TIMEOUT;
|
||||
|
||||
// Minimum number of attempts a request can be scheduled for
|
||||
extern const ULONG MIN_REQ_ATTEMPTS;
|
||||
|
||||
// Value to indicate that a request is to be sent out indefinately
|
||||
extern const ULONG INFINITE_REQS;
|
||||
|
||||
// Minimum/default amount of time between repeated requests (in milliseconds)
|
||||
extern const ULONG MIN_REQ_FREQUENCY;
|
||||
extern const ULONG DEFAULT_REQ_FREQUENCY;
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sProtocolRequest
|
||||
//
|
||||
// Structure to represent a generic request packet, including all the
|
||||
// information needed to schedule the request, send the request, and
|
||||
// (optionally) reschedule the request for another TX/RX attempt
|
||||
//
|
||||
// The default parameters schedule an immediate request (indicated by
|
||||
// passing in '0' for the schedule parameter) to be sent once with
|
||||
// the default timeout value
|
||||
/*=========================================================================*/
|
||||
struct sProtocolRequest : public sProtocolBuffer
|
||||
{
|
||||
public:
|
||||
// Parameterized constructor
|
||||
sProtocolRequest(
|
||||
sSharedBuffer * pBuffer,
|
||||
ULONG schedule = 0,
|
||||
ULONG timeout = DEFAULT_REQ_TIMEOUT,
|
||||
ULONG requests = MIN_REQ_ATTEMPTS,
|
||||
ULONG frequency = DEFAULT_REQ_FREQUENCY,
|
||||
cProtocolNotification * pNotifier = 0 );
|
||||
|
||||
// Parameterized constructor (notification with defaults)
|
||||
sProtocolRequest(
|
||||
sSharedBuffer * pBuffer,
|
||||
cProtocolNotification * pNotifier );
|
||||
|
||||
// Copy constructor
|
||||
sProtocolRequest( const sProtocolRequest & req );
|
||||
|
||||
// Destructor
|
||||
virtual ~sProtocolRequest();
|
||||
|
||||
// (Inline) Get schedule value (value is in milliseconds)
|
||||
ULONG GetSchedule() const
|
||||
{
|
||||
return mSchedule;
|
||||
};
|
||||
|
||||
// (Inline) Get timeout value
|
||||
ULONG GetTimeout() const
|
||||
{
|
||||
return mTimeout;
|
||||
};
|
||||
|
||||
// (Inline) Get requests value
|
||||
ULONG GetRequests() const
|
||||
{
|
||||
return mRequests;
|
||||
};
|
||||
|
||||
// (Inline) Get frequency value (value is in milliseconds)
|
||||
ULONG GetFrequency() const
|
||||
{
|
||||
return mFrequency;
|
||||
};
|
||||
|
||||
const cProtocolNotification * GetNotifier() const
|
||||
{
|
||||
return mpNotifier;
|
||||
};
|
||||
|
||||
// (Inline) Set auxiliary data
|
||||
void SetAuxiliaryData(
|
||||
const BYTE * pData,
|
||||
ULONG dataSz )
|
||||
{
|
||||
mpAuxData = pData;
|
||||
mAuxDataSize = dataSz;
|
||||
};
|
||||
|
||||
// (Inline) Get auxiliary data
|
||||
const BYTE * GetAuxiliaryData( ULONG & dataSz ) const
|
||||
{
|
||||
dataSz = mAuxDataSize;
|
||||
return mpAuxData;
|
||||
};
|
||||
|
||||
// (Inline) Set TX only flag
|
||||
void SetTXOnly()
|
||||
{
|
||||
mbTXOnly = true;
|
||||
};
|
||||
|
||||
// (Inline) Get TX only flag
|
||||
bool IsTXOnly() const
|
||||
{
|
||||
return mbTXOnly;
|
||||
};
|
||||
|
||||
protected:
|
||||
/* Schedule (approximately when to send the initial request) */
|
||||
ULONG mSchedule;
|
||||
|
||||
/* Timeout value for receiving a response */
|
||||
ULONG mTimeout;
|
||||
|
||||
/* Number of requests to schedule (must be at least one) */
|
||||
ULONG mRequests;
|
||||
|
||||
/* Frequency (approximately how long to wait before next request) */
|
||||
ULONG mFrequency;
|
||||
|
||||
/* Notification object */
|
||||
cProtocolNotification * mpNotifier;
|
||||
|
||||
/* Auxiliary data */
|
||||
const BYTE * mpAuxData;
|
||||
|
||||
/* Auxilary data size */
|
||||
ULONG mAuxDataSize;
|
||||
|
||||
/* TX only (i.e. do not wait for a response) ? */
|
||||
bool mbTXOnly;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,363 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
ProtocolServer.h
|
||||
|
||||
DESCRIPTION:
|
||||
Generic protocol packet server
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cProtocolServer
|
||||
Abstract base class for protocol servers
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Connection.h"
|
||||
#include "ProtocolRequest.h"
|
||||
#include "ProtocolLog.h"
|
||||
#include "Event.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Forward Declarations
|
||||
//---------------------------------------------------------------------------
|
||||
class cProtocolServer;
|
||||
struct sServerControl;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Invalid request ID
|
||||
extern const ULONG INVALID_REQUEST_ID;
|
||||
|
||||
// Fill timespec with the time it will be in specified milliseconds
|
||||
// Relative time to Absolute time
|
||||
timespec TimeIn( ULONG millis );
|
||||
|
||||
// Find the milliseconds from current time this timespec will occur
|
||||
// Absolute time to Relative time
|
||||
ULONG TimeFromNow( timespec time );
|
||||
|
||||
// Provide a number for sequencing reference, similar to the windows function
|
||||
ULONGLONG GetTickCount();
|
||||
|
||||
// timespec < comparison method
|
||||
inline bool operator< (const timespec & first, const timespec & second)
|
||||
{
|
||||
return ( (first.tv_sec < second.tv_sec)
|
||||
||( (first.tv_sec == second.tv_sec)
|
||||
&&(first.tv_nsec < second.tv_nsec) ) );
|
||||
}
|
||||
|
||||
// timespec <= comparison method
|
||||
inline bool operator<= (const timespec & first, const timespec & second)
|
||||
{
|
||||
return ( (first.tv_sec < second.tv_sec)
|
||||
||( (first.tv_sec == second.tv_sec)
|
||||
&&(first.tv_nsec <= second.tv_nsec) ) );
|
||||
}
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cProtocolServerRxCallback
|
||||
/*=========================================================================*/
|
||||
class cProtocolServerRxCallback
|
||||
{
|
||||
public:
|
||||
// (Inline) Constructor
|
||||
cProtocolServerRxCallback()
|
||||
: mpServer( 0 )
|
||||
{ };
|
||||
|
||||
// (Inline) Destructor
|
||||
virtual ~cProtocolServerRxCallback() { };
|
||||
|
||||
// (Inline) Set server object to pass results to
|
||||
void SetServer( cProtocolServer * pServer )
|
||||
{
|
||||
mpServer = pServer;
|
||||
};
|
||||
|
||||
// The I/O has been completed, process the results
|
||||
virtual void IOComplete(
|
||||
DWORD status,
|
||||
DWORD bytesReceived );
|
||||
|
||||
protected:
|
||||
/* Protocol server to interact with */
|
||||
cProtocolServer * mpServer;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cProtocolServer
|
||||
/*=========================================================================*/
|
||||
class cProtocolServer
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cProtocolServer(
|
||||
eProtocolType rxType,
|
||||
eProtocolType txType,
|
||||
ULONG bufferSzRx,
|
||||
ULONG logSz );
|
||||
|
||||
// Destructor
|
||||
virtual ~cProtocolServer();
|
||||
|
||||
// Initialize the protocol server
|
||||
bool Initialize();
|
||||
|
||||
// Exit the protocol server
|
||||
bool Exit();
|
||||
|
||||
// Connect to the given communications port
|
||||
bool Connect( LPCSTR pPort );
|
||||
|
||||
// Disconnect from target
|
||||
bool Disconnect();
|
||||
|
||||
// Are we currently connected to a port?
|
||||
bool IsConnected();
|
||||
|
||||
// Add an outgoing protocol request to the protocol server request queue
|
||||
ULONG AddRequest( const sProtocolRequest & req );
|
||||
|
||||
// Remove a previously added protocol request
|
||||
bool RemoveRequest( ULONG reqID );
|
||||
|
||||
// (Inline) Return the protocol log
|
||||
const cProtocolLog & GetLog()
|
||||
{
|
||||
return mLog;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Internal protocol server request/response structure, used to track
|
||||
// info related to sending out a request
|
||||
struct sProtocolReqRsp
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
sProtocolReqRsp(
|
||||
const sProtocolRequest & requestInfo,
|
||||
ULONG requestID,
|
||||
ULONG auxDataMTU );
|
||||
|
||||
// Copy constructor
|
||||
sProtocolReqRsp( const sProtocolReqRsp & reqRsp );
|
||||
|
||||
// (Inline) Reset for next transmission attempt
|
||||
void Reset()
|
||||
{
|
||||
mEncodedSize = mRequest.GetSize();
|
||||
|
||||
mCurrentAuxTx = 0;
|
||||
mbWaitingForResponse = 0;
|
||||
};
|
||||
|
||||
/* Request ID */
|
||||
ULONG mID;
|
||||
|
||||
/* Number of times this request has been attempted */
|
||||
ULONG mAttempts;
|
||||
|
||||
/* Size of encoded data being transmitted */
|
||||
ULONG mEncodedSize;
|
||||
|
||||
/* Number of required auxiliary data transmissions */
|
||||
ULONG mRequiredAuxTxs;
|
||||
|
||||
/* Current auxiliary data transmission */
|
||||
ULONG mCurrentAuxTx;
|
||||
|
||||
/* Are we currently waiting for a response? */
|
||||
bool mbWaitingForResponse;
|
||||
|
||||
/* Underlying protocol request */
|
||||
sProtocolRequest mRequest;
|
||||
};
|
||||
|
||||
// Handle the remove request
|
||||
bool HandleRemoveRequest( ULONG reqID );
|
||||
|
||||
// Schedule a request for transmission
|
||||
bool ScheduleRequest(
|
||||
ULONG reqID,
|
||||
ULONG schedule );
|
||||
|
||||
// (Inline) Get next request's time from mRequestSchedule
|
||||
timespec GetNextRequestTime()
|
||||
{
|
||||
timespec outTime;
|
||||
|
||||
std::set <tSchedule>::iterator pScheduleIter;
|
||||
pScheduleIter = mRequestSchedule.begin();
|
||||
tSchedule entry = *pScheduleIter;
|
||||
|
||||
outTime = entry.first;
|
||||
return outTime;
|
||||
}
|
||||
|
||||
// (Inline) Validate a request that is about to be scheduled
|
||||
virtual bool ValidateRequest( const sProtocolRequest & req )
|
||||
{
|
||||
return req.IsValid();
|
||||
};
|
||||
|
||||
// Reschedule (or cleanup) the active request
|
||||
void RescheduleActiveRequest();
|
||||
|
||||
// Process a single outgoing protocol request
|
||||
void ProcessRequest();
|
||||
|
||||
// Check that system time hasn't moved backwards
|
||||
bool CheckSystemTime();
|
||||
|
||||
// Perform protocol specific communications port initialization
|
||||
virtual bool InitializeComm() = 0;
|
||||
|
||||
// Perform protocol specific communications port cleanup
|
||||
virtual bool CleanupComm() = 0;
|
||||
|
||||
// Encode data for transmission
|
||||
virtual sSharedBuffer * EncodeTxData(
|
||||
sSharedBuffer * pBuffer,
|
||||
bool & bEncoded ) = 0;
|
||||
|
||||
// Decode incoming data into packets returning the last response
|
||||
virtual bool DecodeRxData(
|
||||
ULONG bytesReceived,
|
||||
ULONG & rspIdx,
|
||||
bool & bAbortTx ) = 0;
|
||||
|
||||
// Handle completion of receive data operation
|
||||
void RxComplete(
|
||||
DWORD status,
|
||||
DWORD bytesReceived );
|
||||
|
||||
// Handle the response timer expiring
|
||||
void RxTimeout();
|
||||
|
||||
// Handle completion of transmit data operation
|
||||
virtual void TxComplete();
|
||||
|
||||
// Handle a transmission error
|
||||
void TxError();
|
||||
|
||||
/* Underlying communications object */
|
||||
cConnection * mpConnection;
|
||||
|
||||
/* Underlying connection type */
|
||||
enum eConnectionType
|
||||
{
|
||||
eConnectionType_Begin = 0,
|
||||
|
||||
eConnectionType_RmNet = 1,
|
||||
eConnectionType_SMD = 2,
|
||||
|
||||
eConnectionType_End
|
||||
|
||||
} mConnectionType;
|
||||
|
||||
/* Rx callback */
|
||||
cProtocolServerRxCallback mRxCallback;
|
||||
|
||||
/* ID of Schedule thread */
|
||||
pthread_t mScheduleThreadID;
|
||||
|
||||
// ScheduleThread signal event
|
||||
cEvent mThreadScheduleEvent;
|
||||
|
||||
// Schedule mutex
|
||||
// Ensures exclusive access to mRequestSchedule
|
||||
pthread_mutex_t mScheduleMutex;
|
||||
|
||||
// Is the thread in the process of exiting?
|
||||
// (no new commands will be accepted)
|
||||
bool mbExiting;
|
||||
|
||||
/* Client/server thread control object */
|
||||
sSharedBuffer * mpServerControl;
|
||||
|
||||
/* Protocol request schedule (scheduled time/request ID) */
|
||||
typedef std::pair <timespec, ULONG> tSchedule;
|
||||
std::set < tSchedule, std::less <tSchedule> > mRequestSchedule;
|
||||
|
||||
/* Last system time value (used to check for time changes) */
|
||||
timespec mLastTime;
|
||||
|
||||
/* Protocol request map (request ID mapped to internal req/rsp struct) */
|
||||
std::map <ULONG, sProtocolReqRsp *> mRequestMap;
|
||||
|
||||
/* Last assigned request ID */
|
||||
ULONG mLastRequestID;
|
||||
|
||||
/* Current request being processed */
|
||||
sProtocolReqRsp * mpActiveRequest;
|
||||
|
||||
/* Absolute timeout for mpActiveRequest
|
||||
based on when write was completed */
|
||||
timespec mActiveRequestTimeout;
|
||||
|
||||
/* Data buffer for incoming data */
|
||||
BYTE * mpRxBuffer;
|
||||
|
||||
/* Size of above buffer (i.e. how much data to read in at once) */
|
||||
ULONG mRxBufferSize;
|
||||
|
||||
/* Protocol type for incoming/outgoing data*/
|
||||
eProtocolType mRxType;
|
||||
eProtocolType mTxType;
|
||||
|
||||
/* Protocol log */
|
||||
cProtocolLog mLog;
|
||||
|
||||
// Get a lock on ScheduleMutex
|
||||
bool GetScheduleMutex();
|
||||
|
||||
// Release lock on ScheduleMutex
|
||||
// Signal ScheduleThread if desired
|
||||
bool ReleaseScheduleMutex( bool bSignalThread = true );
|
||||
|
||||
// Schedule Thread gets full access
|
||||
friend void * ScheduleThread( PVOID pArg );
|
||||
|
||||
// Callback objects get full access
|
||||
friend class cProtocolServerRxCallback;
|
||||
};
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QMIBuffers.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QMI service protocol related structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sQMIControlRawTransactionHeader
|
||||
sQMIServiceRawTransactionHeader
|
||||
sQMIRawMessageHeader
|
||||
sQMIRawContentHeader
|
||||
|
||||
sQMIServiceBuffer
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "QMIBuffers.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// sQMIServiceBuffer Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sQMIServiceBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
PARAMETERS:
|
||||
pBuffer [ I ] - Shareable buffer that contains the DIAG data
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sQMIServiceBuffer::sQMIServiceBuffer( sSharedBuffer * pBuffer )
|
||||
: sProtocolBuffer( pBuffer )
|
||||
{
|
||||
sQMIServiceBuffer::Validate();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~sQMIServiceBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sQMIServiceBuffer::~sQMIServiceBuffer()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetResult (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return contents of mandatory result content
|
||||
|
||||
PARAMETERS:
|
||||
returnCode [ I ] - The return code (should be eQMIResultCode)
|
||||
errorCode [ I ] - The error code (should be eQMIErrorCode)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool sQMIServiceBuffer::GetResult(
|
||||
ULONG & returnCode,
|
||||
ULONG & errorCode )
|
||||
{
|
||||
if (IsResponse() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map <ULONG, const sQMIRawContentHeader *>::const_iterator pIter;
|
||||
pIter = mContents.find( QMI_TLV_ID_RESULT );
|
||||
if (pIter == mContents.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const sQMIRawContentHeader * pContent = pIter->second;
|
||||
if (pContent == 0)
|
||||
{
|
||||
ASSERT( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pContent->mLength != 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const WORD * pData = (const WORD *)(++pContent);
|
||||
|
||||
returnCode = (ULONG)*pData++;
|
||||
errorCode = (ULONG)*pData;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
BuildBuffer (Static Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Build a QMI request
|
||||
|
||||
PARAMETERS:
|
||||
serviceType [ I ] - QMI service type
|
||||
msgID [ I ] - The QMI message request ID
|
||||
bResponse [ I ] - Build a response?
|
||||
bIndication [ I ] - Build an indication?
|
||||
pPayload [ I ] - Payload
|
||||
payloadLen [ I ] - Size of above payload
|
||||
|
||||
RETURN VALUE:
|
||||
sSharedBuffer * : The request in an allocated buffer (0 on error)
|
||||
===========================================================================*/
|
||||
sSharedBuffer * sQMIServiceBuffer::BuildBuffer(
|
||||
eQMIService serviceType,
|
||||
WORD msgID,
|
||||
bool bResponse,
|
||||
bool bIndication,
|
||||
const BYTE * pPayload,
|
||||
ULONG payloadLen )
|
||||
{
|
||||
const ULONG szTransHdr = (ULONG)sizeof(sQMIServiceRawTransactionHeader);
|
||||
const ULONG szMsgHdr = (ULONG)sizeof(sQMIRawMessageHeader);
|
||||
const ULONG totalHdrSz = szTransHdr + szMsgHdr;
|
||||
|
||||
// Truncate payload?
|
||||
if (payloadLen > (QMI_MAX_BUFFER_SIZE - totalHdrSz))
|
||||
{
|
||||
payloadLen = QMI_MAX_BUFFER_SIZE - totalHdrSz;
|
||||
}
|
||||
|
||||
// Make sure length agrees with pointer
|
||||
if (pPayload == 0)
|
||||
{
|
||||
payloadLen = 0;
|
||||
}
|
||||
|
||||
// Allocate buffer
|
||||
PBYTE pBuffer = new BYTE[payloadLen + totalHdrSz];
|
||||
if (pBuffer == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Format header
|
||||
sQMIServiceRawTransactionHeader * pHdr = 0;
|
||||
pHdr = (sQMIServiceRawTransactionHeader *)&pBuffer[0];
|
||||
pHdr->mCompound = 0;
|
||||
pHdr->mResponse = 0;
|
||||
pHdr->mIndication = 0;
|
||||
pHdr->mReserved = 0;
|
||||
pHdr->mTransactionID = 1;
|
||||
|
||||
bool bTX = true;
|
||||
if (bResponse == true)
|
||||
{
|
||||
pHdr->mResponse = 1;
|
||||
bTX = false;
|
||||
}
|
||||
else if (bIndication == true)
|
||||
{
|
||||
pHdr->mIndication = 1;
|
||||
bTX = false;
|
||||
}
|
||||
|
||||
pHdr++;
|
||||
|
||||
// Format message header
|
||||
sQMIRawMessageHeader * pMsg = 0;
|
||||
pMsg = (sQMIRawMessageHeader *)pHdr;
|
||||
pMsg->mMessageID = msgID;
|
||||
pMsg->mLength = (WORD)payloadLen;
|
||||
|
||||
// Copy in payload?
|
||||
if (payloadLen > 0 && pPayload != 0)
|
||||
{
|
||||
memcpy( (LPVOID)&pBuffer[totalHdrSz],
|
||||
(LPCVOID)&pPayload[0],
|
||||
(SIZE_T)payloadLen );
|
||||
}
|
||||
|
||||
// Compute total size
|
||||
ULONG sz = payloadLen + totalHdrSz;
|
||||
|
||||
// Build and return the shared buffer
|
||||
eProtocolType pt = MapQMIServiceToProtocol( serviceType, bTX );
|
||||
sSharedBuffer * pBuf = new sSharedBuffer( sz, pBuffer, pt );
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Validate (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Is this open unframed request/response packet valid?
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool sQMIServiceBuffer::Validate()
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
|
||||
// Sanity check protocol type
|
||||
eProtocolType pt = GetType();
|
||||
if (IsQMIProtocol( pt ) == false)
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
const ULONG szTransHdr = (ULONG)sizeof(sQMIServiceRawTransactionHeader);
|
||||
const ULONG szMsgHdr = (ULONG)sizeof(sQMIRawMessageHeader);
|
||||
const ULONG szContentHdr = (ULONG)sizeof(sQMIRawContentHeader);
|
||||
|
||||
// Must be enough space for both headers
|
||||
ULONG sz = GetSize();
|
||||
if (sz < szTransHdr + szMsgHdr)
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
const BYTE * pBuffer = GetBuffer();
|
||||
|
||||
// Obtain transaction header
|
||||
const sQMIServiceRawTransactionHeader * pTransHdr = 0;
|
||||
pTransHdr = (const sQMIServiceRawTransactionHeader *)pBuffer;
|
||||
pBuffer += szTransHdr;
|
||||
|
||||
// This is required to be 0
|
||||
if (pTransHdr->mCompound != 0)
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// These are mutually exclusive
|
||||
if (pTransHdr->mIndication == 1 && pTransHdr->mResponse == 1)
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Requests/responses required valid transaction IDs
|
||||
if ( (pTransHdr->mIndication == 0)
|
||||
&& (pTransHdr->mTransactionID == (WORD)INVALID_QMI_TRANSACTION_ID) )
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
if ( (pTransHdr->mResponse == 1 || pTransHdr->mIndication == 1)
|
||||
&& (IsQMIProtocolRX( pt ) == false) )
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
if ( (pTransHdr->mResponse == 0 && pTransHdr->mIndication == 0)
|
||||
&& (IsQMIProtocolTX( pt ) == false) )
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Obtain message header
|
||||
const sQMIRawMessageHeader * pMsgHdr = 0;
|
||||
pMsgHdr = (const sQMIRawMessageHeader *)pBuffer;
|
||||
pBuffer += szMsgHdr;
|
||||
|
||||
// Validate reported length
|
||||
if (sz != ((ULONG)pMsgHdr->mLength + szTransHdr + szMsgHdr))
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Extract content TLV structures
|
||||
ULONG contentProcessed = 0;
|
||||
ULONG contentSz = (ULONG)pMsgHdr->mLength;
|
||||
while (contentProcessed < contentSz)
|
||||
{
|
||||
const sQMIRawContentHeader * pContent = 0;
|
||||
pContent = (const sQMIRawContentHeader *)pBuffer;
|
||||
|
||||
ULONG tlvLen = szContentHdr + pContent->mLength;
|
||||
|
||||
contentProcessed += tlvLen;
|
||||
if (contentProcessed <= contentSz)
|
||||
{
|
||||
mContents[(ULONG)pContent->mTypeID] = pContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
mContents.clear();
|
||||
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
pBuffer += tlvLen;
|
||||
}
|
||||
|
||||
// Validate TLV reported lengths
|
||||
if (contentProcessed != contentSz)
|
||||
{
|
||||
mbValid = bRC;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Success!
|
||||
bRC = true;
|
||||
|
||||
mbValid = bRC;
|
||||
return mbValid;
|
||||
}
|
||||
|
|
@ -0,0 +1,391 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QMIBuffers.h
|
||||
|
||||
DESCRIPTION:
|
||||
QMI service protocol related structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sQMUXHeader
|
||||
sQMIControlRawTransactionHeader
|
||||
sQMIServiceRawTransactionHeader
|
||||
sQMIRawMessageHeader
|
||||
sQMIRawContentHeader
|
||||
|
||||
sQMIServiceBuffer
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "ProtocolBuffer.h"
|
||||
#include "QMIEnum.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// QMI maximum buffer size (cannot be larger than MAX_SHARED_BUFFER_SIZE)
|
||||
const ULONG QMI_MAX_BUFFER_SIZE = MAX_SHARED_BUFFER_SIZE;
|
||||
|
||||
// Content ID for mandatory result TLV
|
||||
const ULONG QMI_TLV_ID_RESULT = 2;
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
MapQMIServiceToProtocol (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Map QMI service type (eQMIService) and direction to a protocol type
|
||||
(eProtocolType)
|
||||
|
||||
PARAMETERS:
|
||||
serviceType [ I ] - Enum value being mapped
|
||||
bTransmission [ I ] - Is this a transmission (TX vs. RX)?
|
||||
|
||||
RETURN VALUE:
|
||||
eProtocolType
|
||||
===========================================================================*/
|
||||
inline eProtocolType MapQMIServiceToProtocol(
|
||||
eQMIService serviceType,
|
||||
bool bTransmission = true )
|
||||
{
|
||||
eProtocolType pt = ePROTOCOL_ENUM_BEGIN;
|
||||
if (IsValid( serviceType ) == false)
|
||||
{
|
||||
return pt;
|
||||
}
|
||||
|
||||
DWORD tmp = ((DWORD)serviceType * 2) + (DWORD)ePROTOCOL_QMI_CTL_RX;
|
||||
if (bTransmission == true)
|
||||
{
|
||||
tmp++;
|
||||
}
|
||||
|
||||
if (IsQMIProtocol( (eProtocolType)tmp ) == true)
|
||||
{
|
||||
pt = (eProtocolType)tmp;
|
||||
}
|
||||
|
||||
return pt;
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
MapProtocolToQMIService (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Map protocol type (eProtocolType) to QMI service type (eQMIService)
|
||||
|
||||
PARAMETERS:
|
||||
protocolType [ I ] - Enum value being mapped
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline eQMIService MapProtocolToQMIService( eProtocolType protocolType )
|
||||
{
|
||||
eQMIService st = eQMI_SVC_ENUM_BEGIN;
|
||||
if (IsQMIProtocol( protocolType ) == false)
|
||||
{
|
||||
return st;
|
||||
}
|
||||
|
||||
DWORD tmp = ((DWORD)protocolType - (DWORD)ePROTOCOL_QMI_CTL_RX) / 2;
|
||||
if (IsValid( (eQMIService)tmp ) == true)
|
||||
{
|
||||
st = (eQMIService)tmp;
|
||||
}
|
||||
|
||||
return st;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas (pack structs)
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMUXHeader
|
||||
// Struct to represent a QMUX transaction header (raw)
|
||||
/*=========================================================================*/
|
||||
struct sQMUXHeader
|
||||
{
|
||||
public:
|
||||
WORD mLength;
|
||||
BYTE mFlags;
|
||||
BYTE mServiceType;
|
||||
BYTE mClientID;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMIControlRawTransactionHeader
|
||||
// Struct to represent a QMI control transaction header (raw)
|
||||
/*=========================================================================*/
|
||||
struct sQMIControlRawTransactionHeader
|
||||
{
|
||||
public:
|
||||
BYTE mResponse : 1; // Is this a response transaction?
|
||||
BYTE mIndication : 1; // Is this an indication transaction?
|
||||
BYTE mReserved : 6;
|
||||
|
||||
BYTE mTransactionID; // Transaction ID
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMIServiceRawTransactionHeader
|
||||
// Struct to represent a QMI service transaction header (raw)
|
||||
/*=========================================================================*/
|
||||
struct sQMIServiceRawTransactionHeader
|
||||
{
|
||||
public:
|
||||
BYTE mCompound : 1; // Is this a compound transaction?
|
||||
BYTE mResponse : 1; // Is this a response transaction?
|
||||
BYTE mIndication : 1; // Is this an indication transaction?
|
||||
BYTE mReserved : 5;
|
||||
|
||||
WORD mTransactionID; // Transaction ID
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMIRawMessageHeader
|
||||
// Struct to represent a QMI (control/service) message header (raw)
|
||||
/*=========================================================================*/
|
||||
struct sQMIRawMessageHeader
|
||||
{
|
||||
public:
|
||||
WORD mMessageID; // Message ID
|
||||
WORD mLength; // Length of message (not including this header)
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMIRawContentHeader
|
||||
// Struct to represent a QMI (control/service) content
|
||||
// (i.e Type/Length/Value, TLV) header (raw)
|
||||
/*=========================================================================*/
|
||||
struct sQMIRawContentHeader
|
||||
{
|
||||
public:
|
||||
BYTE mTypeID; // Content type ID
|
||||
WORD mLength; // Content length (not including this header)
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( pop )
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sQMIServiceBuffer
|
||||
// Struct to represent a QMI service channel request/response/indication
|
||||
// (shared buffer)
|
||||
/*=========================================================================*/
|
||||
struct sQMIServiceBuffer : public sProtocolBuffer
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
sQMIServiceBuffer( sSharedBuffer * pBuffer );
|
||||
|
||||
// Destructor
|
||||
virtual ~sQMIServiceBuffer();
|
||||
|
||||
// (Inline) Is this a request?
|
||||
bool IsRequest() const
|
||||
{
|
||||
bool bRequest = false;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
bRequest = (pHdr->mResponse == 0 && pHdr->mIndication == 0);
|
||||
}
|
||||
|
||||
return bRequest;
|
||||
};
|
||||
|
||||
// (Inline) Is this a response?
|
||||
bool IsResponse() const
|
||||
{
|
||||
bool bResponse = false;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
bResponse = (pHdr->mResponse == 1);
|
||||
}
|
||||
|
||||
return bResponse;
|
||||
};
|
||||
|
||||
// (Inline) Is this an indication?
|
||||
bool IsIndication() const
|
||||
{
|
||||
bool bInd = false;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
bInd = (pHdr->mIndication == 1);
|
||||
}
|
||||
|
||||
return bInd;
|
||||
};
|
||||
|
||||
// (Inline) Return raw header
|
||||
const sQMIServiceRawTransactionHeader * GetHeader() const
|
||||
{
|
||||
const sQMIServiceRawTransactionHeader * pHdr = 0;
|
||||
if (IsValid() == true)
|
||||
{
|
||||
pHdr = (const sQMIServiceRawTransactionHeader *)GetBuffer();
|
||||
}
|
||||
|
||||
return pHdr;
|
||||
};
|
||||
|
||||
// (Inline) Return the message ID
|
||||
ULONG GetMessageID() const
|
||||
{
|
||||
ULONG id = (ULONG)0xffffffff;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
pHdr++;
|
||||
const sQMIRawMessageHeader * pMsgHdr = 0;
|
||||
pMsgHdr = (sQMIRawMessageHeader *)pHdr;
|
||||
|
||||
id = pMsgHdr->mMessageID;
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
// (Inline) Return the transaction ID
|
||||
WORD GetTransactionID() const
|
||||
{
|
||||
WORD id = (WORD)INVALID_QMI_TRANSACTION_ID;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
id = pHdr->mTransactionID;
|
||||
}
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
// (Inline) Return raw content array
|
||||
const sQMIRawContentHeader * GetRawContents( ULONG & contentLen ) const
|
||||
{
|
||||
// Assume failure
|
||||
ULONG len = 0;
|
||||
const sQMIRawContentHeader * pRaw = 0;
|
||||
|
||||
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
pHdr++;
|
||||
const sQMIRawMessageHeader * pMsgHdr = 0;
|
||||
pMsgHdr = (sQMIRawMessageHeader *)pHdr;
|
||||
|
||||
len = pMsgHdr->mLength;
|
||||
pMsgHdr++;
|
||||
if (len > 0)
|
||||
{
|
||||
pRaw = (const sQMIRawContentHeader *)pMsgHdr;
|
||||
}
|
||||
}
|
||||
|
||||
contentLen = len;
|
||||
return pRaw;
|
||||
};
|
||||
|
||||
// (Inline) Return content structures
|
||||
std::map <ULONG, const sQMIRawContentHeader *> GetContents() const
|
||||
{
|
||||
return mContents;
|
||||
};
|
||||
|
||||
// Return contents of mandatory result content
|
||||
bool GetResult(
|
||||
ULONG & returnCode,
|
||||
ULONG & errorCode );
|
||||
|
||||
// Build a QMI request/response/indication
|
||||
static sSharedBuffer * BuildBuffer(
|
||||
eQMIService serviceType,
|
||||
WORD msgID,
|
||||
bool bResponse = false,
|
||||
bool bIndication = false,
|
||||
const BYTE * pData = 0,
|
||||
ULONG dataLen = 0 );
|
||||
|
||||
protected:
|
||||
// QMI protocol server has to be able to set the transaction ID
|
||||
friend class cQMIProtocolServer;
|
||||
|
||||
// Set the transaction ID
|
||||
void SetTransactionID( WORD tid ) const
|
||||
{
|
||||
if (tid == (WORD)INVALID_QMI_TRANSACTION_ID || IsValid() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sQMIServiceRawTransactionHeader * pHdr = 0;
|
||||
pHdr = (sQMIServiceRawTransactionHeader *)GetHeader();
|
||||
if (pHdr != 0)
|
||||
{
|
||||
pHdr->mTransactionID = tid;
|
||||
}
|
||||
};
|
||||
|
||||
// Is this QMI request/response/indication packet valid?
|
||||
virtual bool Validate();
|
||||
|
||||
/* Content TLV structures (indexed by type ID) */
|
||||
std::map <ULONG, const sQMIRawContentHeader *> mContents;
|
||||
|
||||
private:
|
||||
// Prevent 'upcopying'
|
||||
sQMIServiceBuffer( const sProtocolBuffer & );
|
||||
sQMIServiceBuffer & operator = ( const sProtocolBuffer & );
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,422 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QMIProtocolServer.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QMI protocol server
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cQMIProtocolServer
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "QMIProtocolServer.h"
|
||||
#include "QMIBuffers.h"
|
||||
#include "Comm.h"
|
||||
#include "Socket.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
// cQMIProtocolServer Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cQMIProtocolServer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
PARAMETERS:
|
||||
serviceType [ I ] - QMI service type requested
|
||||
bufferSzRx [ I ] - Size of data buffer for incoming data
|
||||
logSz [ I ] - Size of log (number of buffers)
|
||||
|
||||
SEQUENCING:
|
||||
None (constructs sequencing objects)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cQMIProtocolServer::cQMIProtocolServer(
|
||||
eQMIService serviceType,
|
||||
ULONG bufferSzRx,
|
||||
ULONG logSz )
|
||||
: cProtocolServer( MapQMIServiceToProtocol( serviceType, false ),
|
||||
MapQMIServiceToProtocol( serviceType, true ),
|
||||
bufferSzRx,
|
||||
logSz ),
|
||||
mLastTID( (WORD)INVALID_QMI_TRANSACTION_ID ),
|
||||
mService( serviceType )
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cQMIProtocolServer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
SEQUENCING:
|
||||
None (constructs sequencing objects)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cQMIProtocolServer::~cQMIProtocolServer()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Connect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Connect to the configured QMI service using the given QMI
|
||||
control file
|
||||
|
||||
PARAMETERS:
|
||||
pControlFile [ I ] - QMI control file
|
||||
|
||||
SEQUENCING:
|
||||
This method is sequenced according to the command event, i.e. any
|
||||
other thread that needs to send a command to the protocol server
|
||||
thread will block until this method completes
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::Connect( LPCSTR pControlFile )
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (IsValid( mService ) == false || mService == eQMI_SVC_CONTROL)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
std::string name = pControlFile;
|
||||
if (name.find( "qcqmi" ) != std::string::npos)
|
||||
{
|
||||
mpConnection = new cComm();
|
||||
mConnectionType = eConnectionType_RmNet;
|
||||
}
|
||||
else
|
||||
{
|
||||
// SMD
|
||||
|
||||
if (name.find( "QMUXD:" ) == 0)
|
||||
{
|
||||
// Remove qualifier
|
||||
name = name.substr( 6 );
|
||||
}
|
||||
|
||||
mpConnection = new cSocket();
|
||||
mConnectionType = eConnectionType_SMD;
|
||||
}
|
||||
|
||||
// Pass service file to base class for actual connection
|
||||
bRC = cProtocolServer::Connect( name.c_str() );
|
||||
|
||||
if (bRC == false)
|
||||
{
|
||||
TRACE( "QMI connect %d failed\n", mService );
|
||||
}
|
||||
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ValidateRequest (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Validate a request that is about to be scheduled
|
||||
|
||||
SEQUENCING:
|
||||
This method is sequenced according to the command event, i.e. any
|
||||
other thread that needs to send a command to the protocol server
|
||||
thread will block until this method completes
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::ValidateRequest( const sProtocolRequest & req )
|
||||
{
|
||||
if (cProtocolServer::ValidateRequest( req ) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sQMIServiceBuffer qmiReq( req.GetSharedBuffer() );
|
||||
return qmiReq.IsValid();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
InitializeComm (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Perform protocol specific communications port initialization
|
||||
|
||||
SEQUENCING:
|
||||
None (must be called from protocol server thread)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::InitializeComm()
|
||||
{
|
||||
bool bResult = false;
|
||||
if (mpConnection == 0)
|
||||
{
|
||||
return bResult;
|
||||
}
|
||||
|
||||
if (mConnectionType == eConnectionType_RmNet)
|
||||
{
|
||||
// Setup the QMI Service type
|
||||
int result = mpConnection->SendCtl( QMI_GET_SERVICE_FILE_IOCTL,
|
||||
(void*)(unsigned long)mService );
|
||||
bResult = (result == 0);
|
||||
}
|
||||
else if (mConnectionType == eConnectionType_SMD)
|
||||
{
|
||||
// Setup the QMI Service type
|
||||
int result = mpConnection->SendCtl( eQMUXD_MSG_ALLOC_QMI_CLIENT_ID,
|
||||
(void*)&mService );
|
||||
bResult = (result == 0);
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CleanupComm (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Perform protocol specific communications port cleanup
|
||||
|
||||
SEQUENCING:
|
||||
None (must be called from protocol server thread)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::CleanupComm()
|
||||
{
|
||||
bool bResult = true;
|
||||
|
||||
if (mpConnection != 0
|
||||
&& mConnectionType == eConnectionType_SMD)
|
||||
{
|
||||
// Delete the QMI client
|
||||
|
||||
// NOTE: This is generally unnecessary, when you close the channel
|
||||
// it is deleted
|
||||
int result = mpConnection->SendCtl( eQMUXD_MSG_RELEASE_QMI_CLIENT_ID,
|
||||
0 );
|
||||
bResult = (result == 0);
|
||||
}
|
||||
|
||||
// Nothing to actually do here
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
DecodeRxData (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Decode incoming data into QMI indications/responses
|
||||
|
||||
PARAMETERS:
|
||||
bytesReceived [ I ] - Number of bytes to decoded
|
||||
rspIdx [ O ] - Log index of last valid response (not used)
|
||||
bAbortTx [ O ] - Response aborts current transmission? (not used)
|
||||
|
||||
SEQUENCING:
|
||||
None (must be called from protocol server thread)
|
||||
|
||||
RETURN VALUE:
|
||||
bool - Was a response received?
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::DecodeRxData(
|
||||
ULONG bytesReceived,
|
||||
ULONG & rspIdx,
|
||||
bool & bAbortTx )
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
|
||||
rspIdx = INVALID_LOG_INDEX;
|
||||
bAbortTx = false;
|
||||
|
||||
// Something to decode from?
|
||||
if (bytesReceived == 0)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Set protocol type (we have to be dealing with a valid QMI service)
|
||||
eProtocolType pt = MapQMIServiceToProtocol( mService, false );
|
||||
if (pt == ePROTOCOL_ENUM_BEGIN)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
sSharedBuffer * pTmp = 0;
|
||||
pTmp = new sSharedBuffer( mpRxBuffer, bytesReceived, pt );
|
||||
if (pTmp != 0)
|
||||
{
|
||||
sQMIServiceBuffer tmpBuf( pTmp );
|
||||
if (tmpBuf.IsValid() == true)
|
||||
{
|
||||
rspIdx = mLog.AddBuffer( tmpBuf );
|
||||
if (IsResponse( tmpBuf ) == true)
|
||||
{
|
||||
bRC = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rspIdx = INVALID_LOG_INDEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
EncodeTxData (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Encode data for transmission
|
||||
|
||||
PARAMETERS:
|
||||
pBuffer [ I ] - Data to be encoded
|
||||
bEncoded [ O ] - Do we even encode data?
|
||||
|
||||
SEQUENCING:
|
||||
None (must be called from protocol server thread)
|
||||
|
||||
RETURN VALUE:
|
||||
sSharedBuffer * - Encoded data (0 upon error when encoding is indicated)
|
||||
===========================================================================*/
|
||||
sSharedBuffer * cQMIProtocolServer::EncodeTxData(
|
||||
sSharedBuffer * pBuffer,
|
||||
bool & bEncoded )
|
||||
{
|
||||
WORD tid = ++mLastTID;
|
||||
if (tid == (WORD)INVALID_QMI_TRANSACTION_ID)
|
||||
{
|
||||
tid++;
|
||||
}
|
||||
|
||||
sQMIServiceBuffer tmpBuf( pBuffer );
|
||||
tmpBuf.SetTransactionID( tid );
|
||||
|
||||
// No actual encoding required as we alter the original request
|
||||
bEncoded = false;
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsResponse (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Is the passed in data a response to the current request?
|
||||
|
||||
PARAMETERS:
|
||||
rsp [ I ] - Candidate response
|
||||
|
||||
SEQUENCING:
|
||||
None (must be called from protocol server thread)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQMIProtocolServer::IsResponse( const sProtocolBuffer & rsp )
|
||||
{
|
||||
// Assume not
|
||||
bool bRC = false;
|
||||
if ( (mpActiveRequest == 0)
|
||||
|| (mpActiveRequest->mRequest.IsValid() == false)
|
||||
|| (mpActiveRequest->mbWaitingForResponse == false)
|
||||
|| (rsp.IsValid() == false) )
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
sQMIServiceBuffer qmiReq( mpActiveRequest->mRequest.GetSharedBuffer() );
|
||||
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
|
||||
|
||||
if (qmiReq.IsValid() == false || qmiRsp.IsValid() == false)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
if (qmiRsp.IsResponse() == false)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
WORD reqID = qmiReq.GetTransactionID();
|
||||
WORD rspID = qmiRsp.GetTransactionID();
|
||||
|
||||
if ( (reqID == (WORD)INVALID_QMI_TRANSACTION_ID)
|
||||
|| (rspID == (WORD)INVALID_QMI_TRANSACTION_ID)
|
||||
|| (reqID != rspID) )
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Sadly there are documentated cases of firmware returning responses
|
||||
// with a matching transaction ID but a mismatching message ID. There
|
||||
// is no reason for this to be considered valid behavior as of yet
|
||||
ULONG reqMsgID = qmiReq.GetMessageID();
|
||||
ULONG rspMsgID = qmiRsp.GetMessageID();
|
||||
|
||||
if (reqMsgID != rspMsgID)
|
||||
{
|
||||
return bRC;
|
||||
}
|
||||
|
||||
bRC = true;
|
||||
return bRC;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QMIProtocolServer.h
|
||||
|
||||
DESCRIPTION:
|
||||
QMI protocol server
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cQMIProtocolServer
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "ProtocolServer.h"
|
||||
#include "QMIEnum.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cQMIProtocolServer
|
||||
/*=========================================================================*/
|
||||
class cQMIProtocolServer : public cProtocolServer
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cQMIProtocolServer(
|
||||
eQMIService serviceType,
|
||||
ULONG bufferSzRx,
|
||||
ULONG logSz );
|
||||
|
||||
// Destructor
|
||||
virtual ~cQMIProtocolServer();
|
||||
|
||||
// Connect to the given QMI service using the configured QMI
|
||||
// control file
|
||||
bool Connect( LPCSTR pControlFile );
|
||||
|
||||
// (Inline) Return the QMI service type
|
||||
eQMIService GetServiceType()
|
||||
{
|
||||
return mService;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Validate a request that is about to be scheduled
|
||||
virtual bool ValidateRequest( const sProtocolRequest & req );
|
||||
|
||||
// Perform protocol specific communications port initialization
|
||||
virtual bool InitializeComm();
|
||||
|
||||
// Perform protocol specific communications port cleanup
|
||||
virtual bool CleanupComm();
|
||||
|
||||
// Decode incoming data into packets returning the last response
|
||||
virtual bool DecodeRxData(
|
||||
ULONG bytesReceived,
|
||||
ULONG & rspIdx,
|
||||
bool & bAbortTx );
|
||||
|
||||
// Encode data for transmission
|
||||
virtual sSharedBuffer * EncodeTxData(
|
||||
sSharedBuffer * pBuffer,
|
||||
bool & bEncoded );
|
||||
|
||||
// Is the passed in data a response to the current request?
|
||||
virtual bool IsResponse( const sProtocolBuffer & rsp );
|
||||
|
||||
// (Inline) Is the passed in data a response that aborts the
|
||||
// current request?
|
||||
virtual bool IsTxAbortResponse( const sProtocolBuffer & /* rsp */ )
|
||||
{
|
||||
// QMI doesn't necessarily require this
|
||||
return false;
|
||||
};
|
||||
|
||||
/* Current transaction ID */
|
||||
SHORT mLastTID;
|
||||
|
||||
/* Type of QMI service we are serving */
|
||||
eQMIService mService;
|
||||
};
|
|
@ -0,0 +1,375 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
SharedBuffer.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Shareable protocol structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
|
||||
sSharedBuffer
|
||||
Simple struct to represent a reference counted shareable (no copy)
|
||||
buffer, as the basis for all buffer related classes
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "SharedBuffer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Synchronization object
|
||||
struct sSharedBufferSync
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
sSharedBufferSync()
|
||||
: mbInitialized( false )
|
||||
{
|
||||
int nRet = pthread_mutex_init( &mSyncSection, NULL );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SharedBuffer: Unable to init sync mutex."
|
||||
" Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return;
|
||||
}
|
||||
|
||||
mbInitialized = true;
|
||||
};
|
||||
|
||||
// Destructor
|
||||
~sSharedBufferSync()
|
||||
{
|
||||
mbInitialized = false;
|
||||
int nRet = pthread_mutex_destroy( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SharedBuffer: Unable to destroy sync mutex."
|
||||
" Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Lock sync object
|
||||
void Lock()
|
||||
{
|
||||
if (mbInitialized == true)
|
||||
{
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SharedBuffer: Unable to lock sync mutex."
|
||||
" Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Unlock sync object
|
||||
void Unlock()
|
||||
{
|
||||
if (mbInitialized == true)
|
||||
{
|
||||
int nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SharedBuffer: Unable to unlock sync mutex."
|
||||
" Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
/* DIAG buffer critical section */
|
||||
pthread_mutex_t mSyncSection;
|
||||
|
||||
/* Has this object been initialized? */
|
||||
bool mbInitialized;
|
||||
};
|
||||
|
||||
// Global (across all shared buffers) reference count guard
|
||||
sSharedBufferSync gRefCount;
|
||||
|
||||
/*=========================================================================*/
|
||||
// sSharedBuffer Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sSharedBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor (copy passed in buffer)
|
||||
|
||||
PARAMETERS:
|
||||
pDataToCopy [ I ] - The data buffer to copy (should be non-zero)
|
||||
dataLen [ I ] - The length of the above buffer (should be > 1)
|
||||
dataType [ I ] - Type of data (not used internal to class)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sSharedBuffer::sSharedBuffer(
|
||||
const BYTE * pDataToCopy,
|
||||
ULONG dataLen,
|
||||
ULONG dataType )
|
||||
: mpData( 0 ),
|
||||
mSize( 0 ),
|
||||
mType( dataType ),
|
||||
mRefCount( 0 )
|
||||
{
|
||||
// Length not too small/not too big?
|
||||
if (IsValidSize( dataLen ) == true)
|
||||
{
|
||||
// Yes, data actually exists?
|
||||
if (pDataToCopy != 0)
|
||||
{
|
||||
// Yes, try to allocate memory
|
||||
mpData = new BYTE[dataLen];
|
||||
if (mpData != 0)
|
||||
{
|
||||
// Now copy into our allocation
|
||||
memcpy( (PVOID)mpData,
|
||||
(LPCVOID)pDataToCopy,
|
||||
(SIZE_T)dataLen );
|
||||
|
||||
// Now set the size, we do this last so that our double
|
||||
// deletion logic is only applied if we had an allocation
|
||||
// in the first place
|
||||
mSize = dataLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
sSharedBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor (assume ownership of passed in buffer)
|
||||
|
||||
PARAMETERS:
|
||||
dataLen [ I ] - The length of the above buffer (should be > 1)
|
||||
pDataToOwn [ I ] - The data buffer to assume ownership of (should
|
||||
be non-zero)
|
||||
|
||||
dataType [ I ] - Type of data (not used internal to class)
|
||||
|
||||
NOTE: The order is intentionally reversed from the previous constructor
|
||||
to avoid any cases of mistaken identity (copy versus assume ownership)
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sSharedBuffer::sSharedBuffer(
|
||||
ULONG dataLen,
|
||||
PBYTE pDataToOwn,
|
||||
ULONG dataType )
|
||||
: mpData( 0 ),
|
||||
mSize( 0 ),
|
||||
mType( dataType ),
|
||||
mRefCount( 0 )
|
||||
{
|
||||
// Data actually exists?
|
||||
if (pDataToOwn != 0)
|
||||
{
|
||||
// Yes, length not too small/not too big?
|
||||
if (IsValidSize( dataLen ) == true)
|
||||
{
|
||||
// Yes, assume ownership of the passed in buffer
|
||||
mpData = pDataToOwn;
|
||||
mSize = dataLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This data buffer is not acceptable to us, but we have assumed
|
||||
// ownership of the memory which we will now free
|
||||
delete [] pDataToOwn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~sSharedBuffer (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
sSharedBuffer::~sSharedBuffer()
|
||||
{
|
||||
ASSERT( mRefCount == 0 );
|
||||
|
||||
// Buffer data to free?
|
||||
if (mpData != 0)
|
||||
{
|
||||
// Yes, zero first byte for caution and then delete it
|
||||
mpData[0] = 0;
|
||||
delete [] mpData;
|
||||
|
||||
// Even more caution, zero out pointer
|
||||
mpData = 0;
|
||||
}
|
||||
else if (mSize != 0)
|
||||
{
|
||||
ASSERT( (PVOID)("Double deletion detected in ~sSharedBuffer") == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
operator == (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Equality operator
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool sSharedBuffer::operator == ( const sSharedBuffer & refBuf ) const
|
||||
{
|
||||
// Assume they are not equal
|
||||
bool bEq = false;
|
||||
|
||||
// The buffers must be the same
|
||||
if (mpData == refBuf.mpData)
|
||||
{
|
||||
if (mSize == refBuf.mSize)
|
||||
{
|
||||
if (mRefCount == refBuf.mRefCount)
|
||||
{
|
||||
if (mType == refBuf.mType)
|
||||
{
|
||||
// The shared buffers are the same
|
||||
bEq = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Very odd - the buffers are the same, but not the ref count?!?
|
||||
ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Very odd - the buffers are the same, but not the size?!?
|
||||
ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return bEq;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
operator != (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Inequality operator
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool sSharedBuffer::operator != ( const sSharedBuffer & refBuf ) const
|
||||
{
|
||||
if (*this == refBuf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
AddRef (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Increment reference count
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void sSharedBuffer::AddRef()
|
||||
{
|
||||
gRefCount.Lock();
|
||||
mRefCount++;
|
||||
gRefCount.Unlock();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Release (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Release reference, delete if reference count zero
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void sSharedBuffer::Release()
|
||||
{
|
||||
gRefCount.Lock();
|
||||
|
||||
ASSERT( mRefCount != 0 );
|
||||
|
||||
// Decrement reference count
|
||||
if (mRefCount > 0)
|
||||
{
|
||||
mRefCount--;
|
||||
}
|
||||
|
||||
// ... and delete if reference count now 0
|
||||
if (mRefCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
gRefCount.Unlock();
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
SharedBuffer.h
|
||||
|
||||
DESCRIPTION:
|
||||
Shareable buffer structures and affliated methods
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
sSharedBuffer
|
||||
Simple struct to represent a reference counted shareable (no copy)
|
||||
buffer, as the basis for all buffer related classes
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Forward Declarations
|
||||
//---------------------------------------------------------------------------
|
||||
struct sProtocolBuffer;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Maximum size of a shared buffer
|
||||
const ULONG MAX_SHARED_BUFFER_SIZE = 1024 * 16 + 256;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas (pack structs)
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sSharedBuffer
|
||||
//
|
||||
// Simple struct to represent a reference counted shareable (no copy)
|
||||
// buffer, as the basis for all buffer related classes
|
||||
//
|
||||
// NOTE: Do *NOT* create instances of this structure on the stack, it
|
||||
// must be dynamically allocated in order to function correctly
|
||||
/*=========================================================================*/
|
||||
struct sSharedBuffer
|
||||
{
|
||||
public:
|
||||
// Constructor (copy passed in buffer)
|
||||
sSharedBuffer(
|
||||
const BYTE * pDataToCopy,
|
||||
ULONG dataLen,
|
||||
ULONG dataType );
|
||||
|
||||
// Constructor (assume ownership of passed in buffer)
|
||||
sSharedBuffer(
|
||||
ULONG dataLen,
|
||||
PBYTE pDataToOwn,
|
||||
ULONG dataType );
|
||||
|
||||
// Destructor
|
||||
virtual ~sSharedBuffer();
|
||||
|
||||
// Equality operator
|
||||
bool operator == ( const sSharedBuffer & ) const;
|
||||
|
||||
// Inequality operator
|
||||
bool operator != ( const sSharedBuffer & ) const;
|
||||
|
||||
// (Inline) Get buffer
|
||||
const BYTE * GetBuffer() const
|
||||
{
|
||||
return mpData;
|
||||
};
|
||||
|
||||
// (Inline) Get buffer size
|
||||
ULONG GetSize() const
|
||||
{
|
||||
return mSize;
|
||||
};
|
||||
|
||||
// (Inline) Get buffer type
|
||||
ULONG GetType() const
|
||||
{
|
||||
return mType;
|
||||
};
|
||||
|
||||
// (Inline) Is this buffer valid?
|
||||
bool IsValid() const
|
||||
{
|
||||
return (mpData != 0 && IsValidSize( mSize ));
|
||||
};
|
||||
|
||||
// (Inline) Get reference count
|
||||
ULONG GetRefCount() const
|
||||
{
|
||||
return mRefCount;
|
||||
};
|
||||
|
||||
// (Static Inline) Is the passed in size within the allowable range
|
||||
// a shared buffer?
|
||||
static bool IsValidSize( ULONG sz )
|
||||
{
|
||||
return (sz > 0 && sz <= MAX_SHARED_BUFFER_SIZE);
|
||||
};
|
||||
|
||||
protected:
|
||||
// Add reference
|
||||
void AddRef();
|
||||
|
||||
// Release reference, delete if reference count zero
|
||||
void Release();
|
||||
|
||||
/* Data */
|
||||
PBYTE mpData;
|
||||
|
||||
/* Size of data */
|
||||
ULONG mSize;
|
||||
|
||||
/* Type of data */
|
||||
ULONG mType;
|
||||
|
||||
/* Reference count */
|
||||
ULONG mRefCount;
|
||||
|
||||
private:
|
||||
// Leave copy constructor and assignment operator unimplemented
|
||||
// to prevent unintentional and unauthorized copying of the object
|
||||
// (which would lead to bad reference counting)
|
||||
sSharedBuffer( const sSharedBuffer & );
|
||||
sSharedBuffer & operator = ( const sSharedBuffer & );
|
||||
|
||||
friend struct sProtocolBuffer;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( pop )
|
||||
|
|
@ -0,0 +1,812 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Socket.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Implementation of cSocket class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cSocket
|
||||
This class wraps low level communication to qmuxd
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "Socket.h"
|
||||
#include "ProtocolServer.h"
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread commands
|
||||
#define START_READ_CMD 0
|
||||
#define STOP_READ_CMD 1
|
||||
#define EXIT_CMD 2
|
||||
|
||||
// Size of the QMUXD command payload
|
||||
// GET_CLIENT_ID and RELEASE_CLIENT_ID must pass in a buffer of this size
|
||||
#define PAYLOAD_SIZE 664
|
||||
|
||||
/*=========================================================================*/
|
||||
// struct sQMUXDHeader
|
||||
/*=========================================================================*/
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
struct sQMUXDHeader
|
||||
{
|
||||
/* Total size of header and following buffer */
|
||||
int mTotalSize;
|
||||
|
||||
/* QMUXD client ID */
|
||||
int mQMUXDClientID;
|
||||
|
||||
/* Message type */
|
||||
eQMUXDMessageTypes mQMUXDMsgID;
|
||||
|
||||
/* Duplicate of mQMUXDClientID */
|
||||
int mQMUXDClientIDDuplicate;
|
||||
|
||||
/* Transaction ID */
|
||||
unsigned long mTxID;
|
||||
|
||||
/* System error code */
|
||||
int mSysErrCode;
|
||||
|
||||
/* QMI error code (duplicate of TLV 0x02) */
|
||||
int mQmiErrCode;
|
||||
|
||||
/* SMD channel. 0 = SMD_DATA_5 */
|
||||
int mQMUXDConectionType;
|
||||
|
||||
/* QMI service ID */
|
||||
int mQMUXServiceID;
|
||||
|
||||
/* QMI client ID */
|
||||
unsigned char mQMUXClientID;
|
||||
|
||||
/* QMI flags */
|
||||
unsigned char mRxFlags;
|
||||
|
||||
/* In QMUXD this struct is not packed, so the compiler appends
|
||||
these two bytes */
|
||||
unsigned short int mMissing2Bytes;
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
RxSocketThread (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Thread for simulating asynchronous reads to a socket
|
||||
|
||||
PARAMETERS:
|
||||
pData [ I ] cSocket pointer
|
||||
|
||||
RETURN VALUE:
|
||||
void * - thread exit value (always 0)
|
||||
===========================================================================*/
|
||||
void * RxSocketThread( void * pData )
|
||||
{
|
||||
cSocket * pSocket = (cSocket*)pData;
|
||||
if (pSocket == NULL || pSocket->IsValid() == false)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd_set inputSet, outputSet;
|
||||
FD_ZERO( &inputSet );
|
||||
FD_SET( pSocket->mCommandPipe[READING], &inputSet );
|
||||
int largestFD = pSocket->mCommandPipe[READING];
|
||||
|
||||
int status = 0;
|
||||
while (true)
|
||||
{
|
||||
// No FD_COPY() available
|
||||
memcpy( &outputSet, &inputSet, sizeof( fd_set ) );
|
||||
|
||||
// Wait until we recieve a command or data is available
|
||||
status = select( largestFD + 1, &outputSet, NULL, NULL, NULL );
|
||||
if (status <= 0)
|
||||
{
|
||||
TRACE( "error %d in select, errno %d\n", status, errno );
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET( pSocket->mCommandPipe[READING], &outputSet ) == true)
|
||||
{
|
||||
// Read command value from the pipe
|
||||
BYTE cmd;
|
||||
status = read( pSocket->mCommandPipe[READING], &cmd, 1 );
|
||||
if (status != 1)
|
||||
{
|
||||
TRACE( "cmd error %d\n", status );
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd == START_READ_CMD)
|
||||
{
|
||||
FD_SET( pSocket->mSocket, &inputSet );
|
||||
largestFD = std::max( pSocket->mSocket,
|
||||
pSocket->mCommandPipe[READING] );
|
||||
}
|
||||
else if (cmd == STOP_READ_CMD)
|
||||
{
|
||||
FD_CLR( pSocket->mSocket, &inputSet );
|
||||
largestFD = pSocket->mCommandPipe[READING];
|
||||
}
|
||||
else
|
||||
{
|
||||
// EXIT_CMD or anything else
|
||||
pSocket->mpRxCallback = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET( pSocket->mSocket, &outputSet ) == true)
|
||||
{
|
||||
// Stop watching for read data
|
||||
FD_CLR( pSocket->mSocket, &inputSet );
|
||||
largestFD = pSocket->mCommandPipe[READING];
|
||||
|
||||
// Perform a recv for the header
|
||||
sQMUXDHeader recvHdr;
|
||||
status = recv( pSocket->mSocket,
|
||||
&recvHdr,
|
||||
sizeof( recvHdr ),
|
||||
0 );
|
||||
if (status != sizeof( recvHdr ))
|
||||
{
|
||||
TRACE( "recv error, bad size %d\n", status );
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate and read the remaining data
|
||||
int remainder = recvHdr.mTotalSize - sizeof( recvHdr );
|
||||
if (remainder > pSocket->mBuffSz)
|
||||
{
|
||||
TRACE( "read too large for buffer\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
status = recv( pSocket->mSocket,
|
||||
pSocket->mpBuffer,
|
||||
remainder,
|
||||
0 );
|
||||
|
||||
// Is this one of our IOCTLS or a standard message?
|
||||
if (recvHdr.mQMUXDMsgID == eQMUXD_MSG_WRITE_QMI_SDU)
|
||||
{
|
||||
cIOCallback * pCallback = pSocket->mpRxCallback;
|
||||
pSocket->mpRxCallback = 0;
|
||||
|
||||
if (pCallback == (cIOCallback *)1)
|
||||
{
|
||||
// We wanted to read, but not to be notified
|
||||
}
|
||||
else if (status >= 0)
|
||||
{
|
||||
pCallback->IOComplete( 0, status );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCallback->IOComplete( status, 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pSocket->mpRxCallback = 0;
|
||||
// Notify SendCtl() that control message completed
|
||||
|
||||
if (recvHdr.mQMUXDMsgID == eQMUXD_MSG_ALLOC_QMI_CLIENT_ID)
|
||||
{
|
||||
DWORD clientID;
|
||||
memcpy( &clientID, &pSocket->mpBuffer[0], 4 );
|
||||
|
||||
pSocket->mCtrlMsgComplete.Set( clientID );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just set the event
|
||||
pSocket->mCtrlMsgComplete.Set( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// cSocket Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cSocket (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cSocket::cSocket()
|
||||
: mSocket( INVALID_HANDLE_VALUE ),
|
||||
mbCancelWrite( false ),
|
||||
mpBuffer( 0 ),
|
||||
mBuffSz( 0 ),
|
||||
mRxThreadID( 0 ),
|
||||
mCtrlMsgComplete(),
|
||||
mQMUXDClientID( 0 ),
|
||||
mQMUXClientID( 0 ),
|
||||
mQMUXServiceID( 0 ),
|
||||
mChannelID( -1 ),
|
||||
mQMUXDTxID( 0 )
|
||||
{
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cSocket (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cSocket::~cSocket()
|
||||
{
|
||||
// Disconnect from current port
|
||||
Disconnect();
|
||||
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsValid (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Is this object valid?
|
||||
|
||||
RETURN VALUE:
|
||||
Bool
|
||||
===========================================================================*/
|
||||
bool cSocket::IsValid()
|
||||
{
|
||||
// Nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Connect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Connect to the specified port
|
||||
|
||||
PARAMETERS:
|
||||
pChannel [ I ] - Channel number (IE: "0" = SMD_DATA_5 )
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::Connect( LPCSTR pChannel )
|
||||
{
|
||||
if (IsValid() == false || pChannel == 0 || pChannel[0] == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSocket != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
// Initialize command pipe for read thread
|
||||
int nRet = pipe( mCommandPipe );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "cSocket:Connect() pipe creation failed %d\n", nRet );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the read thread
|
||||
nRet = pthread_create( &mRxThreadID,
|
||||
0,
|
||||
RxSocketThread,
|
||||
this );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "cSocket::Connect() pthread_create = %d\n", nRet );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a socket
|
||||
mSocket = socket( AF_UNIX, SOCK_STREAM, 0 );
|
||||
if (mSocket == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
TRACE( "unable to create socket %d\n", errno );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_un clientSockAddr;
|
||||
memset( &clientSockAddr, 0, sizeof( clientSockAddr ) );
|
||||
clientSockAddr.sun_family = AF_UNIX;
|
||||
|
||||
// Format the client path
|
||||
snprintf( &clientSockAddr.sun_path[0],
|
||||
sizeof( clientSockAddr.sun_path ),
|
||||
"/var/qmux_client_socket%7lu",
|
||||
(unsigned long)getpid() );
|
||||
|
||||
// Delete if it exists already
|
||||
unlink( clientSockAddr.sun_path );
|
||||
|
||||
// Bind to a client address
|
||||
nRet = bind( mSocket,
|
||||
(struct sockaddr *)&clientSockAddr,
|
||||
sizeof( sockaddr_un ) );
|
||||
if (nRet == -1)
|
||||
{
|
||||
TRACE( "bad bind %d\n", errno );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Format the connection path
|
||||
struct sockaddr_un connectSockAddr;
|
||||
memset( &connectSockAddr, 0, sizeof( connectSockAddr ) );
|
||||
connectSockAddr.sun_family = AF_UNIX;
|
||||
|
||||
snprintf( &connectSockAddr.sun_path[0],
|
||||
sizeof( connectSockAddr.sun_path ),
|
||||
"/var/qmux_connect_socket" );
|
||||
|
||||
// Connect to server address
|
||||
nRet = connect( mSocket,
|
||||
(struct sockaddr *)&connectSockAddr,
|
||||
sizeof( sockaddr_un ) );
|
||||
if (nRet < 0)
|
||||
{
|
||||
TRACE( "bad connect %d\n", errno );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
int clientID;
|
||||
nRet = recv( mSocket, &clientID, sizeof( clientID ), 0 );
|
||||
if (nRet != sizeof( clientID ))
|
||||
{
|
||||
printf( "bad client ID %d\n", errno );
|
||||
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save QMUXD Client ID
|
||||
mQMUXDClientID = clientID;
|
||||
|
||||
// Save SMD channel
|
||||
mChannelID = strtol( pChannel, 0, 10 );
|
||||
if (mChannelID == -1)
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
SendCtl (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Send a control message to the lower layer
|
||||
|
||||
PARAMETERS:
|
||||
msgType [ I ] - eQMUXDMessageType
|
||||
pData [I/O] - input or output specific to ioctl request value
|
||||
|
||||
RETURN VALUE:
|
||||
int - control message return value (0 for success)
|
||||
===========================================================================*/
|
||||
int cSocket::SendCtl(
|
||||
UINT msgType,
|
||||
void * pData )
|
||||
{
|
||||
if (mSocket == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
TRACE( "Invalid file handle\n" );
|
||||
return -EBADFD;
|
||||
}
|
||||
|
||||
BYTE msg[sizeof( sQMUXDHeader ) + PAYLOAD_SIZE];
|
||||
memset( &msg[0], 0, sizeof( msg ) );
|
||||
|
||||
// The important QMUXD header values
|
||||
sQMUXDHeader * pHdr = (sQMUXDHeader *)&msg[0];
|
||||
pHdr->mTotalSize = sizeof( msg );
|
||||
pHdr->mQMUXDClientID = mQMUXDClientID;
|
||||
pHdr->mQMUXDMsgID = (eQMUXDMessageTypes)msgType;
|
||||
pHdr->mQMUXDClientIDDuplicate = mQMUXDClientID;
|
||||
|
||||
// mQMUXDTxID could go to INT_MAX, but rather than dealing with possible
|
||||
// overflow in qmuxd or one of the lower layers, we'll stop early
|
||||
mQMUXDTxID++;
|
||||
if (mQMUXDTxID > 100000)
|
||||
{
|
||||
mQMUXDTxID = 1;
|
||||
}
|
||||
pHdr->mTxID = ++mQMUXDTxID;
|
||||
|
||||
// The Payload
|
||||
BYTE * pPayload = &msg[sizeof( sQMUXDHeader )];
|
||||
if (msgType == (int)eQMUXD_MSG_ALLOC_QMI_CLIENT_ID)
|
||||
{
|
||||
memcpy( &mQMUXServiceID, pData, 4 );
|
||||
memcpy( &pPayload[0], &mQMUXServiceID, 4 );
|
||||
}
|
||||
else if (msgType == (int)eQMUXD_MSG_RELEASE_QMI_CLIENT_ID)
|
||||
{
|
||||
memcpy( &pPayload[0], &mQMUXServiceID, 4 );
|
||||
memcpy( &pPayload[4], &mQMUXClientID, 4 );
|
||||
}
|
||||
|
||||
// Send the message
|
||||
int rc = send( mSocket, &msg[0], sizeof( msg ), 0 );
|
||||
if (rc != sizeof( msg ))
|
||||
{
|
||||
TRACE( "bad write %d\n", rc );
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (mpRxCallback == 0)
|
||||
{
|
||||
// No one is currently reading, need to trigger a read
|
||||
// so our data can be recieved
|
||||
RxData( &msg[0], sizeof( msg ), 0 );
|
||||
}
|
||||
|
||||
// Wait for the response (10s timeout)
|
||||
DWORD val;
|
||||
rc = mCtrlMsgComplete.Wait( 10000, val );
|
||||
if (rc != 0)
|
||||
{
|
||||
TRACE( "bad SendCtl() wait %d\n", rc );
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (msgType == (int)eQMUXD_MSG_ALLOC_QMI_CLIENT_ID)
|
||||
{
|
||||
// Grab the client ID
|
||||
mQMUXClientID = val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Disconnect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Disconnect from the current port
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::Disconnect()
|
||||
{
|
||||
// Assume success
|
||||
bool bRC = true;
|
||||
|
||||
if (mCommandPipe[WRITING] != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (mRxThreadID != 0)
|
||||
{
|
||||
// Notify the thread to exit
|
||||
BYTE byte = EXIT_CMD;
|
||||
write( mCommandPipe[WRITING], &byte, 1 );
|
||||
|
||||
// And wait for it
|
||||
int nRC = pthread_join( mRxThreadID, 0 );
|
||||
if (nRC != 0)
|
||||
{
|
||||
TRACE( "failed to join thread %d\n", nRC );
|
||||
bRC = false;
|
||||
}
|
||||
|
||||
mRxThreadID = 0;
|
||||
}
|
||||
|
||||
close( mCommandPipe[WRITING] );
|
||||
close( mCommandPipe[READING] );
|
||||
mCommandPipe[READING] = INVALID_HANDLE_VALUE;
|
||||
mCommandPipe[WRITING] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (mSocket != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
close( mSocket );
|
||||
mSocket = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
// Double check
|
||||
mpRxCallback = 0;
|
||||
|
||||
mCtrlMsgComplete.Clear();
|
||||
mQMUXDClientID = 0;
|
||||
mQMUXClientID = 0;
|
||||
mQMUXServiceID = 0;
|
||||
mQMUXDTxID = 0;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelIO (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress I/O
|
||||
|
||||
PARAMETERS:
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::CancelIO()
|
||||
{
|
||||
if (mSocket == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bRxCancel = CancelRx();
|
||||
bool bTxCancel = CancelTx();
|
||||
|
||||
return (bRxCancel && bTxCancel);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelRx (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress receive operation
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::CancelRx()
|
||||
{
|
||||
if (mSocket == INVALID_HANDLE_VALUE
|
||||
|| mCommandPipe[WRITING] == INVALID_HANDLE_VALUE
|
||||
|| mpRxCallback == 0
|
||||
|| mRxThreadID == 0)
|
||||
{
|
||||
TRACE( "cannot cancel, thread not active\n" );
|
||||
mpRxCallback = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notify the thread to stop reading
|
||||
BYTE byte = STOP_READ_CMD;
|
||||
int nRC = write( mCommandPipe[WRITING], &byte, 1 );
|
||||
if (nRC != 1)
|
||||
{
|
||||
TRACE( "error %d canceling read\n", nRC );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the old callback
|
||||
mpRxCallback = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelTx (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel any in-progress transmit operation
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::CancelTx()
|
||||
{
|
||||
if (mSocket == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mbCancelWrite = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
RxData (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Receive data
|
||||
|
||||
PARAMETERS:
|
||||
pBuf [ I ] - Buffer to contain received data
|
||||
bufSz [ I ] - Amount of data to be received
|
||||
pCallback [ I ] - Callback object to be exercised when the
|
||||
operation completes
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::RxData(
|
||||
BYTE * pBuf,
|
||||
ULONG bufSz,
|
||||
cIOCallback * pCallback )
|
||||
{
|
||||
if (IsValid() == false || mpRxCallback != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pCallback == 0)
|
||||
{
|
||||
// Not interested in being notified, but we still need a value
|
||||
// for this so that only one outstanding I/O operation is active
|
||||
// at any given point in time
|
||||
mpRxCallback = (cIOCallback * )1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpRxCallback = pCallback;
|
||||
}
|
||||
|
||||
mpBuffer = pBuf;
|
||||
mBuffSz = bufSz;
|
||||
|
||||
// Notify the thread to start reading
|
||||
BYTE byte = START_READ_CMD;
|
||||
int nRC = write( mCommandPipe[WRITING], &byte, 1 );
|
||||
if (nRC != 1)
|
||||
{
|
||||
TRACE( "error %d starting read\n", nRC );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
TxData (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Transmit data
|
||||
|
||||
PARAMETERS:
|
||||
pBuf [ I ] - Data to be transmitted
|
||||
bufSz [ I ] - Amount of data to be transmitted
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cSocket::TxData(
|
||||
const BYTE * pBuf,
|
||||
ULONG bufSz )
|
||||
{
|
||||
if (IsValid() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
ULONGLONG nStart = GetTickCount();
|
||||
#endif
|
||||
|
||||
// Allow ourselves to be interupted
|
||||
mbCancelWrite = false;
|
||||
|
||||
// Format the header
|
||||
int totalSz = sizeof( sQMUXDHeader ) + bufSz;
|
||||
BYTE * pMsg = new BYTE[totalSz];
|
||||
if (pMsg == 0)
|
||||
{
|
||||
TRACE( "unable to allocate buffer\n" );
|
||||
return false;
|
||||
}
|
||||
memset( pMsg, 0, totalSz );
|
||||
|
||||
// The important QMUXD header values
|
||||
sQMUXDHeader * pHdr = (sQMUXDHeader *)pMsg;
|
||||
pHdr->mTotalSize = totalSz;
|
||||
pHdr->mQMUXDClientID = mQMUXDClientID;
|
||||
pHdr->mQMUXDMsgID = eQMUXD_MSG_WRITE_QMI_SDU;
|
||||
pHdr->mQMUXDClientIDDuplicate = mQMUXDClientID;
|
||||
|
||||
// mQMUXDTxID could go to INT_MAX, but rather than dealing with possible
|
||||
// overflow in qmuxd or one of the lower layers, we'll stop early
|
||||
mQMUXDTxID++;
|
||||
if (mQMUXDTxID > 100000)
|
||||
{
|
||||
mQMUXDTxID = 1;
|
||||
}
|
||||
pHdr->mTxID = ++mQMUXDTxID;
|
||||
|
||||
pHdr->mQMUXServiceID = mQMUXServiceID;
|
||||
pHdr->mQMUXClientID = mQMUXClientID;
|
||||
|
||||
// The data payload
|
||||
memcpy( &pMsg[sizeof( sQMUXDHeader )], pBuf, bufSz );
|
||||
|
||||
// Send the message
|
||||
int nRet = send( mSocket, pMsg, totalSz, 0 );
|
||||
delete [] pMsg;
|
||||
if (nRet != totalSz)
|
||||
{
|
||||
TRACE( "cSocket::TxData() write returned %d instead of %d\n",
|
||||
nRet,
|
||||
totalSz );
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
TRACE( "Write of %d bytes took %llu miliseconds\n",
|
||||
totalSz,
|
||||
GetTickCount() - nStart );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Socket.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration of cSocket class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cSocket
|
||||
This class wraps low level communication to qmuxd
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Event.h"
|
||||
#include "Connection.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
/*=========================================================================*/
|
||||
// Enum eQMUXDMessageTypes
|
||||
// Types to be passed into SendCtl() for cSocket
|
||||
/*=========================================================================*/
|
||||
enum eQMUXDMessageTypes
|
||||
{
|
||||
eQMUXD_MSG_WRITE_QMI_SDU = 0,
|
||||
eQMUXD_MSG_ALLOC_QMI_CLIENT_ID = 1,
|
||||
eQMUXD_MSG_RELEASE_QMI_CLIENT_ID = 2,
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cSocket
|
||||
/*=========================================================================*/
|
||||
class cSocket : public cConnection
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cSocket();
|
||||
|
||||
// Destructor
|
||||
~cSocket();
|
||||
|
||||
// Is this object valid?
|
||||
bool IsValid();
|
||||
|
||||
// Connect to the specified channel
|
||||
bool Connect( LPCSTR pChannel );
|
||||
|
||||
// Run an IOCTL on the open file handle
|
||||
int SendCtl(
|
||||
UINT ioctlReq,
|
||||
void * pData );
|
||||
|
||||
// Disconnect from the current port
|
||||
bool Disconnect();
|
||||
|
||||
// Configure the port with the passed in parameters
|
||||
bool ConfigureSettings( termios * pSettings );
|
||||
|
||||
// Return the current port settings
|
||||
bool GetSettings( termios * pSettings );
|
||||
|
||||
// Cancel any in-progress I/O
|
||||
bool CancelIO();
|
||||
|
||||
// Cancel any in-progress receive operation
|
||||
bool CancelRx();
|
||||
|
||||
// Cancel any in-progress transmit operation
|
||||
bool CancelTx();
|
||||
|
||||
// Receive data
|
||||
bool RxData(
|
||||
BYTE * pBuf,
|
||||
ULONG bufSz,
|
||||
cIOCallback * pCallback );
|
||||
|
||||
// Transmit data
|
||||
bool TxData(
|
||||
const BYTE * pBuf,
|
||||
ULONG bufSz );
|
||||
|
||||
// (Inline) Return current channel ID
|
||||
int GetChannelID() const
|
||||
{
|
||||
return mChannelID;
|
||||
};
|
||||
|
||||
// Are we currently connected to a port?
|
||||
bool IsConnected()
|
||||
{
|
||||
return (mSocket != INVALID_HANDLE_VALUE);
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
/* Handle to socket */
|
||||
int mSocket;
|
||||
|
||||
// Cancel the write request?
|
||||
bool mbCancelWrite;
|
||||
|
||||
/* Buffer */
|
||||
BYTE * mpBuffer;
|
||||
|
||||
/* Buffer size */
|
||||
ULONG mBuffSz;
|
||||
|
||||
/* Pipe for comunication with thread */
|
||||
int mCommandPipe[2];
|
||||
|
||||
/* Thread ID of Rx Thread. */
|
||||
pthread_t mRxThreadID;
|
||||
|
||||
/* Control message completion event */
|
||||
cEvent mCtrlMsgComplete;
|
||||
|
||||
/* QMUXD client ID */
|
||||
int mQMUXDClientID;
|
||||
|
||||
/* QMUX client and service IDs */
|
||||
int mQMUXClientID;
|
||||
int mQMUXServiceID;
|
||||
|
||||
/* SMD Channel ID. 0 = SMD_DATA_5 */
|
||||
int mChannelID;
|
||||
|
||||
/* The SMD transaction ID */
|
||||
int mQMUXDTxID;
|
||||
|
||||
// Rx thread is allowed complete access
|
||||
friend void * RxSocketThread( void * pData );
|
||||
};
|
|
@ -0,0 +1,200 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
StdAfx.h
|
||||
|
||||
DESCRIPTION:
|
||||
Application Framework eXtenstions for Linux
|
||||
|
||||
PUBLIC CLASSES AND FUNCTIONS:
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
//---------------------------------------------------------------------------
|
||||
// Includes
|
||||
//---------------------------------------------------------------------------
|
||||
#include <fstream>
|
||||
#include <assert.h>
|
||||
#include <termios.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <sstream>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Macro defination
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define ASSERT( x ) assert( x )
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
// TRACE macro
|
||||
#define TRACE( format, arg... ) \
|
||||
if (true) \
|
||||
{ \
|
||||
__android_log_print( ANDROID_LOG_INFO, \
|
||||
"Gobi", "%s:%d: " format, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
##arg ); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define TRACE( format, arg... ) \
|
||||
printf( "%s:%d: " format, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
##arg )
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define TRACE(...)
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// data type defination
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef CONST
|
||||
#define CONST const
|
||||
#endif
|
||||
|
||||
typedef void VOID;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef float FLOAT;
|
||||
typedef long long LONGLONG;
|
||||
typedef unsigned long long ULONGLONG;
|
||||
typedef signed char INT8;
|
||||
typedef double DOUBLE;
|
||||
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int * PUINT;
|
||||
typedef INT HANDLE;
|
||||
typedef HANDLE HMODULE;
|
||||
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
|
||||
typedef unsigned long ULONG;
|
||||
typedef ULONG * PULONG;
|
||||
typedef ULONG * ULONG_PTR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef USHORT * PUSHORT;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef UCHAR * PUCHAR;
|
||||
typedef char * PSZ;
|
||||
|
||||
|
||||
typedef CONST CHAR * LPCSTR;
|
||||
typedef CHAR * LPSTR;
|
||||
|
||||
typedef BYTE * PBYTE;
|
||||
typedef BOOL * PBOOL;
|
||||
typedef INT * PINT;
|
||||
typedef UINT * LPINT;
|
||||
typedef WORD * PWORD;
|
||||
typedef PWORD LPWORD;
|
||||
typedef LONG * LPLONG;
|
||||
typedef DWORD * PDWORD;
|
||||
typedef VOID * PVOID;
|
||||
typedef PVOID LPVOID;
|
||||
typedef const void * LPCVOID;
|
||||
|
||||
typedef size_t SIZE_T;
|
||||
typedef double DATE;
|
||||
|
||||
// Error code
|
||||
#define NO_ERROR 0L
|
||||
#define ERROR_SUCCESS 0L
|
||||
#define ERROR_NO_MORE_ITEMS 259L
|
||||
#define ERROR_CRC 23L
|
||||
#define ERROR_OUTOFMEMORY 14L
|
||||
#define ERROR_CAN_NOT_COMPLETE 1003L
|
||||
#define ERROR_REVISION_MISMATCH 1306L
|
||||
#define ERROR_BAD_ARGUMENTS 160L
|
||||
#define INVALID_SET_FILE_POINTER -1
|
||||
#define VALID_HANDLE_VALUE 0
|
||||
#define INVALID_HANDLE_VALUE -1
|
||||
#define INVALID_FILE_SZ -1
|
||||
|
||||
#define ERROR_GEN_FAILURE 31L
|
||||
#define ERROR_FILE_NOT_FOUND 2L
|
||||
#define ERROR_NOT_ENOUGH_MEMORY 8L
|
||||
#define ERROR_INVALID_PARAMETER 87L
|
||||
#define ERROR_BAD_FORMAT 11L
|
||||
|
||||
|
||||
// Other Constant definitions
|
||||
#define MAX_PATH 512
|
||||
#define INFINITE 0xffffffff
|
||||
|
||||
|
||||
// SIOCIWFIRSTPRIV = 0x8BE0
|
||||
|
||||
// Device I/O control code for setting QMI service
|
||||
#define QMI_GET_SERVICE_FILE_IOCTL 0x8BE0 + 1
|
||||
|
||||
// Device I/O control code for obtaining device VIDPID
|
||||
#define QMI_GET_VIDPID_IOCTL 0x8BE0 + 2
|
||||
|
||||
// Device I/O control code for obtaining device MEID
|
||||
#define QMI_GET_MEID_IOCTL 0x8BE0 + 3
|
||||
|
||||
// Define the directions for pipes
|
||||
#define READING 0
|
||||
#define WRITING 1
|
|
@ -0,0 +1,419 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
SyncQueue.h
|
||||
|
||||
DESCRIPTION:
|
||||
Declaration/Implementation of cSyncQueue class
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cSyncQueue
|
||||
Synchronized shareable (across multiple threads) queue of
|
||||
structures with event notifications
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include <deque>
|
||||
#include "Event.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cSyncQueue
|
||||
/*=========================================================================*/
|
||||
template <class tElementType> class cSyncQueue
|
||||
{
|
||||
public:
|
||||
// (Inline) Constructor
|
||||
cSyncQueue(
|
||||
ULONG maxElements,
|
||||
bool bSignalEvent = false )
|
||||
: mSignature( (ULONG)eSYNC_QUEUE_SIG ),
|
||||
mSignalEvent(),
|
||||
mbSignalEvent( bSignalEvent ),
|
||||
mMaxElements( maxElements ),
|
||||
mTotalElements( 0 )
|
||||
{
|
||||
// Create sync CS
|
||||
int nRet = pthread_mutex_init( &mSyncSection, NULL );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to init sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// (Inline) Destructor
|
||||
~cSyncQueue()
|
||||
{
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Double deletion detected in ~cSyncQueue" == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
EmptyQueue();
|
||||
|
||||
mSignature = 0;
|
||||
int nRet = pthread_mutex_destroy( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to destroy sync mutex."
|
||||
" Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// (Inline) Add an element to the queue
|
||||
bool AddElement( const tElementType & elem )
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return bRC;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Are we out of space?
|
||||
if ((ULONG)mElementDeque.size() >= mMaxElements)
|
||||
{
|
||||
// Yes, drop oldest element
|
||||
mElementDeque.pop_front();
|
||||
}
|
||||
|
||||
// Add new item to the queue
|
||||
mElementDeque.push_back( elem );
|
||||
mTotalElements++;
|
||||
|
||||
// Set event?
|
||||
if (mbSignalEvent == true)
|
||||
{
|
||||
// Signal index of event
|
||||
nRet = mSignalEvent.Set( mTotalElements - 1 );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to signal. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Success!
|
||||
bRC = true;
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return bRC;
|
||||
};
|
||||
|
||||
// (Inline) Add an element to the queue returning the index of
|
||||
// the element
|
||||
bool AddElement(
|
||||
const tElementType & elem,
|
||||
ULONG & idx )
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return bRC;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Are we out of space?
|
||||
if ((ULONG)mElementDeque.size() >= mMaxElements)
|
||||
{
|
||||
mElementDeque.pop_front();
|
||||
}
|
||||
|
||||
// Add new item to the queue
|
||||
mElementDeque.push_back( elem );
|
||||
idx = mTotalElements++;
|
||||
|
||||
// Set event?
|
||||
if (mbSignalEvent == true)
|
||||
{
|
||||
// Signal index of event
|
||||
nRet = mSignalEvent.Set( mTotalElements - 1 );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to signal. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Success!
|
||||
bRC = true;
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return bRC;
|
||||
};
|
||||
|
||||
// (Inline) Return given element in the queue
|
||||
bool GetElement(
|
||||
ULONG idx,
|
||||
tElementType & elem ) const
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return bRC;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this a current element index?
|
||||
ULONG expiredIndices = mTotalElements - (ULONG)mElementDeque.size();
|
||||
if (idx >= expiredIndices)
|
||||
{
|
||||
// Yes, grab it from the deque
|
||||
idx -= expiredIndices;
|
||||
if (idx < (ULONG)mElementDeque.size())
|
||||
{
|
||||
elem = mElementDeque[idx];
|
||||
bRC = true;
|
||||
}
|
||||
}
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return bRC;
|
||||
};
|
||||
|
||||
// (Inline) Empty element queue
|
||||
bool EmptyQueue()
|
||||
{
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return bRC;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
mElementDeque.clear();
|
||||
mTotalElements = 0;
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
bRC = true;
|
||||
return bRC;
|
||||
};
|
||||
|
||||
// (Inline) Return the number of queued elements
|
||||
ULONG GetQueueCount() const
|
||||
{
|
||||
ULONG elems = 0;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return elems;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
elems = (ULONG)mElementDeque.size();
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return elems;
|
||||
};
|
||||
|
||||
// (Inline) Return the total number of elements added to queue
|
||||
ULONG GetTotalCount() const
|
||||
{
|
||||
ULONG elems = 0;
|
||||
if (IsValid() == false)
|
||||
{
|
||||
ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
|
||||
return elems;
|
||||
}
|
||||
|
||||
int nRet = pthread_mutex_lock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
elems = mTotalElements;
|
||||
|
||||
nRet = pthread_mutex_unlock( &mSyncSection );
|
||||
if (nRet != 0)
|
||||
{
|
||||
TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
|
||||
nRet,
|
||||
strerror( nRet ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return elems;
|
||||
};
|
||||
|
||||
// (Inline) Return the signal event
|
||||
cEvent & GetSignalEvent() const
|
||||
{
|
||||
return mSignalEvent;
|
||||
};
|
||||
|
||||
// (Inline) Is this sync queue valid?
|
||||
bool IsValid() const
|
||||
{
|
||||
return (mSignature == (ULONG)eSYNC_QUEUE_SIG);
|
||||
};
|
||||
|
||||
protected:
|
||||
// Object signature
|
||||
enum eClassConstants
|
||||
{
|
||||
eSYNC_QUEUE_SIG = 0x1799A2BC
|
||||
};
|
||||
|
||||
/* Object signature */
|
||||
ULONG mSignature;
|
||||
|
||||
/* Multithreaded mutex type */
|
||||
mutable pthread_mutex_t mSyncSection;
|
||||
|
||||
/* Signal event, set everytime an element is added (if configured) */
|
||||
mutable cEvent mSignalEvent;
|
||||
|
||||
/* Use above signal event? */
|
||||
bool mbSignalEvent;
|
||||
|
||||
/* Maximum number of elements to add to the deque */
|
||||
ULONG mMaxElements;
|
||||
|
||||
/* Total number of elements added to the deque */
|
||||
ULONG mTotalElements;
|
||||
|
||||
/* Element queue */
|
||||
std::deque <tElementType> mElementDeque;
|
||||
};
|
|
@ -0,0 +1,101 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Gobi3000Translation.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Translation for Gobi 3000
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Gobi3000Translation.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetTLV
|
||||
|
||||
DESCRIPTION:
|
||||
Return the starting location and size of TLV buffer.
|
||||
|
||||
NOTE: does not include the TLV header
|
||||
|
||||
PARAMETERS:
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
type [ I ] - Type ID
|
||||
pOutLen [ O ] - Length of the output buffer
|
||||
ppOut [ O ] - Pointer to output buffer
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG GetTLV(
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
BYTE typeID,
|
||||
ULONG * pOutLen,
|
||||
const BYTE ** ppOut )
|
||||
{
|
||||
if (pIn == 0 || pOutLen == 0 || ppOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
for (ULONG offset = 0;
|
||||
offset + sizeof( sQMIRawContentHeader ) <= inLen;
|
||||
offset += sizeof( sQMIRawContentHeader ))
|
||||
{
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pIn + offset);
|
||||
|
||||
// Is it big enough to contain this TLV?
|
||||
if (offset + sizeof( sQMIRawContentHeader ) + pHeader->mLength > inLen)
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
if (pHeader->mTypeID == typeID)
|
||||
{
|
||||
*pOutLen = pHeader->mLength;
|
||||
*ppOut = pIn + offset + sizeof( sQMIRawContentHeader );
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
offset += pHeader->mLength;
|
||||
}
|
||||
|
||||
// TLV not found
|
||||
return eGOBI_ERR_INVALID_RSP;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,177 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Gobi3000TranslationCAT.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Translation for Gobi 3000 (Card Application Toolkit Service)
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Gobi3000Translation.h"
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackCATSendTerminalResponse
|
||||
|
||||
DESCRIPTION:
|
||||
This function sends the terminal response to the device
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
refID [ I ] - UIM reference ID (from CAT event)
|
||||
dataLen [ I ] - Terminal response data length
|
||||
pData [ I ] - Terminal response data
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackCATSendTerminalResponse(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG refID,
|
||||
ULONG dataLen,
|
||||
BYTE * pData )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0 || pData == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add arguments
|
||||
|
||||
// Check size
|
||||
WORD tlvx01Sz = sizeof( sCATSendTerminalResponseRequest_TerminalResponseType )
|
||||
+ (WORD)dataLen;
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x01;
|
||||
pHeader->mLength = tlvx01Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sCATSendTerminalResponseRequest_TerminalResponseType * pTLVx01;
|
||||
pTLVx01 = (sCATSendTerminalResponseRequest_TerminalResponseType*)(pOut + offset);
|
||||
memset( pTLVx01, 0, tlvx01Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx01->mReferenceID = refID;
|
||||
pTLVx01->mTerminalResponseLength = (UINT16)dataLen;
|
||||
|
||||
offset += sizeof( sCATSendTerminalResponseRequest_TerminalResponseType );
|
||||
|
||||
if (dataLen > 0)
|
||||
{
|
||||
memcpy( pOut + offset, pData, dataLen );
|
||||
offset += dataLen;
|
||||
}
|
||||
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackCATSendEnvelopeCommand
|
||||
|
||||
DESCRIPTION:
|
||||
This function sends the envelope command to the device
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
cmdID [ I ] - Envelope command ID
|
||||
dataLen [ I ] - Envelope command data length
|
||||
pData [ I ] - Envelope command data
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackCATSendEnvelopeCommand(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG cmdID,
|
||||
ULONG dataLen,
|
||||
BYTE * pData )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0 || dataLen == 0 || pData == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add arguments
|
||||
|
||||
// Check size
|
||||
WORD tlvx01Sz = sizeof( sCATEnvelopeCommandRequest_EnvelopeCommand )
|
||||
+ (WORD)dataLen;
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x01;
|
||||
pHeader->mLength = tlvx01Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sCATEnvelopeCommandRequest_EnvelopeCommand * pTLVx01;
|
||||
pTLVx01 = (sCATEnvelopeCommandRequest_EnvelopeCommand*)(pOut + offset);
|
||||
memset( pTLVx01, 0, tlvx01Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx01->mEnvelopeCommandType = (eQMICATEnvelopeCommandType)cmdID;
|
||||
pTLVx01->mEnvelopeLength = (UINT16)dataLen;
|
||||
|
||||
offset += sizeof( sCATEnvelopeCommandRequest_EnvelopeCommand );
|
||||
|
||||
if (dataLen > 0)
|
||||
{
|
||||
memcpy( pOut + offset, pData, dataLen );
|
||||
offset += dataLen;
|
||||
}
|
||||
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
1483
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp
Executable file
1483
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp
Executable file
File diff suppressed because it is too large
Load Diff
2022
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationNAS.cpp
Executable file
2022
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationNAS.cpp
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,481 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Gobi3000TranslationOMA.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Translation for Gobi 3000 (OMADM Service)
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Gobi3000Translation.h"
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackOMADMStartSession
|
||||
|
||||
DESCRIPTION:
|
||||
This function starts an OMA-DM session
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
sessionType [ I ] - Type of session to initiate
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackOMADMStartSession(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG sessionType )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add sessionType
|
||||
|
||||
// Check size
|
||||
WORD tlvx10Sz = sizeof( sOMAStartSessionRequest_Type );
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx10Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x10;
|
||||
pHeader->mLength = tlvx10Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sOMAStartSessionRequest_Type * pTLVx10;
|
||||
pTLVx10 = (sOMAStartSessionRequest_Type*)(pOut + offset);
|
||||
memset( pTLVx10, 0, tlvx10Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx10->mSessionType = (eQMIOMASessionTypes)sessionType;
|
||||
|
||||
offset += tlvx10Sz;
|
||||
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ParseOMADMGetSessionInfo
|
||||
|
||||
DESCRIPTION:
|
||||
This function returns information related to the current (or previous
|
||||
if no session is active) OMA-DM session
|
||||
|
||||
PARAMETERS:
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
pSessionState [ O ] - State of session
|
||||
pSessionType [ O ] - Type of session
|
||||
pFailureReason [ O ] - Session failure reason (when state indicates failure)
|
||||
pRetryCount [ O ] - Session retry count (when state indicates retrying)
|
||||
pSessionPause [ O ] - Session pause timer (when state indicates retrying)
|
||||
pTimeRemaining [ O ] - Pause time remaining (when state indicates retrying)
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG ParseOMADMGetSessionInfo(
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pSessionState,
|
||||
ULONG * pSessionType,
|
||||
ULONG * pFailureReason,
|
||||
BYTE * pRetryCount,
|
||||
WORD * pSessionPause,
|
||||
WORD * pTimeRemaining )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pIn == 0 || pSessionState == 0 || pSessionType == 0
|
||||
|| pFailureReason == 0 || pRetryCount == 0 || pSessionPause == 0
|
||||
|| pTimeRemaining == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Find the first TLV
|
||||
const sOMAGetSessionInfoResponse_Info * pTLVx10;
|
||||
ULONG outLenx10;
|
||||
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx10 < sizeof( sOMAGetSessionInfoResponse_Info ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pSessionState = pTLVx10->mSessionState;
|
||||
*pSessionType = pTLVx10->mSessionType;
|
||||
|
||||
// Find the second TLV
|
||||
const sOMAGetSessionInfoResponse_Failure * pTLVx11;
|
||||
ULONG outLenx11;
|
||||
rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx11 < sizeof( sOMAGetSessionInfoResponse_Failure ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pFailureReason = pTLVx11->mSessionFailure;
|
||||
|
||||
// Find the third TLV
|
||||
const sOMAGetSessionInfoResponse_Retry * pTLVx12;
|
||||
ULONG outLenx12;
|
||||
rc = GetTLV( inLen, pIn, 0x12, &outLenx12, (const BYTE **)&pTLVx12 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx12 < sizeof( sOMAGetSessionInfoResponse_Retry ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pRetryCount = pTLVx12->mRetryCount;
|
||||
*pSessionPause = pTLVx12->mRetryPauseTimer;
|
||||
*pTimeRemaining = pTLVx12->mRemainingTime;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ParseOMADMGetPendingNIA
|
||||
|
||||
DESCRIPTION:
|
||||
This function returns information about the pending network initiated
|
||||
alert
|
||||
|
||||
PARAMETERS:
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
pSessionType [ O ] - Type of session
|
||||
pSessionID [ O ] - Unique session ID
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG ParseOMADMGetPendingNIA(
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pSessionType,
|
||||
USHORT * pSessionID )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pIn == 0 || pSessionType == 0 || pSessionID == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Find the TLV
|
||||
const sOMAGetSessionInfoResponse_NIA * pTLVx13;
|
||||
ULONG outLenx13;
|
||||
ULONG rc = GetTLV( inLen, pIn, 0x13, &outLenx13, (const BYTE **)&pTLVx13 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx13 < sizeof( sOMAGetSessionInfoResponse_NIA ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pSessionID = pTLVx13->mSessionID;
|
||||
*pSessionType = pTLVx13->mSessionType;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackOMADMSendSelection
|
||||
|
||||
DESCRIPTION:
|
||||
This function sends the specified OMA-DM selection for the current
|
||||
network initiated session
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
selection [ I ] - Selection
|
||||
sessionID [ I ] - Unique session ID
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackOMADMSendSelection(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG selection,
|
||||
USHORT sessionID )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add selection and session ID
|
||||
|
||||
// Check size
|
||||
WORD tlvx10Sz = sizeof( sOMASendSelectionRequest_Type );
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx10Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x10;
|
||||
pHeader->mLength = tlvx10Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sOMASendSelectionRequest_Type * pTLVx10;
|
||||
pTLVx10 = (sOMASendSelectionRequest_Type*)(pOut + offset);
|
||||
memset( pTLVx10, 0, tlvx10Sz );
|
||||
|
||||
// Set the values
|
||||
pTLVx10->mSelection = (eQMIOMASelections)selection;
|
||||
pTLVx10->mSessionID = sessionID;
|
||||
|
||||
offset += tlvx10Sz;
|
||||
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ParseOMADMGetFeatureSettings
|
||||
|
||||
DESCRIPTION:
|
||||
This function returns the OMA-DM feature settings
|
||||
|
||||
PARAMETERS:
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
pbProvisioning [ O ] - Device provisioning service update enabled
|
||||
pbPRLUpdate [ O ] - PRL service update enabled
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG ParseOMADMGetFeatureSettings(
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pbProvisioning,
|
||||
ULONG * pbPRLUpdate )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pIn == 0 || pbProvisioning == 0 || pbPRLUpdate == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Find the first TLV
|
||||
const sOMAGetFeaturesResponse_Provisioning * pTLVx10;
|
||||
ULONG outLenx10;
|
||||
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx10 < sizeof( sOMAGetFeaturesResponse_Provisioning ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pbProvisioning = pTLVx10->mDeviceProvisioningServiceUpdateEnabled;
|
||||
|
||||
// Find the second TLV
|
||||
const sOMAGetFeaturesResponse_PRLUpdate * pTLVx11;
|
||||
ULONG outLenx11;
|
||||
rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx10 < sizeof( sOMAGetFeaturesResponse_PRLUpdate ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pbPRLUpdate = pTLVx11->mPRLServiceUpdateEnabled;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackOMADMSetProvisioningFeature
|
||||
|
||||
DESCRIPTION:
|
||||
This function sets the OMA-DM device provisioning service
|
||||
update feature setting
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
bProvisioning [ I ] - Device provisioning service update enabled
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackOMADMSetProvisioningFeature(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG bProvisioning )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add bProvisioning
|
||||
|
||||
// Check size
|
||||
WORD tlvx10Sz = sizeof( sOMASetFeaturesRequest_Provisioning );
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx10Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x10;
|
||||
pHeader->mLength = tlvx10Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sOMASetFeaturesRequest_Provisioning * pTLVx10;
|
||||
pTLVx10 = (sOMASetFeaturesRequest_Provisioning*)(pOut + offset);
|
||||
memset( pTLVx10, 0, tlvx10Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx10->mDeviceProvisioningServiceUpdateEnabled = (INT8)bProvisioning;
|
||||
|
||||
offset += tlvx10Sz;
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackOMADMSetPRLUpdateFeature
|
||||
|
||||
DESCRIPTION:
|
||||
This function sets the OMA-DM PRL service update feature setting
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
bPRLUpdate [ I ] - PRL service update enabled
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackOMADMSetPRLUpdateFeature(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG bPRLUpdate )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add bPRLUpdate
|
||||
|
||||
// Check size
|
||||
WORD tlvx11Sz = sizeof( sOMASetFeaturesRequest_PRLUpdate );
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx11Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x11;
|
||||
pHeader->mLength = tlvx11Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sOMASetFeaturesRequest_PRLUpdate * pTLVx11;
|
||||
pTLVx11 = (sOMASetFeaturesRequest_PRLUpdate*)(pOut + offset);
|
||||
memset( pTLVx11, 0, tlvx11Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx11->mPRLServiceUpdateEnabled = (INT8)bPRLUpdate;
|
||||
|
||||
offset += tlvx11Sz;
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
1207
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationPDS.cpp
Executable file
1207
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationPDS.cpp
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,188 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Gobi3000TranslationRMS.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Translation for Gobi 3000 (Remote Management Service)
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Gobi3000Translation.h"
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ParseGetSMSWake
|
||||
|
||||
DESCRIPTION:
|
||||
This function queries the state of the SMS wake functionality
|
||||
|
||||
PARAMETERS:
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
pbEnabled [ O ] - SMS wake functionality enabled?
|
||||
pWakeMask [ O ] - SMS wake mask (only relevant when enabled)
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG ParseGetSMSWake(
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pbEnabled,
|
||||
ULONG * pWakeMask )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pIn == 0 || pbEnabled == 0 || pWakeMask == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Find the first TLV
|
||||
const sRMSGetSMSWakeResponse_State * pTLVx10;
|
||||
ULONG outLenx10;
|
||||
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx10 < sizeof( sRMSGetSMSWakeResponse_State ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
// Find the second TLV
|
||||
const sRMSGetSMSWakeRequest_Mask * pTLVx11;
|
||||
ULONG outLenx11;
|
||||
rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Is the TLV large enough?
|
||||
if (outLenx11 < sizeof( sRMSGetSMSWakeRequest_Mask ))
|
||||
{
|
||||
return eGOBI_ERR_MALFORMED_RSP;
|
||||
}
|
||||
|
||||
*pbEnabled = pTLVx10->mSMSWakeEnabled;
|
||||
*pWakeMask = pTLVx11->mMask;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackSetSMSWake
|
||||
|
||||
DESCRIPTION:
|
||||
This function enables/disables the SMS wake functionality
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
bEnable [ I ] - Enable SMS wake functionality?
|
||||
wakeMask [ I ] - SMS wake mask (only relevant when enabling)
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackSetSMSWake(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
ULONG bEnable,
|
||||
ULONG wakeMask )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Add bEnable
|
||||
|
||||
// Check size
|
||||
WORD tlvx10Sz = sizeof( sRMSSetSMSWakeRequest_State );
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx10Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x10;
|
||||
pHeader->mLength = tlvx10Sz;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
sRMSSetSMSWakeRequest_State * pTLVx10;
|
||||
pTLVx10 = (sRMSSetSMSWakeRequest_State*)(pOut + offset);
|
||||
memset( pTLVx10, 0, tlvx10Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx10->mSMSWakeEnabled = (INT8)bEnable;
|
||||
|
||||
offset += tlvx10Sz;
|
||||
|
||||
// Add wakeMask if enabled
|
||||
if (bEnable != 0)
|
||||
{
|
||||
// Check size
|
||||
WORD tlvx11Sz = sizeof( sRMSSetSMSWakeRequest_Mask );
|
||||
if (*pOutLen < offset + sizeof( sQMIRawContentHeader ) + tlvx11Sz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
pHeader = (sQMIRawContentHeader*)(pOut + offset);
|
||||
pHeader->mTypeID = 0x11;
|
||||
pHeader->mLength = tlvx11Sz;
|
||||
|
||||
offset += sizeof( sQMIRawContentHeader );
|
||||
|
||||
sRMSSetSMSWakeRequest_Mask * pTLVx11;
|
||||
pTLVx11 = (sRMSSetSMSWakeRequest_Mask*)(pOut + offset);
|
||||
memset( pTLVx11, 0, tlvx11Sz );
|
||||
|
||||
// Set the value
|
||||
pTLVx11->mMask = wakeMask;
|
||||
|
||||
offset += tlvx11Sz;
|
||||
}
|
||||
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
1170
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationUIM.cpp
Executable file
1170
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationUIM.cpp
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,174 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
Gobi3000TranslationVoice.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Translation for Gobi 3000 (Voice Service for USSD)
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Gobi3000Translation.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas (pack structs)
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
/*=========================================================================*/
|
||||
// Struct sUSSDInfo
|
||||
// Struct to represent USSD/Alpha information header
|
||||
/*=========================================================================*/
|
||||
struct sUSSDInfoHdr
|
||||
{
|
||||
public:
|
||||
BYTE mDCS;
|
||||
BYTE mLength;
|
||||
|
||||
// Data of 'mLength' follows
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma pack( pop )
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackOriginateUSSD
|
||||
|
||||
DESCRIPTION:
|
||||
This function initiates a USSD operation
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
pInfo [ I ] - USSD information
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackOriginateUSSD(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
BYTE * pInfo )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0 || pInfo == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const WORD INFO_HDR_SZ = sizeof( sUSSDInfoHdr );
|
||||
|
||||
// This assumes that pInfo is at least 2 bytes long
|
||||
sUSSDInfoHdr * pInInfo = (sUSSDInfoHdr *)pInfo;
|
||||
WORD infoLen = pInInfo->mLength + INFO_HDR_SZ;
|
||||
|
||||
// Check size
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + infoLen)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
// Add pInfo
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x01;
|
||||
pHeader->mLength = infoLen;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
// No pTLVx01 since pInfo is our TLV
|
||||
memcpy( (pOut + offset), pInfo, infoLen );
|
||||
|
||||
offset += infoLen;
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
PackAnswerUSSD
|
||||
|
||||
DESCRIPTION:
|
||||
This function responds to a USSD request from the network
|
||||
|
||||
PARAMETERS:
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
pInfo [ I ] - USSD information
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG - Return code
|
||||
===========================================================================*/
|
||||
ULONG PackAnswerUSSD(
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut,
|
||||
BYTE * pInfo )
|
||||
{
|
||||
// Validate arguments
|
||||
if (pOut == 0 || pInfo == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const WORD INFO_HDR_SZ = sizeof( sUSSDInfoHdr );
|
||||
|
||||
// This assumes that pInfo is at least 2 bytes long
|
||||
sUSSDInfoHdr * pInInfo = (sUSSDInfoHdr *)pInfo;
|
||||
WORD infoLen = pInInfo->mLength + INFO_HDR_SZ;
|
||||
|
||||
// Check size
|
||||
if (*pOutLen < sizeof( sQMIRawContentHeader ) + infoLen)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
||||
pHeader->mTypeID = 0x01;
|
||||
pHeader->mLength = infoLen;
|
||||
|
||||
ULONG offset = sizeof( sQMIRawContentHeader );
|
||||
|
||||
// No pTLVx01 since pInfo is our TLV
|
||||
memcpy( (pOut + offset), pInfo, infoLen );
|
||||
|
||||
offset += infoLen;
|
||||
*pOutLen = offset;
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
3486
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationWDS.cpp
Executable file
3486
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationWDS.cpp
Executable file
File diff suppressed because it is too large
Load Diff
1121
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationWMS.cpp
Executable file
1121
gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationWMS.cpp
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,606 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiConnectionMgmt.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Connection Management API for Gobi
|
||||
|
||||
PUBLIC CLASSES AND FUNCTIONS:
|
||||
CGobiConnectionMgmtDLL
|
||||
cGobiConnectionMgmt
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "GobiConnectionMgmt.h"
|
||||
#include "QMIBuffers.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global object
|
||||
CGobiConnectionMgmtDLL gDLL;
|
||||
|
||||
// Interval between traffic processing loop iterations (milliseconds)
|
||||
const ULONG TRAFFIC_INTERVAL_MS = 300000;
|
||||
|
||||
// Maximum amount of time to wait for the traffic thread to exit
|
||||
const ULONG THREAD_EXIT_TIME = 2000;
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
TrafficProcessThread (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
QMI traffic process thread - processes all traffic in order to fire
|
||||
off QMI traffic related callbacks
|
||||
|
||||
PARAMETERS:
|
||||
pArg [ I ] - Object to interface to
|
||||
|
||||
RETURN VALUE:
|
||||
void * - thread exit value (always 0)
|
||||
===========================================================================*/
|
||||
void * TrafficProcessThread( PVOID pArg )
|
||||
{
|
||||
// Keep running?
|
||||
bool bRun = false;
|
||||
|
||||
// Create a vector of the objects to wait on
|
||||
std::vector <cEvent *> events;
|
||||
|
||||
// Store the index to service type for use later
|
||||
std::map <DWORD, eQMIService> services;
|
||||
|
||||
// Grab API object
|
||||
cGobiConnectionMgmt * pAPI = (cGobiConnectionMgmt *)pArg;
|
||||
if (pAPI != 0)
|
||||
{
|
||||
// Time to go to work
|
||||
bRun = true;
|
||||
|
||||
// Add the thread exit event
|
||||
events.push_back( &pAPI->mExitEvent );
|
||||
|
||||
// Grab signal events for our protocol servers
|
||||
std::map <eQMIService, cGobiQMICore::sServerInfo>::const_iterator pIter;
|
||||
pIter = pAPI->mServers.begin();
|
||||
while (pIter != pAPI->mServers.end())
|
||||
{
|
||||
eQMIService svc = pIter->first;
|
||||
cQMIProtocolServer * pServer = pAPI->GetServer( svc );
|
||||
if (pServer != 0)
|
||||
{
|
||||
// Grab the log from the server
|
||||
const cProtocolLog & log = pServer->GetLog();
|
||||
|
||||
// Grab the Signal event, if it exists
|
||||
cEvent & sigEvent = log.GetSignalEvent();
|
||||
|
||||
services[events.size()] = svc;
|
||||
events.push_back( &sigEvent );
|
||||
}
|
||||
|
||||
pIter++;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( "GobiConnectionMgmt traffic thread [%u] started\n",
|
||||
(UINT)pthread_self() );
|
||||
|
||||
// Loop waiting for exit event
|
||||
while (bRun == true)
|
||||
{
|
||||
// Wait for activity
|
||||
DWORD ignoredVal, index;
|
||||
int nRet = WaitOnMultipleEvents( events,
|
||||
TRAFFIC_INTERVAL_MS,
|
||||
ignoredVal,
|
||||
index );
|
||||
|
||||
// Timeout
|
||||
if (nRet == -ETIME)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
// Error?
|
||||
else if (nRet <= 0)
|
||||
{
|
||||
TRACE( "GobiConnectionMgmt traffic thread wait error %d\n", nRet );
|
||||
bRun = false;
|
||||
}
|
||||
// Exit event?
|
||||
else if (index == 0)
|
||||
{
|
||||
bRun = false;
|
||||
}
|
||||
else if (index < events.size())
|
||||
{
|
||||
// Run ProcessTraffic() for this service type
|
||||
if (services.find( index ) != services.end())
|
||||
{
|
||||
pAPI->ProcessTraffic( services[index] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fatal error
|
||||
bRun = false;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( "GobiConnectionMgmt traffic thread [%u] exited\n",
|
||||
(UINT)pthread_self() );
|
||||
|
||||
if (pAPI != 0)
|
||||
{
|
||||
pAPI->mThreadCleanupFinished = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CallbackThread (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Thread to execute a callback asynchronously
|
||||
|
||||
PARAMETERS:
|
||||
pArg [ I ] - The cGobiCMCallback object
|
||||
|
||||
RETURN VALUE:
|
||||
void * - thread exit value (always 0)
|
||||
===========================================================================*/
|
||||
void * CallbackThread( PVOID pArg )
|
||||
{
|
||||
cGobiCMCallback * pCB = (cGobiCMCallback *)pArg;
|
||||
if (pCB == 0)
|
||||
{
|
||||
ASSERT( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCB->Call();
|
||||
|
||||
delete pCB;
|
||||
pCB = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=========================================================================*/
|
||||
// CGobiConnectionMgmtDLL Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CGobiConnectionMgmtDLL (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
CGobiConnectionMgmtDLL::CGobiConnectionMgmtDLL()
|
||||
{
|
||||
// Create sync CS
|
||||
pthread_mutex_init( &mSyncSection, NULL );
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~CGobiConnectionMgmtDLL (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
CGobiConnectionMgmtDLL::~CGobiConnectionMgmtDLL()
|
||||
{
|
||||
std::map <GOBIHANDLE, cGobiConnectionMgmt *> tmpAPI = mAPI;
|
||||
std::map <GOBIHANDLE, cGobiConnectionMgmt *>::const_iterator pIter;
|
||||
pIter = tmpAPI.begin();
|
||||
|
||||
while (pIter != tmpAPI.end())
|
||||
{
|
||||
cGobiConnectionMgmt * pAPI = pIter->second;
|
||||
if (pAPI != 0)
|
||||
{
|
||||
pAPI->Cleanup();
|
||||
delete pAPI;
|
||||
}
|
||||
|
||||
pIter++;
|
||||
}
|
||||
|
||||
mAPI.clear();
|
||||
|
||||
pthread_mutex_destroy( &mSyncSection );
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CreateAPI (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Create a new API object
|
||||
|
||||
RETURN VALUE:
|
||||
GOBIHANDLE - Handle to new API object (0 upon failure)
|
||||
===========================================================================*/
|
||||
GOBIHANDLE CGobiConnectionMgmtDLL::CreateAPI()
|
||||
{
|
||||
pthread_mutex_lock( &mSyncSection );
|
||||
|
||||
cGobiConnectionMgmt * pAPI = new cGobiConnectionMgmt;
|
||||
if (pAPI != 0)
|
||||
{
|
||||
bool bInit = pAPI->Initialize();
|
||||
if (bInit == true)
|
||||
{
|
||||
mAPI[(GOBIHANDLE)pAPI] = pAPI;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &mSyncSection );
|
||||
|
||||
return (GOBIHANDLE)pAPI;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
DeleteAPI (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Delete an existing API object
|
||||
|
||||
PARAMETERS:
|
||||
handle [ I ] - Handle to API object to return
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void CGobiConnectionMgmtDLL::DeleteAPI( GOBIHANDLE handle )
|
||||
{
|
||||
pthread_mutex_lock( &mSyncSection );
|
||||
|
||||
std::map <GOBIHANDLE, cGobiConnectionMgmt *>::iterator pIter;
|
||||
pIter = mAPI.find( handle );
|
||||
if (pIter != mAPI.end())
|
||||
{
|
||||
cGobiConnectionMgmt * pAPI = pIter->second;
|
||||
delete pAPI;
|
||||
|
||||
mAPI.erase( pIter );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &mSyncSection );
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetAPI (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Return the requested API object
|
||||
|
||||
PARAMETERS:
|
||||
handle [ I ] - Handle to API object to return
|
||||
|
||||
RETURN VALUE:
|
||||
cGobiConnectionMgmt *
|
||||
===========================================================================*/
|
||||
cGobiConnectionMgmt * CGobiConnectionMgmtDLL::GetAPI( GOBIHANDLE handle )
|
||||
{
|
||||
cGobiConnectionMgmt * pAPI = 0;
|
||||
|
||||
pthread_mutex_lock( &mSyncSection );
|
||||
|
||||
std::map <GOBIHANDLE, cGobiConnectionMgmt *>::const_iterator pIter;
|
||||
pIter = mAPI.find( handle );
|
||||
if (pIter != mAPI.end())
|
||||
{
|
||||
pAPI = pIter->second;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &mSyncSection );
|
||||
|
||||
return pAPI;
|
||||
}
|
||||
|
||||
/*=========================================================================*/
|
||||
// cGobiConnectionMgmt Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cGobiConnectionMgmt (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cGobiConnectionMgmt::cGobiConnectionMgmt()
|
||||
: cGobiQMICore(),
|
||||
mbThreadStarted( false ),
|
||||
mThreadID( 0 ),
|
||||
mThreadCleanupFinished( false )
|
||||
{
|
||||
// Nothing to do but init those variables
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cGobiConnectionMgmt (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cGobiConnectionMgmt::~cGobiConnectionMgmt()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
ProcessTraffic (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Process traffic in a QMI server protocol log, this is done to
|
||||
exercise QMI indication related callbacks
|
||||
|
||||
PARAMETERS:
|
||||
svc [ I ] - QMI Service type
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void cGobiConnectionMgmt::ProcessTraffic( eQMIService svc )
|
||||
{
|
||||
ULONG count = 0;
|
||||
|
||||
std::map <eQMIService, sServerInfo>::iterator pIter;
|
||||
pIter = mServers.find( svc );
|
||||
if (pIter == mServers.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sServerInfo & si = pIter->second;
|
||||
cQMIProtocolServer * pSvr = si.mpServer;
|
||||
if (pSvr == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the service ID from the service
|
||||
eQMIService svcID = pSvr->GetServiceType();
|
||||
if (svcID == eQMI_SVC_ENUM_BEGIN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the log from the server
|
||||
const cProtocolLog & logSvr = pSvr->GetLog();
|
||||
|
||||
// New items to process?
|
||||
count = logSvr.GetCount();
|
||||
if (count != INVALID_LOG_INDEX && count > si.mLogsProcessed)
|
||||
{
|
||||
for (ULONG i = si.mLogsProcessed; i < count; i++)
|
||||
{
|
||||
sProtocolBuffer buf = logSvr.GetBuffer( i );
|
||||
if (buf.IsValid() == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
eProtocolType pt = buf.GetType();
|
||||
if (IsQMIProtocolRX( pt ) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sQMIServiceBuffer qmiBuf( buf.GetSharedBuffer() );
|
||||
if (qmiBuf.IsIndication() == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ULONG msgID = qmiBuf.GetMessageID();
|
||||
|
||||
tCallbackKey ck( svcID, msgID );
|
||||
std::map <tCallbackKey, tCallbackValue>::iterator pIter;
|
||||
pIter = mCallbacks.find( ck );
|
||||
if (pIter == mCallbacks.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ULONG outLen = 0;
|
||||
const BYTE * pOutput = (const BYTE *)qmiBuf.GetRawContents( outLen );
|
||||
tCallbackValue cv = pIter->second;
|
||||
|
||||
cGenericCallback * pCB = 0;
|
||||
pCB = new cGenericCallback( cv.first,
|
||||
svcID,
|
||||
msgID,
|
||||
cv.second,
|
||||
outLen,
|
||||
pOutput );
|
||||
|
||||
if (pCB != 0)
|
||||
{
|
||||
if (pCB->Initialize() == false)
|
||||
{
|
||||
delete pCB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
si.mLogsProcessed = count;
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Connect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Connect to the specified Gobi device
|
||||
|
||||
PARAMETERS:
|
||||
pQMIFile [ I ] - QMI control file to connect to
|
||||
services [ I ] - QMI services to connect to
|
||||
|
||||
RETURN VALUE:
|
||||
std::set <eQMIService> - Services successfuly configured
|
||||
===========================================================================*/
|
||||
std::set <eQMIService> cGobiConnectionMgmt::Connect(
|
||||
LPCSTR pQMIFile,
|
||||
std::set <eQMIService> & services )
|
||||
{
|
||||
std::set <eQMIService> svcs = cGobiQMICore::Connect( pQMIFile, services );
|
||||
if (svcs.size() > 0)
|
||||
{
|
||||
// Start the traffic processing thread?
|
||||
if (mbThreadStarted == false)
|
||||
{
|
||||
// Clear mExitEvent;
|
||||
mExitEvent.Clear();
|
||||
|
||||
pthread_create( &mThreadID,
|
||||
NULL,
|
||||
TrafficProcessThread,
|
||||
this );
|
||||
|
||||
mbThreadStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
return svcs;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Disconnect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Disconnect from the currently connected Gobi device
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cGobiConnectionMgmt::Disconnect()
|
||||
{
|
||||
// Clear all callback function pointers
|
||||
mCallbacks.clear();
|
||||
|
||||
// Exit traffic processing thread
|
||||
if (mbThreadStarted == true)
|
||||
{
|
||||
// Signal thread to exit
|
||||
mExitEvent.Set( 0 );
|
||||
|
||||
// If we are not being called from the thread itself then wait for
|
||||
// it to exit, if not then it will have to exit automatically
|
||||
if (pthread_self() != mThreadID)
|
||||
{
|
||||
if (mThreadID != 0)
|
||||
{
|
||||
pthread_join( mThreadID, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear out thread handle/ID
|
||||
mbThreadStarted = false;
|
||||
mThreadID = 0;
|
||||
|
||||
return cGobiQMICore::Disconnect();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
SetGenericCallback (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Enable/disable generic callback function
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - Service ID to monitor
|
||||
msgID [ I ] - Message ID to look for
|
||||
pCallback [ I ] - Generic callback pointer
|
||||
userValue [ I ] - User value to pass back to callback
|
||||
|
||||
RETURN VALUE:
|
||||
eGobiError - Return code
|
||||
===========================================================================*/
|
||||
eGobiError cGobiConnectionMgmt::SetGenericCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
tFNGenericCallback pCallback,
|
||||
ULONG_PTR userValue )
|
||||
{
|
||||
// Assume success
|
||||
eGobiError rc = eGOBI_ERR_NONE;
|
||||
|
||||
tCallbackKey ck( svcID, msgID );
|
||||
std::map <tCallbackKey, tCallbackValue>::iterator pIter;
|
||||
pIter = mCallbacks.find( ck );
|
||||
|
||||
bool bOn = (pCallback != 0 && pIter == mCallbacks.end());
|
||||
bool bOff = (pCallback == 0 && pIter != mCallbacks.end());
|
||||
bool bReplace = (pCallback != 0 && pIter != mCallbacks.end());
|
||||
if (bOn == true || bReplace == true)
|
||||
{
|
||||
tCallbackValue cv( pCallback, userValue );
|
||||
mCallbacks[ck] = cv;
|
||||
}
|
||||
else if (bOff == true)
|
||||
{
|
||||
mCallbacks.erase( pIter );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiConnectionMgmt.h
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Connection Management API for Gobi
|
||||
|
||||
PUBLIC CLASSES AND FUNCTIONS:
|
||||
CGobiConnectionMgmtDLL
|
||||
cGobiConnectionMgmt
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
/*=========================================================================*/
|
||||
// Pragmas
|
||||
/*=========================================================================*/
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "GobiQMICore.h"
|
||||
|
||||
#include "QMIBuffers.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Handle to Gobi API
|
||||
typedef ULONG_PTR GOBIHANDLE;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Generic callback function pointer
|
||||
typedef void (* tFNGenericCallback)(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
ULONG_PTR userValue,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut );
|
||||
|
||||
};
|
||||
|
||||
// CallbackThread prototype
|
||||
// Thread to execute a callback asynchronously
|
||||
void * CallbackThread( PVOID pArg );
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cGobiCMCallback
|
||||
/*=========================================================================*/
|
||||
class cGobiCMCallback
|
||||
{
|
||||
public:
|
||||
// (Inline) Constructor
|
||||
cGobiCMCallback()
|
||||
{ };
|
||||
|
||||
// (Inline) Destructor
|
||||
virtual ~cGobiCMCallback()
|
||||
{ };
|
||||
|
||||
// (Inline) Initialize the callback object by starting the thread
|
||||
bool Initialize()
|
||||
{
|
||||
// Start the thread
|
||||
pthread_t threadID;
|
||||
pthread_attr_t attributes;
|
||||
pthread_attr_init( &attributes );
|
||||
pthread_attr_setdetachstate( &attributes, PTHREAD_CREATE_DETACHED );
|
||||
|
||||
int nRC = pthread_create( &threadID,
|
||||
&attributes,
|
||||
CallbackThread,
|
||||
this );
|
||||
|
||||
if (nRC == 0)
|
||||
{
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Call the function
|
||||
virtual void Call() = 0;
|
||||
|
||||
// Function thread gets full access
|
||||
friend void * CallbackThread( PVOID pArg );
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cGenericCallback
|
||||
/*=========================================================================*/
|
||||
class cGenericCallback : public cGobiCMCallback
|
||||
{
|
||||
public:
|
||||
// (Inline) Constructor
|
||||
cGenericCallback(
|
||||
tFNGenericCallback pCallback,
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
ULONG_PTR userValue,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut )
|
||||
: mServiceID( svcID ),
|
||||
mMessageID( msgID ),
|
||||
mUserValue( userValue ),
|
||||
mOutputLen( 0 ),
|
||||
mpCallback( pCallback )
|
||||
{
|
||||
memset( &mOutput[0], 0, QMI_MAX_BUFFER_SIZE );
|
||||
if (outLen <= QMI_MAX_BUFFER_SIZE && pOut != 0)
|
||||
{
|
||||
mOutputLen = outLen;
|
||||
memcpy( &mOutput[0], pOut, outLen );
|
||||
}
|
||||
};
|
||||
|
||||
// (Inline) Destructor
|
||||
virtual ~cGenericCallback()
|
||||
{
|
||||
mpCallback = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
/* Service ID */
|
||||
ULONG mServiceID;
|
||||
|
||||
/* Message ID */
|
||||
ULONG mMessageID;
|
||||
|
||||
/* User value */
|
||||
ULONG_PTR mUserValue;
|
||||
|
||||
/* Actual size of output content */
|
||||
ULONG mOutputLen;
|
||||
|
||||
/* Output content buffer */
|
||||
BYTE mOutput[QMI_MAX_BUFFER_SIZE];
|
||||
|
||||
/* Callback function */
|
||||
tFNGenericCallback mpCallback;
|
||||
|
||||
// Call the function
|
||||
virtual void Call()
|
||||
{
|
||||
if (mpCallback != 0)
|
||||
{
|
||||
mpCallback( mServiceID,
|
||||
mMessageID,
|
||||
mUserValue,
|
||||
mOutputLen,
|
||||
(const BYTE *)&mOutput[0] );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cGobiConnectionMgmt
|
||||
/*=========================================================================*/
|
||||
class cGobiConnectionMgmt : public cGobiQMICore
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cGobiConnectionMgmt();
|
||||
|
||||
// Destructor
|
||||
virtual ~cGobiConnectionMgmt();
|
||||
|
||||
// Connect to the specified Gobi device interface
|
||||
virtual std::set <eQMIService> Connect(
|
||||
LPCSTR pInterface,
|
||||
std::set <eQMIService> & services );
|
||||
|
||||
// Disconnect from the currently connected device interface
|
||||
virtual bool Disconnect();
|
||||
|
||||
// Enable/disable generic callback function
|
||||
eGobiError SetGenericCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
tFNGenericCallback pCallback,
|
||||
ULONG_PTR userValue );
|
||||
|
||||
protected:
|
||||
// Process new traffic
|
||||
void ProcessTraffic( eQMIService svc );
|
||||
|
||||
/* Is there an active thread? */
|
||||
bool mbThreadStarted;
|
||||
|
||||
/* ID of traffic processing thread */
|
||||
pthread_t mThreadID;
|
||||
|
||||
/* Traffic processing thread exit event */
|
||||
cEvent mExitEvent;
|
||||
|
||||
/* Has the protocol server thread finished cleanup? */
|
||||
bool mThreadCleanupFinished;
|
||||
|
||||
/* Generic callback function key/value */
|
||||
typedef std::pair <ULONG, ULONG> tCallbackKey;
|
||||
typedef std::pair <tFNGenericCallback, ULONG_PTR> tCallbackValue;
|
||||
|
||||
/* Callback functions */
|
||||
std::map <tCallbackKey, tCallbackValue> mCallbacks;
|
||||
|
||||
// Traffic process thread gets full access
|
||||
friend VOID * TrafficProcessThread( PVOID pArg );
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class CGobiConnectionMgmtDLL
|
||||
/*=========================================================================*/
|
||||
class CGobiConnectionMgmtDLL
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CGobiConnectionMgmtDLL();
|
||||
|
||||
// Destructor
|
||||
virtual ~CGobiConnectionMgmtDLL();
|
||||
|
||||
// Create a new API object
|
||||
GOBIHANDLE CreateAPI();
|
||||
|
||||
// Delete an existing API object
|
||||
void DeleteAPI( GOBIHANDLE handle );
|
||||
|
||||
// Return the requested API object
|
||||
cGobiConnectionMgmt * GetAPI( GOBIHANDLE handle );
|
||||
|
||||
protected:
|
||||
/* API interface object */
|
||||
std::map <GOBIHANDLE, cGobiConnectionMgmt *> mAPI;
|
||||
|
||||
/* Synchronization object */
|
||||
mutable pthread_mutex_t mSyncSection;
|
||||
};
|
||||
|
||||
extern CGobiConnectionMgmtDLL gDLL;
|
File diff suppressed because it is too large
Load Diff
6289
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtAPIEnums.h
Executable file
6289
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtAPIEnums.h
Executable file
File diff suppressed because it is too large
Load Diff
28009
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtAPIStructs.h
Executable file
28009
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtAPIStructs.h
Executable file
File diff suppressed because it is too large
Load Diff
20395
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtExports.cpp
Executable file
20395
gobi-api/GobiAPI_2012-09-12-0719/GobiConnectionMgmt/GobiConnectionMgmtExports.cpp
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,309 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiCMCallback.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Contains the implementation of each Gobi CM callback function.
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "SampleCM.h"
|
||||
#include "GobiCMCallback.h"
|
||||
#include <sstream>
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
WDSEventReportCallback (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Function called by WDS event report callback
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - QMI service ID
|
||||
msgID [ I ] - QMI message ID
|
||||
handle [ I ] - Handle to Gobi API connection
|
||||
outLen [ I ] - Length of indication buffer
|
||||
pOut [ I ] - Indication buffer
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void WDSEventReportCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE /* handle */,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut )
|
||||
{
|
||||
if (gpCM == 0 || svcID != 1 || msgID != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &pOut[0], outLen );
|
||||
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( 0x17 );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sWDSEventReportIndication_DataBearerTechnology))
|
||||
{
|
||||
pTmp++;
|
||||
const sWDSEventReportIndication_DataBearerTechnology * pDBT =
|
||||
(const sWDSEventReportIndication_DataBearerTechnology *)pTmp;
|
||||
|
||||
gpCM->OnDataBearerCBNotification( pDBT->mDataBearerTechnology );
|
||||
}
|
||||
}
|
||||
|
||||
ULONGLONG txTotalBytes = ULLONG_MAX;
|
||||
ULONGLONG rxTotalBytes = ULLONG_MAX;
|
||||
|
||||
pIter = tlvs.find( 0x19 );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sWDSEventReportIndication_TXBytes))
|
||||
{
|
||||
pTmp++;
|
||||
const sWDSEventReportIndication_TXBytes * pTX =
|
||||
(const sWDSEventReportIndication_TXBytes *)pTmp;
|
||||
|
||||
txTotalBytes = pTX->mTXByteTotal;
|
||||
}
|
||||
}
|
||||
|
||||
pIter = tlvs.find( 0x1A );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sWDSEventReportIndication_RXBytes))
|
||||
{
|
||||
pTmp++;
|
||||
const sWDSEventReportIndication_RXBytes * pRX =
|
||||
(const sWDSEventReportIndication_RXBytes *)pTmp;
|
||||
|
||||
rxTotalBytes = pRX->mRXByteTotal;
|
||||
}
|
||||
}
|
||||
|
||||
if (txTotalBytes != ULLONG_MAX || rxTotalBytes != ULLONG_MAX)
|
||||
{
|
||||
gpCM->OnByteTotalsNotification( rxTotalBytes, txTotalBytes );
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
WDSSessionStateCallback (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Function called by WDS packet service status callback
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - QMI service ID
|
||||
msgID [ I ] - QMI message ID
|
||||
handle [ I ] - Handle to Gobi API connection
|
||||
outLen [ I ] - Length of indication buffer
|
||||
pOut [ I ] - Indication buffer
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void WDSSessionStateCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE /* handle */,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut )
|
||||
{
|
||||
if (gpCM == 0 || svcID != 1 || msgID != 34)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG state = ULONG_MAX;
|
||||
|
||||
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &pOut[0], outLen );
|
||||
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( 0x01 );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sWDSPacketServiceStatusReportIndication_Status))
|
||||
{
|
||||
pTmp++;
|
||||
const sWDSPacketServiceStatusReportIndication_Status * pState =
|
||||
(const sWDSPacketServiceStatusReportIndication_Status *)pTmp;
|
||||
|
||||
state = pState->mConnectionStatus;
|
||||
}
|
||||
}
|
||||
|
||||
if (state != ULONG_MAX)
|
||||
{
|
||||
gpCM->OnSessionStateCBNotification( state );
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
NASEventReportCallback (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Function called by NAS event report callback
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - QMI service ID
|
||||
msgID [ I ] - QMI message ID
|
||||
handle [ I ] - Handle to Gobi API connection
|
||||
outLen [ I ] - Length of indication buffer
|
||||
pOut [ I ] - Indication buffer
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void NASEventReportCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE /* handle */,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut )
|
||||
{
|
||||
if (gpCM == 0 || svcID != 3 || msgID != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &pOut[0], outLen );
|
||||
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( 0x10 );
|
||||
if (pIter == tlvs.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sNASEventReportIndication_SignalStrength))
|
||||
{
|
||||
pTmp++;
|
||||
const sNASEventReportIndication_SignalStrength * pSS =
|
||||
(const sNASEventReportIndication_SignalStrength *)pTmp;
|
||||
|
||||
gpCM->OnSignalStrengthCBNotificaion( pSS->mSignalStrengthdBm,
|
||||
pSS->mRadioInterface );
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
NASServingSystemCallback (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Function called by NAS serving system callback
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - QMI service ID
|
||||
msgID [ I ] - QMI message ID
|
||||
handle [ I ] - Handle to Gobi API connection
|
||||
outLen [ I ] - Length of indication buffer
|
||||
pOut [ I ] - Indication buffer
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
void NASServingSystemCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE /* handle */,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut )
|
||||
{
|
||||
if (gpCM == 0 || svcID != 3 || msgID != 36)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &pOut[0], outLen );
|
||||
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( 0x10 );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
if (pTmp->mLength >= sizeof (sNASServingSystemIndication_RoamingIndicator))
|
||||
{
|
||||
pTmp++;
|
||||
const sNASServingSystemIndication_RoamingIndicator * pRI =
|
||||
(const sNASServingSystemIndication_RoamingIndicator *)pTmp;
|
||||
|
||||
BYTE roam = pRI->mRoamingIndicator;
|
||||
if (roam == 0xFF)
|
||||
{
|
||||
gpCM->SetRoam( "Unknown" );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream roamStr;
|
||||
roamStr << roam;
|
||||
gpCM->SetRoam( roamStr.str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pIter = tlvs.find( 0x11 );
|
||||
if (pIter != tlvs.end())
|
||||
{
|
||||
const sQMIRawContentHeader * pTmp = pIter->second;
|
||||
ULONG tlvLen = (ULONG)pTmp->mLength;
|
||||
ULONG dsLen = (ULONG)sizeof( sNASServingSystemIndication_DataServices );
|
||||
if (tlvLen < dsLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pTmp++;
|
||||
const sNASServingSystemIndication_DataServices * pDS =
|
||||
(const sNASServingSystemIndication_DataServices *)pTmp;
|
||||
|
||||
ULONG dcCount = (ULONG)pDS->mNumberOfDataCapabilities;
|
||||
ULONG dcSz = (ULONG)sizeof( eQMINASDataServiceCapabilities2 );
|
||||
dsLen += dcCount * dcSz;
|
||||
if (tlvLen < dsLen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pDS++;
|
||||
gpCM->OnDataCapsNotification( dcCount,
|
||||
(eQMINASDataServiceCapabilities2 *)pDS );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiCMCallback.h
|
||||
|
||||
DESCRIPTION:
|
||||
Contains the declaration of each Gobi CM callback function,
|
||||
structures needed for these callbacks and message IDs for
|
||||
each callback
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "GobiCMDLL.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// WDS event report callback
|
||||
void WDSEventReportCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE handle,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut );
|
||||
|
||||
// WDS packet service status callback
|
||||
void WDSSessionStateCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE handle,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut );
|
||||
|
||||
// NAS event report callback
|
||||
void NASEventReportCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE handle,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut );
|
||||
|
||||
// NAS serving system callback
|
||||
void NASServingSystemCallback(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
GOBIHANDLE handle,
|
||||
ULONG outLen,
|
||||
const BYTE * pOut );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,266 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiCMDLL.h
|
||||
|
||||
DESCRIPTION:
|
||||
Simple class to load and interface to the Gobi CM DLL
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cGobiCMDLL
|
||||
This class loads the Gobi CM DLL and then interfaces to it
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "GobiConnectionMgmtAPI.h"
|
||||
#include "GobiConnectionMgmtAPIStructs.h"
|
||||
#include <map>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
// Handle to Gobi API
|
||||
typedef ULONG_PTR GOBIHANDLE;
|
||||
|
||||
// The maximum number of signals
|
||||
const ULONG MAX_SIGNALS = 12;
|
||||
|
||||
// The maximum number of data capabilities
|
||||
const ULONG MAX_DATA_CAPABILITIES = 12;
|
||||
|
||||
// Gobi input/output function pointer
|
||||
typedef ULONG (* tFNGobiInputOutput)(
|
||||
GOBIHANDLE handle,
|
||||
ULONG to,
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut );
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
GetTLVs (Internal Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Convert response buffer to a TLV map
|
||||
|
||||
PARAMETERS:
|
||||
pRsp [ I ] - The response buffer
|
||||
rspSz [ I ] - The size of the above buffer
|
||||
|
||||
RETURN VALUE:
|
||||
std::map <UINT8, const sQMIRawContentHeader *>
|
||||
===========================================================================*/
|
||||
inline std::map <UINT8, const sQMIRawContentHeader *> GetTLVs(
|
||||
const UINT8 * pRsp,
|
||||
ULONG rspSz )
|
||||
{
|
||||
std::map <UINT8, const sQMIRawContentHeader *> retMap;
|
||||
|
||||
ULONG dataProcessed = 0;
|
||||
const UINT8 * pData = &pRsp[0];
|
||||
while (dataProcessed < rspSz)
|
||||
{
|
||||
dataProcessed += (ULONG)sizeof( sQMIRawContentHeader );
|
||||
if (dataProcessed > rspSz)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const sQMIRawContentHeader * pTLV = (const sQMIRawContentHeader *)pData;
|
||||
dataProcessed += (ULONG)pTLV->mLength;
|
||||
if (dataProcessed > rspSz)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
retMap[pTLV->mTypeID] = pTLV;
|
||||
pData = &pRsp[dataProcessed];
|
||||
}
|
||||
|
||||
return retMap;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cGobiCMDLL
|
||||
/*=========================================================================*/
|
||||
class cGobiCMDLL
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cGobiCMDLL()
|
||||
: mhGobi( 0 )
|
||||
{ }
|
||||
|
||||
// Destructor
|
||||
~cGobiCMDLL()
|
||||
{ }
|
||||
|
||||
// Connect
|
||||
ULONG Connect( LPCSTR pInterface );
|
||||
|
||||
// Disconnect
|
||||
ULONG Disconnect();
|
||||
|
||||
// Start data session
|
||||
ULONG StartDataSession(
|
||||
LPCSTR pAPN,
|
||||
LPCSTR pUser,
|
||||
LPCSTR pPwd,
|
||||
ULONG * pSessionID,
|
||||
ULONG * pFailureCode );
|
||||
|
||||
// Cancel data session
|
||||
ULONG CancelDataSession();
|
||||
|
||||
// Stop data session
|
||||
ULONG StopDataSession( ULONG sessionID );
|
||||
|
||||
// Get session state
|
||||
ULONG GetSessionState( ULONG * pSessionState );
|
||||
|
||||
// Get session duration
|
||||
ULONG GetSessionDuration( ULONGLONG * pSessionDuration );
|
||||
|
||||
// Get data bearer technology
|
||||
ULONG GetDataBearerTechnology( ULONG * pDataBearerTech );
|
||||
|
||||
// Get connection rate
|
||||
ULONG GetConnectionRate(
|
||||
ULONG * pCurTX,
|
||||
ULONG * pCurRX,
|
||||
ULONG * pMaxTX,
|
||||
ULONG * pMaxRX );
|
||||
|
||||
// Get firmware revision
|
||||
ULONG GetFirmwareRevision(
|
||||
BYTE strSz,
|
||||
CHAR * pStr );
|
||||
|
||||
// Get manufacturer
|
||||
ULONG GetManufacturer(
|
||||
BYTE strSz,
|
||||
CHAR * pStr );
|
||||
|
||||
// Get model ID
|
||||
ULONG GetModelID(
|
||||
BYTE strSz,
|
||||
CHAR * pStr );
|
||||
|
||||
// Get hardware revision
|
||||
ULONG GetHardwareRevision(
|
||||
BYTE strSz,
|
||||
CHAR * pStr );
|
||||
|
||||
// Get voice number
|
||||
ULONG GetVoiceNumber(
|
||||
BYTE voiceSz,
|
||||
CHAR * pVoiceStr,
|
||||
BYTE minSz,
|
||||
CHAR * pMINStr );
|
||||
|
||||
// Get serial numbers
|
||||
ULONG GetSerialNumbers(
|
||||
BYTE esnSz,
|
||||
CHAR * pESNStr,
|
||||
BYTE imeiSz,
|
||||
CHAR * pIMEIStr,
|
||||
BYTE meidSz,
|
||||
CHAR * pMEIDStr );
|
||||
|
||||
// Get IMSI
|
||||
ULONG GetIMSI(
|
||||
BYTE imsiSz,
|
||||
CHAR * pIMSIStr );
|
||||
|
||||
// Get signal strengths
|
||||
ULONG GetSignalStrengths(
|
||||
INT8 * pSigStrengths,
|
||||
ULONG * pRadioInterfaces );
|
||||
|
||||
// Get serving network
|
||||
ULONG GetServingNetwork(
|
||||
ULONG * pDataCapabilities,
|
||||
WORD * pMCC,
|
||||
WORD * pMNC,
|
||||
BYTE nameSize,
|
||||
CHAR * pName,
|
||||
WORD * pSID,
|
||||
WORD * pNID,
|
||||
ULONG * pRoam );
|
||||
|
||||
// Get home network
|
||||
ULONG GetHomeNetwork(
|
||||
WORD * pHomeMCC,
|
||||
WORD * pHomeMNC,
|
||||
BYTE homeNameSize,
|
||||
CHAR * pHomeName,
|
||||
WORD * pSID,
|
||||
WORD * pNID );
|
||||
|
||||
// Set WDS event report callback
|
||||
ULONG SetWDSEventReportCB(
|
||||
tFNGenericCallback pCallback,
|
||||
BYTE interval );
|
||||
|
||||
// Set WDS packet service status callback
|
||||
ULONG SetWDSSessionStateCB( tFNGenericCallback pCallback );
|
||||
|
||||
// Set NAS event report callback
|
||||
ULONG SetNASEventReportCB(
|
||||
tFNGenericCallback pCallback,
|
||||
BYTE thresholdsSize,
|
||||
INT8 * pThresholds );
|
||||
|
||||
// Set NAS serving system callback
|
||||
ULONG SetNASServingSystemCB( tFNGenericCallback pCallback );
|
||||
|
||||
protected:
|
||||
|
||||
// Call a Gobi CM API function that returns a string
|
||||
ULONG GetString(
|
||||
tFNGobiInputOutput mpFnString,
|
||||
BYTE tlvID,
|
||||
BYTE strSz,
|
||||
CHAR * pStr );
|
||||
|
||||
/* Handle to Gobi API */
|
||||
GOBIHANDLE mhGobi;
|
||||
};
|
|
@ -0,0 +1,316 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QTSampleCM.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QT implementation of the Sample CM
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cQTSampleCM
|
||||
QT implementation of the Sample CM
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "QTSampleCM.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
// Free Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
AsyncConnectThread (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Start a data session
|
||||
|
||||
PARAMETERS:
|
||||
pData [ I ] - cQTSampleCM object
|
||||
|
||||
RETURN VALUE:
|
||||
void * - always NULL
|
||||
===========================================================================*/
|
||||
void * AsyncConnectThread( void * pData )
|
||||
{
|
||||
cQTSampleCM * pCM = (cQTSampleCM*)pData;
|
||||
if (pCM == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Open the dialog window, disable the info and connection stats buttons
|
||||
pCM->mView.rootContext()->setContextProperty( "dialogText",
|
||||
"Connecting, please wait..." );
|
||||
pCM->mView.rootContext()->setContextProperty( "windowState",
|
||||
"connectingDialog" );
|
||||
|
||||
ULONG failureCode = 0xFFFFFFFF;
|
||||
ULONG rc = pCM->OnStartDataSession( &failureCode );
|
||||
if (rc != eGOBI_ERR_NONE)
|
||||
{
|
||||
std::ostringstream error;
|
||||
error << "Failed to connect, error " << rc;
|
||||
|
||||
TRACE( "rc %lu, failure code %lu", rc, failureCode );
|
||||
|
||||
// Show failure code, if present
|
||||
if (rc == 1014 && failureCode != 0xFFFFFFFF)
|
||||
{
|
||||
error << "\nCall failure reason " << failureCode;
|
||||
}
|
||||
|
||||
pCM->mView.rootContext()->setContextProperty( "dialogText",
|
||||
error.str().c_str() );
|
||||
|
||||
pCM->SetConnectButtonText( "Connect" );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCM->mView.rootContext()->setContextProperty( "dialogText", "Success!" );
|
||||
|
||||
// Connect button should be updated by state change indication
|
||||
}
|
||||
|
||||
// Leave the dialog up for 2s
|
||||
sleep( 2 );
|
||||
|
||||
pCM->mView.rootContext()->setContextProperty( "windowState", "" );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
OnInfosButton (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Move to the info stats page
|
||||
|
||||
PARAMETERS:
|
||||
pCM [ I ] - cQTSampleCM object
|
||||
|
||||
RETURN VALUE:
|
||||
QVariant - always 0
|
||||
===========================================================================*/
|
||||
QVariant OnInfosButton( cQTSampleCM * pCM )
|
||||
{
|
||||
pCM->mView.rootContext()->setContextProperty( "windowState", "infos" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
OnConnectionsButton (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Move to the connection stats page
|
||||
|
||||
PARAMETERS:
|
||||
pCM [ I ] - cQTSampleCM object
|
||||
|
||||
RETURN VALUE:
|
||||
QVariant - always 0
|
||||
===========================================================================*/
|
||||
QVariant OnConnectionsButton( cQTSampleCM * pCM )
|
||||
{
|
||||
// "" is the default state (connection stats page)
|
||||
pCM->mView.rootContext()->setContextProperty( "windowState", "" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
OnConnectButton (Free Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Start, cancel, or disconnect from a data session
|
||||
|
||||
NOTE: The UI is not updated until this function returns, so the connection
|
||||
will be established asynchronously
|
||||
|
||||
PARAMETERS:
|
||||
pCM [ I ] - cQTSampleCM object
|
||||
|
||||
RETURN VALUE:
|
||||
QVariant - always 0
|
||||
===========================================================================*/
|
||||
QVariant OnConnectButton( cQTSampleCM * pCM )
|
||||
{
|
||||
// Double check if there a device connected
|
||||
if (pCM->mDeviceID.size() == 0
|
||||
|| pCM->mConnectButtonText.compare( "No Device" ) == 0)
|
||||
{
|
||||
TRACE( "No Device" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Start a connection
|
||||
if (pCM->mConnectButtonText.compare( "Connect" ) == 0)
|
||||
{
|
||||
pCM->SetConnectButtonText( "Cancel" );
|
||||
|
||||
// Create a detached thread to start the connection asynchronously
|
||||
pthread_attr_t attributes;
|
||||
pthread_attr_init( &attributes );
|
||||
pthread_attr_setdetachstate( &attributes, PTHREAD_CREATE_DETACHED );
|
||||
|
||||
pthread_create( &pCM->mAsyncConnectThreadID,
|
||||
&attributes,
|
||||
AsyncConnectThread,
|
||||
pCM );
|
||||
}
|
||||
else if (pCM->mConnectButtonText.compare( "Cancel" ) == 0)
|
||||
{
|
||||
pCM->OnCancelDataSession();
|
||||
|
||||
pCM->SetConnectButtonText( "Connect" );
|
||||
}
|
||||
else if (pCM->mConnectButtonText.compare( "Disconnect" ) == 0)
|
||||
{
|
||||
pCM->OnStopDataSession();
|
||||
|
||||
pCM->SetConnectButtonText( "Connect" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Externally connected, etc
|
||||
TRACE( "Unknown connect button state %s",
|
||||
pCM->mConnectButtonText.c_str() );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=========================================================================*/
|
||||
// cQTSampleCM Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Init (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Initialize GUI
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cQTSampleCM::Init()
|
||||
{
|
||||
// Use the current screen orientation
|
||||
mView.setOrientation( QmlApplicationViewer::ScreenOrientationAuto );
|
||||
|
||||
// The buttons
|
||||
mView.rootContext()->setContextProperty( "connectButton",
|
||||
&mConnectButton );
|
||||
mView.rootContext()->setContextProperty( "infosButton",
|
||||
&mInfosButton );
|
||||
mView.rootContext()->setContextProperty( "connectionsButton",
|
||||
&mConnectionsButton );
|
||||
|
||||
// The input fields
|
||||
mView.rootContext()->setContextProperty( "apnNameText", &mAPNText );
|
||||
mView.rootContext()->setContextProperty( "usernameText", &mUsernameText );
|
||||
mView.rootContext()->setContextProperty( "passwordText", &mPasswordText );
|
||||
|
||||
// Default button value
|
||||
SetConnectButtonText( "No Device" );
|
||||
|
||||
// Default state
|
||||
mView.rootContext()->setContextProperty( "windowState", "" );
|
||||
mView.rootContext()->setContextProperty( "dialogText", "" );
|
||||
|
||||
bool bRC = cSampleCM::Init();
|
||||
|
||||
mView.setMainQmlFile( "qml/GobiSampleCM/main.qml" );
|
||||
mView.show();
|
||||
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Run (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Run the GUI (blocks until exit)
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
int cQTSampleCM::Run()
|
||||
{
|
||||
return mApp.exec();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Disconnect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Calls GobiDisconnect
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG
|
||||
===========================================================================*/
|
||||
ULONG cQTSampleCM::Disconnect()
|
||||
{
|
||||
SetConnectButtonText( "No device" );
|
||||
|
||||
return cSampleCM::Disconnect();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
ETHOD:
|
||||
OnStartDataSession (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Updates apn, username, and password input field values before starting
|
||||
a data session
|
||||
|
||||
PARAMETERS:
|
||||
pFailureCode [ O ] - Call failure code, if provided
|
||||
|
||||
RETURN VALUE:
|
||||
ULONG
|
||||
===========================================================================*/
|
||||
ULONG cQTSampleCM::OnStartDataSession( ULONG * pFailureCode )
|
||||
{
|
||||
// Grab the APN, username, and password
|
||||
mAPN = mAPNText.getText().toUtf8().constData();
|
||||
mUsername = mUsernameText.getText().toUtf8().constData();
|
||||
mPassword = mPasswordText.getText().toUtf8().constData();
|
||||
|
||||
return cSampleCM::OnStartDataSession( pFailureCode );
|
||||
}
|
|
@ -0,0 +1,459 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
QTSampleCM.h
|
||||
|
||||
DESCRIPTION:
|
||||
QT implementation of the Sample CM
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cButton
|
||||
Generic clickable button for QT
|
||||
cTextInput
|
||||
Generic text input field for QT
|
||||
cQTSampleCM
|
||||
QT implementation of the Sample CM
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include <QtGui/QApplication>
|
||||
#include "qmlapplicationviewer.h"
|
||||
#include <qvariant.h>
|
||||
#include <qdeclarativecontext.h>
|
||||
|
||||
#include "SampleCM.h"
|
||||
|
||||
// Prototypes
|
||||
class cQTSampleCM;
|
||||
void * AsyncConnectThread( void * pData );
|
||||
QVariant OnInfosButton( cQTSampleCM * pCM );
|
||||
QVariant OnConnectionsButton( cQTSampleCM * pCM );
|
||||
QVariant OnConnectButton( cQTSampleCM * pCM );
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cButton
|
||||
// Generic clickable button for QT
|
||||
/*=========================================================================*/
|
||||
class cButton : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
cButton( cQTSampleCM * pCM,
|
||||
QVariant (*pOnClick)( cQTSampleCM * ) )
|
||||
{
|
||||
mpCM = pCM;
|
||||
mpOnClick = pOnClick;
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
// Function to be run on a click event
|
||||
QVariant Click()
|
||||
{
|
||||
if (mpOnClick != 0)
|
||||
{
|
||||
return mpOnClick( mpCM );
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/* The main object */
|
||||
cQTSampleCM * mpCM;
|
||||
|
||||
/* Function to run when clicked */
|
||||
QVariant (* mpOnClick)( cQTSampleCM * );
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// cTextInput
|
||||
// Generic text input field for QT
|
||||
/*=========================================================================*/
|
||||
class cTextInput : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString text READ getText WRITE setText )
|
||||
|
||||
public slots:
|
||||
|
||||
// Get the value
|
||||
QString getText() const
|
||||
{
|
||||
return mText;
|
||||
}
|
||||
|
||||
// Set the value
|
||||
void setText( const QString & text )
|
||||
{
|
||||
mText = text;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/* The text */
|
||||
QString mText;
|
||||
};
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cQTSampleCM
|
||||
/*=========================================================================*/
|
||||
class cQTSampleCM : public cSampleCM
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cQTSampleCM( int argc, char ** argv )
|
||||
: mApp( argc, argv ),
|
||||
mConnectButtonText( "No Device" ),
|
||||
mConnectButton( this, OnConnectButton ),
|
||||
mInfosButton( this, OnInfosButton ),
|
||||
mConnectionsButton( this, OnConnectionsButton )
|
||||
{ }
|
||||
|
||||
// Initialize UI, begin waiting for devices
|
||||
bool Init();
|
||||
|
||||
// Run the GUI (blocks until exit)
|
||||
int Run();
|
||||
|
||||
// Disconnect
|
||||
ULONG Disconnect();
|
||||
|
||||
// Process a start data session request
|
||||
ULONG OnStartDataSession( ULONG * pFailureCode );
|
||||
|
||||
// Set mState and the connection button
|
||||
void SetState( const std::string & state )
|
||||
{
|
||||
cSampleCM::SetState( state );
|
||||
|
||||
// Update the connection button as well
|
||||
switch (mSessionState)
|
||||
{
|
||||
case eQMIConnectionStatus_Disconnected:
|
||||
{
|
||||
SetConnectButtonText( "Connect" );
|
||||
|
||||
if (mInitialState != eQMIConnectionStatus_Disconnected
|
||||
&& mInitialState != eQMIConnectionStatus_Suspended)
|
||||
{
|
||||
// Clear the initial state
|
||||
mInitialState = eQMIConnectionStatus_Disconnected;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eQMIConnectionStatus_Connected:
|
||||
{
|
||||
if (mInitialState != eQMIConnectionStatus_Disconnected
|
||||
&& mInitialState != eQMIConnectionStatus_Suspended)
|
||||
{
|
||||
SetConnectButtonText( "External Con" );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConnectButtonText( "Disconnect" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eQMIConnectionStatus_Authenticating:
|
||||
{
|
||||
if (mInitialState != eQMIConnectionStatus_Disconnected
|
||||
&& mInitialState != eQMIConnectionStatus_Suspended)
|
||||
{
|
||||
SetConnectButtonText( "Ext Connecting" );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConnectButtonText( "Cancel" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eQMIConnectionStatus_Suspended:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// No more than 12 characters
|
||||
if (mState.size() > 12)
|
||||
{
|
||||
mState.resize( 12 );
|
||||
}
|
||||
|
||||
// Note: "state" is already a property, can't duplicate
|
||||
// using "status" instead
|
||||
mView.rootContext()->setContextProperty( "status", mState.c_str() );
|
||||
}
|
||||
|
||||
// Set mRSSI
|
||||
void SetRSSI( const std::string & rssi )
|
||||
{
|
||||
cSampleCM::SetRSSI( rssi );
|
||||
|
||||
mView.rootContext()->setContextProperty( "rssi", mRSSI.c_str() );
|
||||
}
|
||||
|
||||
// Set mTech
|
||||
void SetTech( const std::string & tech )
|
||||
{
|
||||
cSampleCM::SetTech( tech );
|
||||
|
||||
// No more than 12 characters
|
||||
if (mTech.size() > 12)
|
||||
{
|
||||
mTech.resize( 12 );
|
||||
}
|
||||
|
||||
mView.rootContext()->setContextProperty( "tech", mTech.c_str() );
|
||||
}
|
||||
|
||||
// Set mRx
|
||||
void SetRx( const std::string & rx )
|
||||
{
|
||||
cSampleCM::SetRx( rx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "rx", mRx.c_str() );
|
||||
}
|
||||
|
||||
// Set mTx
|
||||
void SetTx( const std::string & tx )
|
||||
{
|
||||
cSampleCM::SetTx( tx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "tx", mTx.c_str() );
|
||||
}
|
||||
|
||||
// Set mMaxRx
|
||||
void SetMaxRx( const std::string & maxRx )
|
||||
{
|
||||
cSampleCM::SetMaxRx( maxRx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "maxRx", mMaxRx.c_str() );
|
||||
}
|
||||
|
||||
// Set mMaxTx
|
||||
void SetMaxTx( const std::string & maxTx )
|
||||
{
|
||||
cSampleCM::SetMaxTx( maxTx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "maxTx", mMaxTx.c_str() );
|
||||
}
|
||||
|
||||
// Set mRoam
|
||||
void SetRoam( const std::string & roam )
|
||||
{
|
||||
cSampleCM::SetRoam( roam );
|
||||
|
||||
mView.rootContext()->setContextProperty( "roam", mRoam.c_str() );
|
||||
}
|
||||
|
||||
// Set mDuration
|
||||
void SetDuration( const std::string & duration )
|
||||
{
|
||||
cSampleCM::SetDuration( duration );
|
||||
|
||||
mView.rootContext()->setContextProperty( "duration", mDuration.c_str() );
|
||||
}
|
||||
|
||||
// Set mLifeDuration
|
||||
void SetLifeDuration( const std::string & lifeDuration )
|
||||
{
|
||||
cSampleCM::SetLifeDuration( lifeDuration );
|
||||
|
||||
mView.rootContext()->setContextProperty( "lifeDuration", mLifeDuration.c_str() );
|
||||
}
|
||||
|
||||
// Set mLifeRx
|
||||
void SetLifeRx( const std::string & lifeRx )
|
||||
{
|
||||
cSampleCM::SetLifeRx( lifeRx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "lifeRx", mLifeRx.c_str() );
|
||||
}
|
||||
|
||||
// Set mLifeTx
|
||||
void SetLifeTx( const std::string & lifeTx )
|
||||
{
|
||||
cSampleCM::SetLifeTx( lifeTx );
|
||||
|
||||
mView.rootContext()->setContextProperty( "lifeTx", mLifeTx.c_str() );
|
||||
}
|
||||
|
||||
// Set mManufact
|
||||
void SetManufact( const std::string & manufact )
|
||||
{
|
||||
cSampleCM::SetManufact( manufact );
|
||||
|
||||
mView.rootContext()->setContextProperty( "manufact", mManufact.c_str() );
|
||||
}
|
||||
|
||||
// Set mModel
|
||||
void SetModel( const std::string & model )
|
||||
{
|
||||
cSampleCM::SetModel( model );
|
||||
|
||||
// No more than 20 characters
|
||||
if (mModel.size() > 20)
|
||||
{
|
||||
mModel.resize( 20 );
|
||||
}
|
||||
|
||||
mView.rootContext()->setContextProperty( "model", mModel.c_str() );
|
||||
}
|
||||
|
||||
// Set mHardware
|
||||
void SetHardware( const std::string & hardware )
|
||||
{
|
||||
cSampleCM::SetHardware( hardware );
|
||||
|
||||
mView.rootContext()->setContextProperty( "hardware", mHardware.c_str() );
|
||||
}
|
||||
|
||||
// Set mFirmware
|
||||
void SetFirmware( const std::string & firmware )
|
||||
{
|
||||
cSampleCM::SetFirmware( firmware );
|
||||
|
||||
// No more than 20 characters
|
||||
if (mFirmware.size() > 20)
|
||||
{
|
||||
mFirmware.resize( 20 );
|
||||
}
|
||||
|
||||
mView.rootContext()->setContextProperty( "firmware", mFirmware.c_str() );
|
||||
}
|
||||
|
||||
// Set mMDN
|
||||
void SetMDN( const std::string & mdn )
|
||||
{
|
||||
cSampleCM::SetMDN( mdn );
|
||||
|
||||
mView.rootContext()->setContextProperty( "mdn", mMDN.c_str() );
|
||||
}
|
||||
|
||||
// Set mMIN
|
||||
void SetMIN( const std::string & min )
|
||||
{
|
||||
cSampleCM::SetMIN( min );
|
||||
|
||||
mView.rootContext()->setContextProperty( "min", mMIN.c_str() );
|
||||
}
|
||||
|
||||
// Set mESN
|
||||
void SetESN( const std::string & esn )
|
||||
{
|
||||
cSampleCM::SetESN( esn );
|
||||
|
||||
mView.rootContext()->setContextProperty( "esn", mESN.c_str() );
|
||||
}
|
||||
|
||||
// Set mMEID
|
||||
void SetMEID( const std::string & meid )
|
||||
{
|
||||
cSampleCM::SetMEID( meid );
|
||||
|
||||
mView.rootContext()->setContextProperty( "meid", mMEID.c_str() );
|
||||
}
|
||||
|
||||
// Set mIMEI
|
||||
void SetIMEI( const std::string & imei )
|
||||
{
|
||||
cSampleCM::SetIMEI( imei );
|
||||
|
||||
mView.rootContext()->setContextProperty( "imei", mIMEI.c_str() );
|
||||
}
|
||||
|
||||
// Set mIMSI
|
||||
void SetIMSI( const std::string & imsi )
|
||||
{
|
||||
cSampleCM::SetIMSI( imsi );
|
||||
|
||||
mView.rootContext()->setContextProperty( "imsi", mIMSI.c_str() );
|
||||
}
|
||||
|
||||
// Set mConnectButtonText
|
||||
void SetConnectButtonText( const std::string & connectButtonText )
|
||||
{
|
||||
mConnectButtonText = connectButtonText;
|
||||
|
||||
mView.rootContext()->setContextProperty( "connectButtonText",
|
||||
connectButtonText.c_str() );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/* QApplication object */
|
||||
QApplication mApp;
|
||||
|
||||
/* QmlApplicationViewer object */
|
||||
QmlApplicationViewer mView;
|
||||
|
||||
/* APN text input field */
|
||||
cTextInput mAPNText;
|
||||
|
||||
/* Username text input field */
|
||||
cTextInput mUsernameText;
|
||||
|
||||
/* Password text input field */
|
||||
cTextInput mPasswordText;
|
||||
|
||||
/* "Connect" button's text */
|
||||
std::string mConnectButtonText;
|
||||
|
||||
/* "Connect" button */
|
||||
cButton mConnectButton;
|
||||
|
||||
/* "Info Stats" button */
|
||||
cButton mInfosButton;
|
||||
|
||||
/* "Connection Stats" button */
|
||||
cButton mConnectionsButton;
|
||||
|
||||
/* Async connection thread ID */
|
||||
pthread_t mAsyncConnectThreadID;
|
||||
|
||||
// Friend functions
|
||||
friend void * AsyncConnectThread( void * pData );
|
||||
friend QVariant OnInfosButton( cQTSampleCM * pCM );
|
||||
friend QVariant OnConnectionsButton( cQTSampleCM * pCM );
|
||||
friend QVariant OnConnectButton( cQTSampleCM * pCM );
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,398 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
SampleCM.h
|
||||
|
||||
DESCRIPTION:
|
||||
Generic class to act as Sample CM interface
|
||||
|
||||
PUBLIC CLASSES AND METHODS:
|
||||
cSampleCM
|
||||
Generic class to act as Sample CM interface
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pragmas
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "GobiCMDLL.h"
|
||||
#include "Event.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
|
||||
// Prototypes
|
||||
void * DeviceDetectionThread( void * pData );
|
||||
void * UpdateNetworkInfo( void * pData );
|
||||
|
||||
// A global pointer to the CM, used by the callbacks
|
||||
extern class cSampleCM * gpCM;
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cSampleCM
|
||||
/*=========================================================================*/
|
||||
class cSampleCM
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cSampleCM()
|
||||
: mDeviceID(),
|
||||
mSessionState( 0 ),
|
||||
mSessionID( 0xFFFFFFFF ),
|
||||
mInitialState( 0xFFFFFFFF ),
|
||||
mStartTime( 0 ),
|
||||
mPreviousRX( 0 ),
|
||||
mPreviousTX( 0 ),
|
||||
mTotalRX( 0 ),
|
||||
mTotalTX( 0 ),
|
||||
mLifeTotalRX( 0 ),
|
||||
mLifeTotalTX( 0 ),
|
||||
mCurrentDuration( 0 ),
|
||||
mTotalDuration( 0 ),
|
||||
mLifeTotalDuration( 0 ),
|
||||
mbInitiatedStartDataSession( false ),
|
||||
mbInitiatedStopDataSession( false ),
|
||||
mDataBearerTech( eQMIDataBearerTechnologies_Unknown ),
|
||||
mDeviceDetectionThreadID( 0 ),
|
||||
mUpdateNetworkInfoThreadID( 0 )
|
||||
{
|
||||
mDeviceDetectionStopPipe[READING] = -1;
|
||||
mDeviceDetectionStopPipe[WRITING] = -1;
|
||||
|
||||
// Create an ordered list of service preferences
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_CDMA1xEVDORevB );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_CDMA1xEVDORevA );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_CDMA1xEVDORev0 );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_CDMA );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_DCHSDPAPlus );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_HSDPAPlus );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_HSDPA );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_WCDMA );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_EGPRS );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_GPRS );
|
||||
mPreferredServices.push_back( eQMINASDataServiceCapabilities2_GSM );
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~cSampleCM();
|
||||
|
||||
// Initialize UI, begin waiting for devices
|
||||
virtual bool Init();
|
||||
|
||||
// Connect to a device and send initial callback registrations
|
||||
virtual ULONG Connect( LPCSTR pInterface );
|
||||
|
||||
// Disconnect from a device and set members as "Unknown"
|
||||
virtual ULONG Disconnect();
|
||||
|
||||
// Process a start data session request
|
||||
virtual ULONG OnStartDataSession( ULONG * pFailureCode );
|
||||
|
||||
// Process a cancel data session request
|
||||
virtual ULONG OnCancelDataSession();
|
||||
|
||||
// Process a stop data session request
|
||||
virtual ULONG OnStopDataSession();
|
||||
|
||||
// Set mState
|
||||
virtual void SetState( const std::string & state )
|
||||
{
|
||||
mState = state;
|
||||
}
|
||||
|
||||
// Set mRSSI
|
||||
virtual void SetRSSI( const std::string & rssi )
|
||||
{
|
||||
mRSSI = rssi;
|
||||
}
|
||||
|
||||
// Set mTech
|
||||
virtual void SetTech( const std::string & tech )
|
||||
{
|
||||
mTech = tech;
|
||||
}
|
||||
|
||||
// Set mRx
|
||||
virtual void SetRx( const std::string & rx )
|
||||
{
|
||||
mRx = rx;
|
||||
}
|
||||
|
||||
// Set mTx
|
||||
virtual void SetTx( const std::string & tx )
|
||||
{
|
||||
mTx = tx;
|
||||
}
|
||||
|
||||
// Set mMaxRx
|
||||
virtual void SetMaxRx( const std::string & maxRx )
|
||||
{
|
||||
mMaxRx = maxRx;
|
||||
}
|
||||
|
||||
// Set mMaxTx
|
||||
virtual void SetMaxTx( const std::string & maxTx )
|
||||
{
|
||||
mMaxTx = maxTx;
|
||||
}
|
||||
|
||||
// Set mRoam
|
||||
virtual void SetRoam( const std::string & roam )
|
||||
{
|
||||
mRoam = roam;
|
||||
}
|
||||
|
||||
// Set mDuration
|
||||
virtual void SetDuration( const std::string & duration )
|
||||
{
|
||||
mDuration = duration;
|
||||
}
|
||||
|
||||
// Set mLifeDuration
|
||||
virtual void SetLifeDuration( const std::string & lifeDuration )
|
||||
{
|
||||
mLifeDuration = lifeDuration;
|
||||
}
|
||||
|
||||
// Set mLifeRx
|
||||
virtual void SetLifeRx( const std::string & lifeRx )
|
||||
{
|
||||
mLifeRx = lifeRx;
|
||||
}
|
||||
|
||||
// Set mLifeTx
|
||||
virtual void SetLifeTx( const std::string & lifeTx )
|
||||
{
|
||||
mLifeTx = lifeTx;
|
||||
}
|
||||
|
||||
// Set mManufact
|
||||
virtual void SetManufact( const std::string & manufact )
|
||||
{
|
||||
mManufact = manufact;
|
||||
}
|
||||
|
||||
// Set mModel
|
||||
virtual void SetModel( const std::string & model )
|
||||
{
|
||||
mModel = model;
|
||||
}
|
||||
|
||||
// Set mHardware
|
||||
virtual void SetHardware( const std::string & hardware )
|
||||
{
|
||||
mHardware = hardware;
|
||||
}
|
||||
|
||||
// Set mFirmware
|
||||
virtual void SetFirmware( const std::string & firmware )
|
||||
{
|
||||
mFirmware = firmware;
|
||||
}
|
||||
|
||||
// Set mMDN
|
||||
virtual void SetMDN( const std::string & mdn )
|
||||
{
|
||||
mMDN = mdn;
|
||||
}
|
||||
|
||||
// Set mMIN
|
||||
virtual void SetMIN( const std::string & min )
|
||||
{
|
||||
mMIN = min;
|
||||
}
|
||||
|
||||
// Set mESN
|
||||
virtual void SetESN( const std::string & esn )
|
||||
{
|
||||
mESN = esn;
|
||||
}
|
||||
|
||||
// Set mMEID
|
||||
virtual void SetMEID( const std::string & meid )
|
||||
{
|
||||
mMEID = meid;
|
||||
}
|
||||
|
||||
// Set mIMEI
|
||||
virtual void SetIMEI( const std::string & imei )
|
||||
{
|
||||
mIMEI = imei;
|
||||
}
|
||||
|
||||
// Set mIMSI
|
||||
virtual void SetIMSI( const std::string & imsi )
|
||||
{
|
||||
mIMSI = imsi;
|
||||
}
|
||||
|
||||
// Handle signal strength callback notification
|
||||
void OnSignalStrengthCBNotificaion(
|
||||
INT8 signalStr,
|
||||
ULONG radioInterface );
|
||||
|
||||
// Handle session state callback notification
|
||||
void OnSessionStateCBNotification( ULONG state );
|
||||
|
||||
// Handle data bearer callback notification
|
||||
void OnDataBearerCBNotification( ULONG dataBearerTech );
|
||||
|
||||
// Handle data capabilities callback notification
|
||||
void OnDataCapsNotification(
|
||||
ULONG numDataCaps,
|
||||
eQMINASDataServiceCapabilities2 * pDataCaps );
|
||||
|
||||
// Handle byte totals callback notification
|
||||
void OnByteTotalsNotification( ULONGLONG rx, ULONGLONG tx );
|
||||
|
||||
// Update the signal strength and technology
|
||||
void UpdateSignalAndTech();
|
||||
|
||||
// Update the session state
|
||||
void UpdateSessionState(
|
||||
bool bExternal,
|
||||
ULONG state );
|
||||
|
||||
// Calculate and update the connection time being displayed
|
||||
void UpdateTimeDisplay();
|
||||
|
||||
// Calculate and update the tx and rx rates being displayed
|
||||
void UpdateRateDisplay();
|
||||
|
||||
// Check data bearer and duration, which are only available while
|
||||
// connected
|
||||
void CheckConnectedStats();
|
||||
|
||||
// Update the device info stats
|
||||
void UpdateDeviceInfo();
|
||||
|
||||
// Update the Connection Stats
|
||||
void UpdateConnectionInfo();
|
||||
|
||||
protected:
|
||||
|
||||
/* Class for interfacing with Gobi API */
|
||||
cGobiCMDLL mGobi;
|
||||
|
||||
/* Connected device's ID */
|
||||
std::string mDeviceID;
|
||||
|
||||
/* All the display elements */
|
||||
std::string mState;
|
||||
std::string mRSSI;
|
||||
std::string mTech;
|
||||
std::string mRx;
|
||||
std::string mTx;
|
||||
std::string mMaxRx;
|
||||
std::string mMaxTx;
|
||||
std::string mRoam;
|
||||
std::string mDuration;
|
||||
std::string mLifeDuration;
|
||||
std::string mLifeRx;
|
||||
std::string mLifeTx;
|
||||
std::string mManufact;
|
||||
std::string mModel;
|
||||
std::string mHardware;
|
||||
std::string mFirmware;
|
||||
std::string mMDN;
|
||||
std::string mMIN;
|
||||
std::string mESN;
|
||||
std::string mMEID;
|
||||
std::string mIMEI;
|
||||
std::string mIMSI;
|
||||
|
||||
/* All the input elements */
|
||||
std::string mAPN;
|
||||
std::string mUsername;
|
||||
std::string mPassword;
|
||||
|
||||
/* Session state */
|
||||
ULONG mSessionState;
|
||||
|
||||
/* Data session ID */
|
||||
ULONG mSessionID;
|
||||
|
||||
/* Initial state, used to determine if the connection
|
||||
was initiated internally or externally */
|
||||
ULONG mInitialState;
|
||||
|
||||
/* Preferred service order */
|
||||
std::list <ULONG> mPreferredServices;
|
||||
|
||||
/* Stores the time that connection was started */
|
||||
ULONGLONG mStartTime;
|
||||
|
||||
/* Stores the connection rates updated by callbacks */
|
||||
ULONGLONG mPreviousRX;
|
||||
ULONGLONG mPreviousTX;
|
||||
ULONGLONG mTotalRX;
|
||||
ULONGLONG mTotalTX;
|
||||
ULONGLONG mLifeTotalRX;
|
||||
ULONGLONG mLifeTotalTX;
|
||||
|
||||
// Current and total durations
|
||||
ULONGLONG mCurrentDuration;
|
||||
ULONGLONG mTotalDuration;
|
||||
ULONGLONG mLifeTotalDuration;
|
||||
|
||||
/* Did we initiate a start data session? */
|
||||
bool mbInitiatedStartDataSession;
|
||||
|
||||
/* Did we initiate a stop data session? */
|
||||
bool mbInitiatedStopDataSession;
|
||||
|
||||
/* Current signal map */
|
||||
std::map <ULONG, INT8> mServiceSignals;
|
||||
|
||||
/* Current data bearer technology */
|
||||
ULONG mDataBearerTech;
|
||||
|
||||
/* Current data capabilities */
|
||||
std::list <ULONG> mDataCapabilities;
|
||||
|
||||
/* Handle to the device detection thread */
|
||||
pthread_t mDeviceDetectionThreadID;
|
||||
int mDeviceDetectionStopPipe[2];
|
||||
|
||||
// Device detection "thread"
|
||||
friend void * DeviceDetectionThread( void * pData );
|
||||
|
||||
/* Handle to the UpdateNetworkInfo thread */
|
||||
pthread_t mUpdateNetworkInfoThreadID;
|
||||
cEvent mUpdateNetworkInfoEvent;
|
||||
|
||||
// Async Network info updater
|
||||
friend void * UpdateNetworkInfoThread( void * pData );
|
||||
};
|
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
|
@ -0,0 +1,823 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
main.qml
|
||||
|
||||
DESCRIPTION:
|
||||
Graphic meta description for Gobi Sample CM
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
import QtQuick 1.0
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: mainWindow
|
||||
width: 360
|
||||
height: 360
|
||||
color: "#000000"
|
||||
state: windowState
|
||||
|
||||
// This window is not stretched to fullscreen
|
||||
// which is what we want to demonstrate for now
|
||||
Rectangle
|
||||
{
|
||||
width: 360
|
||||
height: 360
|
||||
color: "#ffffff"
|
||||
|
||||
// The box on the left hand side of the screen
|
||||
Rectangle
|
||||
{
|
||||
x: 15
|
||||
y: 15
|
||||
width: 80
|
||||
height: 330
|
||||
color: "#ffffff"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
border.width: 2
|
||||
border.color: "#000000"
|
||||
|
||||
// The connection stats button
|
||||
Rectangle
|
||||
{
|
||||
id: connectIcon
|
||||
width: 60
|
||||
height: 70
|
||||
color: "#ffffff"
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Image
|
||||
{
|
||||
width: 50
|
||||
height: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
source: "Connect.png"
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: "Connection"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 5
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 9
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: connectionsButtonArea
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
connectionsButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The info stats button
|
||||
Rectangle
|
||||
{
|
||||
id: infoIcon
|
||||
x: 10
|
||||
y: 90
|
||||
width: 60
|
||||
height: 70
|
||||
color: "#ffffff"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Image
|
||||
{
|
||||
width: 50
|
||||
height: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
source: "Info.png"
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: "Information"
|
||||
font.pixelSize: 9
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 5
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: infosButtonArea
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
infosButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The "connect" button
|
||||
Rectangle
|
||||
{
|
||||
id: connectionButtonID
|
||||
x: 240
|
||||
y: 10
|
||||
width: 100
|
||||
height: 30
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
Text
|
||||
{
|
||||
text: connectButtonText
|
||||
font.pixelSize: 16
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
connectButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map a property ID to its human readable text
|
||||
function getName( propID )
|
||||
{
|
||||
if (propID == "status")
|
||||
{
|
||||
return "State"
|
||||
}
|
||||
|
||||
if (propID == "rssi")
|
||||
{
|
||||
return "RSSI (db)"
|
||||
}
|
||||
|
||||
if (propID == "tech")
|
||||
{
|
||||
return "Technology"
|
||||
}
|
||||
|
||||
if (propID == "rx")
|
||||
{
|
||||
return "Current RX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "tx")
|
||||
{
|
||||
return "Current TX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "maxRx")
|
||||
{
|
||||
return "Maximum RX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "maxTx")
|
||||
{
|
||||
return "Maximum TX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "roam")
|
||||
{
|
||||
return "Roaming Indicator"
|
||||
}
|
||||
|
||||
if (propID == "duration")
|
||||
{
|
||||
return "Connection Duration"
|
||||
}
|
||||
|
||||
if (propID == "lifeDuration")
|
||||
{
|
||||
return "Life Total Connection Duration"
|
||||
}
|
||||
|
||||
if (propID == "lifeRx")
|
||||
{
|
||||
return "Life Total RX Bytes"
|
||||
}
|
||||
|
||||
if (propID == "lifeTx")
|
||||
{
|
||||
return "Life Total TX Bytes"
|
||||
}
|
||||
|
||||
if (propID == "manufact")
|
||||
{
|
||||
return "Manufacturer"
|
||||
}
|
||||
|
||||
if (propID == "model")
|
||||
{
|
||||
return "Model ID"
|
||||
}
|
||||
|
||||
if (propID == "hardware")
|
||||
{
|
||||
return "Hardware Revision"
|
||||
}
|
||||
|
||||
if (propID == "firmware")
|
||||
{
|
||||
return "Firmware Revision"
|
||||
}
|
||||
|
||||
if (propID == "mdn")
|
||||
{
|
||||
return "MDN"
|
||||
}
|
||||
|
||||
if (propID == "min")
|
||||
{
|
||||
return "MIN"
|
||||
}
|
||||
|
||||
if (propID == "esn")
|
||||
{
|
||||
return "ESN"
|
||||
}
|
||||
|
||||
if (propID == "meid")
|
||||
{
|
||||
return "MEID"
|
||||
}
|
||||
|
||||
if (propID == "imei")
|
||||
{
|
||||
return "IMEI"
|
||||
}
|
||||
|
||||
if (propID == "imsi")
|
||||
{
|
||||
return "IMSI"
|
||||
}
|
||||
|
||||
return "Bad PropID"
|
||||
}
|
||||
|
||||
// Map a property ID to its variable
|
||||
function getValue( propID )
|
||||
{
|
||||
if (propID == "status")
|
||||
{
|
||||
return status
|
||||
}
|
||||
|
||||
if (propID == "rssi")
|
||||
{
|
||||
return rssi
|
||||
}
|
||||
|
||||
if (propID == "tech")
|
||||
{
|
||||
return tech
|
||||
}
|
||||
|
||||
if (propID == "rx")
|
||||
{
|
||||
return rx
|
||||
}
|
||||
|
||||
if (propID == "tx")
|
||||
{
|
||||
return tx
|
||||
}
|
||||
|
||||
if (propID == "maxRx")
|
||||
{
|
||||
return maxRx
|
||||
}
|
||||
|
||||
if (propID == "maxTx")
|
||||
{
|
||||
return maxTx
|
||||
}
|
||||
|
||||
if (propID == "roam")
|
||||
{
|
||||
return roam
|
||||
}
|
||||
|
||||
if (propID == "duration")
|
||||
{
|
||||
return duration
|
||||
}
|
||||
|
||||
if (propID == "lifeDuration")
|
||||
{
|
||||
return lifeDuration
|
||||
}
|
||||
|
||||
if (propID == "lifeRx")
|
||||
{
|
||||
return lifeRx
|
||||
}
|
||||
|
||||
if (propID == "lifeTx")
|
||||
{
|
||||
return lifeTx
|
||||
}
|
||||
|
||||
if (propID == "manufact")
|
||||
{
|
||||
return manufact
|
||||
}
|
||||
|
||||
if (propID == "model")
|
||||
{
|
||||
return model
|
||||
}
|
||||
|
||||
if (propID == "hardware")
|
||||
{
|
||||
return hardware
|
||||
}
|
||||
|
||||
if (propID == "firmware")
|
||||
{
|
||||
return firmware
|
||||
}
|
||||
|
||||
if (propID == "mdn")
|
||||
{
|
||||
return mdn
|
||||
}
|
||||
|
||||
if (propID == "min")
|
||||
{
|
||||
return min
|
||||
}
|
||||
|
||||
if (propID == "esn")
|
||||
{
|
||||
return esn
|
||||
}
|
||||
|
||||
if (propID == "meid")
|
||||
{
|
||||
return meid
|
||||
}
|
||||
|
||||
if (propID == "imei")
|
||||
{
|
||||
return imei
|
||||
}
|
||||
|
||||
if (propID == "imsi")
|
||||
{
|
||||
return imsi
|
||||
}
|
||||
|
||||
return "Bad PropID"
|
||||
}
|
||||
|
||||
// Connection statistics list
|
||||
Rectangle
|
||||
{
|
||||
id: connectionStatistics
|
||||
x: 110
|
||||
y: 50
|
||||
width: 230
|
||||
height: 180
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
delegate: Item
|
||||
{
|
||||
x: 5
|
||||
height: 15
|
||||
Row
|
||||
{
|
||||
id: connectionStatistic
|
||||
spacing: 10
|
||||
|
||||
// PropID is a unique identification string
|
||||
// used to generate a human readable string and
|
||||
// link to variable
|
||||
property string propID: "unknown"
|
||||
|
||||
Text
|
||||
{
|
||||
text: getName( propID )
|
||||
width: 150
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: getValue( propID )
|
||||
width: 80
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: ListModel
|
||||
{
|
||||
id: connectionStats
|
||||
ListElement { propID: "status" }
|
||||
ListElement { propID: "rssi" }
|
||||
ListElement { propID: "tech" }
|
||||
ListElement { propID: "rx" }
|
||||
ListElement { propID: "tx" }
|
||||
ListElement { propID: "maxRx" }
|
||||
ListElement { propID: "maxTx" }
|
||||
ListElement { propID: "roam" }
|
||||
ListElement { propID: "duration" }
|
||||
ListElement { propID: "lifeDuration" }
|
||||
ListElement { propID: "lifeRx" }
|
||||
ListElement { propID: "lifeTx" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Info statistics list
|
||||
Rectangle
|
||||
{
|
||||
id: infos
|
||||
x: 110
|
||||
y: 50
|
||||
width: 230
|
||||
height: 180
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
visible: false
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
delegate: Item
|
||||
{
|
||||
x: 5
|
||||
height: 15
|
||||
Row
|
||||
{
|
||||
id: info
|
||||
spacing: 10
|
||||
|
||||
// PropID is a unique identification string
|
||||
// used to generate a human readable string and
|
||||
// link to variable
|
||||
property string propID: "unknown"
|
||||
|
||||
Text
|
||||
{
|
||||
text: getName( propID )
|
||||
width: 100
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: getValue( propID )
|
||||
width: 120
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: ListModel
|
||||
{
|
||||
ListElement { propID: "manufact" }
|
||||
ListElement { propID: "model" }
|
||||
ListElement { propID: "hardware" }
|
||||
ListElement { propID: "firmware" }
|
||||
ListElement { propID: "mdn" }
|
||||
ListElement { propID: "min" }
|
||||
ListElement { propID: "esn" }
|
||||
ListElement { propID: "meid" }
|
||||
ListElement { propID: "imei" }
|
||||
ListElement { propID: "imsi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The close button
|
||||
Rectangle
|
||||
{
|
||||
x: 280
|
||||
y: 315
|
||||
width: 60
|
||||
height: 30
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
Text
|
||||
{
|
||||
anchors.fill: parent
|
||||
text: "Close"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 16
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
Qt.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: apnTextID
|
||||
x: 110
|
||||
y: 246
|
||||
width: 73
|
||||
height: 20
|
||||
text: "APN"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: usernameTextID
|
||||
x: 110
|
||||
y: 266
|
||||
width: 73
|
||||
height: 20
|
||||
text: "Username"
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: passwordTextID
|
||||
x: 110
|
||||
y: 286
|
||||
width: 73
|
||||
height: 20
|
||||
text: "Password"
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
// The APN text box
|
||||
Rectangle
|
||||
{
|
||||
id: apnTextBoxID
|
||||
x: 190
|
||||
y: 246
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.width: 2
|
||||
border.color: "#000000"
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: apnName
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: apnNameText
|
||||
property: "text"
|
||||
value: apnName.text
|
||||
}
|
||||
}
|
||||
|
||||
// The Username text box
|
||||
Rectangle
|
||||
{
|
||||
id: usernameTextBoxID
|
||||
x: 190
|
||||
y: 266
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: username
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: usernameText
|
||||
property: "text"
|
||||
value: username.text
|
||||
}
|
||||
}
|
||||
|
||||
// Password text box
|
||||
Rectangle
|
||||
{
|
||||
id: passwordTextBoxID
|
||||
x: 190
|
||||
y: 286
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: password
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: passwordText
|
||||
property: "text"
|
||||
value: password.text
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog window to be shown
|
||||
Rectangle
|
||||
{
|
||||
id: connectingDialog
|
||||
x: 55
|
||||
y: 105
|
||||
width: 250
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
z: 1
|
||||
visible: false
|
||||
|
||||
Text
|
||||
{
|
||||
id: connectingDialogText
|
||||
text: dialogText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
// State transitions
|
||||
states:
|
||||
[
|
||||
// Info state, shown when info button is clicked
|
||||
State
|
||||
{
|
||||
name: "infos"
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionButtonID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: apnTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: usernameTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: passwordTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: apnTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: usernameTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: passwordTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionStatistics
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: infos
|
||||
visible: true
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectingDialog
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
|
||||
// Connecting Dialog state, shown when connecting
|
||||
State
|
||||
{
|
||||
name: "connectingDialog"
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectingDialog
|
||||
visible: true
|
||||
}
|
||||
|
||||
// Disable the "info stats" button while the connection dialog is up
|
||||
PropertyChanges
|
||||
{
|
||||
target: infosButtonArea
|
||||
visible: false
|
||||
}
|
||||
|
||||
// Disable the "connection stats" button while the connection
|
||||
// dialog is up
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionsButtonArea
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 418 KiB |
|
@ -0,0 +1,45 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
main.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
Entry point to the Gobi Sample CM
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
#include "QTSampleCM.h"
|
||||
|
||||
Q_DECL_EXPORT int main( int argc, char ** argv )
|
||||
{
|
||||
cQTSampleCM cm( argc, argv );
|
||||
cm.Init();
|
||||
|
||||
// This function blocks until the app closes
|
||||
return cm.Run();
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
|
@ -0,0 +1,823 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
main.qml
|
||||
|
||||
DESCRIPTION:
|
||||
Graphic meta description for Gobi Sample CM
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
===========================================================================*/
|
||||
|
||||
import QtQuick 1.0
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: mainWindow
|
||||
width: 360
|
||||
height: 360
|
||||
color: "#000000"
|
||||
state: windowState
|
||||
|
||||
// This window is not stretched to fullscreen
|
||||
// which is what we want to demonstrate for now
|
||||
Rectangle
|
||||
{
|
||||
width: 360
|
||||
height: 360
|
||||
color: "#ffffff"
|
||||
|
||||
// The box on the left hand side of the screen
|
||||
Rectangle
|
||||
{
|
||||
x: 15
|
||||
y: 15
|
||||
width: 80
|
||||
height: 330
|
||||
color: "#ffffff"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
border.width: 2
|
||||
border.color: "#000000"
|
||||
|
||||
// The connection stats button
|
||||
Rectangle
|
||||
{
|
||||
id: connectIcon
|
||||
width: 60
|
||||
height: 70
|
||||
color: "#ffffff"
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Image
|
||||
{
|
||||
width: 50
|
||||
height: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
source: "Connect.png"
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: "Connection"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 5
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 9
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: connectionsButtonArea
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
connectionsButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The info stats button
|
||||
Rectangle
|
||||
{
|
||||
id: infoIcon
|
||||
x: 10
|
||||
y: 90
|
||||
width: 60
|
||||
height: 70
|
||||
color: "#ffffff"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Image
|
||||
{
|
||||
width: 50
|
||||
height: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
source: "Info.png"
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: "Information"
|
||||
font.pixelSize: 9
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 5
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: infosButtonArea
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
infosButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The "connect" button
|
||||
Rectangle
|
||||
{
|
||||
id: connectionButtonID
|
||||
x: 240
|
||||
y: 10
|
||||
width: 100
|
||||
height: 30
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
Text
|
||||
{
|
||||
text: connectButtonText
|
||||
font.pixelSize: 16
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
connectButton.Click()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map a property ID to its human readable text
|
||||
function getName( propID )
|
||||
{
|
||||
if (propID == "status")
|
||||
{
|
||||
return "State"
|
||||
}
|
||||
|
||||
if (propID == "rssi")
|
||||
{
|
||||
return "RSSI (db)"
|
||||
}
|
||||
|
||||
if (propID == "tech")
|
||||
{
|
||||
return "Technology"
|
||||
}
|
||||
|
||||
if (propID == "rx")
|
||||
{
|
||||
return "Current RX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "tx")
|
||||
{
|
||||
return "Current TX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "maxRx")
|
||||
{
|
||||
return "Maximum RX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "maxTx")
|
||||
{
|
||||
return "Maximum TX Rate (bps)"
|
||||
}
|
||||
|
||||
if (propID == "roam")
|
||||
{
|
||||
return "Roaming Indicator"
|
||||
}
|
||||
|
||||
if (propID == "duration")
|
||||
{
|
||||
return "Connection Duration"
|
||||
}
|
||||
|
||||
if (propID == "lifeDuration")
|
||||
{
|
||||
return "Life Total Connection Duration"
|
||||
}
|
||||
|
||||
if (propID == "lifeRx")
|
||||
{
|
||||
return "Life Total RX Bytes"
|
||||
}
|
||||
|
||||
if (propID == "lifeTx")
|
||||
{
|
||||
return "Life Total TX Bytes"
|
||||
}
|
||||
|
||||
if (propID == "manufact")
|
||||
{
|
||||
return "Manufacturer"
|
||||
}
|
||||
|
||||
if (propID == "model")
|
||||
{
|
||||
return "Model ID"
|
||||
}
|
||||
|
||||
if (propID == "hardware")
|
||||
{
|
||||
return "Hardware Revision"
|
||||
}
|
||||
|
||||
if (propID == "firmware")
|
||||
{
|
||||
return "Firmware Revision"
|
||||
}
|
||||
|
||||
if (propID == "mdn")
|
||||
{
|
||||
return "MDN"
|
||||
}
|
||||
|
||||
if (propID == "min")
|
||||
{
|
||||
return "MIN"
|
||||
}
|
||||
|
||||
if (propID == "esn")
|
||||
{
|
||||
return "ESN"
|
||||
}
|
||||
|
||||
if (propID == "meid")
|
||||
{
|
||||
return "MEID"
|
||||
}
|
||||
|
||||
if (propID == "imei")
|
||||
{
|
||||
return "IMEI"
|
||||
}
|
||||
|
||||
if (propID == "imsi")
|
||||
{
|
||||
return "IMSI"
|
||||
}
|
||||
|
||||
return "Bad PropID"
|
||||
}
|
||||
|
||||
// Map a property ID to its variable
|
||||
function getValue( propID )
|
||||
{
|
||||
if (propID == "status")
|
||||
{
|
||||
return status
|
||||
}
|
||||
|
||||
if (propID == "rssi")
|
||||
{
|
||||
return rssi
|
||||
}
|
||||
|
||||
if (propID == "tech")
|
||||
{
|
||||
return tech
|
||||
}
|
||||
|
||||
if (propID == "rx")
|
||||
{
|
||||
return rx
|
||||
}
|
||||
|
||||
if (propID == "tx")
|
||||
{
|
||||
return tx
|
||||
}
|
||||
|
||||
if (propID == "maxRx")
|
||||
{
|
||||
return maxRx
|
||||
}
|
||||
|
||||
if (propID == "maxTx")
|
||||
{
|
||||
return maxTx
|
||||
}
|
||||
|
||||
if (propID == "roam")
|
||||
{
|
||||
return roam
|
||||
}
|
||||
|
||||
if (propID == "duration")
|
||||
{
|
||||
return duration
|
||||
}
|
||||
|
||||
if (propID == "lifeDuration")
|
||||
{
|
||||
return lifeDuration
|
||||
}
|
||||
|
||||
if (propID == "lifeRx")
|
||||
{
|
||||
return lifeRx
|
||||
}
|
||||
|
||||
if (propID == "lifeTx")
|
||||
{
|
||||
return lifeTx
|
||||
}
|
||||
|
||||
if (propID == "manufact")
|
||||
{
|
||||
return manufact
|
||||
}
|
||||
|
||||
if (propID == "model")
|
||||
{
|
||||
return model
|
||||
}
|
||||
|
||||
if (propID == "hardware")
|
||||
{
|
||||
return hardware
|
||||
}
|
||||
|
||||
if (propID == "firmware")
|
||||
{
|
||||
return firmware
|
||||
}
|
||||
|
||||
if (propID == "mdn")
|
||||
{
|
||||
return mdn
|
||||
}
|
||||
|
||||
if (propID == "min")
|
||||
{
|
||||
return min
|
||||
}
|
||||
|
||||
if (propID == "esn")
|
||||
{
|
||||
return esn
|
||||
}
|
||||
|
||||
if (propID == "meid")
|
||||
{
|
||||
return meid
|
||||
}
|
||||
|
||||
if (propID == "imei")
|
||||
{
|
||||
return imei
|
||||
}
|
||||
|
||||
if (propID == "imsi")
|
||||
{
|
||||
return imsi
|
||||
}
|
||||
|
||||
return "Bad PropID"
|
||||
}
|
||||
|
||||
// Connection statistics list
|
||||
Rectangle
|
||||
{
|
||||
id: connectionStatistics
|
||||
x: 110
|
||||
y: 50
|
||||
width: 230
|
||||
height: 180
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
delegate: Item
|
||||
{
|
||||
x: 5
|
||||
height: 15
|
||||
Row
|
||||
{
|
||||
id: connectionStatistic
|
||||
spacing: 10
|
||||
|
||||
// PropID is a unique identification string
|
||||
// used to generate a human readable string and
|
||||
// link to variable
|
||||
property string propID: "unknown"
|
||||
|
||||
Text
|
||||
{
|
||||
text: getName( propID )
|
||||
width: 150
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: getValue( propID )
|
||||
width: 80
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: ListModel
|
||||
{
|
||||
id: connectionStats
|
||||
ListElement { propID: "status" }
|
||||
ListElement { propID: "rssi" }
|
||||
ListElement { propID: "tech" }
|
||||
ListElement { propID: "rx" }
|
||||
ListElement { propID: "tx" }
|
||||
ListElement { propID: "maxRx" }
|
||||
ListElement { propID: "maxTx" }
|
||||
ListElement { propID: "roam" }
|
||||
ListElement { propID: "duration" }
|
||||
ListElement { propID: "lifeDuration" }
|
||||
ListElement { propID: "lifeRx" }
|
||||
ListElement { propID: "lifeTx" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Info statistics list
|
||||
Rectangle
|
||||
{
|
||||
id: infos
|
||||
x: 110
|
||||
y: 50
|
||||
width: 230
|
||||
height: 180
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
visible: false
|
||||
|
||||
ListView
|
||||
{
|
||||
anchors.fill: parent
|
||||
delegate: Item
|
||||
{
|
||||
x: 5
|
||||
height: 15
|
||||
Row
|
||||
{
|
||||
id: info
|
||||
spacing: 10
|
||||
|
||||
// PropID is a unique identification string
|
||||
// used to generate a human readable string and
|
||||
// link to variable
|
||||
property string propID: "unknown"
|
||||
|
||||
Text
|
||||
{
|
||||
text: getName( propID )
|
||||
width: 100
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
text: getValue( propID )
|
||||
width: 120
|
||||
font.pixelSize: 10
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: ListModel
|
||||
{
|
||||
ListElement { propID: "manufact" }
|
||||
ListElement { propID: "model" }
|
||||
ListElement { propID: "hardware" }
|
||||
ListElement { propID: "firmware" }
|
||||
ListElement { propID: "mdn" }
|
||||
ListElement { propID: "min" }
|
||||
ListElement { propID: "esn" }
|
||||
ListElement { propID: "meid" }
|
||||
ListElement { propID: "imei" }
|
||||
ListElement { propID: "imsi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The close button
|
||||
Rectangle
|
||||
{
|
||||
x: 280
|
||||
y: 315
|
||||
width: 60
|
||||
height: 30
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
Text
|
||||
{
|
||||
anchors.fill: parent
|
||||
text: "Close"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 16
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
Qt.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: apnTextID
|
||||
x: 110
|
||||
y: 246
|
||||
width: 73
|
||||
height: 20
|
||||
text: "APN"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: usernameTextID
|
||||
x: 110
|
||||
y: 266
|
||||
width: 73
|
||||
height: 20
|
||||
text: "Username"
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: passwordTextID
|
||||
x: 110
|
||||
y: 286
|
||||
width: 73
|
||||
height: 20
|
||||
text: "Password"
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
// The APN text box
|
||||
Rectangle
|
||||
{
|
||||
id: apnTextBoxID
|
||||
x: 190
|
||||
y: 246
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.width: 2
|
||||
border.color: "#000000"
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: apnName
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: apnNameText
|
||||
property: "text"
|
||||
value: apnName.text
|
||||
}
|
||||
}
|
||||
|
||||
// The Username text box
|
||||
Rectangle
|
||||
{
|
||||
id: usernameTextBoxID
|
||||
x: 190
|
||||
y: 266
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: username
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: usernameText
|
||||
property: "text"
|
||||
value: username.text
|
||||
}
|
||||
}
|
||||
|
||||
// Password text box
|
||||
Rectangle
|
||||
{
|
||||
id: passwordTextBoxID
|
||||
x: 190
|
||||
y: 286
|
||||
width: 150
|
||||
height: 20
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
|
||||
TextInput
|
||||
{
|
||||
anchors.fill: parent
|
||||
id: password
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: passwordText
|
||||
property: "text"
|
||||
value: password.text
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog window to be shown
|
||||
Rectangle
|
||||
{
|
||||
id: connectingDialog
|
||||
x: 55
|
||||
y: 105
|
||||
width: 250
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
border.color: "#000000"
|
||||
border.width: 2
|
||||
z: 1
|
||||
visible: false
|
||||
|
||||
Text
|
||||
{
|
||||
id: connectingDialogText
|
||||
text: dialogText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
// State transitions
|
||||
states:
|
||||
[
|
||||
// Info state, shown when info button is clicked
|
||||
State
|
||||
{
|
||||
name: "infos"
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionButtonID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: apnTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: usernameTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: passwordTextID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: apnTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: usernameTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: passwordTextBoxID
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionStatistics
|
||||
visible: false
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: infos
|
||||
visible: true
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectingDialog
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
|
||||
// Connecting Dialog state, shown when connecting
|
||||
State
|
||||
{
|
||||
name: "connectingDialog"
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectingDialog
|
||||
visible: true
|
||||
}
|
||||
|
||||
// Disable the "info stats" button while the connection dialog is up
|
||||
PropertyChanges
|
||||
{
|
||||
target: infosButtonArea
|
||||
visible: false
|
||||
}
|
||||
|
||||
// Disable the "connection stats" button while the connection
|
||||
// dialog is up
|
||||
PropertyChanges
|
||||
{
|
||||
target: connectionsButtonArea
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
Gobi Extensible API 2012-09-12-0719
|
||||
|
||||
This readme covers important information concerning
|
||||
the Gobi Extensible API.
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. What's new in this release
|
||||
2. Known issues
|
||||
3. Build steps
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
1. WHAT'S NEW
|
||||
|
||||
This Release (Gobi Extensible API 2012-09-12-0719)
|
||||
a. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. C (80-VB816-21)
|
||||
CAT ICD Rev. L (80-VB816-11)
|
||||
DMS ICD Rev. N (80-VB816-4)
|
||||
LOC ICD Rev. G (80-VB816-17)
|
||||
NAS ICD Rev. YC (80-VB816-6)
|
||||
PBM ICD Rev. K (80-VB816-15)
|
||||
PDC ICD Rev. A (80-VB816-38)
|
||||
PDS ICD Rev. N (80-VB816-8)
|
||||
UIM ICD Rev. Y (80-VB816-12)
|
||||
Voice ICD Rev. M (80-VB816-10)
|
||||
WDS ICD Rev. YC (80-VB816-5)
|
||||
WMS ICD Rev. K (80-VB816-9)
|
||||
Addendum ICD Rev. C (80-VK268-3)
|
||||
|
||||
Prior Release (Gobi Extensible API 2012-08-23-0740)
|
||||
a. Updated reference platform to Nexus 7 tablet, kernel 3.1.10
|
||||
b. Updated icons in GobiSampleCM
|
||||
c. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. C (80-VB816-21)
|
||||
CAT ICD Rev. L (80-VB816-11)
|
||||
DMS ICD Rev. N (80-VB816-4)
|
||||
LOC ICD Rev. F (80-VB816-17)
|
||||
NAS ICD Rev. YC (80-VB816-6)
|
||||
PBM ICD Rev. J (80-VB816-15)
|
||||
PDC ICD Rev. A (80-VB816-38)
|
||||
PDS ICD Rev. N (80-VB816-8)
|
||||
UIM ICD Rev. Y (80-VB816-12)
|
||||
Voice ICD Rev. M (80-VB816-10)
|
||||
WDS ICD Rev. YB (80-VB816-5)
|
||||
WMS ICD Rev. K (80-VB816-9)
|
||||
Addendum ICD Rev. C (80-VK268-3)
|
||||
|
||||
Prior Release (Gobi Extensible API 2012-08-08-1042)
|
||||
a. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. C (80-VB816-21)
|
||||
CAT ICD Rev. L (80-VB816-11)
|
||||
DMS ICD Rev. N (80-VB816-4)
|
||||
LOC ICD Rev. F (80-VB816-17)
|
||||
NAS ICD Rev. YC (80-VB816-6)
|
||||
PBM ICD Rev. J (80-VB816-15)
|
||||
PDS ICD Rev. N (80-VB816-8)
|
||||
UIM ICD Rev. Y (80-VB816-12)
|
||||
Voice ICD Rev. M (80-VB816-10)
|
||||
WDS ICD Rev. YB (80-VB816-5)
|
||||
WMS ICD Rev. K (80-VB816-9)
|
||||
Addendum ICD Rev. C (80-VK268-3)
|
||||
|
||||
Prior Release (Gobi Extensible API 2012-07-12-1036)
|
||||
a. Cleanup correctly during Disconnect() to fix possible race condition
|
||||
which could cause future connections to have read timeouts.
|
||||
b. Add a device access qualifier for SMD connections, for example:
|
||||
"QMUXD:0" for the first SMD channel.
|
||||
c. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. C (80-VB816-21)
|
||||
CAT ICD Rev. L (80-VB816-11)
|
||||
DMS ICD Rev. N (80-VB816-4)
|
||||
LOC ICD Rev. F (80-VB816-17)
|
||||
NAS ICD Rev. YC (80-VB816-6)
|
||||
PBM ICD Rev. H (80-VB816-15)
|
||||
PDS ICD Rev. N (80-VB816-8)
|
||||
UIM ICD Rev. W (80-VB816-12)
|
||||
Voice ICD Rev. M (80-VB816-10)
|
||||
WDS ICD Rev. YB (80-VB816-5)
|
||||
WMS ICD Rev. H (80-VB816-9)
|
||||
Addendum ICD Rev. C (80-VK268-3)
|
||||
|
||||
Prior Release (Gobi Extensible API 2012-06-18-1054)
|
||||
a. Added support for SMD devices
|
||||
b. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. B (80-VB816-21)
|
||||
CAT ICD Rev. L (80-VB816-11)
|
||||
DMS ICD Rev. N (80-VB816-4)
|
||||
LOC ICD Rev. F (80-VB816-17)
|
||||
NAS ICD Rev. YA (80-VB816-6)
|
||||
PBM ICD Rev. H (80-VB816-15)
|
||||
PDS ICD Rev. N (80-VB816-8)
|
||||
UIM ICD Rev. V (80-VB816-12)
|
||||
Voice ICD Rev. L (80-VB816-10)
|
||||
WDS ICD Rev. YA (80-VB816-5)
|
||||
WMS ICD Rev. H (80-VB816-9)
|
||||
Addendum ICD Rev. C (80-VK268-3)
|
||||
|
||||
Prior Release (Gobi Extensible API 2012-01-12-1106)
|
||||
a. Addition of Gobi Sample CM (documentation is on QDevNet -
|
||||
the use of this me be subject to additional license terms)
|
||||
b. Updated API reflect the following QMI ICDs:
|
||||
AUTH ICD Rev. B (80-VB816-21)
|
||||
CAT ICD Rev. J (80-VB816-11)
|
||||
DMS ICD Rev. K (80-VB816-4)
|
||||
LOC ICD Rev. D (80-VB816-17)
|
||||
NAS ICD Rev. W (80-VB816-6)
|
||||
PBM ICD Rev. F (80-VB816-15)
|
||||
PDS 1 ICD Rev. J (80-VB816-8)
|
||||
PDS 2 ICD Rev. D (80-VB816-14)
|
||||
UIM ICD Rev. T (80-VB816-12)
|
||||
Voice ICD Rev. J (80-VB816-10)
|
||||
WDS ICD Rev. U (80-VB816-5)
|
||||
WMS ICD Rev. F (80-VB816-9)
|
||||
|
||||
Prior Release (Gobi Extensible API 2011-12-15-0819)
|
||||
a. Initial beta code release
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
2. KNOWN ISSUES
|
||||
|
||||
No known issues.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
3. BUILD STEPS
|
||||
|
||||
a. Start in the 'GobiConnectionMgmt' folder
|
||||
b. For Android, run:
|
||||
make Android ANDROID_PATH=<path to android toolchain>
|
||||
For x86, run:
|
||||
make
|
||||
|
||||
-------------------------------------------------------------------------------
|
|
@ -0,0 +1,137 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiError.h
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Gobi Errors
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
/*=========================================================================*/
|
||||
// Pragmas
|
||||
/*=========================================================================*/
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "QMIEnum.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*=========================================================================*/
|
||||
// eGobiError Enumeration
|
||||
// Gobi API Error Enumeration
|
||||
/*=========================================================================*/
|
||||
enum eGobiError
|
||||
{
|
||||
eGOBI_ERR_ENUM_BEGIN = -1,
|
||||
|
||||
eGOBI_ERR_NONE, // 00 Success
|
||||
eGOBI_ERR_GENERAL, // 01 General error
|
||||
eGOBI_ERR_INTERNAL, // 02 Internal error
|
||||
eGOBI_ERR_MEMORY, // 03 Memory error
|
||||
eGOBI_ERR_INVALID_ARG, // 04 Invalid argument
|
||||
eGOBI_ERR_BUFFER_SZ, // 05 Buffer too small
|
||||
eGOBI_ERR_NO_DEVICE, // 06 Unable to detect device
|
||||
eGOBI_ERR_INVALID_DEVID, // 07 Invalid device ID
|
||||
eGOBI_ERR_NO_CONNECTION, // 08 No connection to device
|
||||
eGOBI_ERR_IFACE, // 09 Unable to obtain required interace
|
||||
eGOBI_ERR_CONNECT, // 10 Unable to connect to interface
|
||||
eGOBI_ERR_REQ_SCHEDULE, // 11 Unable to schedule request
|
||||
eGOBI_ERR_REQUEST, // 12 Error sending request
|
||||
eGOBI_ERR_RESPONSE, // 13 Error receiving response
|
||||
eGOBI_ERR_REQUEST_TO, // 14 Timeout while sending request
|
||||
eGOBI_ERR_RESPONSE_TO, // 15 Timeout while receiving response
|
||||
eGOBI_ERR_MALFORMED_RSP, // 16 Malformed response received
|
||||
eGOBI_ERR_INVALID_RSP, // 17 Invalid/error response received
|
||||
eGOBI_ERR_INVALID_FILE, // 18 Invalid file path
|
||||
eGOBI_ERR_FILE_OPEN, // 19 Unable to open file
|
||||
eGOBI_ERR_FILE_COPY, // 20 Unable to copy file
|
||||
eGOBI_ERR_QDL_SCM, // 21 Unable to open service control mgr
|
||||
eGOBI_ERR_NO_QDL_SVC, // 22 Unable to detect QDL service
|
||||
eGOBI_ERR_NO_QDL_SVC_INFO, // 23 Unable to obtain QDL service info
|
||||
eGOBI_ERR_NO_QDL_SVC_PATH, // 24 Unable to locate QSL service
|
||||
eGOBI_ERR_QDL_SVC_CFG, // 25 Unable to reconfigure QDL service
|
||||
eGOBI_ERR_QDL_SVC_IFACE, // 26 Unable to interface to QDL service
|
||||
eGOBI_ERR_OFFLINE, // 27 Unable to set device offline
|
||||
eGOBI_ERR_RESET, // 28 Unable to reset device
|
||||
eGOBI_ERR_NO_SIGNAL, // 29 No available signal
|
||||
eGOBI_ERR_MULTIPLE_DEVICES, // 30 Multiple devices detected
|
||||
eGOBI_ERR_DRIVER, // 31 Error interfacing to driver
|
||||
eGOBI_ERR_NO_CANCELABLE_OP, // 32 No cancelable operation is pending
|
||||
eGOBI_ERR_CANCEL_OP, // 33 Error canceling outstanding operation
|
||||
eGOBI_ERR_QDL_CRC, // 34 QDL image data CRC error
|
||||
eGOBI_ERR_QDL_PARSING, // 35 QDL image data parsing error
|
||||
eGOBI_ERR_QDL_AUTH, // 36 QDL image authentication error
|
||||
eGOBI_ERR_QDL_WRITE, // 37 QDL image write error
|
||||
eGOBI_ERR_QDL_OPEN_SIZE, // 38 QDL image size error
|
||||
eGOBI_ERR_QDL_OPEN_TYPE, // 39 QDL image type error
|
||||
eGOBI_ERR_QDL_OPEN_PROT, // 40 QDL memory protection error
|
||||
eGOBI_ERR_QDL_OPEN_SKIP, // 41 QDL image not required
|
||||
eGOBI_ERR_QDL_ERR_GENERAL, // 42 QDL general error
|
||||
eGOBI_ERR_QDL_BAR_MODE, // 43 QDL BAR mode error
|
||||
|
||||
eGOBI_ERR_ENUM_END,
|
||||
|
||||
// Offset from which mapped QMI error codes start from (see eQMIErrorCode)
|
||||
eGOBI_ERR_QMI_OFFSET = 1000,
|
||||
};
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
IsValid (Inline Method)
|
||||
|
||||
DESCRIPTION:
|
||||
eGobiError validity check
|
||||
|
||||
PARAMETERS:
|
||||
ec [ I ] - Enum value being verified
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
inline bool IsValid( eGobiError ec )
|
||||
{
|
||||
bool retVal = false;
|
||||
if (ec > eGOBI_ERR_ENUM_BEGIN && ec < eGOBI_ERR_ENUM_END)
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
if (ec >= eGOBI_ERR_QMI_OFFSET)
|
||||
{
|
||||
ULONG tmp = (ULONG)ec - (ULONG)eGOBI_ERR_QMI_OFFSET;
|
||||
retVal = ::IsValid( (eQMIErrorCode)tmp );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
};
|
|
@ -0,0 +1,531 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiQMICore.cpp
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Gobi QMI Based API Core
|
||||
|
||||
PUBLIC CLASSES AND FUNCTIONS:
|
||||
cGobiQMICore
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "StdAfx.h"
|
||||
#include "GobiQMICore.h"
|
||||
|
||||
#include "QMIBuffers.h"
|
||||
#include "ProtocolNotification.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
// cGobiQMICore Methods
|
||||
/*=========================================================================*/
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
cGobiQMICore (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Constructor
|
||||
|
||||
RETURN VALUE:
|
||||
None
|
||||
===========================================================================*/
|
||||
cGobiQMICore::cGobiQMICore()
|
||||
: mLastError( eGOBI_ERR_NONE )
|
||||
{
|
||||
mInterface[0] = 0;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
~cGobiQMICore (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Destructor
|
||||
|
||||
RETURN VALUE:
|
||||
BOOL
|
||||
===========================================================================*/
|
||||
cGobiQMICore::~cGobiQMICore()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Initialize (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Initialize the object
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cGobiQMICore::Initialize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Cleanup (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cleanup the object
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cGobiQMICore::Cleanup()
|
||||
{
|
||||
Disconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Connect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Connect to the specified Gobi device
|
||||
|
||||
PARAMETERS:
|
||||
pQMIFile [ I ] - Gobi device interface to connect to
|
||||
services [ I ] - QMI services to connect to
|
||||
|
||||
RETURN VALUE:
|
||||
std::set <eQMIService> - Services successfuly configured
|
||||
===========================================================================*/
|
||||
std::set <eQMIService> cGobiQMICore::Connect(
|
||||
LPCSTR pInterface,
|
||||
std::set <eQMIService> & services )
|
||||
{
|
||||
// The services we successfully connected to
|
||||
std::set <eQMIService> retServices;
|
||||
|
||||
// Clear last error recorded
|
||||
ClearLastError();
|
||||
|
||||
size_t ifaceLen = strnlen( pInterface, MAX_PATH ) + 1;
|
||||
if (ifaceLen >= (size_t)MAX_PATH)
|
||||
{
|
||||
mLastError = eGOBI_ERR_INVALID_ARG;
|
||||
return retServices;
|
||||
}
|
||||
|
||||
// Allocate configured QMI servers
|
||||
std::set <eQMIService>::const_iterator pIter = services.begin();
|
||||
while (pIter != services.end())
|
||||
{
|
||||
cQMIProtocolServer * pSvr = 0;
|
||||
pSvr = new cQMIProtocolServer( *pIter, 8192, 512 );
|
||||
if (pSvr != 0)
|
||||
{
|
||||
// Initialize server (we don't care about the return code
|
||||
// since the following Connect() call will fail if we are
|
||||
// unable to initialize the server)
|
||||
pSvr->Initialize();
|
||||
|
||||
bool bRC = pSvr->Connect( pInterface );
|
||||
if (bRC == true)
|
||||
{
|
||||
sServerInfo si( pSvr );
|
||||
std::pair <eQMIService, sServerInfo> entry( *pIter, si );
|
||||
mServers.insert( entry );
|
||||
|
||||
retServices.insert( *pIter );
|
||||
}
|
||||
}
|
||||
|
||||
pIter++;
|
||||
}
|
||||
|
||||
// All servers fail?
|
||||
if (retServices.size() == 0)
|
||||
{
|
||||
// Yes, disconnect them all
|
||||
Disconnect();
|
||||
|
||||
// ... and set the error code
|
||||
mLastError = eGOBI_ERR_CONNECT;
|
||||
}
|
||||
|
||||
memcpy( mInterface, pInterface, ifaceLen );
|
||||
return retServices;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Disconnect (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Disconnect from the currently connected Gobi device
|
||||
|
||||
RETURN VALUE:
|
||||
bool
|
||||
===========================================================================*/
|
||||
bool cGobiQMICore::Disconnect()
|
||||
{
|
||||
// Clear last error recorded
|
||||
ClearLastError();
|
||||
|
||||
// Clear device interface
|
||||
mInterface[0] = 0;
|
||||
|
||||
// Assume failure
|
||||
bool bRC = false;
|
||||
if (mServers.size() == 0)
|
||||
{
|
||||
mLastError = eGOBI_ERR_NO_CONNECTION;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
// Disconnect/clean-up all configured QMI servers
|
||||
std::map <eQMIService, sServerInfo>::iterator pIter;
|
||||
pIter = mServers.begin();
|
||||
|
||||
while (pIter != mServers.end())
|
||||
{
|
||||
sServerInfo & si = pIter->second;
|
||||
cQMIProtocolServer * pSvr = si.mpServer;
|
||||
if (pSvr != 0)
|
||||
{
|
||||
pSvr->Disconnect();
|
||||
pSvr->Exit();
|
||||
|
||||
delete pSvr;
|
||||
}
|
||||
|
||||
si.mLogsProcessed = 0;
|
||||
pIter++;
|
||||
}
|
||||
|
||||
mServers.clear();
|
||||
|
||||
bRC = true;
|
||||
return bRC;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
Send (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Send a request using the specified QMI protocol server and wait for (and
|
||||
then return) the response
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - QMI service type
|
||||
msgID [ I ] - QMI message ID
|
||||
to [ I ] - Timeout value (in milliseconds)
|
||||
inLen [ I ] - Length of input buffer
|
||||
pIn [ I ] - Input buffer
|
||||
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
|
||||
contain, upon output the number of BYTEs copied
|
||||
to pOut
|
||||
pOut [ O ] - Output buffer
|
||||
|
||||
RETURN VALUE:
|
||||
eGobiError - The result
|
||||
===========================================================================*/
|
||||
eGobiError cGobiQMICore::Send(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
ULONG to,
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut )
|
||||
{
|
||||
// Clear last error recorded
|
||||
ClearLastError();
|
||||
|
||||
if (msgID > 0xffff)
|
||||
{
|
||||
mLastError = eGOBI_ERR_INVALID_ARG;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
sSharedBuffer * pRequest = 0;
|
||||
pRequest = sQMIServiceBuffer::BuildBuffer( (eQMIService)svcID,
|
||||
(WORD)msgID,
|
||||
false,
|
||||
false,
|
||||
pIn,
|
||||
inLen );
|
||||
|
||||
if (pRequest == 0)
|
||||
{
|
||||
mLastError = eGOBI_ERR_MEMORY;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
// We use the event based notification approach
|
||||
cSyncQueue <sProtocolNotificationEvent> evts( 12, true );
|
||||
cProtocolQueueNotification pn( &evts );
|
||||
|
||||
// Build the request object
|
||||
sProtocolRequest req( pRequest, 0, to, 1, 1, &pn );
|
||||
if (to == 0)
|
||||
{
|
||||
mLastError = eGOBI_ERR_INTERNAL;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
// Grab the server
|
||||
std::map <eQMIService, cGobiQMICore::sServerInfo>::iterator pSvrIter;
|
||||
pSvrIter = mServers.find( (eQMIService)svcID );
|
||||
if (pSvrIter == mServers.end())
|
||||
{
|
||||
mLastError = eGOBI_ERR_NO_CONNECTION;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
sServerInfo & si = pSvrIter->second;
|
||||
cQMIProtocolServer * pSvr = si.mpServer;
|
||||
if (pSvr == 0 || pSvr->IsConnected() == false)
|
||||
{
|
||||
mLastError = eGOBI_ERR_NO_CONNECTION;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
// Grab the log from the server
|
||||
const cProtocolLog & protocolLog = pSvr->GetLog();
|
||||
|
||||
// Schedule the request
|
||||
ULONG reqID = pSvr->AddRequest( req );
|
||||
if (reqID == INVALID_REQUEST_ID)
|
||||
{
|
||||
mLastError = eGOBI_ERR_REQ_SCHEDULE;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
// Store for external cancel
|
||||
si.mRequestID = reqID;
|
||||
|
||||
bool bReq = false;
|
||||
bool bExit = false;
|
||||
DWORD idx;
|
||||
|
||||
// Returned response
|
||||
sProtocolBuffer rsp;
|
||||
|
||||
// Process up to the indicated timeout
|
||||
cEvent & sigEvt = evts.GetSignalEvent();
|
||||
while (bExit == false)
|
||||
{
|
||||
int wc = sigEvt.Wait( to, idx );
|
||||
if (wc == ETIME)
|
||||
{
|
||||
if (bReq == true)
|
||||
{
|
||||
mLastError = eGOBI_ERR_RESPONSE_TO;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLastError = eGOBI_ERR_REQUEST_TO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (wc != 0)
|
||||
{
|
||||
mLastError = eGOBI_ERR_INTERNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
sProtocolNotificationEvent evt;
|
||||
bool bEvt = evts.GetElement( idx, evt );
|
||||
if (bEvt == false)
|
||||
{
|
||||
mLastError = eGOBI_ERR_INTERNAL;
|
||||
bExit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (evt.mEventType)
|
||||
{
|
||||
case ePROTOCOL_EVT_REQ_ERR:
|
||||
mLastError = eGOBI_ERR_REQUEST;
|
||||
bExit = true;
|
||||
break;
|
||||
|
||||
case ePROTOCOL_EVT_RSP_ERR:
|
||||
mLastError = eGOBI_ERR_RESPONSE;
|
||||
bExit = true;
|
||||
break;
|
||||
|
||||
case ePROTOCOL_EVT_REQ_SENT:
|
||||
{
|
||||
// Grab the as-sent request
|
||||
DWORD id = evt.mParam2;
|
||||
sProtocolBuffer tmpReq = protocolLog.GetBuffer( id );
|
||||
sSharedBuffer * pTmpRequest = tmpReq.GetSharedBuffer();
|
||||
if (pTmpRequest != 0)
|
||||
{
|
||||
// Grab the transaction ID
|
||||
sQMIServiceBuffer actualReq( pTmpRequest );
|
||||
si.mRequestTXID = actualReq.GetTransactionID();
|
||||
}
|
||||
|
||||
bReq = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ePROTOCOL_EVT_RSP_RECV:
|
||||
// Success!
|
||||
rsp = protocolLog.GetBuffer( evt.mParam2 );
|
||||
bExit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (mLastError == eGOBI_ERR_INTERNAL)
|
||||
|| (mLastError == eGOBI_ERR_REQUEST_TO)
|
||||
|| (mLastError == eGOBI_ERR_RESPONSE_TO) )
|
||||
{
|
||||
// Remove the request as our protocol notification object is
|
||||
// about to go out of scope and hence be destroyed
|
||||
pSvr->RemoveRequest( reqID );
|
||||
}
|
||||
|
||||
if (rsp.IsValid() == false)
|
||||
{
|
||||
return GetCorrectedLastError();
|
||||
}
|
||||
|
||||
// Did we receive a valid QMI response?
|
||||
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
|
||||
if (qmiRsp.IsValid() == false)
|
||||
{
|
||||
mLastError = eGOBI_ERR_MALFORMED_RSP;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
// Caller might not be interested in actual output (beyond error code)
|
||||
ULONG maxSz = 0;
|
||||
if (pOutLen != 0)
|
||||
{
|
||||
maxSz = *pOutLen;
|
||||
}
|
||||
|
||||
if (maxSz > 0)
|
||||
{
|
||||
// TLV 2 is always present
|
||||
ULONG needSz = 0;
|
||||
const BYTE * pData = (const BYTE *)qmiRsp.GetRawContents( needSz );
|
||||
if (needSz == 0 || pData == 0)
|
||||
{
|
||||
return eGOBI_ERR_INVALID_RSP;
|
||||
}
|
||||
|
||||
*pOutLen = needSz;
|
||||
if (needSz > maxSz)
|
||||
{
|
||||
return eGOBI_ERR_BUFFER_SZ;
|
||||
}
|
||||
|
||||
memcpy( pOut, pData, needSz );
|
||||
}
|
||||
|
||||
// Check the mandatory QMI result TLV for success
|
||||
ULONG rc = 0;
|
||||
ULONG ec = 0;
|
||||
bool bResult = qmiRsp.GetResult( rc, ec );
|
||||
if (bResult == false)
|
||||
{
|
||||
mLastError = eGOBI_ERR_MALFORMED_RSP;
|
||||
return mLastError;
|
||||
}
|
||||
else if (rc != 0)
|
||||
{
|
||||
return GetCorrectedQMIError( ec );
|
||||
}
|
||||
|
||||
// Success!
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
METHOD:
|
||||
CancelSend (Public Method)
|
||||
|
||||
DESCRIPTION:
|
||||
Cancel the most recent in-progress Send() based operation
|
||||
|
||||
PARAMETERS:
|
||||
svcID [ I ] - Service whose outstanding request is to be cancelled
|
||||
pTXID [ O ] - QMI transaction ID of outstanding request
|
||||
|
||||
RETURN VALUE:
|
||||
eGobiError - The result
|
||||
===========================================================================*/
|
||||
eGobiError cGobiQMICore::CancelSend(
|
||||
ULONG svcID,
|
||||
ULONG * pTXID )
|
||||
{
|
||||
// Grab the server
|
||||
std::map <eQMIService, cGobiQMICore::sServerInfo>::iterator pSvrIter;
|
||||
pSvrIter = mServers.find( (eQMIService)svcID );
|
||||
if (pSvrIter == mServers.end())
|
||||
{
|
||||
mLastError = eGOBI_ERR_NO_CONNECTION;
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
sServerInfo & si = pSvrIter->second;
|
||||
cQMIProtocolServer * pSvr = si.mpServer;
|
||||
if (pSvr == 0)
|
||||
{
|
||||
return eGOBI_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
if (si.mRequestID == 0xffffffff)
|
||||
{
|
||||
return eGOBI_ERR_NO_CANCELABLE_OP;
|
||||
}
|
||||
|
||||
bool bRemove = pSvr->RemoveRequest( si.mRequestID );
|
||||
if (bRemove == false)
|
||||
{
|
||||
return eGOBI_ERR_CANCEL_OP;
|
||||
}
|
||||
|
||||
if (pTXID != 0)
|
||||
{
|
||||
*pTXID = si.mRequestTXID;
|
||||
}
|
||||
|
||||
return eGOBI_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/*===========================================================================
|
||||
FILE:
|
||||
GobiQMICore.h
|
||||
|
||||
DESCRIPTION:
|
||||
QUALCOMM Gobi QMI Based API Core
|
||||
|
||||
PUBLIC CLASSES AND FUNCTIONS:
|
||||
cGobiQMICore
|
||||
|
||||
Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Code Aurora Forum nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
==========================================================================*/
|
||||
|
||||
/*=========================================================================*/
|
||||
// Pragmas
|
||||
/*=========================================================================*/
|
||||
#pragma once
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include Files
|
||||
//---------------------------------------------------------------------------
|
||||
#include "ProtocolBuffer.h"
|
||||
#include "QMIProtocolServer.h"
|
||||
#include "SyncQueue.h"
|
||||
#include "GobiError.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
// Class cGobiQMICore
|
||||
/*=========================================================================*/
|
||||
class cGobiQMICore
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
cGobiQMICore();
|
||||
|
||||
// Destructor
|
||||
virtual ~cGobiQMICore();
|
||||
|
||||
// Initialize the object
|
||||
virtual bool Initialize();
|
||||
|
||||
// Cleanup the object
|
||||
virtual bool Cleanup();
|
||||
|
||||
// (Inline) Return the server as determined by the service type
|
||||
cQMIProtocolServer * GetServer( eQMIService svc )
|
||||
{
|
||||
cQMIProtocolServer * pSvr = 0;
|
||||
|
||||
std::map <eQMIService, sServerInfo>::const_iterator pIter;
|
||||
pIter = mServers.find( svc );
|
||||
|
||||
if (pIter != mServers.end())
|
||||
{
|
||||
const sServerInfo & si = pIter->second;
|
||||
pSvr = si.mpServer;
|
||||
}
|
||||
|
||||
return pSvr;
|
||||
};
|
||||
|
||||
// (Inline) Clear last error recorded
|
||||
void ClearLastError()
|
||||
{
|
||||
mLastError = eGOBI_ERR_NONE;
|
||||
};
|
||||
|
||||
// (Inline) Get last error recorded
|
||||
eGobiError GetLastError()
|
||||
{
|
||||
return mLastError;
|
||||
};
|
||||
|
||||
// (Inline) Return the last recorded error (if this happens to indicate
|
||||
// that no error occurred then return eGOBI_ERR_INTERNAL)
|
||||
eGobiError GetCorrectedLastError()
|
||||
{
|
||||
eGobiError ec = GetLastError();
|
||||
if (ec == eGOBI_ERR_NONE)
|
||||
{
|
||||
ec = eGOBI_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return ec;
|
||||
};
|
||||
|
||||
// (Inline) Return the correct QMI error (if this happens to indicate
|
||||
// that no error occurred then return the mapped eQMI_ERR_INTERNAL
|
||||
// value)
|
||||
eGobiError GetCorrectedQMIError( ULONG qmiErrorCode )
|
||||
{
|
||||
ULONG ec = (ULONG)eQMI_ERR_INTERNAL + (ULONG)eGOBI_ERR_QMI_OFFSET;
|
||||
if (qmiErrorCode != (ULONG)eQMI_ERR_NONE)
|
||||
{
|
||||
ec = qmiErrorCode + (ULONG)eGOBI_ERR_QMI_OFFSET;
|
||||
}
|
||||
|
||||
return (eGobiError)ec;
|
||||
};
|
||||
|
||||
// Connect to the specified Gobi device interface
|
||||
virtual std::set <eQMIService> Connect(
|
||||
LPCSTR pInterface,
|
||||
std::set <eQMIService> & services );
|
||||
|
||||
// Disconnect from the currently connected device interface
|
||||
virtual bool Disconnect();
|
||||
|
||||
// Send a request using the specified QMI protocol server and wait
|
||||
// for (and then return) the response
|
||||
eGobiError Send(
|
||||
ULONG svcID,
|
||||
ULONG msgID,
|
||||
ULONG to,
|
||||
ULONG inLen,
|
||||
const BYTE * pIn,
|
||||
ULONG * pOutLen,
|
||||
BYTE * pOut );
|
||||
|
||||
// Cancel the most recent in-progress Send() based operation
|
||||
eGobiError CancelSend(
|
||||
ULONG svcID,
|
||||
ULONG * pTXID );
|
||||
|
||||
protected:
|
||||
/* Device interface */
|
||||
CHAR mInterface[MAX_PATH];
|
||||
|
||||
/* QMI protocol server/protocol server log count */
|
||||
struct sServerInfo
|
||||
{
|
||||
public:
|
||||
// Constructor (default)
|
||||
sServerInfo()
|
||||
: mpServer( 0 ),
|
||||
mLogsProcessed( 0 ),
|
||||
mRequestID( 0xffffffff ),
|
||||
mRequestTXID( 0xffffffff )
|
||||
{ };
|
||||
|
||||
// Constructor (parameterized)
|
||||
sServerInfo( cQMIProtocolServer * pServer )
|
||||
: mpServer( pServer ),
|
||||
mLogsProcessed( 0 ),
|
||||
mRequestID( 0xffffffff ),
|
||||
mRequestTXID( 0xffffffff )
|
||||
{ };
|
||||
|
||||
/* Protocol server */
|
||||
cQMIProtocolServer * mpServer;
|
||||
|
||||
/* Protocol server logs processed */
|
||||
ULONG mLogsProcessed;
|
||||
|
||||
/* Last scheduled request ID */
|
||||
ULONG mRequestID;
|
||||
|
||||
/* Last schedule request QMI transaction ID */
|
||||
ULONG mRequestTXID;
|
||||
};
|
||||
|
||||
/* QMI protocol servers */
|
||||
std::map <eQMIService, sServerInfo> mServers;
|
||||
|
||||
/* Last error recorded */
|
||||
eGobiError mLastError;
|
||||
};
|
Loading…
Reference in New Issue