|
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 #include <kernel.h> // For Kern |
|
20 #include "isicommunicationmanager.h" // For DISINameService |
|
21 #include "misiobjectrouterif.h" // For MISIObjectRouterIf |
|
22 #include "isicommunicationmanagertrace.h" // For C_TRACE, ASSERT_RESET.. and fault codes |
|
23 #include "memapi.h" // For MemApi |
|
24 #include <phonetisi.h> // For ISI_HEADER_SIZE |
|
25 #include <pn_const.h> // For PN_OBJ_ROUTING_REQ... |
|
26 #include "nsisi.h" // For PN_NAMESERVICE |
|
27 #include "misiobjectrouterif.h" // For MISIObjectRouterIf |
|
28 #include "iadhelpers.h" // For SET_RECEIVER_OBJ... |
|
29 #include <iscnokiadefinitions.h> // For THIS_DEVICE |
|
30 #include "isaaccessextension.h" // For DIsaAccessExtension |
|
31 #include "isiindicationhandler.h" // For DISIIndicationHandler |
|
32 #include "ape_commgrisi.h" // For APE_COMMGR.. |
|
33 |
|
34 |
|
35 // Faults |
|
36 enum TISICommunicationManagerFaults |
|
37 { |
|
38 EISICommunicationManagerMemAllocFailure = 0x01, |
|
39 EISICommunicationManagerMemAllocFailure1, |
|
40 EISICommunicationManagerNullPointer, |
|
41 EISICommunicationManagerUnknownMessage, |
|
42 EISICommunicationManagerMutexCreateFailed, |
|
43 EISICommunicationManagerMutexWaitFailed, |
|
44 }; |
|
45 |
|
46 |
|
47 /* PUTB8 macro writes byte value to given address. |
|
48 * This macro is used mainly by other PUTBXX macros. |
|
49 */ |
|
50 #define PUTB8(p,v) \ |
|
51 {(*(TUint8 *)(p)) = ((TUint8)(v));} |
|
52 |
|
53 |
|
54 /* PUTB16 macro writes 16-bit value in Big Endian format |
|
55 * to given address. 16-bit value is written as two separate |
|
56 * bytes, and so this macro can write 16-bit value to whatever |
|
57 * address, regardless of the processor alignment restrictions |
|
58 */ |
|
59 #define PUTB16(p,v) \ |
|
60 {PUTB8((p),(TUint16)(v)>>8); PUTB8((TUint8*)(p)+1,v);} |
|
61 |
|
62 |
|
63 /* PUTB32 macro writes 32-bit value in Big Endian format |
|
64 * to given address. 32-bit value is written as four separate |
|
65 * bytes, and so this macro can write 32-bit value to whatever |
|
66 * address, regardless of the processor alignment restrictions |
|
67 */ |
|
68 #define PUTB32(p,v) \ |
|
69 {PUTB16((p),(TUint32)(v)>>16); PUTB16((TUint8*)(p)+2,(TUint32)(v));} |
|
70 |
|
71 |
|
72 /** |
|
73 * Big Endian to local endian type |
|
74 */ |
|
75 /* GETB8 macro returns byte value from given address. |
|
76 * This macro is used mainly by other GETBXX macros. |
|
77 */ |
|
78 #define GETB8(p) \ |
|
79 (*(TUint8 *)(p)) |
|
80 |
|
81 |
|
82 /* GETB16 macro reads 16-bit value in Big Endian format |
|
83 * from given address. 16-bit value is read as two separate |
|
84 * bytes, and so this macro can read 16-bit value from whatever |
|
85 * address, regardless of the processor alignment restrictions |
|
86 */ |
|
87 #define GETB16(p) \ |
|
88 (((TUint16) GETB8(p)<<8) | (TUint16) GETB8((TUint8 *)(p)+1)) |
|
89 |
|
90 |
|
91 /* GETB32 macro reads 32-bit value in Big Endian format |
|
92 * from given address. 32-bit value is read as four separate |
|
93 * bytes, and so this macro can read 32-bit value from whatever |
|
94 * address, regardless of the processor alignment restrictions |
|
95 */ |
|
96 #define GETB32(p) \ |
|
97 (((TUint32) GETB16(p)<<16) | (TUint32) GETB16((TUint8 *)(p)+2)) |
|
98 |
|
99 |
|
100 DMutex* DISICommunicationManager::iCommunicationManagerMutex = NULL; |
|
101 _LIT8( KCommunicationManagerMutex, "KCommunicationManagerMutex" ); |
|
102 |
|
103 const TUint32 KCommunicationManagerUID( 0x2002B3D0 ); |
|
104 const TUint8 KFiller( 0 ); |
|
105 const TInt KInitDfcPriority( 7 ); |
|
106 |
|
107 |
|
108 DISICommunicationManager::DISICommunicationManager( |
|
109 // None |
|
110 ) |
|
111 : iObjId( 0x00 ) |
|
112 { |
|
113 C_TRACE( ( _T( "DISICommunicationManager::DISICommunicationManager 0x%x 0x%x>" ), iObjId, iRouter ) ); |
|
114 iRouter = MISIObjectRouterIf::Connect( KCommunicationManagerUID, iObjId, this ); |
|
115 ASSERT_RESET_ALWAYS( iRouter, ( EISICommunicationManagerNullPointer | EDISICommunicationManagerTraceId << KClassIdentifierShift ) ); |
|
116 // Must be > KMutexOrdGeneral1 for nesting purposes because trx shared memory uses KMutexOrdGeneral1 |
|
117 TInt err( Kern::MutexCreate( iCommunicationManagerMutex, KCommunicationManagerMutex, KMutexOrdGeneral2 ) ); |
|
118 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EISICommunicationManagerMutexCreateFailed | EDISICommunicationManagerTraceId << KClassIdentifierShift ) ); |
|
119 iInitDfc = new TDfc( InitDfc, this, DIsaAccessExtension::GetDFCThread( EIADExtensionDfcQueue ), KInitDfcPriority ); |
|
120 ASSERT_RESET_ALWAYS( iInitDfc, ( EISICommunicationManagerMemAllocFailure | EDISICommunicationManagerTraceId << KClassIdentifierShift ) ); |
|
121 iISIIndicationHandler = new DISIIndicationHandler( iRouter ); |
|
122 ASSERT_RESET_ALWAYS( iISIIndicationHandler, ( EISICommunicationManagerMemAllocFailure1 | EDISICommunicationManagerTraceId << KClassIdentifierShift ) ); |
|
123 iInitDfc->Enque(); |
|
124 C_TRACE( ( _T( "DISICommunicationManager::DISICommunicationManager 0x%x 0x%x<" ), iObjId, iRouter ) ); |
|
125 } |
|
126 |
|
127 void DISICommunicationManager::InitDfc( |
|
128 TAny* aPtr // Pointer to this object. |
|
129 ) |
|
130 { |
|
131 C_TRACE( ( _T( "DISICommunicationManager::InitDfc 0x%x>" ), aPtr ) ); |
|
132 DISICommunicationManager* tmp = reinterpret_cast<DISICommunicationManager*>( aPtr ); |
|
133 tmp->SendNameAddReqs(); |
|
134 C_TRACE( ( _T( "DISICommunicationManager::InitDfc<" ) ) ); |
|
135 } |
|
136 |
|
137 void DISICommunicationManager::SendNameAddReqs() |
|
138 { |
|
139 C_TRACE( ( _T( "DISICommunicationManager::SendNameAddReqs>" ) ) ); |
|
140 //PN_COMMGR name |
|
141 TUint16 msgLength( ISI_HEADER_SIZE + SIZE_PNS_NAME_ADD_REQ ); |
|
142 TDes8& addMsg = MemApi::AllocBlock( msgLength ); |
|
143 addMsg.SetLength( msgLength ); |
|
144 TUint8* addPtr = const_cast<TUint8*>( addMsg.Ptr() ); |
|
145 addPtr[ ISI_HEADER_OFFSET_MEDIA ] = PN_MEDIA_ROUTING_REQ; |
|
146 SET_RECEIVER_DEV( addPtr, PN_DEV_OWN ); |
|
147 SET_SENDER_DEV( addPtr, PN_DEV_OWN ); |
|
148 addPtr[ ISI_HEADER_OFFSET_RESOURCEID ] = PN_NAMESERVICE; |
|
149 SET_LENGTH( addPtr, ( msgLength - PN_HEADER_SIZE ) ); |
|
150 SET_RECEIVER_OBJ( addPtr, PN_OBJ_ROUTER ); |
|
151 SET_SENDER_OBJ( addPtr, PN_OBJ_EVENT_MULTICAST ); |
|
152 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_UTID ] = 0x00; |
|
153 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_SUBFUNCTION ] = PNS_NAME_ADD_REQ; |
|
154 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_RESERVED1 ] = KFiller; |
|
155 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_RESERVED2 ] = KFiller; |
|
156 PUTB32( &addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_NAME ], PN_COMMGR ); |
|
157 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_DEV ] = PN_DEV_OWN; |
|
158 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_OBJ ] = PN_OBJ_EVENT_MULTICAST; |
|
159 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_FLAGS ] = PN_NAME_UNDEF; |
|
160 addPtr[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_RESERVED ] = KFiller; |
|
161 //PN_APE_COMMGR name |
|
162 TDes8& addMsg2 = MemApi::AllocBlock( msgLength ); |
|
163 addMsg2.SetLength( msgLength ); |
|
164 addMsg2.Copy( addMsg ); |
|
165 TUint8* addPtr2 = const_cast<TUint8*>( addMsg2.Ptr() ); |
|
166 PUTB32( &addPtr2[ ISI_HEADER_SIZE + PNS_NAME_ADD_REQ_OFFSET_NAMEENTRY + PN_NAME_SRV_ITEM_STR_OFFSET_NAME ], PN_APE_COMMGR ); |
|
167 iRouter->Send( addMsg, PN_OBJ_EVENT_MULTICAST ); |
|
168 iRouter->Send( addMsg2, PN_OBJ_EVENT_MULTICAST ); |
|
169 C_TRACE( ( _T( "DISICommunicationManager::SendNameAddReqs<" ) ) ); |
|
170 } |
|
171 |
|
172 |
|
173 DISICommunicationManager::~DISICommunicationManager( |
|
174 // None |
|
175 ) |
|
176 { |
|
177 C_TRACE( ( _T( "DISICommunicationManager::~DISICommunicationManager>" ) ) ); |
|
178 if( iISIIndicationHandler ) |
|
179 { |
|
180 delete iISIIndicationHandler; |
|
181 iISIIndicationHandler = NULL; |
|
182 } |
|
183 iInitDfc->Cancel(); |
|
184 delete iInitDfc; |
|
185 iInitDfc = NULL; |
|
186 iCommunicationManagerMutex = NULL; |
|
187 C_TRACE( ( _T( "DISICommunicationManager::~DISICommunicationManager<" ) ) ); |
|
188 } |
|
189 |
|
190 |
|
191 void DISICommunicationManager::Receive( const TDesC8& aMessage ) |
|
192 { |
|
193 C_TRACE( ( _T( "DISICommunicationManager::Receive 0x%x>" ), &aMessage ) ); |
|
194 TInt err( Kern::MutexWait( *iCommunicationManagerMutex ) ); |
|
195 ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EISICommunicationManagerMutexWaitFailed | EDISICommunicationManagerTraceId << KClassIdentifierShift ) ); |
|
196 //TODO check nameadd resps for own nameadd success |
|
197 for( TInt i( 0 ); i < aMessage.Length(); i++ ) |
|
198 { |
|
199 C_TRACE( ( _T( "index[ %d ] data 0x%x"), i, aMessage.Ptr()[i] ) ); |
|
200 } |
|
201 |
|
202 const TUint8* msgPtr( aMessage.Ptr() ); |
|
203 TDes8* blockPtr = reinterpret_cast<TDes8*>( const_cast<TDesC8*>(&aMessage) ); |
|
204 |
|
205 switch( msgPtr[ ISI_HEADER_OFFSET_RESOURCEID ] ) |
|
206 { |
|
207 case PN_COMMGR: |
|
208 { |
|
209 C_TRACE( ( _T( "DISICommunicationManager message to PN_COMMGR" ) ) ); |
|
210 break; |
|
211 } |
|
212 case PN_APE_COMMGR: //PN_APE_COMMGR |
|
213 { |
|
214 if( msgPtr[ ISI_HEADER_OFFSET_MESSAGEID ] == APE_COMMGR_SUBSCRIBE_REQ ) |
|
215 { |
|
216 SendPNSSubscribeResp( *blockPtr ); |
|
217 if( msgPtr[ ISI_HEADER_OFFSET_SENDERDEVICE ] == PN_DEV_OWN ) |
|
218 { |
|
219 C_TRACE( ( _T( "DISICommunicationManager PNS_SUBSCRIBE_REQ from APE" ) ) ); |
|
220 iISIIndicationHandler->Subscribe( *blockPtr ); |
|
221 } |
|
222 } |
|
223 else |
|
224 { |
|
225 C_TRACE( ( _T( "DISICommunicationManager unknown PN_APE_COMMGR message" ) ) ); |
|
226 } |
|
227 break; |
|
228 } |
|
229 default: |
|
230 { |
|
231 C_TRACE( ( _T( "DISICommunicationManager unknown message to communication manager" ) ) ); |
|
232 break; |
|
233 } |
|
234 } |
|
235 MemApi::DeallocBlock( *blockPtr ); |
|
236 Kern::MutexSignal( *iCommunicationManagerMutex ); |
|
237 C_TRACE( ( _T( "DISICommunicationManager::Receive<" ) ) ); |
|
238 } |
|
239 |
|
240 void DISICommunicationManager::SendPNSSubscribeResp( const TDesC8& aMessage ) |
|
241 { |
|
242 C_TRACE( ( _T( "DISICommunicationManager::SendPNSSubscribeResp 0x%x>" ), &aMessage ) ); |
|
243 TUint16 msgLength( ISI_HEADER_SIZE + SIZE_APE_COMMGR_SUBSCRIBE_RESP ); |
|
244 TDes8& respMsg = MemApi::AllocBlock( msgLength ); |
|
245 respMsg.SetLength( msgLength ); |
|
246 TUint8* msgPtr = const_cast<TUint8*>( aMessage.Ptr() ); |
|
247 TUint8* respPtr = const_cast<TUint8*>( respMsg.Ptr() ); |
|
248 respPtr[ ISI_HEADER_OFFSET_MEDIA ] = msgPtr[ ISI_HEADER_OFFSET_MEDIA ]; |
|
249 SET_RECEIVER_DEV( respPtr, msgPtr[ ISI_HEADER_OFFSET_SENDERDEVICE ] ); |
|
250 SET_SENDER_DEV( respPtr, PN_DEV_OWN ); |
|
251 respPtr[ ISI_HEADER_OFFSET_RESOURCEID ] = PN_APE_COMMGR; |
|
252 SET_LENGTH( respPtr, ( msgLength - PN_HEADER_SIZE ) ); |
|
253 SET_RECEIVER_OBJ( respPtr, msgPtr[ ISI_HEADER_OFFSET_SENDEROBJECT ] ); |
|
254 SET_SENDER_OBJ( respPtr, PN_OBJ_ROUTER ); |
|
255 respPtr[ ISI_HEADER_SIZE + APE_COMMGR_SUBSCRIBE_RESP_OFFSET_TRANSID ] = msgPtr[ ISI_HEADER_OFFSET_TRANSID ]; |
|
256 respPtr[ ISI_HEADER_SIZE + APE_COMMGR_SUBSCRIBE_RESP_OFFSET_MESSAGEID ] = APE_COMMGR_SUBSCRIBE_RESP; |
|
257 if( msgPtr[ ISI_HEADER_OFFSET_SENDERDEVICE ] == PN_DEV_OWN ) |
|
258 { |
|
259 respPtr[ ISI_HEADER_SIZE + APE_COMMGR_SUBSCRIBE_RESP_OFFSET_RESULT ] = APE_COMMGR_OK; |
|
260 } |
|
261 else |
|
262 { |
|
263 respPtr[ ISI_HEADER_SIZE + APE_COMMGR_SUBSCRIBE_RESP_OFFSET_RESULT ] = APE_COMMGR_NOT_ALLOWED; |
|
264 } |
|
265 |
|
266 |
|
267 for( TInt i( 0 ); i < respMsg.Length(); i++ ) |
|
268 { |
|
269 C_TRACE( ( _T( "indeksi[ %d ] data 0x%x"), i, respMsg.Ptr()[i] ) ); |
|
270 } |
|
271 |
|
272 iRouter->Send( respMsg, PN_OBJ_EVENT_MULTICAST ); |
|
273 C_TRACE( ( _T( "DISICommunicationManager::SendPNSSubscribeResp<" ) ) ); |
|
274 } |
|
275 |
|
276 |
|
277 DECLARE_STANDARD_EXTENSION() |
|
278 { |
|
279 Kern::Printf( "ISI Communication Manager extension>" ); |
|
280 // Create a container extension |
|
281 DISICommunicationManager* extension = new DISICommunicationManager(); |
|
282 TRACE_ASSERT( extension ); |
|
283 Kern::Printf( "ISI Communication Manager extension<" ); |
|
284 return extension ? KErrNone : KErrNoMemory; |
|
285 } |
|
286 |
|
287 |