|
1 /* |
|
2 * Copyright (c) 2008 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "btrfcommpushserverconnection.h" |
|
20 #include "fs_methodcall.h" |
|
21 #include "pushexception.h" |
|
22 #include "pusherrorcodes.h" |
|
23 #include "serviceclasshandler.h" |
|
24 #include "bluetoothnamelookup.h" |
|
25 #include "javacommonutils.h" |
|
26 |
|
27 using namespace std; |
|
28 using namespace java::util; |
|
29 using namespace java::push; |
|
30 |
|
31 namespace java |
|
32 { |
|
33 namespace bluetooth |
|
34 { |
|
35 |
|
36 const wchar_t BT_GOEP_PROTOCOL[]=L"btgoep"; |
|
37 |
|
38 OS_EXPORT RFCOMMPushServerConnection::RFCOMMPushServerConnection( |
|
39 const wstring aUri, const wstring aFilter,ServerConnectionFactoryBase* aFactory): |
|
40 mAcceptMonitor(NULL), |
|
41 mConnectionUri(aUri), |
|
42 mConnectionFilter(aFilter), |
|
43 mRFCOMMServer(NULL), |
|
44 mConnectionFactory(aFactory), |
|
45 mIsGOEP(false), |
|
46 mPendingConnection(false), |
|
47 mListening(false), |
|
48 mCreatedByPush(false), |
|
49 mClearServiceClassBitsFlag(true) |
|
50 { |
|
51 JELOG2(EJavaBluetooth); |
|
52 |
|
53 // Create Bluetooth Parameters |
|
54 mBtUrlParams = new BtUrlParams(mConnectionUri, mConnectionFilter); |
|
55 mFunctionServer = new BluetoothFunctionServer(); |
|
56 // Create a Server Object and store it as member. |
|
57 mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer); |
|
58 } |
|
59 |
|
60 OS_EXPORT RFCOMMPushServerConnection::~RFCOMMPushServerConnection() |
|
61 { |
|
62 JELOG2(EJavaBluetooth); |
|
63 delete mBtUrlParams; |
|
64 deleteServer(); |
|
65 delete mFunctionServer; |
|
66 } |
|
67 |
|
68 /** |
|
69 * This method is called by Push framework to start listening. |
|
70 * Steps to be followed to start listening. |
|
71 * 1. Prompt user to switch in Bluetooth if it is switched off. |
|
72 * 2. Create BtRFCOMMServer and ask it to start listening. |
|
73 * |
|
74 * |
|
75 */ |
|
76 OS_EXPORT void RFCOMMPushServerConnection::open(ConnectionListener* aListener) |
|
77 { |
|
78 JELOG2(EJavaBluetooth); |
|
79 mConnectionListener = aListener; |
|
80 |
|
81 bool authenticate = mBtUrlParams->getParamAuthenticate(); |
|
82 bool authorize = mBtUrlParams->getParamAuthorize(); |
|
83 bool encrypt = mBtUrlParams->getParamEncrypt(); |
|
84 |
|
85 int error = 0; |
|
86 |
|
87 // Open RFCOMM Server. |
|
88 error = mRFCOMMServer->openServer(authorize, authenticate, encrypt); |
|
89 if (error < 0) |
|
90 { |
|
91 std::string errTxt("ERROR!!! Unable to Open RFCOMM Server."); |
|
92 throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__, |
|
93 __FUNCTION__, __LINE__); |
|
94 } |
|
95 |
|
96 int channel = mRFCOMMServer->GetRfListeningChannel(); |
|
97 |
|
98 std::wstring uuid = mBtUrlParams->getServiceUuid(); |
|
99 std::wstring serviceName = mBtUrlParams->getParamName(); |
|
100 |
|
101 LOG1(EJavaBluetooth, EInfo, |
|
102 " RFCOMMPushServerConnection::open Protocol:%S", |
|
103 mBtUrlParams->getProtocol().c_str()); |
|
104 if (0 == mBtUrlParams->getProtocol().compare(BT_GOEP_PROTOCOL)) |
|
105 { |
|
106 mIsGOEP = true; |
|
107 } |
|
108 // Initialize Services |
|
109 error = mRFCOMMServer->initializeServiceRecord( |
|
110 channel, uuid,serviceName, mIsGOEP); |
|
111 |
|
112 if (error < 0) |
|
113 { |
|
114 std::string errTxt("ERROR!!! Unable to Initialize channel Server."); |
|
115 throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__, |
|
116 __FUNCTION__, __LINE__); |
|
117 } |
|
118 |
|
119 // Restore Persistent Record (if any) |
|
120 mRFCOMMServer->restorePersistentRecord(); |
|
121 |
|
122 // Ask server to start |
|
123 mRFCOMMServer->asyncAccept(this, mBtUrlParams); |
|
124 |
|
125 // We are listening now. |
|
126 mListening = true; |
|
127 |
|
128 // Reset the flag |
|
129 mClearServiceClassBitsFlag = true; |
|
130 } |
|
131 |
|
132 /* |
|
133 * When server is push registered, and manual launched server is closed, |
|
134 * it is not required to clear the service class bits |
|
135 * associated with this service. |
|
136 */ |
|
137 OS_EXPORT void RFCOMMPushServerConnection::unsetClearServiceClassBitsFlag() |
|
138 { |
|
139 JELOG2(EJavaBluetooth); |
|
140 mClearServiceClassBitsFlag = false; |
|
141 } |
|
142 |
|
143 OS_EXPORT void RFCOMMPushServerConnection::close() |
|
144 { |
|
145 JELOG2(EJavaBluetooth); |
|
146 if (true == mClearServiceClassBitsFlag) |
|
147 { |
|
148 ServiceClassHandler::setDeviceServiceClass(0); |
|
149 } |
|
150 mPendingConnection = false; |
|
151 mAcceptMonitor = NULL; |
|
152 mListening = false; |
|
153 mRFCOMMServer->CloseServer(); |
|
154 } |
|
155 |
|
156 /* |
|
157 * Gets the connection URI used to open this server connection. |
|
158 */ |
|
159 OS_EXPORT std::wstring RFCOMMPushServerConnection::getUri() const |
|
160 { |
|
161 JELOG2(EJavaBluetooth); |
|
162 return mConnectionUri; |
|
163 } |
|
164 |
|
165 /* |
|
166 * Gets the connection Filter string associate with this connection. |
|
167 */ |
|
168 OS_EXPORT std::wstring RFCOMMPushServerConnection::getFilter() const |
|
169 { |
|
170 JELOG2(EJavaBluetooth); |
|
171 return mConnectionFilter; |
|
172 } |
|
173 |
|
174 OS_EXPORT void RFCOMMPushServerConnection::setFilter( |
|
175 const std::wstring& aFilter) |
|
176 { |
|
177 JELOG2(EJavaBluetooth); |
|
178 mConnectionFilter = aFilter; |
|
179 } |
|
180 |
|
181 void RFCOMMPushServerConnection::handleConnectionRequest( |
|
182 BluetoothClientConnection* aClientConnection, TInt err) |
|
183 { |
|
184 JELOG2(EJavaBluetooth); |
|
185 //Here we handle checking of parameters and deciding to invoke push. |
|
186 //Check all parameters |
|
187 if (KErrNone != err) |
|
188 { |
|
189 if (NULL != mAcceptMonitor) |
|
190 { |
|
191 mAcceptMonitor->notify(); |
|
192 } |
|
193 mListening = false; |
|
194 return; |
|
195 } |
|
196 mConnectionFactory->setPendingMsgFlag(mConnectionUri, true); |
|
197 |
|
198 std::wstring* remoteDeviceName = NULL; |
|
199 |
|
200 BluetoothNameLookup * nameLookup = NULL; |
|
201 |
|
202 long long remoteDevAddr = aClientConnection->getRemoteAddress(); |
|
203 |
|
204 TRAPD(lookupErr, |
|
205 { |
|
206 nameLookup = BluetoothNameLookup::NewL(); |
|
207 remoteDeviceName = nameLookup->doDeviceNameLookupL(remoteDevAddr); |
|
208 delete nameLookup; |
|
209 } |
|
210 ); |
|
211 |
|
212 if (KErrNone != lookupErr) |
|
213 { |
|
214 remoteDeviceName = new std::wstring( |
|
215 JavaCommonUtils::longLongToWstring(remoteDevAddr)); |
|
216 } |
|
217 |
|
218 mConnectionListener->msgArrived(*remoteDeviceName); |
|
219 |
|
220 delete remoteDeviceName; |
|
221 |
|
222 // This means that when jsr gets this object, it must complete |
|
223 // acceptAndOpen immediately |
|
224 mPendingConnection = true; |
|
225 mListening = false; |
|
226 |
|
227 // Store this as member. We can later return this when queried from jsr. |
|
228 mClientConnection = aClientConnection; |
|
229 |
|
230 if (NULL != mAcceptMonitor) |
|
231 { |
|
232 mAcceptMonitor->notify(); |
|
233 } |
|
234 } |
|
235 |
|
236 OS_EXPORT void RFCOMMPushServerConnection::setAcceptMonitor( |
|
237 java::util::Monitor* aMonitor) |
|
238 { |
|
239 mAcceptMonitor = aMonitor; |
|
240 mRFCOMMServer->avoidFilter(); |
|
241 } |
|
242 |
|
243 OS_EXPORT void RFCOMMPushServerConnection::unsetAcceptMonitor() |
|
244 { |
|
245 mAcceptMonitor = NULL; |
|
246 } |
|
247 |
|
248 OS_EXPORT bool RFCOMMPushServerConnection::isActive() |
|
249 { |
|
250 JELOG2(EJavaBluetooth); |
|
251 bool result = (mPendingConnection || mListening); |
|
252 LOG1(EJavaBluetooth, EInfo, |
|
253 "+ RFCOMMPushServerConnection::isActive: bool result: %d", result); |
|
254 return result; |
|
255 } |
|
256 |
|
257 OS_EXPORT bool RFCOMMPushServerConnection::isGOEPConnection() |
|
258 { |
|
259 return mIsGOEP; |
|
260 } |
|
261 |
|
262 OS_EXPORT bool RFCOMMPushServerConnection::isConnectionAccepted() |
|
263 { |
|
264 return mPendingConnection; |
|
265 } |
|
266 |
|
267 OS_EXPORT bool RFCOMMPushServerConnection::isListening() |
|
268 { |
|
269 return mListening; |
|
270 } |
|
271 |
|
272 OS_EXPORT bool RFCOMMPushServerConnection::isCreatedByPush() |
|
273 { |
|
274 return mCreatedByPush; |
|
275 } |
|
276 |
|
277 OS_EXPORT void RFCOMMPushServerConnection::setCreatedByPush() |
|
278 { |
|
279 mCreatedByPush = true; |
|
280 } |
|
281 |
|
282 OS_EXPORT |
|
283 RFCOMMServerConnection* RFCOMMPushServerConnection::getServerObject() |
|
284 { |
|
285 JELOG2(EJavaBluetooth); |
|
286 if (mRFCOMMServer) |
|
287 { |
|
288 LOG(EJavaBluetooth,EInfo, |
|
289 "- RFCOMMPushServerConnection::getServerObject Returning existing RFCOMM Server"); |
|
290 return mRFCOMMServer; |
|
291 } |
|
292 else |
|
293 { |
|
294 mRFCOMMServer = new RFCOMMServerConnection(mFunctionServer); |
|
295 LOG(EJavaBluetooth, EInfo, |
|
296 "- RFCOMMPushServerConnection::getServerObject Returning new RFCOMM Server"); |
|
297 return mRFCOMMServer; |
|
298 } |
|
299 } |
|
300 |
|
301 OS_EXPORT void RFCOMMPushServerConnection::deleteServer() |
|
302 { |
|
303 JELOG2(EJavaBluetooth); |
|
304 if (mRFCOMMServer) |
|
305 { |
|
306 delete mRFCOMMServer; |
|
307 mRFCOMMServer = NULL; |
|
308 return; |
|
309 } |
|
310 } |
|
311 |
|
312 OS_EXPORT |
|
313 BluetoothClientConnection* RFCOMMPushServerConnection::getConnectedClient() |
|
314 { |
|
315 JELOG2(EJavaBluetooth); |
|
316 //NOTE: ISSUE: IS there a chance that there can be multiple clients |
|
317 //connecting to the push midlet before launch of midlet? |
|
318 //In that case we need to return clients in the order in which they were |
|
319 //accepted. |
|
320 //Code will be something like return acceptedConnections->deQueue() |
|
321 //and in handleConnectionRequest we must |
|
322 //have acceptedConnection->enQueue(client); |
|
323 // |
|
324 mConnectionFactory->setPendingMsgFlag(mConnectionUri, false); |
|
325 |
|
326 // Handed over the accepted connection. And hence, resetting the flag back |
|
327 mPendingConnection = false; |
|
328 |
|
329 return mClientConnection; |
|
330 } |
|
331 |
|
332 } //end namespace bluetooth |
|
333 } //end namespace java |