--- a/atext/client/src/atextclient.cpp Fri Jan 15 08:13:17 2010 +0200
+++ b/atext/client/src/atextclient.cpp Mon Jan 18 21:23:18 2010 +0200
@@ -467,11 +467,11 @@
const TUidType serverUid( KNullUid, KNullUid, KATExtSrvUid3 );
RProcess server;
TInt retTemp = server.Create( KATExtSrvExe, KNullDesC, serverUid );
- server.SetPriority( EPriorityHigh );
if ( retTemp != KErrNone )
{
return retTemp;
}
+ server.SetPriority( EPriorityHigh );
TRequestStatus status;
server.Rendezvous( status );
if ( status != KRequestPending )
--- a/atext/client/src/atextcommon.cpp Fri Jan 15 08:13:17 2010 +0200
+++ b/atext/client/src/atextcommon.cpp Mon Jan 18 21:23:18 2010 +0200
@@ -203,11 +203,11 @@
const TUidType serverUid( KNullUid, KNullUid, KATExtSrvUid3 );
RProcess server;
TInt retTemp = server.Create( KATExtCommonSrvExe, KNullDesC, serverUid );
- server.SetPriority( EPriorityHigh );
if ( retTemp != KErrNone )
{
return retTemp;
}
+ server.SetPriority( EPriorityHigh );
TRequestStatus status;
server.Rendezvous( status );
if ( status != KRequestPending )
--- a/atext/server/inc/atextmetadata.h Fri Jan 15 08:13:17 2010 +0200
+++ b/atext/server/inc/atextmetadata.h Mon Jan 18 21:23:18 2010 +0200
@@ -15,7 +15,6 @@
*
*/
-
#ifndef C_CATEXTMETADATA_H
#define C_CATEXTMETADATA_H
@@ -26,13 +25,20 @@
class CATExtPluginBase;
class CATExtListen;
-/** Support types supported by RSS file (M|P|S) */
+/** Panic categories */
+enum TATExtPanicCategories
+ {
+ EPanicCategoryFaultyMaster = 1,
+ EPanicCategoryPluginType = 2
+ };
+
+/** Support types supported by RSS file (M|P|O) */
enum TATExtSupportType
{
ESupportTypeUndefined = KErrNotFound,
ESupportTypeMaster = 0,
- ESupportTypePrimary,
- ESupportTypeSecondary
+ ESupportTypePartial,
+ ESupportTypeObserver
};
/** Operation types, either for command handling or for URC receiving */
@@ -128,25 +134,25 @@
public:
- TATExtSearchHelper() : iPrimaryIndex( KErrNotFound ),
- iSecondaryIndex( KErrNotFound ) {}
+ TATExtSearchHelper() : iPartialIndex( KErrNotFound ),
+ iObserverIndex( KErrNotFound ) {}
/**
- * Index to the primary entry
+ * Index to the partial entry
*/
- TInt iPrimaryIndex;
+ TInt iPartialIndex;
/**
- * Index to the secondary entry
+ * Index to the observer entry
*/
- TInt iSecondaryIndex;
+ TInt iObserverIndex;
};
/**
* Class to store data needed for one AT command support.
* This includes the support's type and the plugin entry.
- * Thus one plugin's RSS file may contain multiple M|P|S entries.
+ * Thus one plugin's RSS file may contain multiple M|P|O entries.
*
* @since S60 v5.0
*/
@@ -156,7 +162,7 @@
public:
/**
- * Support's type (M|P|S)
+ * Support's type (M|P|O)
*/
TATExtSupportType iSupportType;
@@ -313,7 +319,10 @@
CArrayFixFlat<TATExtOneCmdSupport>* aSupport ) :
iAtCmdFull( aAtCmdFull ),
iMessage( aMessage ),
- iSupport( aSupport ) {}
+ iSupport( aSupport ),
+ iEntry( NULL ),
+ iStartIndex( KErrNotFound ),
+ iSupportFound( EFalse ){}
/**
* Full AT command for which to check the support
@@ -328,7 +337,7 @@
/**
* AT command's plugin entry support data.
- * Used by SendToMultipleSecondaryL() and FindFirstSecondarySupportL().
+ * Used by SendToMultipleObserverL() and FindFirstObserverSupportL().
*/
CArrayFixFlat<TATExtOneCmdSupport>* iSupport;
@@ -338,11 +347,16 @@
TATExtPluginEntry* iEntry;
/**
- * Starts index for searches with HandlePrimaryPluginSupportL() and
- * HandleSecondaryPluginSupportL()
+ * Start index for searches with HandlePartialAndMasterPluginSupportL() and
+ * HandleObserverPluginSupportL()
*/
TInt iStartIndex;
+ /**
+ * Found plugin support for HandlePartialAndMasterPluginSupportL().
+ */
+ TBool iSupportFound;
+
};
/**
@@ -835,7 +849,7 @@
* @param aCommands Command buffer from where to extract the next subcommand
* @param aStartIndex Start index for the found command
* @param aEndIndex End index for the found command
- * @param aSupportType Support's type (M|P|S)
+ * @param aSupportType Support's type (M|P|O)
* @return Symbian error code on error, KErrNone otherwise
*/
TInt ExtractNextCommand( const TDesC8& aCommands,
@@ -855,7 +869,7 @@
* @param aAtCmdBase Base AT command which to add to support data
* (base part without parameters)
* @param aPluginUid Plugin's UID to find from plugin data
- * @param aSupportType Support's type (M|P|S)
+ * @param aSupportType Support's type (M|P|O)
* @param aCleanupInfo Cleanup information
* @return None
*/
@@ -870,7 +884,7 @@
* @since S60 5.0
* @param aEntries Plugin entries for support
* @param aEntryIndex Plugin index entry
- * @param aSupportType Support's type (M|P|S)
+ * @param aSupportType Support's type (M|P|O)
* @param aSearchHelper The search helper
* @return Index to the added entry, KErrNotSupported otherwise
*/
@@ -893,26 +907,26 @@
TATExtOneCmdSupport& aOneCmdSupport );
/**
- * Adds new primary plugin entry link from plugin support entry to plugin
+ * Adds new partial plugin entry link from plugin support entry to plugin
* entry
*
* @since S60 5.0
* @return Index to the added entry, KErrNotSupported otherwise
*/
- TInt AddNewPrimaryMetadataEntryLinkL(
+ TInt AddNewPartialMetadataEntryLinkL(
CArrayFixFlat<TATExtOneCmdSupport>* aEntries,
TATExtSearchHelper& aSearchHelper,
TATExtOneCmdSupport& aOneCmdSupport );
/**
- * Adds new secondary plugin entry link from plugin support entry to plugin
- * entry. Search starts from the front as there could be multiple S plugins
+ * Adds new observer plugin entry link from plugin support entry to plugin
+ * entry. Search starts from the front as there could be multiple O plugins
* but only one or two M/P plugins.
*
* @since S60 5.0
* @return Index to the added entry, KErrNotSupported otherwise
*/
- TInt AddNewSecondaryMetadataEntryLinkL(
+ TInt AddNewObserverMetadataEntryLinkL(
CArrayFixFlat<TATExtOneCmdSupport>* aEntries,
TATExtSearchHelper& aSearchHelper,
TATExtOneCmdSupport& aOneCmdSupport );
@@ -1054,56 +1068,50 @@
void CreateSelfReplyData( const RMessage2& aMessage );
/**
- * Handles support when a master plugin is detected in the plugin data
- * via support data's link (support for a full AT command). If a master
- * plugin is detected then reply is detected from that plugin. No further
- * sending to primary or secondary plugins is repformed.
+ * Handles support when a master or partial plugin is detected in the plugin
+ * data via support data's link. If a partial or master plugin is detected
+ * then reply is expected from that plugin. Also if one or more observer
+ * plugins are detected then no reply is expected from them.
*
* @since S60 5.0
- * @param aEntrySupport Support data to the first found master plugin
- * @param aReplyExpected ETrue if reply is expected from the master plugin,
- * EFalse if no reply is expected from the master plugin,
+ * @param aEntrySupport Support data to the first found partial or master plugin
+ * @param aStartIndex Start index to search the next observer plugin
+ * @param aReplyExpected ETrue if reply is expected from the partial or master plugin,
+ * EFalse if no reply is expected from the partial or master plugin,
* (i.e. no support found)
* @return ETrue if support found, EFalse otherwise
*/
- TBool HandleMasterPluginSupportL( TATExtEntrySupport& aEntrySupport,
- TBool& aReplyExpected );
+ TBool HandleMasterAndPartialPluginSupportL(
+ TATExtEntrySupport& aEntrySupport,
+ TInt aStartIndex,
+ TBool& aReplyExpected );
/**
- * Handles support when a primary plugin is detect in the plugin data
- * via support data's link. If a primary plugin is detected then reply is
- * expected from that plugin. Also if one or more secondary plugins are
- * detected then no reply is expected from them.
- *
- * @since S60 5.0
- * @param aEntrySupport Support data to the first found primary plugin
- * @param aStartIndex Start index to search the next secondary plugin
- * @param aReplyExpected ETrue if reply is expected from the primary plugin,
- * EFalse if no reply is expected from the primary plugin,
- * (i.e. no support found)
- * @return ETrue if support found, EFalse otherwise
- */
- TBool HandlePrimaryPluginSupportL( TATExtEntrySupport& aEntrySupport,
- TInt aStartIndex,
- TBool& aReplyExpected );
-
- /**
- * Handles support when a secondary plugin is detected in the plugin data
- * via support data's link. If only one secondary plugin is detected then
- * reply is expected from that plugin. Instead, if more than one secondary
+ * Handles support when a observer plugin is detected in the plugin data
+ * via support data's link. If only one observer plugin is detected then
+ * reply is expected from that plugin. Instead, if more than one observer
* plugins are detected then no reply is expected from them.
*
* @since S60 5.0
- * @param aEntrySupport Support data to the first found secondary plugin
+ * @param aEntrySupport Support data to the first found observer plugin
* entry
- * @param aStartIndex Start index to search the next secondary plugin
+ * @param aStartIndex Start index to search the next observer plugin
* @param aReplyExpected ETrue if reply is expected from one or more plugins,
* EFalse if no reply is expected from any of the plugins
* @return ETrue if support found, EFalse otherwise
*/
- TBool HandleSecondaryPluginSupportL( TATExtEntrySupport& aEntrySupport,
- TInt aStartIndex,
- TBool& aReplyExpected );
+ TBool HandleObserverPluginSupportL( TATExtEntrySupport& aEntrySupport,
+ TInt aStartIndex,
+ TBool& aReplyExpected );
+
+ /**
+ * Finds exclusive partial plugin support
+ *
+ * @since S60 5.0
+ * @param aEntrySupport Support data to the first found partial plugin entry
+ * @return ETrue if exclusive support found, EFalse otherwise
+ */
+ TBool FindExclusivePartialSupportL( TATExtEntrySupport& aEntrySupport );
/**
* Finds support entries from support data for a given base AT command
@@ -1173,27 +1181,27 @@
const TDesC8* aAtCmdFull=NULL );
/**
- * Sends an AT commands to multiple secondary plugins, starting from a
+ * Sends an AT commands to multiple observer plugins, starting from a
* given position.
*
* @since S60 5.0
* @param aEntrySupport Entry support data to position from where to start
- * sending to the found secondary plugins
+ * sending to the found observer plugins
* @param aAtCmdFull Full AT command to send (base part + parameters)
* @return None
*/
- void SendToMultipleSecondaryL( TATExtEntrySupport& aEntrySupport,
+ void SendToMultipleObserverL( TATExtEntrySupport& aEntrySupport,
const TDesC8* aAtCmdFull );
/**
- * Finds the first secondary plugin support from a given starting position
+ * Finds the first observer plugin support from a given starting position
*
* @since S60 5.0
* @param aEntrySupport Entry support data to the next entry after the found
- * secondary plugin entry; marks the start for search
+ * observer plugin entry; marks the start for search
* @return ETrue if support found, EFalse otherwise
*/
- TBool FindFirstSecondarySupportL( TATExtEntrySupport& aEntrySupport );
+ TBool FindFirstObserverSupportL( TATExtEntrySupport& aEntrySupport );
/**
* Extracts one NVRAM entry from a pipe-character delimited NVRAM buffer
--- a/atext/server/src/atextmetadata.cpp Fri Jan 15 08:13:17 2010 +0200
+++ b/atext/server/src/atextmetadata.cpp Mon Jan 18 21:23:18 2010 +0200
@@ -21,21 +21,21 @@
* future needs:
*
* Three types of support:
- * 1) Master (M): Does not send to S if support found.
- * 2) Primary (P): Sends to all S if support found.
- * 3) Secondary (S): Process the command and give or not give reply, based on
+ * 1) Master (M): Sends to all O if support found. Panics if > 1 M.
+ * 2) Partial (P): Sends to all O if support found. Replies "ERROR" if two P supports.
+ * 3) Observer (O): Process the command and give or not give reply, based on
* the following logic:
*
- * => [If] M found, handle command and send reply, stop, [else]
- * [If] P found, handle command and send reply + send to N S {no reply}, stop, [else]
- * [If] > 1 S found, send to N S {no reply}, stop, [else]
- * [If] only 1 S found, handle command and send reply, stop, [else]
+ * => [If] M found, handle command and send reply + send to N O {no reply}, stop, [else]
+ * [If] P found, handle command and send reply + send to N O {no reply}, stop, [else]
+ * [If] > 1 O found, send to N O {no reply}, stop, [else]
+ * [If] only 1 O found, handle command and send reply, stop, [else]
* Write "ERROR" to client, complete message with KErrNone
*
* When incoming reply:
* => If reply from M, write to client, stop, [else]
* If reply from P, write to client, stop, [else]
- * If reply from S and M, P nor other S exist, write to client, stop, [else]
+ * If reply from O and M, P nor other O exist, write to client, stop, [else]
* Complete message with KErrNone and empty string
*
* Note: Empty string and "ERROR" string are managed already in HandleCommand()
@@ -1359,14 +1359,17 @@
case 'm':
aSupportType = ESupportTypeMaster;
break;
- case 'P': // Primary plugin
+ case 'P': // Partial plugin
case 'p':
- aSupportType = ESupportTypePrimary;
+ aSupportType = ESupportTypePartial;
break;
- case 'S': // Secondary plugin
- case 's':
- aSupportType = ESupportTypeSecondary;
+ case 'O': // Observer plugin
+ case 'o':
+ aSupportType = ESupportTypeObserver;
break;
+ default:
+ _LIT( KPluginType, "PluginType" );
+ User::Panic( KPluginType, EPanicCategoryPluginType );
}
i++;
if ( i >= count )
@@ -1519,18 +1522,18 @@
oneCmdSupport );
}
break;
- case ESupportTypePrimary:
+ case ESupportTypePartial:
{
- retVal = AddNewPrimaryMetadataEntryLinkL( aEntries,
+ retVal = AddNewPartialMetadataEntryLinkL( aEntries,
aSearchHelper,
oneCmdSupport );
}
break;
- case ESupportTypeSecondary:
+ case ESupportTypeObserver:
{
- retVal = AddNewSecondaryMetadataEntryLinkL( aEntries,
- aSearchHelper,
- oneCmdSupport );
+ retVal = AddNewObserverMetadataEntryLinkL( aEntries,
+ aSearchHelper,
+ oneCmdSupport );
}
break;
default:
@@ -1552,79 +1555,88 @@
TATExtOneCmdSupport& aOneCmdSupport )
{
TRACE_FUNC_ENTRY
+ if ( aEntries->Count() > 0 )
+ {
+ TATExtOneCmdSupport& oneCmdSupport = (*aEntries)[0];
+ if ( oneCmdSupport.iSupportType == ESupportTypeMaster )
+ {
+ _LIT( KFaultyMaster, "FaultyMaster" );
+ User::Panic( KFaultyMaster, EPanicCategoryFaultyMaster );
+ }
+ }
aEntries->InsertL( 0, aOneCmdSupport );
- if ( aSearchHelper.iPrimaryIndex >= 0 )
+ if ( aSearchHelper.iPartialIndex >= 0 )
{
- aSearchHelper.iPrimaryIndex++;
+ aSearchHelper.iPartialIndex++;
}
- if ( aSearchHelper.iSecondaryIndex >= 0 )
+ if ( aSearchHelper.iObserverIndex >= 0 )
{
- aSearchHelper.iSecondaryIndex++;
+ aSearchHelper.iObserverIndex++;
}
TRACE_FUNC_EXIT
return 0;
}
// ---------------------------------------------------------------------------
-// Adds new primary plugin entry link from plugin support entry to plugin
+// Adds new partial plugin entry link from plugin support entry to plugin
// entry
// ---------------------------------------------------------------------------
//
-TInt CATExtMetadata::AddNewPrimaryMetadataEntryLinkL(
+TInt CATExtMetadata::AddNewPartialMetadataEntryLinkL(
CArrayFixFlat<TATExtOneCmdSupport>* aEntries,
TATExtSearchHelper& aSearchHelper,
TATExtOneCmdSupport& aOneCmdSupport )
{
TRACE_FUNC_ENTRY
- TInt i = aSearchHelper.iPrimaryIndex;
+ TInt i = aSearchHelper.iPartialIndex;
if ( i < 0 )
{
TInt count = aEntries->Count();
for ( i=0; i<count; i++ )
{
TATExtOneCmdSupport& oneCmdSupport = (*aEntries)[i];
- if ( oneCmdSupport.iSupportType==ESupportTypePrimary ||
- oneCmdSupport.iSupportType==ESupportTypeSecondary )
+ if ( oneCmdSupport.iSupportType==ESupportTypePartial ||
+ oneCmdSupport.iSupportType==ESupportTypeObserver )
{
break;
}
}
- aSearchHelper.iPrimaryIndex = i;
+ aSearchHelper.iPartialIndex = i;
}
aEntries->InsertL( i, aOneCmdSupport );
- if ( aSearchHelper.iSecondaryIndex >= 0 )
+ if ( aSearchHelper.iObserverIndex >= 0 )
{
- aSearchHelper.iSecondaryIndex++;
+ aSearchHelper.iObserverIndex++;
}
TRACE_FUNC_EXIT
return i;
}
// ---------------------------------------------------------------------------
-// Adds new secondary plugin entry link from plugin support entry to plugin
-// entry. Search starts from the front as there could be multiple S plugins
+// Adds new observer plugin entry link from plugin support entry to plugin
+// entry. Search starts from the front as there could be multiple O plugins
// but only one or two M/P plugins.
// ---------------------------------------------------------------------------
//
-TInt CATExtMetadata::AddNewSecondaryMetadataEntryLinkL(
+TInt CATExtMetadata::AddNewObserverMetadataEntryLinkL(
CArrayFixFlat<TATExtOneCmdSupport>* aEntries,
TATExtSearchHelper& aSearchHelper,
TATExtOneCmdSupport& aOneCmdSupport )
{
TRACE_FUNC_ENTRY
- TInt i = aSearchHelper.iSecondaryIndex;
+ TInt i = aSearchHelper.iObserverIndex;
if ( i < 0 )
{
TInt count = aEntries->Count();
for ( i=0; i<count; i++ )
{
TATExtOneCmdSupport& oneCmdSupport = (*aEntries)[i];
- if ( oneCmdSupport.iSupportType == ESupportTypeSecondary )
+ if ( oneCmdSupport.iSupportType == ESupportTypeObserver )
{
break;
}
}
- aSearchHelper.iSecondaryIndex = i;
+ aSearchHelper.iObserverIndex = i;
}
aEntries->InsertL( i, aOneCmdSupport );
TRACE_FUNC_EXIT
@@ -1974,20 +1986,26 @@
entrySupport.iEntry = &(*iPluginData)[oneCmdSupport.iEntryIndex];
if ( oneCmdSupport.iSupportType == ESupportTypeMaster )
{
- supported = HandleMasterPluginSupportL(
- entrySupport,
- aComplInfo.iReplyExpected );
- }
- else if ( oneCmdSupport.iSupportType == ESupportTypePrimary )
- {
- supported = HandlePrimaryPluginSupportL(
+ supported = HandleMasterAndPartialPluginSupportL(
entrySupport,
i+1,
aComplInfo.iReplyExpected );
}
- else if ( oneCmdSupport.iSupportType == ESupportTypeSecondary )
+ else if ( oneCmdSupport.iSupportType == ESupportTypePartial )
{
- supported = HandleSecondaryPluginSupportL(
+ supported = FindExclusivePartialSupportL( entrySupport );
+ if ( !supported )
+ {
+ break;
+ }
+ supported = HandleMasterAndPartialPluginSupportL(
+ entrySupport,
+ i+1,
+ aComplInfo.iReplyExpected );
+ }
+ else if ( oneCmdSupport.iSupportType == ESupportTypeObserver )
+ {
+ supported = HandleObserverPluginSupportL(
entrySupport,
i+1,
aComplInfo.iReplyExpected );
@@ -2022,50 +2040,27 @@
}
// ---------------------------------------------------------------------------
-// Handles support when a master plugin is detected in the plugin data via
-// support data's link (support for a full AT command). If a master plugin is
-// detected then reply is detected from that plugin. No further sending to
-// primary or secondary plugins is repformed.
+// Handles support when a master or partial plugin is detected in the plugin
+// data via support data's link. If a partial or master plugin is detected
+// then reply is expected from that plugin. Also if one or more observer
+// plugins are detected then no reply is expected from them.
// ---------------------------------------------------------------------------
//
-TBool CATExtMetadata::HandleMasterPluginSupportL(
- TATExtEntrySupport& aEntrySupport,
- TBool& aReplyExpected )
- {
- TRACE_FUNC_ENTRY
- aReplyExpected = EFalse;
- TBool supported = HandleCommandSupportL( aEntrySupport );
- if ( !supported )
- {
- TRACE_FUNC_EXIT
- return EFalse;
- }
- iCmdData.iReplyExpected = ETrue; // Set before HandleCommandL()
- HandleCommandL( aEntrySupport, ETrue );
- aReplyExpected = ETrue;
- TRACE_FUNC_EXIT
- return ETrue;
- }
-
-// ---------------------------------------------------------------------------
-// Handles support when a primary plugin is detect in the plugin data via
-// support data's link. If a primary plugin is detected then reply is expected
-// from that plugin. Also if one or more secondary plugins are detected then
-// no reply is expected from them.
-// ---------------------------------------------------------------------------
-//
-TBool CATExtMetadata::HandlePrimaryPluginSupportL(
+TBool CATExtMetadata::HandleMasterAndPartialPluginSupportL(
TATExtEntrySupport& aEntrySupport,
TInt aStartIndex,
TBool& aReplyExpected )
{
TRACE_FUNC_ENTRY
aReplyExpected = EFalse;
- TBool supported = HandleCommandSupportL( aEntrySupport );
- if ( !supported )
+ if ( !aEntrySupport.iSupportFound )
{
- TRACE_FUNC_EXIT
- return EFalse;
+ TBool supported = HandleCommandSupportL( aEntrySupport );
+ if ( !supported )
+ {
+ TRACE_FUNC_EXIT
+ return EFalse;
+ }
}
// If HandleCommand() is implemented synchronously, the command must be
// saved before executing as CompleteCommandMessage() closes the string
@@ -2076,7 +2071,7 @@
iCmdData.iReplyExpected = ETrue; // Set before HandleCommandL()
HandleCommandL( aEntrySupport, ETrue );
aEntrySupport.iStartIndex = aStartIndex;
- SendToMultipleSecondaryL( aEntrySupport, atCmdFull );
+ SendToMultipleObserverL( aEntrySupport, atCmdFull );
CleanupStack::PopAndDestroy( atCmdFull );
aReplyExpected = ETrue;
TRACE_FUNC_EXIT
@@ -2084,28 +2079,31 @@
}
// ---------------------------------------------------------------------------
-// Handles support when a secondary plugin is detected in the plugin data via
-// support data's link. If only one secondary plugin is detected then reply is
-// expected from that plugin. Instead, if more than one secondary plugins are
+// Handles support when a observer plugin is detected in the plugin data via
+// support data's link. If only one observer plugin is detected then reply is
+// expected from that plugin. Instead, if more than one observer plugins are
// detected then no reply is expected from them.
// ---------------------------------------------------------------------------
//
-TBool CATExtMetadata::HandleSecondaryPluginSupportL(
+TBool CATExtMetadata::HandleObserverPluginSupportL(
TATExtEntrySupport& aEntrySupport,
TInt aStartIndex,
TBool& aReplyExpected )
{
TRACE_FUNC_ENTRY
aReplyExpected = EFalse;
- TBool supported = HandleCommandSupportL( aEntrySupport );
- if ( !supported )
+ if ( !aEntrySupport.iSupportFound )
{
- TRACE_FUNC_EXIT
- return EFalse;
+ TBool supported = HandleCommandSupportL( aEntrySupport );
+ if ( !supported )
+ {
+ TRACE_FUNC_EXIT
+ return EFalse;
+ }
}
TATExtEntrySupport nextSupport = aEntrySupport;
nextSupport.iStartIndex = aStartIndex;
- TBool entryFound = FindFirstSecondarySupportL( nextSupport );
+ TBool entryFound = FindFirstObserverSupportL( nextSupport );
if ( entryFound )
{
// Entry found; send all without reply request
@@ -2116,7 +2114,7 @@
atCmdFullPtr.Copy( aEntrySupport.iAtCmdFull );
// Now execute the HandleCommand()
HandleCommandL( aEntrySupport, EFalse );
- SendToMultipleSecondaryL( nextSupport, atCmdFull );
+ SendToMultipleObserverL( nextSupport, atCmdFull );
CleanupStack::PopAndDestroy( atCmdFull );
}
else
@@ -2131,6 +2129,41 @@
}
// ---------------------------------------------------------------------------
+// Finds exclusive partial plugin support
+// ---------------------------------------------------------------------------
+//
+TBool CATExtMetadata::FindExclusivePartialSupportL(
+ TATExtEntrySupport& aEntrySupport )
+ {
+ TRACE_FUNC_ENTRY
+ TInt i;
+ TInt supports;
+ TInt count = aEntrySupport.iSupport->Count();
+ for ( i=0,supports=0; i<count; i++ )
+ {
+ TATExtOneCmdSupport& oneCmdSupport = (*aEntrySupport.iSupport)[i];
+ if ( oneCmdSupport.iSupportType == ESupportTypePartial )
+ {
+ aEntrySupport.iSupportFound = EFalse;
+ aEntrySupport.iEntry = &(*iPluginData)[oneCmdSupport.iEntryIndex];
+ TBool supported = HandleCommandSupportL( aEntrySupport );
+ if ( supported )
+ {
+ aEntrySupport.iSupportFound = ETrue;
+ supports++;
+ }
+ if ( supports != 1 )
+ {
+ TRACE_FUNC_EXIT
+ return EFalse;
+ }
+ }
+ }
+ TRACE_FUNC_EXIT
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
// Finds support entries from support data for a given base AT command
// ---------------------------------------------------------------------------
//
@@ -2171,8 +2204,8 @@
}
// Now, as the normal data was inserted *before* the auxiliary data, the
// auxiliary data is in front of the created "support" array for each M, P
- // and S entry. This insertion is faster than the other way around as there
- // can be multiple S plugins for the same command but usually much less
+ // and O entry. This insertion is faster than the other way around as there
+ // can be multiple O plugins for the same command but usually much less
// auxiliary entries for the same command.
#if defined(_DEBUG) && defined( PRJ_PRINT_SUPPORT_DATA )
PrintFoundEntries( support );
@@ -2290,7 +2323,7 @@
iCmdData.iCmdMessage = aEntrySupport.iMessage;
iCmdData.iHandler = aEntrySupport.iEntry;
}
- // No "else" here as HandleCommandL() is used also with secondary plugins
+ // No "else" here as HandleCommandL() is used also with observer plugins
if ( !aAtCmdFull )
{
TRACE_INFO(( _L8("Handling command '%S' for UID:0x%08X, aReplyNeeded=%d..."), &iCmdData.iCmdBuffer, aEntrySupport.iEntry->iPluginUid, aReplyNeeded ));
@@ -2311,11 +2344,11 @@
}
// ---------------------------------------------------------------------------
-// Sends an AT commands to multiple secondary plugins, starting from a given
+// Sends an AT commands to multiple observer plugins, starting from a given
// position.
// ---------------------------------------------------------------------------
//
-void CATExtMetadata::SendToMultipleSecondaryL(
+void CATExtMetadata::SendToMultipleObserverL(
TATExtEntrySupport& aEntrySupport,
const TDesC8* aAtCmdFull )
{
@@ -2330,25 +2363,34 @@
for ( i=aEntrySupport.iStartIndex; i<count; i++ )
{
TATExtOneCmdSupport& oneCmdSupport = (*aEntrySupport.iSupport)[i];
- if ( oneCmdSupport.iSupportType != ESupportTypeSecondary )
+ if ( oneCmdSupport.iSupportType != ESupportTypeObserver )
{
continue;
}
- aEntrySupport.iEntry = &(*iPluginData)[i];
- TBool supported = HandleCommandSupportL( aEntrySupport, aAtCmdFull );
+ aEntrySupport.iEntry = &(*iPluginData)[oneCmdSupport.iEntryIndex];
+ TBool supported = EFalse;
+ if ( !aEntrySupport.iSupportFound )
+ {
+ supported = HandleCommandSupportL( aEntrySupport, aAtCmdFull );
+ }
if ( supported )
{
HandleCommandL( aEntrySupport, EFalse, aAtCmdFull );
+ aEntrySupport.iSupportFound = ETrue;
+ }
+ if ( i < count-1 )
+ {
+ aEntrySupport.iSupportFound = EFalse;
}
}
TRACE_FUNC_EXIT
}
// ---------------------------------------------------------------------------
-// Finds the first secondary plugin support from a given starting position
+// Finds the first observer plugin support from a given starting position
// ---------------------------------------------------------------------------
//
-TBool CATExtMetadata::FindFirstSecondarySupportL(
+TBool CATExtMetadata::FindFirstObserverSupportL(
TATExtEntrySupport& aEntrySupport )
{
TRACE_FUNC_ENTRY
@@ -2362,14 +2404,16 @@
for ( i=aEntrySupport.iStartIndex; i<count; i++ )
{
TATExtOneCmdSupport& oneCmdSupport = (*aEntrySupport.iSupport)[i];
- if ( oneCmdSupport.iSupportType != ESupportTypeSecondary )
+ if ( oneCmdSupport.iSupportType != ESupportTypeObserver )
{
continue;
}
- aEntrySupport.iEntry = &(*iPluginData)[i];
+ aEntrySupport.iSupportFound = EFalse;
+ aEntrySupport.iEntry = &(*iPluginData)[oneCmdSupport.iEntryIndex];
TBool supported = HandleCommandSupportL( aEntrySupport );
if ( supported )
{
+ aEntrySupport.iSupportFound = ETrue;
TRACE_FUNC_EXIT
return ETrue;
}
--- a/bthci/hci2implementations/qdps/symbian/group/qdp_symbian.mmp Fri Jan 15 08:13:17 2010 +0200
+++ b/bthci/hci2implementations/qdps/symbian/group/qdp_symbian.mmp Mon Jan 18 21:23:18 2010 +0200
@@ -28,8 +28,23 @@
SOURCEPATH ../src
-MACRO BROKEN_CASIRA_1_1
-MACRO BROKEN_BELKIN_2_1
+// Macros to enable particular fixes in the QDP:
+//
+// Most controllers require LPM requests to be serialised.
+MACRO SERIAL_LOW_POWER_MODE_REQUESTS
+//
+// CSR controllers (version 1.1) error a set event mask even though it is
+// just the specification default mask that is provided as a parameter.
+MACRO IGNORE_INVALID_HCI_PARAMETER_ERROR_ON_SET_EVENT_MASK_ON_VERSION_1_1
+//
+// Some Broadcom controllers don't complete outstanding events on disconnection.
+// Generally linked with ADD_CONNECTION_HANDLE_FOR_TRUNCATED_INVALID_CONNECTION_HANDLE_ERROR_EVENTS
+MACRO FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
+//
+// Some Broadcom controllers truncate certain command complete events that
+// should include a connection handle (when the reported error is "invalid
+// connection handle". Generally linked with FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
+MACRO ADD_CONNECTION_HANDLE_FOR_TRUNCATED_INVALID_CONNECTION_HANDLE_ERROR_EVENTS
RESOURCE qdp_symbian.rss
--- a/bthci/hci2implementations/qdps/symbian/inc/hcieventmodifiable.h Fri Jan 15 08:13:17 2010 +0200
+++ b/bthci/hci2implementations/qdps/symbian/inc/hcieventmodifiable.h Mon Jan 18 21:23:18 2010 +0200
@@ -47,6 +47,8 @@
*/
void SetErrorCode(THCIErrorCode aErrorCode);
+
+ TPtrC8& EventData();
private:
/* explicit constructor */
--- a/bthci/hci2implementations/qdps/symbian/inc/hcisymbianqdp.h Fri Jan 15 08:13:17 2010 +0200
+++ b/bthci/hci2implementations/qdps/symbian/inc/hcisymbianqdp.h Mon Jan 18 21:23:18 2010 +0200
@@ -24,6 +24,7 @@
#include <bluetooth/hci/hcicmdqueuedecisionplugin.h>
#include <bluetooth/hci/hcicmdqueuedecisioninterface.h>
#include <bluetooth/hci/hcitypes.h>
+#include <bluetooth/hci/hciconsts.h>
/**
This class represents a QDP that is relevant for hardware that is perfect,
@@ -37,69 +38,59 @@
public:
static CHCISymbianQdp* NewL();
+private: // from CHCICmdQueueDecisionPlugin
virtual TAny* Interface(TUid aUid);
- // virtuals from MHCICmdQueueDecisionInterface
+private: // virtuals from MHCICmdQueueDecisionInterface
TBool MhcqdiDoesCommandRequireWorkaround(const CHCICommandQItem& aParent);
-
CHCICommandQItem* MhcqdiGetPreChildCommand(const CHCICommandQItem& aParent,
const CHCICommandQItem* const aPreviousWorkaroundCmd,
const THCIEventBase* const aPreviousCmdResult);
-
CHCICommandQItem* MhcqdiGetPostChildCommand(const CHCICommandQItem& aParent,
const CHCICommandQItem* const aPreviousPostChild,
const THCIEventBase* aPreviousCmdResult);
-
THCIEventBase* MhcqdiGetFakedUnsolicitedEvent(const CHCICommandQItem& aParent,
const THCIEventBase* aPreviousFakedEvent);
-
void MhcqdiCommandAboutToBeDeleted(const CHCICommandQItem& aDyingCmd);
-
TInt MhcqdiCanSend(CHCICommandQItem& aCommand, const TDblQue<const CHCICommandQItem>& aSentCommands);
-
TUint MhcqdiTimeoutRequired(const CHCICommandQItem& aCmdAboutToBeSent);
-
void MhcqdiMatchedEventReceived(const THCIEventBase& aEvent, const CHCICommandQItem& aRelatedCommand);
-
TCommandErroredAction MhcqdiMatchedErrorEventReceived(const THCIEventBase& aErrorEvent,
const CHCICommandQItem& aRelatedCommand);
-
void MhcqdiUnmatchedEventReceived(const THCIEventBase& aEvent);
-
TCommandTimedOutAction MhcqdiCommandTimedOut(const CHCICommandQItem& aCommand,
const TDblQue<const CHCICommandQItem>& aSentCommands,
TUint aCurrentCommandCredits,
TUint& aCreditsToBeRefunded);
-
void MhcqdiSetPhysicalLinksState(const MPhysicalLinksState& aPhysicalLinkState);
-
void MhcqdiSetHardResetInitiator(const MHardResetInitiator& aHardResetInitiator);
-
void MhcqdiSetHCICommandQueue(MHCICommandQueue& aHCICommandQueue);
-
void MhcqdiSetTimeouts(TUint aQueueStarvationTimeout, TUint aMaxHciCommandTimeout);
-
TUint MhcqdiReset();
+private: // from MHCICmdQueueEventModifierInterface
void MhcqemiMatchedEventReceived(THCIEventBase& aEvent, const CHCICommandQItem& aRelatedCommand);
-
void MhcqemiUnmatchedEventReceived(THCIEventBase& aEvent);
+private: // from MHCICmdQueueUtilityUser
void MhcquuSetUtilitiesProvider(MHCICmdQueueUtilities& aProvider);
+
private:
// The initial number of command credits for the HCI Command Queue.
const static TInt KHCIDefaultCmdCredits = 1;
- // Workarounds for broken firmware
- void FirmwareFixIgnoreErrorOnSetEventMaskForCasira(THCIEventBase& aEvent);
- void FirmwareFixFakeCompletionEventsOnDisconnectionForBelkin(THCIEventBase& aEvent);
-
+ // Workarounds for controller problems
+ void FixIgnoreInvalidHciParameterErrorOnSetEventMaskOnVersion1_1(THCIEventBase& aEvent);
+ void FixFakeCompletionEventsOnDisconnection(THCIEventBase& aEvent);
+ void FixAddConnectionHandleForTruncatedInvalidConnectionHandleErrorEvents(THCIEventBase& aEvent, const CHCICommandQItem* aRelatedCommand);
+
private:
CHCISymbianQdp();
private:
MHCICmdQueueUtilities* iProvider;
TUint8 iHCIVersion;
+ TBuf8<KHCIMaxEventSize> iEventModBuffer; // utility buffer for the backend of modified/injected events
};
#endif // HCISYMBIANQDP_H
--- a/bthci/hci2implementations/qdps/symbian/src/hcieventmodifiable.cpp Fri Jan 15 08:13:17 2010 +0200
+++ b/bthci/hci2implementations/qdps/symbian/src/hcieventmodifiable.cpp Mon Jan 18 21:23:18 2010 +0200
@@ -26,6 +26,11 @@
iErrorCode = aErrorCode;
}
+TPtrC8& THCIEventModifiable::EventData()
+ {
+ return iEventData;
+ }
+
THCIEventModifiable::THCIEventModifiable()
: THCIEventBase(KNullDesC8)
{
--- a/bthci/hci2implementations/qdps/symbian/src/hcisymbianqdp.cpp Fri Jan 15 08:13:17 2010 +0200
+++ b/bthci/hci2implementations/qdps/symbian/src/hcisymbianqdp.cpp Mon Jan 18 21:23:18 2010 +0200
@@ -30,12 +30,43 @@
#include <bluetooth/hci/readclockoffsetevent.h>
#include <bluetooth/hci/authenticationcompleteevent.h>
#include <bluetooth/hci/readlocalversioninfocompleteevent.h>
+#include <bluetooth/hci/writelinkpolicysettingscommand.h>
+#include <bluetooth/hci/readlinkpolicysettingscommand.h>
+#include <bluetooth/hci/readlmphandlecommand.h>
+#include <bluetooth/hci/rolediscoverycommand.h>
+#include <bluetooth/hci/sniffsubratingcommand.h>
+#include <bluetooth/hci/flushcommand.h>
+#include <bluetooth/hci/readautomaticflushtimeoutcommand.h>
+#include <bluetooth/hci/writeautomaticflushtimeoutcommand.h>
+#include <bluetooth/hci/readtransmitpowerlevelcommand.h>
+#include <bluetooth/hci/readlinksupervisiontimeoutcommand.h>
+#include <bluetooth/hci/writelinksupervisiontimeoutcommand.h>
+#include <bluetooth/hci/readfailedcontactcountercommand.h>
+#include <bluetooth/hci/resetfailedcontactcountercommand.h>
+#include <bluetooth/hci/readlinkqualitycommand.h>
+#include <bluetooth/hci/readrssicommand.h>
+#include <bluetooth/hci/readafhchannelmapcommand.h>
+#include <bluetooth/hci/readclockcommand.h>
+
#include <bluetooth/logger.h>
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_QDP_SYMBIAN);
#endif
+#ifdef _DEBUG
+PANICCATEGORY("qdpsymbia");
+#endif // _DEBUG
+
+void AppendConnectionHandle(TDes8& aDes, THCIConnectionHandle aConnectionHandle)
+ {
+ LOG_STATIC_FUNC
+ THCIConnHandle connHandle = aConnectionHandle.ConnHandle();
+ LOG1(_L8("Appending connection handle = 0x%04x"), connHandle);
+ TUint8 val[2] = {connHandle & 0xff, connHandle >> 8};
+ aDes.Append(val, 2);
+ }
+
/*static*/ CHCISymbianQdp* CHCISymbianQdp::NewL()
{
LOG_STATIC_FUNC
@@ -121,25 +152,28 @@
{
LOG_FUNC
- if (!aSentCommands.IsEmpty())
- {
- // Def088959 - The following unhandled commands are blocked to avoid operational errors.
- // Note: This workaround currently resides in this Symbian QDP, but may require further
- // modification or placement depending on target hardware characteristics. This workaround
- // may not be required for all controllers.
-
- THCIOpcode opcode=aSentCommands.Last()->Command().Opcode();
- if (opcode == KHoldModeOpcode ||
- opcode == KSniffModeOpcode ||
- opcode == KExitSniffModeOpcode ||
- opcode == KSwitchRoleOpcode ||
- opcode == KParkModeOpcode ||
- opcode == KExitParkModeOpcode)
- {
- return EBlock;
- }
- }
- //otherwise allow command queue to proceed
+#ifdef SERIAL_LOW_POWER_MODE_REQUESTS
+ if (!aSentCommands.IsEmpty())
+ {
+ THCIOpcode opcode = aSentCommands.Last()->Command().Opcode();
+ // The following commands are blocked to avoid ambiguity in matching mode change
+ // events. This ensures they are issued serially to the controller to prevent any confusion.
+ // Note: This workaround currently resides in this Symbian QDP, but may require further
+ // modification or placement depending on target hardware characteristics. This workaround
+ // may not be required for all controllers.
+ if(opcode == KHoldModeOpcode
+ || opcode == KSniffModeOpcode
+ || opcode == KExitSniffModeOpcode
+ || opcode == KSwitchRoleOpcode
+ || opcode == KParkModeOpcode
+ || opcode == KExitParkModeOpcode)
+ {
+ return EBlock;
+ }
+ }
+#endif // SERIAL_LOW_POWER_MODE_REQUESTS
+
+ // if no other issue then allow command queue to proceed
return EContinue;
}
@@ -157,8 +191,8 @@
// Cache the HCI version number of the controller. This allows
// us to ignore errors from specific versions of controllers
- if ( aEvent.EventCode() == ECommandCompleteEvent
- && THCICommandCompleteEvent::Cast(aEvent).CommandOpcode() == KReadLocalVersionInfoOpcode)
+ if(aEvent.EventCode() == ECommandCompleteEvent
+ && THCICommandCompleteEvent::Cast(aEvent).CommandOpcode() == KReadLocalVersionInfoOpcode)
{
const TReadLocalVersionInfoCompleteEvent& readLocalVersionCompleteEvent = TReadLocalVersionInfoCompleteEvent::Cast(aEvent);
iHCIVersion = readLocalVersionCompleteEvent.Version();
@@ -169,14 +203,19 @@
{
LOG_FUNC
-#ifdef BROKEN_CASIRA_1_1
- FirmwareFixIgnoreErrorOnSetEventMaskForCasira(aEvent);
-#endif // BROKEN_CASIRA_1_1
+#ifdef IGNORE_INVALID_HCI_PARAMETER_ERROR_ON_SET_EVENT_MASK_ON_VERSION_1_1
+ FixIgnoreInvalidHciParameterErrorOnSetEventMaskOnVersion1_1(aEvent);
+#endif // IGNORE_INVALID_HCI_PARAMETER_ERROR_ON_SET_EVENT_MASK_ON_VERSION_1_1
-#ifdef BROKEN_BELKIN_2_1
- FirmwareFixFakeCompletionEventsOnDisconnectionForBelkin(aEvent);
-#endif // BROKEN_BELKIN_2_1
+#ifdef FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
+ FixFakeCompletionEventsOnDisconnection(aEvent);
+#endif // FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
+#ifdef ADD_CONNECTION_HANDLE_FOR_TRUNCATED_INVALID_CONNECTION_HANDLE_ERROR_EVENTS
+ FixAddConnectionHandleForTruncatedInvalidConnectionHandleErrorEvents(aEvent, &aRelatedCommand);
+#endif // ADD_CONNECTION_HANDLE_FOR_TRUNCATED_INVALID_CONNECTION_HANDLE_ERROR_EVENTS
+
+ // Don't forget to call the non-modifiable version of this function too
MhcqdiMatchedEventReceived(aEvent, aRelatedCommand);
}
@@ -197,54 +236,171 @@
// Notification function. No need to do anything.
}
-void CHCISymbianQdp::FirmwareFixIgnoreErrorOnSetEventMaskForCasira(THCIEventBase& aEvent)
+void CHCISymbianQdp::FixIgnoreInvalidHciParameterErrorOnSetEventMaskOnVersion1_1(THCIEventBase& aEvent)
{
LOG_FUNC
- // Casiras with 1.1 firmware return an EInvalidHCIParameter error
- // when SetEventMask is called. We still want to call SetEventMask but
- // on this (old/buggy) firmware, ignore the returned EInvalidHCIParameter
+ // Some controllers supporting Bluetooth 1.1 return an EInvalidHCIParameter error
+ // when SetEventMask is called. We still want to call SetEventMask and catch any actual
+ // error in the stack (since it means that stack start up has failed).
+ // In this case, stack start-up is fine, just ignore the returned EInvalidHCIParameter
- if ( aEvent.ErrorCode() == EInvalidHCIParameter
- && aEvent.EventCode() == ECommandCompleteEvent
- && KSetEventMaskOpcode == THCICommandCompleteEvent::Cast(aEvent).CommandOpcode()
- && iHCIVersion == EHWHCIv1_1)
+ if(aEvent.ErrorCode() == EInvalidHCIParameter
+ && aEvent.EventCode() == ECommandCompleteEvent
+ && KSetEventMaskOpcode == THCICommandCompleteEvent::Cast(aEvent).CommandOpcode()
+ && iHCIVersion == EHWHCIv1_1)
{
- THCIEventBase& modevent = const_cast<THCIEventBase&>(aEvent);
- THCIEventModifiable& event = reinterpret_cast<THCIEventModifiable&>(modevent);
+ LOG(_L8("Ignoring Invalid HCI Parameter error for Set Event Mask"));
+ THCIEventModifiable& event = static_cast<THCIEventModifiable&>(aEvent);
event.SetErrorCode(EOK);
}
}
-void CHCISymbianQdp::FirmwareFixFakeCompletionEventsOnDisconnectionForBelkin(THCIEventBase& aEvent)
+void CHCISymbianQdp::FixFakeCompletionEventsOnDisconnection(THCIEventBase& aEvent)
{
LOG_FUNC
- // For Belkin 2.1 controllers, if we receive a "Disconnection Complete Event"
- // then look for a "Authentication Requested" command or "Read Clock Offset" on
- // the sent queue, and if found, then fake up an completion event (with reason
- // code copied from the Disconnection Complete Event) and inject this into the
- // queue. This is because the Belkin 2.1 controllers fail to send a completion
- // event for "Read Clock Offset" and "Request Authentication" (and maybe others)
- // themselves (i.e. these are firmware bugs we're working around)
+ // Some controllers fail to follow the HCI specification w.r.t. events on disconnection.
+ // The specification indicates outstanding data on a connection handle to be considered
+ // removed when a disconnection occurs. Events however are not guarded by such text
+ // and should always be returned (with an appropriate error code).
+ // The command queue expects these events (as it is programmed to the spec) so if a
+ // controller fails to perform the task, we have to make up the shortfall. Currently
+ // the following events are the ones that fail to be generated in the controllers.
+ // This issue has been observed with:
+ //
+ // * Authentication_Complete
+ // * Read_Clock_Offset
- if (aEvent.EventCode() == EDisconnectionCompleteEvent && iHCIVersion == EHWHCIv2_1)
+ if(aEvent.EventCode() == EDisconnectionCompleteEvent)
{
const TDisconnectionCompleteEvent& disconnEvent = TDisconnectionCompleteEvent::Cast(aEvent);
THCIConnectionHandle handle = disconnEvent.ConnectionHandle();
THCIErrorCode reason = static_cast<THCIErrorCode>(disconnEvent.Reason());
- if (iProvider->FindOutstandingCommand(KAuthenticationRequestedOpcode) != NULL)
+ if(iProvider->FindOutstandingCommand(KAuthenticationRequestedOpcode))
{
- TBuf8<KHCIMaxEventSize> eventBuf1;
- TAuthenticationCompleteEvent authenticationCompleteEvent(reason, handle, eventBuf1);
+ LOG(_L8("Injecting Authentication Complete Event"));
+ TAuthenticationCompleteEvent authenticationCompleteEvent(reason, handle, iEventModBuffer);
iProvider->InjectEvent(authenticationCompleteEvent);
}
- if (iProvider->FindOutstandingCommand(KReadClockOffsetOpcode) != NULL)
+ if(iProvider->FindOutstandingCommand(KReadClockOffsetOpcode))
+ {
+ LOG(_L8("Injecting Read Clock Offset Complete Event"));
+ THCIClockOffset clockOffset = 0;
+ TReadClockOffsetEvent readClockOffsetEvent(reason, handle, clockOffset, iEventModBuffer);
+ iProvider->InjectEvent(readClockOffsetEvent);
+ }
+ }
+ }
+
+/**
+Utility template class for FixAddConnectionHandleForTruncatedInvalidConnectionHandleErrorEvents function.
+*/
+template<class XCommandCompleteCommandClass>
+struct AttemptToFixCommandCompleteEvent
+ {
+ static void CheckAndFix(THCICommandCompleteEvent& aEvent, const CHCICommandQItem* aRelatedCommand, TDes8& aNewBuffer, TInt aCorrectSize, TInt aExpectedSizeMissing)
+ {
+ LOG_STATIC_FUNC
+ THCIEventModifiable& event = static_cast<THCIEventModifiable&>(static_cast<THCIEventBase&>(aEvent));
+ // Check to see if the data is truncated - only apply the fix if it is
+ if(event.EventData().Length() == (aCorrectSize-aExpectedSizeMissing))
{
- TBuf8<KHCIMaxEventSize> eventBuf2;
- THCIClockOffset clockOffset = 0;
- TReadClockOffsetEvent readClockOffsetEvent(reason, handle, clockOffset, eventBuf2);
- iProvider->InjectEvent(readClockOffsetEvent);
+ // This is actually a best effort guess that the connection handle is missing. Fixing this isn't simple because
+ // we need a bigger buffer than we may have - so we have to create our own backing buffer for the event.
+ LOG1(_L8("Modifying Command Complete event (opcode = 0x%04x) to add Connection Handle"), aEvent.CommandOpcode());
+ aNewBuffer.FillZ(aCorrectSize); // ensure buffer is clean
+ aNewBuffer.Copy(event.EventData());
+ if(aRelatedCommand)
+ {
+ const XCommandCompleteCommandClass& cmd = static_cast<const XCommandCompleteCommandClass&>(aRelatedCommand->Command());
+ AppendConnectionHandle(aNewBuffer, cmd.ConnectionHandle());
+ }
+ else
+ {
+ // we have no connection handle to insert in, so pick one that can
+ // never be valid.
+ AppendConnectionHandle(aNewBuffer, KInvalidConnectionHandle);
+ }
+ aNewBuffer.SetLength(aCorrectSize);
+ event.EventData().Set(aNewBuffer); // update event to point to new buffer
+ }
+ // Ensure that now the event is correct.
+ ASSERT_DEBUG(event.EventData().Length() == aCorrectSize);
+ }
+ };
+
+void CHCISymbianQdp::FixAddConnectionHandleForTruncatedInvalidConnectionHandleErrorEvents(THCIEventBase& aEvent, const CHCICommandQItem* aRelatedCommand)
+ {
+ LOG_FUNC
+ // Some controllers do not follow the HCI specification in that they do not always return
+ // an event of the correct size - in this case controllers omit a connection handle field when
+ // erroring with "invalid connection handle" error code. One can argue about this but the
+ // command queue is designed with the spec in mind so just adjust the events as appropriate.
+ //
+ // Notably command complete events are the events with issues; if a command status is used
+ // then the error code is communicated without any other parameters, and the resulting events will
+ // not generally be generated (see FixFakeCompletionEventsOnDisconnection).
+ // Current events that have observed (^) this issue (or could potentially have this issue (*)) are:
+ //
+ // ^ Command_Complete (Write_Link_Policy_Settings)
+ // ^ Command_Complete (Read_Link_Policy_Settings)
+ // * Command_Complete (Read_LMP_Handle)
+ // ^ Command_Complete (Role_Discovery)
+ // ^ Command_Complete (Sniff_Subrating)
+ // * Command_Complete (Flush)
+ // * Command_Complete (Read_Auto_Flush_Timeout)
+ // * Command_Complete (Write_Auto_Flush_Timeout)
+ // * Command_Complete (Read_Transmit_Power_Level)
+ // * Command_Complete (Read_Link_Supervision_Timeout)
+ // * Command_Complete (Write_Link_Supervision_Timeout)
+ // * Command_Complete (Read_Failed_Contact_Counter)
+ // * Command_Complete (Reset_Failed_Contact_Counter)
+ // * Command_Complete (Read_Link_Quality)
+ // * Command_Complete (Read_RSSI)
+ // * Command_Complete (Read_AFH_Channel_Map)
+ // * Command_Complete (Read_Clock)
+ //
+ // Only those actually observed as issues are included - the others are commented out for reference
+
+ if(aEvent.ErrorCode() == ENoConnection)
+ {
+ if(aEvent.EventCode() == ECommandCompleteEvent)
+ {
+ THCICommandCompleteEvent& completeEvent = THCICommandCompleteEvent::Cast(aEvent);
+ // Macro to make the code more concise
+ #define _CHECK_AND_FIX(_COMMAND_NAME, _CORRECT_SIZE, _MISSING_SIZE) \
+ case K##_COMMAND_NAME##Opcode:\
+ AttemptToFixCommandCompleteEvent<C##_COMMAND_NAME##Command>::CheckAndFix(completeEvent, aRelatedCommand, iEventModBuffer, (_CORRECT_SIZE), (_MISSING_SIZE));\
+ break
+ switch(completeEvent.CommandOpcode())
+ {
+ _CHECK_AND_FIX(WriteLinkPolicySettings, 8, sizeof(THCIConnHandle));
+ _CHECK_AND_FIX(ReadLinkPolicySettings, 10, sizeof(THCIConnHandle) + sizeof(TUint16));
+ _CHECK_AND_FIX(RoleDiscovery, 9, sizeof(THCIConnHandle) + sizeof(TUint8));
+ _CHECK_AND_FIX(SniffSubrating, 8, sizeof(THCIConnHandle));
+
+ // These below are included as they potentially could have the same problem,
+ // however in practice this issue has not been observed.
+ // _CHECK_AND_FIX(ReadLMPHandle, 13, sizeof(THCIConnHandle) + sizeof(TUint8) + sizeof(TUint32));
+ // _CHECK_AND_FIX(Flush, 8, sizeof(THCIConnHandle) + sizeof(TUint8) + sizeof(TUint32));
+ // _CHECK_AND_FIX(ReadAutomaticFlushTimeout, 10, sizeof(THCIConnHandle) + sizeof(TUint16));
+ // _CHECK_AND_FIX(WriteAutomaticFlushTimeout, 8, sizeof(THCIConnHandle));
+ // _CHECK_AND_FIX(ReadTransmitPowerLevel, 9, sizeof(THCIConnHandle) + sizeof(TUint8));
+ // _CHECK_AND_FIX(ReadLinkSupervisionTimeout, 10, sizeof(THCIConnHandle) + sizeof(TUint16));
+ // _CHECK_AND_FIX(WriteLinkSupervisionTimeout, 8, sizeof(THCIConnHandle));
+ // _CHECK_AND_FIX(ReadFailedContactCounter, 10, sizeof(THCIConnHandle) + sizeof(TUint16));
+ // _CHECK_AND_FIX(ResetFailedContactCounter, 8, sizeof(THCIConnHandle));
+ // _CHECK_AND_FIX(ReadLinkQuality, 9, sizeof(THCIConnHandle));
+ // _CHECK_AND_FIX(ReadRSSI, 9, sizeof(THCIConnHandle) + sizeof(TUint8));
+ // _CHECK_AND_FIX(ReadAFHChannelMap, 19, sizeof(THCIConnHandle) + sizeof(TUint8) + 10);
+ // _CHECK_AND_FIX(ReadClock, 14, sizeof(THCIConnHandle) + sizeof(TUint32) + sizeof(TUint16));
+
+ default:
+ // just ignore
+ break;
+ }
+ #undef _CHECK_AND_FIX
}
}
}
@@ -253,9 +409,9 @@
{
LOG_FUNC
-#ifdef BROKEN_BELKIN_2_1
- FirmwareFixFakeCompletionEventsOnDisconnectionForBelkin(aEvent);
-#endif // BROKEN_BELKIN_2_1
+#ifdef FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
+ FixFakeCompletionEventsOnDisconnection(aEvent);
+#endif // FAKE_COMPLETION_EVENTS_ON_DISCONNECTION
MhcqdiUnmatchedEventReceived(aEvent);
}
@@ -288,7 +444,7 @@
}
void CHCISymbianQdp::MhcqdiSetTimeouts(TUint /*aQueueStarvationTimeout*/,
- TUint /*aMaxHciCommandTimeout*/)
+ TUint /*aMaxHciCommandTimeout*/)
{
LOG_FUNC
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/layers.sysdef.xml Mon Jan 18 21:23:18 2010 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE SystemDefinition SYSTEM "sysdef_1_4_0.dtd" [
+ <!ENTITY layer_real_source_path "sf/os/bt" >
+]>
+
+<SystemDefinition name="bt" schema="1.4.0">
+ <systemModel>
+ <layer name="os_layer">
+ <module name="bt">
+ <unit unitID="lcdo.bt" mrp="" bldFile="&layer_real_source_path;/group" name="bt" />
+ </module>
+ </layer>
+ </systemModel>
+</SystemDefinition>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/package_definition.xml Mon Jan 18 21:23:18 2010 +0200
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+ <package id="bt" name="Bluetooth" levels="adaptation hw-if plugin framework server app-if">
+ <collection id="bluetooth" name="Bluetooth Core" level="framework">
+ <component id="btstack" name="Bluetooth Stack" introduced="6.0" purpose="optional">
+ <unit bldFile="bluetooth/btstack" mrp="bluetooth/btstack/bluetooth_stack.mrp"/>
+ </component>
+ <component id="btcomm" name="Bluetooth CSY" introduced="6.0" purpose="optional" class="plugin">
+ <unit bldFile="bluetooth/btcomm" mrp="bluetooth/btcomm/bluetooth_btcomm.mrp"/>
+ </component>
+ <component id="btsdp" name="Bluetooth SDP" introduced="6.1" purpose="optional">
+ <unit bldFile="bluetooth/btsdp" mrp="bluetooth/btsdp/bluetooth_sdp.mrp"/>
+ </component>
+ <component id="btextnotifiers" name="Bluetooth Notifiers Support" introduced="6.1" purpose="optional">
+ <unit bldFile="bluetooth/btextnotifiers" mrp="bluetooth/btextnotifiers/bluetooth_btextnotifiers.mrp"/>
+ </component>
+ <component id="gavdp" name="Bluetooth GAVDP" introduced="8.1" purpose="optional">
+ <unit bldFile="bluetooth/gavdp/group" mrp="bluetooth/gavdp/group/bluetooth_gavdp.mrp"/>
+ </component>
+ <component id="btexample" name="Bluetooth Examples and Tests" introduced="6.1" purpose="development" filter="test">
+ <unit mrp="bluetooth/btexample/test/bluetooth_tests_examples.mrp" bldFile="bluetooth/btexample/test/group"/>
+ </component>
+ <component id="btlogger" name="Bluetooth Logging Engine" introduced="9.2" purpose="optional">
+ <unit bldFile="bluetooth/btlogger/group" mrp="bluetooth/btlogger/group/bluetooth_logger.mrp"/>
+ </component>
+ <component id="btdocs" name="Bluetooth Documentation" purpose="development" class="doc">
+ <unit mrp="bluetooth/btdocs/bluetooth_documentation.mrp"/>
+ </component>
+ </collection>
+ <collection id="bluetoothmgmt" name="Bluetooth Management" level="plugin">
+ <component id="btmgr" name="Bluetooth Manager" introduced="6.0" purpose="optional">
+ <unit bldFile="bluetoothmgmt/btmgr" mrp="bluetoothmgmt/btmgr/bluetooth_manager.mrp"/>
+ </component>
+ <component id="btconfig" name="Bluetooth Config" purpose="optional" class="config">
+ <unit bldFile="bluetoothmgmt/btconfig" mrp="bluetoothmgmt/btconfig/bluetooth_config.mrp"/>
+ </component>
+ <component id="btrom" name="Bluetooth ROM" introduced="9.1" purpose="optional">
+ <unit bldFile="bluetoothmgmt/btrom" mrp="bluetoothmgmt/btrom/bluetooth_rom.mrp"/>
+ </component>
+ <component id="bluetoothclientlib" name="Bluetooth Client Library" introduced="6.0" purpose="optional">
+ <unit bldFile="bluetoothmgmt/bluetoothclientlib" mrp="bluetoothmgmt/bluetoothclientlib/bluetooth_user.mrp"/>
+ </component>
+ <component id="btcommon" name="Bluetooth Build Utilities" purpose="optional" filter="test">
+ <unit mrp="bluetoothmgmt/btcommon/bluetooth_common.mrp" bldFile="bluetoothmgmt/btcommon"/>
+ </component>
+ </collection>
+ <collection id="bluetoothcommsprofiles" name="Bluetooth Comms Profiles" level="app-if">
+ <component id="btpan" name="Bluetooth PAN Profile" introduced="8.1" purpose="optional" class="plugin">
+ <unit bldFile="bluetoothcommsprofiles/btpan/group" mrp="bluetoothcommsprofiles/btpan/group/bluetooth_pan.mrp"/>
+ </component>
+ </collection>
+ <collection id="bthci" name="Host Controller Interface" level="server">
+ <component id="bthci2" name="Bluetooth HCI Framework 2" introduced="9.2" purpose="optional">
+ <unit bldFile="bthci/bthci2/group" mrp="bthci/bthci2/group/bluetooth_hci_v2_framework.mrp"/>
+ </component>
+ <component id="hciextensioninterface" name="Bluetooth HCI Extension Interface" introduced="6.1" purpose="optional">
+ <unit bldFile="bthci/hciextensioninterface" mrp="bthci/hciextensioninterface/bluetooth_hciproxy.mrp"/>
+ </component>
+ <component id="hci2implementations" name="Bluetooth HCI 2 Reference Implementations" introduced="9.2" purpose="optional" class="plugin">
+ <unit bldFile="bthci/hci2implementations/group" mrp="bthci/hci2implementations/group/bluetooth_hci_v2_implementations.mrp"/>
+ </component>
+ </collection>
+ <collection id="irda" name="IrDA" level="plugin">
+ <component id="irdastack" name="IrDA Stack" purpose="optional">
+ <unit bldFile="irda/irdastack/group" mrp="irda/irdastack/group/infra-red_irda.mrp"/>
+ </component>
+ </collection>
+ <collection id="bluetoothapitest" name="Bluetooth API Tests" level="app-if">
+ <component id="bluetoothsvs" name="Bluetooth Verification Suite" introduced="^3" purpose="development" filter="test">
+ <unit mrp="bluetoothapitest/bluetoothsvs/group/bluetoothsvs.mrp" bldFile="bluetoothapitest/bluetoothsvs/group"/>
+ </component>
+ </collection>
+ <collection id="bt_info" name="Bluetooth Info" level="app-if">
+ <component id="bt_plat" filter="s60" class="api">
+ <unit bldFile="bt_plat/group"/>
+ </component>
+ <component id="bt_metadata" name="Bluetooth Metadata" class="config" introduced="^3" purpose="development" target="desktop">
+ <unit mrp="bt_info/bt_metadata/bt_metadata.mrp"/>
+ </component>
+ </collection>
+ </package>
+</SystemDefinition>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdef_1_4_0.dtd Mon Jan 18 21:23:18 2010 +0200
@@ -0,0 +1,86 @@
+ <!ELEMENT SystemDefinition (systemModel?, build?)>
+ <!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (logicalset* | module*)*>
+ <!ATTLIST layer
+ name CDATA #REQUIRED
+ levels CDATA #IMPLIED
+ span CDATA #IMPLIED>
+ <!ELEMENT logicalset (logicalsubset* | module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalset name CDATA #REQUIRED>
+ <!ELEMENT logicalsubset (module* | unit* | package* | prebuilt*)*>
+ <!ATTLIST logicalsubset name CDATA #REQUIRED>
+ <!ELEMENT module (component* | unit* | package* | prebuilt*)*>
+ <!ATTLIST module
+ name CDATA #REQUIRED
+ level CDATA #IMPLIED>
+ <!ELEMENT component (unit* | package* | prebuilt*)*>
+ <!ATTLIST component name CDATA #REQUIRED>
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+ unitID ID #REQUIRED
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ bldFile CDATA #REQUIRED
+ priority CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT package EMPTY>
+ <!ATTLIST package
+ name CDATA #REQUIRED
+ mrp CDATA #REQUIRED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT prebuilt EMPTY>
+ <!ATTLIST prebuilt
+ name CDATA #REQUIRED
+ version CDATA #REQUIRED
+ late (Y|N) #IMPLIED
+ filter CDATA #IMPLIED
+ contract CDATA #IMPLIED>
+ <!ELEMENT build (option* | target+ | targetList+ | unitList+ | configuration+)*>
+ <!ELEMENT unitList (unitRef+)>
+ <!ATTLIST unitList
+ name ID #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT unitRef EMPTY>
+ <!ATTLIST unitRef unit IDREF #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+ name ID #REQUIRED
+ abldTarget CDATA #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+ name ID #REQUIRED
+ abldOption CDATA #REQUIRED
+ description CDATA #REQUIRED
+ enable (Y | N | y | n) #REQUIRED>
+ <!ELEMENT configuration (unitListRef+ | layerRef+ | task+)*>
+ <!ATTLIST configuration
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ filter CDATA #REQUIRED>
+ <!ELEMENT task ( unitListRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT unitListRef EMPTY>
+ <!ATTLIST unitListRef unitList IDREF #REQUIRED>
+ <!ELEMENT layerRef EMPTY>
+ <!ATTLIST layerRef layerName CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+ command CDATA #REQUIRED
+ targetList IDREFS #IMPLIED
+ unitParallel (Y | N | y | n) #REQUIRED
+ targetParallel (Y | N | y | n) #IMPLIED>
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+ name CDATA #REQUIRED
+ cwd CDATA #REQUIRED
+ command CDATA #REQUIRED>