|
1 /* |
|
2 * Copyright (c) 2005-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 "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 * This file was autogenerated by rpcgen, but should be modified by the developer. |
|
16 * Make sure you don't use the -component_mod flag in future or this file will be overwritten. |
|
17 * Fri Sep 19 13:14:28 2003 |
|
18 * System Includes |
|
19 * |
|
20 */ |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 #include <stdio.h> |
|
26 #include <unistd.h> |
|
27 #include <errno.h> |
|
28 |
|
29 |
|
30 /**************************************************************************************** |
|
31 * |
|
32 * Local Includes |
|
33 * |
|
34 ***************************************************************************************/ |
|
35 #include "CSvcMobster.h" |
|
36 #include "mobster.h" |
|
37 #include "../ThreadLibrary/CAThread.h" |
|
38 #include "mobster_client_server_protocol.h" |
|
39 |
|
40 |
|
41 /**************************************************************************************** |
|
42 * |
|
43 * Definitions |
|
44 * |
|
45 ***************************************************************************************/ |
|
46 #ifndef WIN32 |
|
47 #define ADDRESS_INTEGER s_addr |
|
48 #define closesocket(x) (shutdown(x,SHUT_RDWR),close(x)) |
|
49 #endif |
|
50 |
|
51 /**************************************************************************************** |
|
52 * |
|
53 * File-scope variables |
|
54 * |
|
55 ***************************************************************************************/ |
|
56 static CComponentManager<CSMobster> *iComponentManager; |
|
57 static CAThread *iServerThread; |
|
58 static int iServerListenSocket, iStopRequestedFlag; |
|
59 |
|
60 /**************************************************************************************** |
|
61 * |
|
62 * Implementation |
|
63 * |
|
64 ***************************************************************************************/ |
|
65 |
|
66 |
|
67 /**************************************************************************************** |
|
68 * |
|
69 * PUBLIC: GetInstanceKeyFromArgs |
|
70 * |
|
71 ***************************************************************************************/ |
|
72 int CSvcMobster::GetInstanceKeyFromArgs( int aMethod, void *aArgs ) |
|
73 { |
|
74 int rv; |
|
75 int *ia; |
|
76 TUUAddress *ua; |
|
77 |
|
78 switch( aMethod ) { |
|
79 |
|
80 case DSTR_REMOVEDEVICE: |
|
81 case GETDEVICEINFO: |
|
82 case GETDEVICELOG: |
|
83 case STOPDEVICE: |
|
84 ia = (int*)aArgs; |
|
85 rv = *ia; |
|
86 break; |
|
87 |
|
88 case SETREMOTEUUADDRESS: |
|
89 ua = (TUUAddress*)aArgs; |
|
90 rv = ua->iDeviceID; |
|
91 break; |
|
92 |
|
93 default: |
|
94 rv = ERR_INVALID_METHOD; |
|
95 break; |
|
96 } |
|
97 return rv; |
|
98 } |
|
99 |
|
100 |
|
101 /**************************************************************************************** |
|
102 * |
|
103 * PUBLIC: SetError |
|
104 * |
|
105 ***************************************************************************************/ |
|
106 int CSvcMobster::SetError( int aMethod, void *aArgs, int aError ) |
|
107 { |
|
108 int rv; |
|
109 TComponentList *cl; |
|
110 TDeviceDesc *dd; |
|
111 TVarData *vd; |
|
112 |
|
113 switch( aMethod ) { |
|
114 |
|
115 case LIST_DEVICES: |
|
116 cl = (TComponentList*)aArgs; |
|
117 if( aError != ERR_NONE ) { |
|
118 if( cl->TComponentList_val != NULL ) { |
|
119 free(cl->TComponentList_val); |
|
120 cl->TComponentList_val = NULL; |
|
121 } |
|
122 cl->TComponentList_len = 0; |
|
123 } |
|
124 rv = ERR_NONE; |
|
125 break; |
|
126 |
|
127 case GETDEVICEINFO: |
|
128 dd = (TDeviceDesc*)aArgs; |
|
129 dd->iMTID = aError; |
|
130 rv = ERR_NONE; |
|
131 break; |
|
132 |
|
133 case GETDEVICELOG: |
|
134 vd = (TVarData*)aArgs; |
|
135 if( aError != ERR_NONE ) { |
|
136 if( vd->TVarData_val != NULL ) { |
|
137 free(vd->TVarData_val); |
|
138 vd->TVarData_val = NULL; |
|
139 } |
|
140 vd->TVarData_len = 0; |
|
141 } |
|
142 rv = ERR_NONE; |
|
143 break; |
|
144 |
|
145 default: |
|
146 rv = ERR_INVALID_METHOD; |
|
147 break; |
|
148 } |
|
149 return rv; |
|
150 } |
|
151 |
|
152 |
|
153 /**************************************************************************************** |
|
154 * |
|
155 * PUBLIC: StartRPCService |
|
156 * |
|
157 ***************************************************************************************/ |
|
158 int CSvcMobster::StartRPCService( CComponentManager<CSMobster> *aComponentManager, TChannelAddress *aArg ) |
|
159 { |
|
160 TThreadError terr; |
|
161 int err; |
|
162 struct sockaddr_in local_address; |
|
163 |
|
164 // prologue |
|
165 assert( iComponentManager == NULL ); |
|
166 assert( iServerThread == NULL ); |
|
167 |
|
168 // create a socket to listen for connections |
|
169 iServerListenSocket = socket( AF_INET, SOCK_STREAM, 0 ); |
|
170 if( iServerListenSocket == -1 ) { |
|
171 return ERR_CREATE_SOCKET_FAILED; |
|
172 } |
|
173 |
|
174 // bind the specified port (ignore address) |
|
175 local_address.sin_family = AF_INET; |
|
176 local_address.sin_addr.ADDRESS_INTEGER = INADDR_ANY; |
|
177 local_address.sin_port = htons(aArg->iPort); |
|
178 err = bind( iServerListenSocket, (struct sockaddr *)&local_address, sizeof(local_address) ); |
|
179 if( err == -1 ) { |
|
180 closesocket( iServerListenSocket ); |
|
181 return ERR_BIND_FAILED; |
|
182 } |
|
183 |
|
184 // listen |
|
185 err = listen( iServerListenSocket, 5 ); |
|
186 if( err == -1 ) { |
|
187 closesocket( iServerListenSocket ); |
|
188 return ERR_LISTEN_FAILED; |
|
189 } |
|
190 |
|
191 // ok the socket is all setup to do an accept - so we pass over to the other thread |
|
192 // and let the main call continue |
|
193 iStopRequestedFlag = 0; |
|
194 iServerThread = new CAThread( "CSvcMobster::iServerThread" ); |
|
195 assert( iServerThread != NULL ); |
|
196 terr = iServerThread->StartThread( (void*)CSvcMobster::WaitForConnectionsFromTerminalEmulations, NULL, &err ); |
|
197 if( terr != TE_NONE ) { |
|
198 closesocket( iServerListenSocket ); |
|
199 delete iServerThread; |
|
200 iServerThread = NULL; |
|
201 return ERR_CREATE_SERVER_THREAD_FAILED; |
|
202 } |
|
203 |
|
204 // done |
|
205 iComponentManager = aComponentManager; |
|
206 return ERR_NONE; |
|
207 } |
|
208 |
|
209 |
|
210 /**************************************************************************************** |
|
211 * |
|
212 * PUBLIC: StopRPCService |
|
213 * |
|
214 ***************************************************************************************/ |
|
215 int CSvcMobster::StopRPCService() |
|
216 { |
|
217 TThreadError terr; |
|
218 |
|
219 // close the socket to stop the thread |
|
220 iStopRequestedFlag = 1; |
|
221 closesocket( iServerListenSocket ); |
|
222 terr = iServerThread->WaitForThread( -1 ); |
|
223 if( terr != TE_NONE ) { |
|
224 fprintf( stderr, "WARNING: CSvcMobster::StopRPCService - WaitForThread returned %d.\n", terr ); |
|
225 } |
|
226 |
|
227 // clean up the thread |
|
228 if( iServerThread != NULL ) { |
|
229 delete iServerThread; |
|
230 iServerThread = NULL; |
|
231 } |
|
232 |
|
233 // reset the component manager (though not responsible for delete) |
|
234 iComponentManager = NULL; |
|
235 return ERR_NONE; |
|
236 } |
|
237 |
|
238 |
|
239 /**************************************************************************************** |
|
240 * |
|
241 * PRIVATE: WaitForConnectionsFromTerminalEmulations |
|
242 * |
|
243 ***************************************************************************************/ |
|
244 void CSvcMobster::WaitForConnectionsFromTerminalEmulations( void ) |
|
245 { |
|
246 int client_sockfd; |
|
247 |
|
248 // repeat until StopRPCService is called (or an error occurs) |
|
249 while( 1 ) { |
|
250 |
|
251 // wait for a connection |
|
252 client_sockfd = accept( iServerListenSocket, NULL, NULL ); |
|
253 if( client_sockfd == -1 ) { |
|
254 if( ((errno != 0) && (errno != EINVAL)) || ((errno == EINVAL) && (iStopRequestedFlag == 0)) ) { |
|
255 fprintf( stderr, "WARNING: Accept has failed with errno = %d.\n", errno ); |
|
256 } |
|
257 break; |
|
258 } |
|
259 |
|
260 // we have a socket -- now it has to do the c/s protocol so that we know which |
|
261 // MT to connect it to -- but if there is a problem then this could block |
|
262 // forever -- so I'm going to create a thread per connection to deal with this. |
|
263 // These threads are responsible for cleaning themselves up. |
|
264 #ifdef WIN32 |
|
265 { |
|
266 HANDLE client_thread; |
|
267 client_thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)CSvcMobster::ConnectClientToMobileTermination, (void*)client_sockfd, 0, NULL ); |
|
268 if( client_thread == NULL ) { |
|
269 fprintf( stderr, "WARNING: Failed to create the client thread to connect to MobileTermination (%d).\n", GetLastError() ); |
|
270 } |
|
271 client_thread = NULL; |
|
272 #else |
|
273 { |
|
274 int err; |
|
275 pthread_t client_thread; |
|
276 err = pthread_create( &client_thread, NULL, (void*(*)(void*))(CSvcMobster::ConnectClientToMobileTermination), (void*)client_sockfd ); |
|
277 if( err != 0 ) { |
|
278 fprintf( stderr, "WARNING: Failed to create the client thread to connect to MobileTermination (%d).\n", errno ); |
|
279 } |
|
280 client_thread = 0; |
|
281 } |
|
282 #endif |
|
283 |
|
284 // this is all we have to do |
|
285 } |
|
286 |
|
287 // done |
|
288 return; |
|
289 } |
|
290 |
|
291 |
|
292 /**************************************************************************************** |
|
293 * |
|
294 * PRIVATE: ConnectClientToMobileTermination |
|
295 * |
|
296 ***************************************************************************************/ |
|
297 void CSvcMobster::ConnectClientToMobileTermination( int aSock ) |
|
298 { |
|
299 int mtid, err; |
|
300 CSMobster *mt; |
|
301 |
|
302 // do the csprotocol across the socket to get the config info |
|
303 mtid = client_server_protocol( aSock ); |
|
304 if( mtid < 0 ) { |
|
305 fprintf( stderr, "WARNING: Invalid MTID received (%d).\n", mtid ); |
|
306 closesocket( aSock ); |
|
307 return; |
|
308 } |
|
309 |
|
310 // try and get the instance |
|
311 mt = iComponentManager->GetInstance( mtid ); |
|
312 if( mt == NULL ) { |
|
313 fprintf( stderr, "WARNING: Client requested non-existant device %d.\n", mtid ); |
|
314 closesocket( aSock ); |
|
315 return; |
|
316 } |
|
317 |
|
318 // pass the new socket to the mt |
|
319 err = mt->settesocket( aSock ); |
|
320 if( err != ERR_NONE ) { |
|
321 fprintf( stderr, "WARNING: Failed to set the socket on device %d (%d).\n", mtid, err ); |
|
322 closesocket( aSock ); |
|
323 return; |
|
324 } |
|
325 |
|
326 // all done -- thread exit |
|
327 #ifdef WIN32 |
|
328 ExitThread( 0 ); |
|
329 #else |
|
330 pthread_exit( 0 ); |
|
331 #endif |
|
332 } |
|
333 |