|
1 /* |
|
2 * Copyright (c) 2004 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 "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: Implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <btmanclient.h> |
|
19 #include <bt_sock.h> |
|
20 |
|
21 #ifdef __SERIES60_ |
|
22 #include <btnotif.h> |
|
23 #endif |
|
24 |
|
25 #include "CTcBtManager.h" |
|
26 #include "TTcBtFactory.h" |
|
27 |
|
28 #include "debuglog.h" |
|
29 |
|
30 /// See https://www.bluetooth.org/foundry/assignnumb/document/service_discovery |
|
31 const TInt KTcSerialClassID( 0x1101 ); |
|
32 const TInt KTcRootBrowseGroup( 0x1002 ); |
|
33 |
|
34 /// Name and description of our BT service in SDP. |
|
35 _LIT( KTcServiceName, "TestClient" ); |
|
36 _LIT( KTcServiceDescription, "Serial IUTCP connection" ); |
|
37 |
|
38 CTcBtManager* CTcBtManager::NewL( const TTcBtFactory& aFactory ) |
|
39 { |
|
40 CTcBtManager* self = new( ELeave ) CTcBtManager( aFactory ); |
|
41 |
|
42 CleanupStack::PushL( self ); |
|
43 self->ConstructL(); |
|
44 CleanupStack::Pop( self ); |
|
45 |
|
46 return self; |
|
47 } |
|
48 |
|
49 CTcBtManager::~CTcBtManager() |
|
50 { |
|
51 LOG( _L("CTcBtManager::~CTcBtManager()") ); |
|
52 Close(); |
|
53 iSockServ.Close(); |
|
54 } |
|
55 |
|
56 CTcBtManager::CTcBtManager( const TTcBtFactory& /*aFactory*/ ) |
|
57 { |
|
58 } |
|
59 |
|
60 void CTcBtManager::ConstructL() |
|
61 { |
|
62 LOG( _L("CTcBtManager::ConstructL()") ); |
|
63 User::LeaveIfError( iSockServ.Connect() ); |
|
64 iConn.SetObserver( this ); |
|
65 iConn.SetConnection( &iSockServ, NULL ); |
|
66 } |
|
67 |
|
68 void CTcBtManager::ConnectL( TInetAddr* /*aRemoteAddr*/ ) |
|
69 { |
|
70 LOG( _L("CTcBtManager::ConnectL()") ); |
|
71 // Make sure that BT is enabled |
|
72 TurnOnBtL(); |
|
73 |
|
74 // Start waiting for connections |
|
75 iConn.ConnectL(); |
|
76 |
|
77 #ifndef __BLUETOOTH_API_V2__ |
|
78 // Define security requirements (lowest possible) |
|
79 SetSecurityL( iConn.LocalPort(), EFalse, EFalse, EFalse ); |
|
80 #endif |
|
81 |
|
82 // Start advertising the local BT channel for our service |
|
83 StartAdvertiserL( iConn.LocalPort() ); |
|
84 LOG( _L("CTcBtManager::ConnectL() end") ); |
|
85 } |
|
86 |
|
87 void CTcBtManager::Close() |
|
88 { |
|
89 LOG( _L("CTcBtManager::Close()") ); |
|
90 // Stop advertising our service |
|
91 StopAdvertiser(); |
|
92 |
|
93 // Shut down the service port |
|
94 iConn.Close(); |
|
95 } |
|
96 |
|
97 void CTcBtManager::Send( const TDesC8& aDes ) |
|
98 { |
|
99 iConn.Send( aDes ); |
|
100 } |
|
101 |
|
102 void CTcBtManager::Receive( TDes8& aDes ) |
|
103 { |
|
104 iConn.Receive( aDes ); |
|
105 } |
|
106 |
|
107 void CTcBtManager::ReceiveOneOrMore( TDes8& aDes ) |
|
108 { |
|
109 iConn.ReceiveOneOrMore( aDes ); |
|
110 } |
|
111 |
|
112 void CTcBtManager::SetObserver( MTcBearerObserver* aObserver ) |
|
113 { |
|
114 iObserver = aObserver; |
|
115 } |
|
116 |
|
117 void CTcBtManager::GetLocalAddressL( TDes& /*aDes*/ ) |
|
118 { |
|
119 User::Leave( KErrNotSupported ); |
|
120 } |
|
121 |
|
122 void CTcBtManager::BearerCompletion( MTcBearerObserver::TOperation aOp, |
|
123 TInt aStatus ) |
|
124 { |
|
125 LOG( _L("CTcBtManager::BearerCompletion( %d, %d ) start"), aOp, aStatus ); |
|
126 if( ( aOp == MTcBearerObserver::EConnect ) && !aStatus ) |
|
127 { |
|
128 // A client has connected, mark the service as fully booked |
|
129 // It's safe to ignore any leaves |
|
130 TRAP_IGNORE( MakeAvailableL( EFalse ) ) |
|
131 } |
|
132 |
|
133 if( iObserver ) |
|
134 { |
|
135 iObserver->BearerCompletion( aOp, aStatus ); |
|
136 } |
|
137 LOG( _L("CTcBtManager::BearerCompletion() end") ); |
|
138 } |
|
139 |
|
140 void CTcBtManager::StartAdvertiserL( TInt aChannel ) |
|
141 { |
|
142 LOG( _L("CTcBtManager::StartAdvertiserL( %d ) start"), aChannel ); |
|
143 StopAdvertiser(); |
|
144 |
|
145 User::LeaveIfError( iSdpServ.Connect() ); |
|
146 User::LeaveIfError( iSdpDb.Open( iSdpServ ) ); |
|
147 |
|
148 // Create service record |
|
149 iSdpDb.CreateServiceRecordL( KTcSerialClassID, iSdpRecord ); |
|
150 |
|
151 LOG( _L("CTcBtManager::StartAdvertiserL() created service record") ); |
|
152 |
|
153 // Add a Protocol to the record |
|
154 CSdpAttrValueDES* protocolDesList = CSdpAttrValueDES::NewDESL( NULL ); |
|
155 CleanupStack::PushL( protocolDesList ); |
|
156 |
|
157 TBuf8< 1 > channel; |
|
158 channel.Append( (TChar)aChannel ); |
|
159 |
|
160 protocolDesList |
|
161 ->StartListL() // List of protocols required for this method |
|
162 ->BuildDESL() |
|
163 ->StartListL() |
|
164 ->BuildUUIDL( KL2CAP ) |
|
165 ->EndListL() |
|
166 |
|
167 ->BuildDESL() |
|
168 ->StartListL() |
|
169 ->BuildUUIDL( KRFCOMM ) |
|
170 ->BuildUintL( channel ) |
|
171 ->EndListL() |
|
172 ->EndListL(); |
|
173 |
|
174 iSdpDb.UpdateAttributeL( iSdpRecord, |
|
175 KSdpAttrIdProtocolDescriptorList, |
|
176 *protocolDesList ); |
|
177 |
|
178 CleanupStack::PopAndDestroy( protocolDesList ); |
|
179 |
|
180 LOG( _L("CTcBtManager::StartAdvertiserL() adding uid") ); |
|
181 |
|
182 // Add a Unique ID to the record |
|
183 iSdpDb.UpdateAttributeL( iSdpRecord, |
|
184 KSdpAttrIdServiceID, |
|
185 0x10001234 ); // REPLACE!! |
|
186 |
|
187 LOG( _L("CTcBtManager::StartAdvertiserL() adding name") ); |
|
188 |
|
189 // Add a name to the record |
|
190 iSdpDb.UpdateAttributeL( iSdpRecord, |
|
191 KSdpAttrIdBasePrimaryLanguage |
|
192 + KSdpAttrIdOffsetServiceName, |
|
193 KTcServiceName ); |
|
194 |
|
195 LOG( _L("CTcBtManager::StartAdvertiserL() adding description") ); |
|
196 |
|
197 // Add a description to the record |
|
198 iSdpDb.UpdateAttributeL( iSdpRecord, |
|
199 KSdpAttrIdBasePrimaryLanguage |
|
200 + KSdpAttrIdOffsetServiceDescription, |
|
201 KTcServiceDescription ); |
|
202 |
|
203 // "Attach" our service to the root browse group. |
|
204 // This is required by some BT devices for successful remote SDP query |
|
205 TUUID rootTUUID( KTcRootBrowseGroup ); |
|
206 CSdpAttrValueUUID* rootBrowseGroupAttr = CSdpAttrValueUUID::NewUUIDL( rootTUUID ); |
|
207 CleanupStack::PushL( rootBrowseGroupAttr ); |
|
208 iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdBrowseGroupList, *rootBrowseGroupAttr ); |
|
209 CleanupStack::PopAndDestroy( rootBrowseGroupAttr ); |
|
210 |
|
211 MakeAvailableL( ETrue ); |
|
212 LOG( _L("CTcBtManager::StartAdvertiserL() end") ); |
|
213 } |
|
214 |
|
215 void CTcBtManager::StopAdvertiser() |
|
216 { |
|
217 LOG( _L("CTcBtManager::StopAdvertiser()") ); |
|
218 if( iSdpDb.SubSessionHandle() && iSdpRecord ) |
|
219 { |
|
220 TRAP_IGNORE( iSdpDb.DeleteRecordL( iSdpRecord ) ) |
|
221 iSdpRecord = 0; |
|
222 } |
|
223 } |
|
224 |
|
225 void CTcBtManager::MakeAvailableL( TBool aIsAvailable ) |
|
226 { |
|
227 // Fully unused (0xFF) or Fully used (0x00) |
|
228 TUint state = aIsAvailable ? 0xFF : 0x00; |
|
229 LOG( _L("CTcBtManager::MakeAvailableL( %d ) start, state = %d"), aIsAvailable, state ); |
|
230 |
|
231 // Update the availibility attribute field |
|
232 iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdServiceAvailability, state ); |
|
233 |
|
234 // Mark the record as changed - by increasing its state number (version) |
|
235 iSdpDb.UpdateAttributeL( iSdpRecord, KSdpAttrIdServiceRecordState, |
|
236 ++iSdpRecordState ); |
|
237 LOG( _L("CTcBtManager::MakeAvailableL() end") ); |
|
238 } |
|
239 |
|
240 // Note that security settings should be implemented for 8.x in BtConnection level |
|
241 // That is not done yet!!!!! TODO when 8.x hw must be used |
|
242 #ifndef __BLUETOOTH_API_V2__ |
|
243 void CTcBtManager::SetSecurityL( TInt aChannel, |
|
244 TBool aAuthentication, |
|
245 TBool aEncryption, |
|
246 TBool aAuthorisation ) |
|
247 { |
|
248 LOG( _L("CTcBtManager::SetSecurityL() start") ); |
|
249 RBTMan secManager; |
|
250 User::LeaveIfError( secManager.Connect() ); |
|
251 CleanupClosePushL( secManager ); |
|
252 |
|
253 RBTSecuritySettings secSession; |
|
254 User::LeaveIfError( secSession.Open( secManager ) ); |
|
255 CleanupClosePushL( secSession ); |
|
256 |
|
257 // Define security requirements for our application and RFCOMM. |
|
258 TBTServiceSecurity settings( TUid::Uid( 0x10001234 ), KSolBtRFCOMM, aChannel ); |
|
259 settings.SetAuthentication( aAuthentication ); |
|
260 settings.SetEncryption( aEncryption ); |
|
261 settings.SetAuthorisation( aAuthorisation ); |
|
262 |
|
263 // Register security settings, wait for async operation to complete |
|
264 TRequestStatus status; |
|
265 secSession.RegisterService( settings, status ); |
|
266 User::WaitForRequest( status ); |
|
267 |
|
268 // Report any errors |
|
269 User::LeaveIfError( status.Int() ); |
|
270 |
|
271 CleanupStack::PopAndDestroy( 2 ); // secSession, secManager |
|
272 LOG( _L("CTcBtManager::SetSecurityL() end") ); |
|
273 } |
|
274 #endif |
|
275 |
|
276 void CTcBtManager::TurnOnBtL() |
|
277 { |
|
278 #ifdef __SERIES60_ |
|
279 LOG( _L("CTcBtManager::TurnOnBtL() start") ); |
|
280 |
|
281 // Connect to notitifier service |
|
282 RNotifier notifier; |
|
283 User::LeaveIfError( notifier.Connect() ); |
|
284 CleanupClosePushL( notifier ); |
|
285 |
|
286 // Request notification about power, don't care about the results |
|
287 // This results in a UI popup being displayed to the user shortly |
|
288 TRequestStatus status; |
|
289 TPckgBuf< TBool > pckg; |
|
290 TPckgBuf< TBool > resultPckg; |
|
291 notifier.StartNotifierAndGetResponse( status, |
|
292 KPowerModeSettingNotifierUid, |
|
293 pckg, |
|
294 resultPckg ); |
|
295 User::WaitForRequest( status ); |
|
296 // Disable error checking. this would make auto-reconnect impossible |
|
297 // The power notifier reports an error if the time between the last |
|
298 // connection attempt and this connection is too small (even if it |
|
299 // doesn't hurt..) |
|
300 //User::LeaveIfError( status.Int() ); |
|
301 |
|
302 notifier.CancelNotifier( KPowerModeSettingNotifierUid ); |
|
303 |
|
304 CleanupStack::PopAndDestroy(); // notifier |
|
305 LOG( _L("CTcBtManager::TurnOnBtL() end") ); |
|
306 #endif |
|
307 } |