Revision: 201001
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 21:23:18 +0200
changeset 1 b4a7eebaaebf
parent 0 29b1cd4cb562
child 2 91980f93208a
Revision: 201001 Kit: 201003
atext/client/src/atextclient.cpp
atext/client/src/atextcommon.cpp
atext/server/inc/atextmetadata.h
atext/server/src/atextmetadata.cpp
bthci/hci2implementations/qdps/symbian/group/qdp_symbian.mmp
bthci/hci2implementations/qdps/symbian/inc/hcieventmodifiable.h
bthci/hci2implementations/qdps/symbian/inc/hcisymbianqdp.h
bthci/hci2implementations/qdps/symbian/src/hcieventmodifiable.cpp
bthci/hci2implementations/qdps/symbian/src/hcisymbianqdp.cpp
layers.sysdef.xml
package_definition.xml
sysdef_1_4_0.dtd
--- 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>