|
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 * System Includes |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 #include <assert.h> |
|
22 #include <winsock2.h> |
|
23 #include <rpc/rpc.h> |
|
24 |
|
25 /******************************************************************************* |
|
26 * |
|
27 * Local Includes |
|
28 * |
|
29 ******************************************************************************/ |
|
30 #include "CServiceAgentBase.h" |
|
31 #include "../../Core/UCCS_ServiceValues.h" |
|
32 #include "../../Core/UCCS_ErrorCodes.h" |
|
33 #include "../../../SocketLibrary/socket_helper.h" |
|
34 #include "../../../include/penstd.h" |
|
35 |
|
36 |
|
37 /******************************************************************************* |
|
38 * |
|
39 * Definitions |
|
40 * |
|
41 ******************************************************************************/ |
|
42 #define MAXBUFFERSIZE 2048 |
|
43 |
|
44 |
|
45 /******************************************************************************* |
|
46 * |
|
47 * Macro Functions |
|
48 * |
|
49 ******************************************************************************/ |
|
50 |
|
51 |
|
52 /******************************************************************************* |
|
53 * |
|
54 * Constructor / Destructor |
|
55 * |
|
56 ******************************************************************************/ |
|
57 CServiceAgentBase::CServiceAgentBase() |
|
58 { |
|
59 } |
|
60 |
|
61 |
|
62 CServiceAgentBase::~CServiceAgentBase() |
|
63 { |
|
64 } |
|
65 |
|
66 |
|
67 /******************************************************************************* |
|
68 * |
|
69 * SECTION: Methods to construct and manipulated the reply |
|
70 * |
|
71 ******************************************************************************/ |
|
72 /******************************************************************************* |
|
73 * |
|
74 * PROTECTED METHOD: CreateBaseReply -- IService::IssueCommand() is required to |
|
75 * return a valid request reply record. This record MUST MUST MUST contain a |
|
76 * set of basic fields. This method creates _all_ the basic fields, some will |
|
77 * have to be updated later. |
|
78 * |
|
79 ******************************************************************************/ |
|
80 CDataRecord *CServiceAgentBase::CreateBaseReply( CDataRecord *aRequest ) |
|
81 { |
|
82 CDataRecord *service_request_reply; |
|
83 int err; |
|
84 int service_id; |
|
85 int method_id; |
|
86 char *service_host; |
|
87 char *service_name; |
|
88 char *call; |
|
89 |
|
90 // check params |
|
91 assert( aRequest != NULL ); |
|
92 |
|
93 // create the reply object |
|
94 service_request_reply = new CDataRecord(); |
|
95 assert( service_request_reply != NULL ); |
|
96 |
|
97 // get the service name |
|
98 err = aRequest->GetFieldAsString( "SVCNAME", &service_name ); |
|
99 if( err != UCCS_OK ) |
|
100 { |
|
101 // If the service name does not exist then resort to the legacy method |
|
102 |
|
103 // get the service id |
|
104 err = aRequest->GetFieldAsInt( "SVCID", &service_id ); |
|
105 assert( err == UCCS_OK ); |
|
106 err = aRequest->GetFieldAsString( "SVCHOST", &service_host ); |
|
107 assert( err == UCCS_OK ); |
|
108 service_request_reply->NewField( STD_REPLY_FIELD_SERVICE_ID, service_id ); |
|
109 service_request_reply->NewField( STD_REPLY_FIELD_SERVICE_HOST, service_host ); |
|
110 } |
|
111 else |
|
112 { |
|
113 service_request_reply->NewField( STD_REPLY_FIELD_SERVICE_NAME, service_name ); |
|
114 } |
|
115 |
|
116 // get the methodid -- default to -1 if not there -- error must be caught by caller |
|
117 method_id = -1; |
|
118 aRequest->GetFieldAsInt( "METHODID", &method_id ); |
|
119 |
|
120 // now set all the values |
|
121 service_request_reply->NewField( STD_REPLY_FIELD_METHODID, method_id ); |
|
122 service_request_reply->NewField( STD_REPLY_FIELD_REQUESTCOMPLETIONCODE, ERR_INVALID_ERROR_CODE); |
|
123 service_request_reply->NewField( STD_REPLY_FIELD_REQUESTCOMPLETIONDESC, GetPenstdErrorString(ERR_INVALID_ERROR_CODE) ); |
|
124 |
|
125 // Check to see if this request is a new generic stub call and log the CALL value |
|
126 err = aRequest->GetFieldAsString( "CALL", &call ); |
|
127 if( err == UCCS_OK ) |
|
128 { |
|
129 service_request_reply->NewField( STD_REPLY_FIELD_CALL, call ); |
|
130 } |
|
131 |
|
132 return service_request_reply; |
|
133 } |
|
134 |
|
135 |
|
136 /******************************************************************************* |
|
137 * |
|
138 * PROTECTED METHOD: UpdateCompletionCode |
|
139 * |
|
140 ******************************************************************************/ |
|
141 void CServiceAgentBase::UpdateCompletionCode( CDataRecord *aReply, int aError ) |
|
142 { |
|
143 int completion_code, err, rpc_error_int; |
|
144 char *rpc_error_string; |
|
145 |
|
146 // verify params |
|
147 assert( aReply != NULL ); |
|
148 |
|
149 // a reply can only have it's completion code set once |
|
150 err = aReply->GetFieldAsInt( "REQUESTCOMPLETIONCODE", &completion_code ); |
|
151 assert( err == UCCS_OK ); |
|
152 assert( completion_code == ERR_INVALID_ERROR_CODE ); |
|
153 |
|
154 // now update the record |
|
155 err = aReply->ChangeFieldData( STD_REPLY_FIELD_REQUESTCOMPLETIONCODE, aError ); |
|
156 assert( err == UCCS_OK ); |
|
157 err = aReply->ChangeFieldData( STD_REPLY_FIELD_REQUESTCOMPLETIONDESC, GetPenstdErrorString(aError) ); |
|
158 assert( err == UCCS_OK ); |
|
159 |
|
160 // add any custom fields |
|
161 if( aError == ERR_RPC_ERROR ) { |
|
162 rpc_error_string = GetLastRPCError( &rpc_error_int ); |
|
163 aReply->NewField( "RPC_ERROR_STRING", rpc_error_string ); |
|
164 aReply->NewField( "RPC_ERROR_INT", rpc_error_int ); |
|
165 } |
|
166 } |
|
167 |
|
168 |
|
169 /******************************************************************************* |
|
170 * |
|
171 * PROTECTED METHOD: GetLastRPCError |
|
172 * |
|
173 ******************************************************************************/ |
|
174 char *CServiceAgentBase::GetLastRPCError( int *aIntError ) |
|
175 { |
|
176 *aIntError = NULL; |
|
177 return "(unimplemented)"; |
|
178 } |
|
179 |
|
180 |
|
181 /******************************************************************************* |
|
182 * |
|
183 * SECTION: Stub Helpers |
|
184 * |
|
185 ******************************************************************************/ |
|
186 |
|
187 |
|
188 /******************************************************************************* |
|
189 * |
|
190 * PROTECTED METHOD: GetStringArgument |
|
191 * |
|
192 ******************************************************************************/ |
|
193 int CServiceAgentBase::GetStringArgument( char *aFieldName, char **aOutput, int aParamIndex, int aOptional, CDataRecord *aRequest, CDataRecord *aReply ) |
|
194 { |
|
195 int err; |
|
196 |
|
197 // check params |
|
198 assert( aFieldName != NULL ); |
|
199 assert( aOutput != NULL ); |
|
200 |
|
201 // get the field |
|
202 err = aRequest->GetFieldAsString( aFieldName, aOutput ); |
|
203 |
|
204 // if missing and optional then ok -- DEFAULT IS ALWAYS BE NULL |
|
205 if( (err != UCCS_OK) && (aOptional != 0) ) { |
|
206 *aOutput = NULL; |
|
207 return 0; |
|
208 } |
|
209 |
|
210 // otherwise a missing value is not allowed |
|
211 if( err != UCCS_OK ) { |
|
212 aReply->NewField( "MISSINGPARAMINDEX", aParamIndex ); |
|
213 UpdateCompletionCode( aReply, ERR_MISSING_PARAMETER ); |
|
214 return -1; |
|
215 } |
|
216 |
|
217 // otherwise return OK |
|
218 return 0; |
|
219 } |
|
220 |
|
221 |
|
222 /******************************************************************************* |
|
223 * |
|
224 * PROTECTED METHOD: GetIntegerArgument |
|
225 * |
|
226 ******************************************************************************/ |
|
227 int CServiceAgentBase::GetIntegerArgument( char *aFieldName, int *aOutput, int aParamIndex, int aOptional, CDataRecord *aRequest, CDataRecord *aReply ) |
|
228 { |
|
229 int err; |
|
230 |
|
231 // check params |
|
232 assert( aFieldName != NULL ); |
|
233 assert( aOutput != NULL ); |
|
234 |
|
235 // get the field |
|
236 err = aRequest->GetFieldAsInt( aFieldName, aOutput ); |
|
237 |
|
238 // if missing and optional then ok -- DEFAULT MUST ALWAYS BE NULL |
|
239 if( (err != UCCS_OK) && (aOptional != 0) ) { |
|
240 *aOutput = NULL; |
|
241 return 0; |
|
242 } |
|
243 |
|
244 // otherwise a missing value is not allowed |
|
245 if( err != UCCS_OK ) { |
|
246 aReply->NewField( "MISSINGPARAMINDEX", aParamIndex ); |
|
247 UpdateCompletionCode( aReply, ERR_MISSING_PARAMETER ); |
|
248 return -1; |
|
249 } |
|
250 |
|
251 // otherwise return OK |
|
252 return 0; |
|
253 } |
|
254 |
|
255 /******************************************************************************* |
|
256 * |
|
257 * PROTECTED METHOD: AddIteratedIntegerFieldName |
|
258 * |
|
259 ******************************************************************************/ |
|
260 void CServiceAgentBase::AddIteratedIntegerFieldName( char *aFieldname, int aIndex, int aValue, CDataRecord *aReply ) |
|
261 { |
|
262 int err; |
|
263 char fieldname[MAXBUFFERSIZE]; |
|
264 |
|
265 sprintf( fieldname, "%s_%d", aFieldname, aIndex ); |
|
266 err = aReply->NewField( fieldname, aValue ); |
|
267 assert( err == UCCS_OK ); |
|
268 } |
|
269 |
|
270 |
|
271 /******************************************************************************* |
|
272 * |
|
273 * PROTECTED METHOD: AddIteratedStringFieldName |
|
274 * |
|
275 ******************************************************************************/ |
|
276 void CServiceAgentBase::AddIteratedStringFieldName( char *aFieldname, int aIndex, char *aValue, CDataRecord *aReply ) |
|
277 { |
|
278 int err; |
|
279 char fieldname[MAXBUFFERSIZE]; |
|
280 |
|
281 sprintf( fieldname, "%s_%d", aFieldname, aIndex ); |
|
282 err = aReply->NewField( fieldname, aValue ); |
|
283 assert( err == UCCS_OK ); |
|
284 } |
|
285 |
|
286 |
|
287 /******************************************************************************* |
|
288 * |
|
289 * PROTECTED METHOD: AddressToInt |
|
290 * |
|
291 ******************************************************************************/ |
|
292 int CServiceAgentBase::AddressToInt( char *aAddress ) |
|
293 { |
|
294 int is_ip, addr; |
|
295 struct hostent *hostname; |
|
296 |
|
297 // see if this is an IP address - if so then convert it and return |
|
298 is_ip = is_ip_address( aAddress ); |
|
299 if( is_ip != 0 ) { |
|
300 return inet_addr(aAddress); |
|
301 } |
|
302 |
|
303 // otherwise try and resolve it as a hostname (must be ipv4) |
|
304 hostname = gethostbyname( aAddress ); |
|
305 if( hostname != NULL ) { |
|
306 if( hostname->h_length == 4 ) { |
|
307 addr = *((int*)(hostname->h_addr)); |
|
308 return addr; |
|
309 } |
|
310 } |
|
311 |
|
312 // if this doesn't work then we just send zero to let if fail |
|
313 return 0; |
|
314 } |
|
315 |
|
316 |
|
317 /******************************************************************************* |
|
318 * |
|
319 * PROTECTED METHOD: IntToAddress |
|
320 * |
|
321 ******************************************************************************/ |
|
322 char *CServiceAgentBase::IntToAddress( int aAddr ) |
|
323 { |
|
324 int haddr = ntohl(aAddr); |
|
325 sprintf( iAddressString, "%d.%d.%d.%d", ((haddr>>24)&0x000000FF), |
|
326 ((haddr>>16)&0x000000FF), |
|
327 ((haddr>>8)&0x000000FF), |
|
328 ((haddr>>0)&0x000000FF) ); |
|
329 return iAddressString; |
|
330 } |
|
331 |
|
332 |
|
333 /******************************************************************************* |
|
334 * |
|
335 * PROTECTED METHOD: XdrFree |
|
336 * |
|
337 ******************************************************************************/ |
|
338 void CServiceAgentBase::XdrFree( char **ptr, int *len ) |
|
339 { |
|
340 XDR x; |
|
341 |
|
342 // check params |
|
343 assert( ptr != NULL ); |
|
344 assert( *ptr!= NULL ); |
|
345 assert( len != NULL ); |
|
346 |
|
347 // set the operation |
|
348 x.x_op = XDR_FREE; |
|
349 |
|
350 // now call the free function |
|
351 xdr_bytes( &x, ptr, len, 0xFFFFFFFF ); |
|
352 |
|
353 // done |
|
354 *ptr = NULL; |
|
355 *len = 0; |
|
356 return; |
|
357 } |
|
358 |
|
359 |