|
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: IpcClient is the client side implementation |
|
15 * |
|
16 */ |
|
17 #include <memory> |
|
18 #include <sstream> |
|
19 #include <stdlib.h> |
|
20 |
|
21 #include "logger.h" |
|
22 #include "javasymbianoslayer.h" |
|
23 |
|
24 #include "ipcclient.h" |
|
25 #include "rcomms.h" |
|
26 #include "creceiver.h" |
|
27 #include "common.h" |
|
28 |
|
29 namespace java |
|
30 { |
|
31 namespace comms |
|
32 { |
|
33 using java::util::ScopedLock; |
|
34 |
|
35 IpcClient::IpcClient(IpcListener* aListener) : CActive(EPriorityStandard), |
|
36 mAddress(0), mRunning(false), mReceiver(0), mListener(aListener) |
|
37 { |
|
38 } |
|
39 |
|
40 IpcClient::~IpcClient() |
|
41 { |
|
42 } |
|
43 |
|
44 int IpcClient::connect(int aAddr) |
|
45 { |
|
46 ScopedLock lock(mMutex); |
|
47 |
|
48 if (mRunning) return 0; |
|
49 |
|
50 mAddress = aAddr; |
|
51 // create unique thread name |
|
52 std::stringstream name; |
|
53 name << "JavaCommsClient-" << mAddress << "-" << this << "-" << rand(); |
|
54 std::auto_ptr<HBufC> threadName(stringToDes(name.str().c_str())); |
|
55 |
|
56 TInt rc = mThread.Create( |
|
57 threadName->Des(), |
|
58 reinterpret_cast<TThreadFunction>(messageLoop), |
|
59 KCommsStackSize, |
|
60 NULL, |
|
61 this); |
|
62 |
|
63 if (rc == KErrNone) |
|
64 { |
|
65 // make sure that thread has been started ok before we continue. |
|
66 TRequestStatus rendezvousStatus; |
|
67 mThread.Rendezvous(rendezvousStatus); |
|
68 mThread.Resume(); |
|
69 User::WaitForRequest(rendezvousStatus); |
|
70 rc = rendezvousStatus.Int(); |
|
71 if (rc == KErrNone) |
|
72 { |
|
73 mRunning = true; |
|
74 } |
|
75 } |
|
76 |
|
77 if (rc != KErrNone) |
|
78 { |
|
79 mThread.Close(); |
|
80 ELOG3(EJavaComms, "%s failed to java-comms-%d, err = %d", __PRETTY_FUNCTION__, aAddr, rc); |
|
81 } |
|
82 |
|
83 return rc; |
|
84 } |
|
85 |
|
86 void IpcClient::disconnect() |
|
87 { |
|
88 ScopedLock lock(mMutex); |
|
89 |
|
90 if (!mRunning) return; |
|
91 |
|
92 TRequestStatus status; |
|
93 mThread.Logon(status); |
|
94 |
|
95 TRequestStatus* istatus = &iStatus; |
|
96 mThread.RequestComplete(istatus, KErrNone); |
|
97 |
|
98 User::WaitForRequest(status); |
|
99 mThread.Close(); |
|
100 LOG1(EJavaComms, EInfo, "IpcClient disconnected from java-comms-%d", mAddress); |
|
101 } |
|
102 |
|
103 void IpcClient::error(TInt aError) |
|
104 { |
|
105 ELOG2(EJavaComms, "%s, err = %d", __PRETTY_FUNCTION__, aError); |
|
106 TRequestStatus* status = &iStatus; |
|
107 User::RequestComplete(status, aError); |
|
108 } |
|
109 |
|
110 |
|
111 int IpcClient::send(ipcMessage_t* aMsg) |
|
112 { |
|
113 // ScopedLock lock(mMutex); |
|
114 |
|
115 int rc = KErrNotReady; |
|
116 if (mRunning) |
|
117 { |
|
118 std::auto_ptr<HBufC8> msg(messageToDes(*aMsg)); |
|
119 rc = mComms.Send(msg->Des()); |
|
120 } |
|
121 |
|
122 if (rc) |
|
123 { |
|
124 ELOG2(EJavaComms, "%s failed, err = %d", __PRETTY_FUNCTION__, rc); |
|
125 } |
|
126 return rc; |
|
127 } |
|
128 |
|
129 void IpcClient::RunL() |
|
130 { |
|
131 // JELOG2(EJavaComms); |
|
132 mRunning = false; // don't allow sends while exiting |
|
133 |
|
134 mReceiver->Cancel(); |
|
135 mComms.Disconnect(); |
|
136 CActiveScheduler::Stop(); |
|
137 } |
|
138 |
|
139 void IpcClient::DoCancel() |
|
140 { |
|
141 ELOG1(EJavaComms, "%s", __PRETTY_FUNCTION__); |
|
142 } |
|
143 |
|
144 TInt IpcClient::RunError(TInt aError) |
|
145 { |
|
146 ELOG2(EJavaComms, "%s, err = %d", __PRETTY_FUNCTION__, aError); |
|
147 return KErrNone; |
|
148 } |
|
149 |
|
150 void IpcClient::messageLoop(TAny* aArgs) |
|
151 { |
|
152 std::auto_ptr<CTrapCleanup> cleanup(CTrapCleanup::New()); |
|
153 TInt r = KErrNoMemory; |
|
154 if (cleanup.get()) |
|
155 { |
|
156 IpcClient* me = reinterpret_cast<IpcClient*>(aArgs); |
|
157 TRAP(r,me->doMainL()); |
|
158 me->mListener->onExit(); |
|
159 me->mRunning = false; |
|
160 } |
|
161 // disconnect blocks until this notification |
|
162 RThread::Rendezvous(r); |
|
163 } |
|
164 |
|
165 void IpcClient::doMainL() |
|
166 { |
|
167 CActiveScheduler* s = new(ELeave) CActiveScheduler; |
|
168 CleanupStack::PushL(s); |
|
169 CActiveScheduler::Install(s); |
|
170 |
|
171 std::stringstream address; |
|
172 address << "java-comms-" << mAddress; |
|
173 |
|
174 std::auto_ptr<HBufC> serverName(stringToDes(address.str().c_str())); |
|
175 |
|
176 User::LeaveIfError(mComms.Connect(serverName->Des())); |
|
177 LOG1(EJavaComms, EInfo, "IpcClient connected to %s", address.str().c_str()); |
|
178 |
|
179 mReceiver = new(ELeave) CReceiver(*this, *mListener, mComms); |
|
180 CleanupStack::PushL(mReceiver); |
|
181 mReceiver->Receive(); |
|
182 |
|
183 CActiveScheduler::Add(this); |
|
184 iStatus = KRequestPending; |
|
185 SetActive(); |
|
186 |
|
187 // connect blocks until this notification |
|
188 RThread::Rendezvous(KErrNone); |
|
189 mListener->onStart(); |
|
190 |
|
191 CActiveScheduler::Start(); |
|
192 |
|
193 CleanupStack::PopAndDestroy(mReceiver); |
|
194 CleanupStack::PopAndDestroy(s); |
|
195 } |
|
196 |
|
197 } // namespace comms |
|
198 } // namespace java |