|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <kernel.h> // For Kern |
|
21 #include <kern_priv.h> // For DMutex |
|
22 |
|
23 #include <mmuxtrxif.h> // For MMuxTrxIf |
|
24 #include <mtrxmuxif.h> // For MTrxMuxIf, EMultiplexer... faults |
|
25 |
|
26 #include "multiplexer.h" // For DMultiplexer |
|
27 #include "mux.h" // For DMux |
|
28 #include "multiplexertrace.h" // For C_TRACE.. |
|
29 |
|
30 // Faults |
|
31 enum TMultiplexerFaults |
|
32 { |
|
33 EMultiplexerMemAllocFailure = 0x00, |
|
34 EMultiplexerMemAllocFailure2, |
|
35 EMultiplexerNullParam, |
|
36 EMultiplexerInvalidTrxId, |
|
37 EMultiplexerMutexCreateFailed, |
|
38 EMultiplexerMutexWaitFailed, |
|
39 }; |
|
40 |
|
41 // CONSTS |
|
42 DMux* DMultiplexer::iShMultiplexers[ EAmountOfTrxs ] = { NULL }; |
|
43 DMutex* DMultiplexer::iShMultiplexersMutex = NULL; |
|
44 _LIT8( KMultiplexerMutex, "KMultiplexerMutex" ); |
|
45 |
|
46 DMultiplexer::DMultiplexer( |
|
47 // None |
|
48 ) |
|
49 { |
|
50 |
|
51 C_TRACE( ( _T( "DMultiplexer::DMultiplexer>" ) ) ); |
|
52 // We need DMutex because lock is held while allocating memory and we do not have strict perf requirements for registerings. |
|
53 TInt err( Kern::MutexCreate( iShMultiplexersMutex, KMultiplexerMutex, KMutexOrdGeneral0 ) ); |
|
54 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EMultiplexerMutexCreateFailed | EDMultiplexerTraceId << KClassIdentifierShift ) ); |
|
55 // No need to protect cause done only from one thread. |
|
56 for( TInt i( 0 ); i < EAmountOfTrxs; i++ ) |
|
57 { |
|
58 iShMultiplexers[ i ] = NULL; |
|
59 } |
|
60 C_TRACE( ( _T( "DMultiplexer::DMultiplexer<" ) ) ); |
|
61 |
|
62 } |
|
63 |
|
64 DMultiplexer::~DMultiplexer( |
|
65 // None |
|
66 ) |
|
67 { |
|
68 |
|
69 C_TRACE( ( _T( "DMultiplexer::~DMultiplexer>" ) ) ); |
|
70 // No protection needed, cause done only when kernel restarts and from one thread. |
|
71 for( TInt i( 0 ); i < EAmountOfTrxs; i++ ) |
|
72 { |
|
73 DMux* temp = iShMultiplexers[ i ]; |
|
74 delete temp; |
|
75 temp = NULL; |
|
76 iShMultiplexers[ i ] = NULL; |
|
77 } |
|
78 // No need to check, either we have it or we had reboted. |
|
79 iShMultiplexersMutex->Close( NULL ); |
|
80 C_TRACE( ( _T( "DMultiplexer::~DMultiplexer<" ) ) ); |
|
81 |
|
82 } |
|
83 |
|
84 /* |
|
85 * Registers a transceiver with unique transceiver identifier to multiplexer. |
|
86 * Returns an interface to transceiver to use multiplexer services. |
|
87 */ |
|
88 MTrxMuxIf* DMultiplexer::RegisterTrx( |
|
89 MMuxTrxIf* aTrx, |
|
90 const TUint8 aTrxId |
|
91 ) |
|
92 { |
|
93 |
|
94 C_TRACE( ( _T( "DMultiplexer::RegisterTrx 0x%x id %d>" ), aTrx, aTrxId ) ); |
|
95 DMux* mux = GetMuxForTrx( aTrxId ); |
|
96 mux->SetTrx( aTrx ); |
|
97 C_TRACE( ( _T( "DMultiplexer::RegisterTrx 0x%x id %d mux 0x%x<" ), aTrx, aTrxId, mux ) ); |
|
98 return mux; |
|
99 |
|
100 } |
|
101 |
|
102 /* |
|
103 * Registers a link with unique link identifier to multiplexer to send and receive data through |
|
104 * transceiver identified with unique transceiver id. |
|
105 * Returns an interface to link to use multiplexer services. |
|
106 */ |
|
107 MLinkMuxIf* DMultiplexer::RegisterLink( |
|
108 MMuxLinkIf* aLink, |
|
109 const TUint8 aTrxId, |
|
110 const TUint8 aLinkId |
|
111 ) |
|
112 { |
|
113 |
|
114 C_TRACE( ( _T( "DMultiplexer::RegisterLink 0x%x id %d %d>" ), aLink, aLinkId, aTrxId ) ); |
|
115 ASSERT_RESET_ALWAYS( ( aLink ), ( EMultiplexerNullParam | EDMultiplexerTraceId << KClassIdentifierShift ) ); |
|
116 ASSERT_RESET_ALWAYS( ( EAmountOfTrxs > aTrxId ), ( EMultiplexerInvalidTrxId | EDMultiplexerTraceId << KClassIdentifierShift ) ); |
|
117 DMux* mux = GetMuxForTrx( aTrxId ); |
|
118 mux->SetLink( aLink, aLinkId ); |
|
119 C_TRACE( ( _T( "DMultiplexer::RegisterLink 0x%x id %d %d mux 0x%x<" ), aLink, aLinkId, aTrxId, mux ) ); |
|
120 return mux; |
|
121 |
|
122 } |
|
123 |
|
124 /* |
|
125 * Creates new multiplexer for transceiver if not existing, if exists selects the existing one. |
|
126 * Returns a pointer to transceivers multiplexer. |
|
127 */ |
|
128 DMux* DMultiplexer::GetMuxForTrx( |
|
129 const TUint8 aTrxId |
|
130 ) |
|
131 { |
|
132 |
|
133 C_TRACE( ( _T( "DMultiplexer::GetMuxForTrx id %d>" ), aTrxId ) ); |
|
134 TInt err( Kern::MutexWait( *iShMultiplexersMutex ) ); |
|
135 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EMultiplexerMutexWaitFailed| EDMultiplexerTraceId << KClassIdentifierShift ) ); |
|
136 DMux* mux = iShMultiplexers[ aTrxId ]; |
|
137 if( !mux ) |
|
138 { |
|
139 DMux* newMux = new DMux( aTrxId ); |
|
140 iShMultiplexers[ aTrxId ] = newMux; |
|
141 mux = newMux; |
|
142 } |
|
143 ASSERT_RESET_ALWAYS( ( mux ), EMultiplexerMemAllocFailure ); |
|
144 Kern::MutexSignal( *iShMultiplexersMutex ); |
|
145 C_TRACE( ( _T( "DMultiplexer::GetMuxForTrx mux 0x%x id %d<" ), mux, aTrxId ) ); |
|
146 return mux; |
|
147 |
|
148 } |
|
149 |
|
150 DECLARE_STANDARD_EXTENSION() |
|
151 { |
|
152 |
|
153 Kern::Printf( "Multiplexer (L2) extension>" ); |
|
154 // Create a container extension |
|
155 DMultiplexer* extension = new DMultiplexer(); |
|
156 ASSERT_RESET_ALWAYS( ( extension ), ( EMultiplexerMemAllocFailure2 | EDMultiplexerTraceId << KClassIdentifierShift ) ); |
|
157 Kern::Printf( "Multiplexer (L2) extension<" ); |
|
158 return extension ? KErrNone : KErrNoMemory; |
|
159 |
|
160 } |