]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/libopensrf/osrf_app_session.c
uber-patch from Scott McKellar cleans up large amounts of const-correctness issues...
[OpenSRF.git] / src / libopensrf / osrf_app_session.c
1 #include <opensrf/osrf_app_session.h>
2 #include <time.h>
3
4 /* the global app_session cache */
5 osrfHash* osrfAppSessionCache = NULL;
6
7 // --------------------------------------------------------------------------
8 // --------------------------------------------------------------------------
9 // Request API
10 // --------------------------------------------------------------------------
11
12 /** Allocation and initializes a new app_request object */
13 osrf_app_request* _osrf_app_request_init( 
14                 osrf_app_session* session, osrf_message* msg ) {
15
16         osrf_app_request* req = 
17                 (osrf_app_request*) safe_malloc(sizeof(osrf_app_request));
18
19         req->session            = session;
20         req->request_id = msg->thread_trace;
21         req->complete           = 0;
22         req->payload            = msg;
23         req->result                     = NULL;
24         req->reset_timeout  = 0;
25
26         return req;
27
28 }
29
30
31 void osrfAppSessionCleanup() {
32         osrfHashFree(osrfAppSessionCache);      
33 }
34
35
36
37 /** Frees memory used by an app_request object */
38 void _osrf_app_request_free( void * req ){
39         if( req == NULL ) return;
40         osrfAppRequest* r = (osrfAppRequest*) req;
41         if( r->payload ) osrf_message_free( r->payload );
42         free( r );
43 }
44
45 /** Pushes the given message onto the list of 'responses' to this request */
46 void _osrf_app_request_push_queue( osrf_app_request* req, osrf_message* result ){
47         if(req == NULL || result == NULL) return;
48         osrfLogDebug( OSRF_LOG_MARK,  "App Session pushing request [%d] onto request queue", result->thread_trace );
49         if(req->result == NULL) {
50                 req->result = result;
51
52         } else {
53                 
54                 osrf_message* ptr = req->result;
55                 osrf_message* ptr2 = req->result->next;
56                 while( ptr2 ) {
57                         ptr = ptr2;
58                         ptr2 = ptr2->next;
59                 }
60                 ptr->next = result;
61         }
62 }
63
64 /** Removes this app_request from our session request set */
65 void osrf_app_session_request_finish( 
66                 osrf_app_session* session, int req_id ){
67
68         if(session == NULL) return;
69         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
70         if(req == NULL) return;
71         osrfListRemove( req->session->request_queue, req->request_id );
72 }
73
74
75 void osrf_app_session_request_reset_timeout( osrf_app_session* session, int req_id ) {
76         if(session == NULL) return;
77         osrfLogDebug( OSRF_LOG_MARK, "Resetting request timeout %d", req_id );
78         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
79         if(req == NULL) return;
80         req->reset_timeout = 1;
81 }
82
83 /** Checks the receive queue for messages.  If any are found, the first
84   * is popped off and returned.  Otherwise, this method will wait at most timeout 
85   * seconds for a message to appear in the receive queue.  Once it arrives it is returned.
86   * If no messages arrive in the timeout provided, null is returned.
87   */
88 osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout ) {
89
90         if(req == NULL) return NULL;
91
92         if( req->result != NULL ) {
93                 /* pop off the first message in the list */
94                 osrf_message* tmp_msg = req->result;
95                 req->result = req->result->next;
96                 return tmp_msg;
97         }
98
99         time_t start = time(NULL);      
100         time_t remaining = (time_t) timeout;
101
102         while( remaining >= 0 ) {
103                 /* tell the session to wait for stuff */
104                 osrfLogDebug( OSRF_LOG_MARK,  "In app_request receive with remaining time [%d]", (int) remaining );
105
106                 osrf_app_session_queue_wait( req->session, 0, NULL );
107
108                 if( req->result != NULL ) { /* if we received anything */
109                         /* pop off the first message in the list */
110                         osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
111                         osrf_message* ret_msg = req->result;
112                         osrf_message* tmp_msg = ret_msg->next;
113                         req->result = tmp_msg;
114                         if (ret_msg->sender_locale) {
115                                 if (req->session->session_locale)
116                                         free(req->session->session_locale);
117                                 req->session->session_locale = strdup(ret_msg->sender_locale);
118                         }
119                         return ret_msg;
120                 }
121
122                 if( req->complete )
123                         return NULL;
124
125                 osrf_app_session_queue_wait( req->session, (int) remaining, NULL );
126
127                 if( req->result != NULL ) { /* if we received anything */
128                         /* pop off the first message in the list */
129                         osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
130                         osrf_message* ret_msg = req->result;
131                         osrf_message* tmp_msg = ret_msg->next;
132                         req->result = tmp_msg;
133                         if (ret_msg->sender_locale) {
134                                 if (req->session->session_locale)
135                                         free(req->session->session_locale);
136                                 req->session->session_locale = strdup(ret_msg->sender_locale);
137                         }
138                         return ret_msg;
139                 }
140                 if( req->complete )
141                         return NULL;
142
143                 if(req->reset_timeout) {
144                         remaining = (time_t) timeout;
145                         req->reset_timeout = 0;
146                         osrfLogDebug( OSRF_LOG_MARK, "Received a timeout reset");
147                 } else {
148                         remaining -= (int) (time(NULL) - start);
149                 }
150         }
151
152         osrfLogInfo( OSRF_LOG_MARK, "Returning NULL from app_request_recv after timeout");
153         return NULL;
154 }
155
156 /** Resend this requests original request message */
157 int _osrf_app_request_resend( osrf_app_request* req ) {
158         if(req == NULL) return 0;
159         if(!req->complete) {
160                 osrfLogDebug( OSRF_LOG_MARK,  "Resending request [%d]", req->request_id );
161                 return _osrf_app_session_send( req->session, req->payload );
162         }
163         return 1;
164 }
165
166
167
168 // --------------------------------------------------------------------------
169 // --------------------------------------------------------------------------
170 // Session API
171 // --------------------------------------------------------------------------
172
173 /** returns a session from the global session hash */
174 char* osrf_app_session_set_locale( osrf_app_session* session, const char* locale ) {
175         if (!session || !locale)
176                 return NULL;
177
178         if(session->session_locale)
179                 free(session->session_locale);
180
181         session->session_locale = strdup( locale );
182         return session->session_locale;
183 }
184
185 /** returns a session from the global session hash */
186 osrf_app_session* osrf_app_session_find_session( const char* session_id ) {
187         if(session_id) return osrfHashGet(osrfAppSessionCache, session_id);
188         return NULL;
189 }
190
191
192 /** adds a session to the global session cache */
193 void _osrf_app_session_push_session( osrf_app_session* session ) {
194         if(!session) return;
195         if( osrfAppSessionCache == NULL ) osrfAppSessionCache = osrfNewHash();
196         if( osrfHashGet( osrfAppSessionCache, session->session_id ) ) return;
197         osrfHashSet( osrfAppSessionCache, session, session->session_id );
198 }
199
200 /** Allocates and initializes a new app_session */
201
202 osrf_app_session* osrfAppSessionClientInit( const char* remote_service ) {
203         return osrf_app_client_session_init( remote_service );
204 }
205
206 osrf_app_session* osrf_app_client_session_init( const char* remote_service ) {
207
208         if (!remote_service) {
209                 osrfLogWarning( OSRF_LOG_MARK, "No remote service specified in osrf_app_client_session_init");
210                 return NULL;
211         }
212
213         osrf_app_session* session = safe_malloc(sizeof(osrf_app_session));      
214
215         session->transport_handle = osrf_system_get_transport_client();
216         if( session->transport_handle == NULL ) {
217                 osrfLogWarning( OSRF_LOG_MARK, "No transport client for service 'client'");
218                 free( session );
219                 return NULL;
220         }
221
222         osrfStringArray* arr = osrfNewStringArray(8);
223         osrfConfigGetValueList(NULL, arr, "/domains/domain");
224         char* domain = osrfStringArrayGetString(arr, 0);
225
226         if (!domain) {
227                 osrfLogWarning( OSRF_LOG_MARK, "No domains specified in the OpenSRF config file");
228                 free( session );
229                 osrfStringArrayFree(arr);
230                 return NULL;
231         }
232
233         char* router_name = osrfConfigGetValue(NULL, "/router_name");
234         if (!router_name) {
235                 osrfLogWarning( OSRF_LOG_MARK, "No router name specified in the OpenSRF config file");
236                 free( session );
237                 osrfStringArrayFree(arr);
238                 return NULL;
239         }
240
241         char target_buf[512];
242         target_buf[ 0 ] = '\0';
243
244         int len = snprintf( target_buf, sizeof(target_buf), "%s@%s/%s",
245                         router_name ? router_name : "(null)",
246                         domain ? domain : "(null)",
247                         remote_service ? remote_service : "(null)" );
248         osrfStringArrayFree(arr);
249         //free(domain);
250         free(router_name);
251
252         if( len >= sizeof( target_buf ) ) {
253                 osrfLogWarning( OSRF_LOG_MARK, "Buffer overflow for remote_id");
254                 free( session );
255                 return NULL;
256         }
257
258         session->request_queue = osrfNewList();
259         session->request_queue->freeItem = &_osrf_app_request_free;
260         session->remote_id = strdup(target_buf);
261         session->orig_remote_id = strdup(session->remote_id);
262         session->remote_service = strdup(remote_service);
263         session->session_locale = NULL;
264
265         #ifdef ASSUME_STATELESS
266         session->stateless = 1;
267         osrfLogDebug( OSRF_LOG_MARK, "%s session is stateless", remote_service );
268         #else
269         session->stateless = 0;
270         osrfLogDebug( OSRF_LOG_MARK, "%s session is NOT stateless", remote_service );
271         #endif
272
273         /* build a chunky, random session id */
274         char id[256];
275
276         snprintf(id, sizeof(id), "%f.%d%ld", get_timestamp_millis(), (int)time(NULL), (long) getpid());
277         session->session_id = strdup(id);
278         osrfLogDebug( OSRF_LOG_MARK,  "Building a new client session with id [%s] [%s]", 
279                         session->remote_service, session->session_id );
280
281         session->thread_trace = 0;
282         session->state = OSRF_SESSION_DISCONNECTED;
283         session->type = OSRF_SESSION_CLIENT;
284         //session->next = NULL;
285
286         session->userData = NULL;
287         session->userDataFree = NULL;
288         
289         _osrf_app_session_push_session( session );
290         return session;
291 }
292
293 osrf_app_session* osrf_app_server_session_init( 
294                 const char* session_id, const char* our_app, const char* remote_id ) {
295
296         osrfLogDebug( OSRF_LOG_MARK, "Initing server session with session id %s, service %s,"
297                         " and remote_id %s", session_id, our_app, remote_id );
298
299         osrf_app_session* session = osrf_app_session_find_session( session_id );
300         if(session) return session;
301
302         session = safe_malloc(sizeof(osrf_app_session));        
303
304         session->transport_handle = osrf_system_get_transport_client();
305         if( session->transport_handle == NULL ) {
306                 osrfLogWarning( OSRF_LOG_MARK, "No transport client for service '%s'", our_app );
307                 return NULL;
308         }
309
310         int stateless = 0;
311         char* statel = osrf_settings_host_value("/apps/%s/stateless", our_app );
312         if(statel) stateless = atoi(statel);
313         free(statel);
314
315
316         session->request_queue = osrfNewList();
317         session->request_queue->freeItem = &_osrf_app_request_free;
318         session->remote_id = strdup(remote_id);
319         session->orig_remote_id = strdup(remote_id);
320         session->session_id = strdup(session_id);
321         session->remote_service = strdup(our_app);
322         session->stateless = stateless;
323
324         #ifdef ASSUME_STATELESS
325         session->stateless = 1;
326         #endif
327
328         session->thread_trace = 0;
329         session->state = OSRF_SESSION_DISCONNECTED;
330         session->type = OSRF_SESSION_SERVER;
331
332         session->userData = NULL;
333         session->userDataFree = NULL;
334         
335         _osrf_app_session_push_session( session );
336         return session;
337
338 }
339
340
341
342 /** frees memory held by a session */
343 void _osrf_app_session_free( osrf_app_session* session ){
344         if(session==NULL)
345                 return;
346
347         if( session->userDataFree && session->userData ) 
348                 session->userDataFree(session->userData);
349         
350         if(session->session_locale)
351                 free(session->session_locale);
352
353         free(session->remote_id);
354         free(session->orig_remote_id);
355         free(session->session_id);
356         free(session->remote_service);
357         osrfListFree(session->request_queue);
358         free(session);
359 }
360
361 int osrfAppSessionMakeRequest(
362                 osrf_app_session* session, const jsonObject* params, 
363                 const char* method_name, int protocol, string_array* param_strings ) {
364
365         return osrf_app_session_make_locale_req( session, params, 
366                         method_name, protocol, param_strings, NULL );
367 }
368
369 int osrfAppSessionMakeLocaleRequest(
370                 osrf_app_session* session, const jsonObject* params, const char* method_name,
371                 int protocol, string_array* param_strings, char* locale ) {
372
373         return osrf_app_session_make_locale_req( session, params, 
374                         method_name, protocol, param_strings, locale );
375 }
376
377 int osrf_app_session_make_req( 
378                 osrf_app_session* session, const jsonObject* params, 
379                 const char* method_name, int protocol, string_array* param_strings) {
380
381         return osrf_app_session_make_locale_req(session, params,
382                         method_name, protocol, param_strings, NULL);
383 }
384
385 int osrf_app_session_make_locale_req( 
386                 osrf_app_session* session, const jsonObject* params, const char* method_name,
387                 int protocol, string_array* param_strings, char* locale ) {
388         if(session == NULL) return -1;
389
390         osrfLogMkXid();
391
392         osrf_message* req_msg = osrf_message_init( REQUEST, ++(session->thread_trace), protocol );
393         osrf_message_set_method(req_msg, method_name);
394
395         if (locale) {
396                 osrf_message_set_locale(req_msg, locale);
397         } else if (session->session_locale) {
398                 osrf_message_set_locale(req_msg, session->session_locale);
399         }
400
401         if(params) {
402                 osrf_message_set_params(req_msg, params);
403
404         } else {
405
406                 if(param_strings) {
407                         int i;
408                         for(i = 0; i!= param_strings->size ; i++ ) {
409                                 osrf_message_add_param(req_msg,
410                                         string_array_get_string(param_strings,i));
411                         }
412                 }
413         }
414
415         osrf_app_request* req = _osrf_app_request_init( session, req_msg );
416         if(_osrf_app_session_send( session, req_msg ) ) {
417                 osrfLogWarning( OSRF_LOG_MARK,  "Error sending request message [%d]", session->thread_trace );
418                 return -1;
419         }
420
421         osrfLogDebug( OSRF_LOG_MARK,  "Pushing [%d] onto request queue for session [%s] [%s]",
422                         req->request_id, session->remote_service, session->session_id );
423         osrfListSet( session->request_queue, req, req->request_id ); 
424         return req->request_id;
425 }
426
427 void osrf_app_session_set_complete( osrf_app_session* session, int request_id ) {
428         if(session == NULL)
429                 return;
430
431         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
432         if(req) req->complete = 1;
433 }
434
435 int osrf_app_session_request_complete( const osrf_app_session* session, int request_id ) {
436         if(session == NULL)
437                 return 0;
438         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
439         if(req)
440                 return req->complete;
441         return 0;
442 }
443
444
445 /** Resets the remote connection id to that of the original*/
446 void osrf_app_session_reset_remote( osrf_app_session* session ){
447         if( session==NULL )
448                 return;
449
450         free(session->remote_id);
451         osrfLogDebug( OSRF_LOG_MARK,  "App Session [%s] [%s] resetting remote id to %s",
452                         session->remote_service, session->session_id, session->orig_remote_id );
453
454         session->remote_id = strdup(session->orig_remote_id);
455 }
456
457 void osrf_app_session_set_remote( osrf_app_session* session, const char* remote_id ) {
458         if(session == NULL)
459                 return;
460         if( session->remote_id )
461                 free(session->remote_id );
462         session->remote_id = strdup( remote_id );
463 }
464
465 /** pushes the given message into the result list of the app_request
466   with the given request_id */
467 int osrf_app_session_push_queue( 
468                 osrf_app_session* session, osrf_message* msg ){
469         if(session == NULL || msg == NULL) return 0;
470
471         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, msg->thread_trace );
472         if(req == NULL) return 0;
473         _osrf_app_request_push_queue( req, msg );
474
475         return 0;
476 }
477
478 int osrfAppSessionConnect( osrf_app_session* session ) { 
479         return osrf_app_session_connect(session);
480 }
481
482
483 /** Attempts to connect to the remote service */
484 int osrf_app_session_connect(osrf_app_session* session){
485         
486         if(session == NULL)
487                 return 0;
488
489         if(session->state == OSRF_SESSION_CONNECTED) {
490                 return 1;
491         }
492
493         int timeout = 5; /* XXX CONFIG VALUE */
494
495         osrfLogDebug( OSRF_LOG_MARK,  "AppSession connecting to %s", session->remote_id );
496
497         /* defaulting to protocol 1 for now */
498         osrf_message* con_msg = osrf_message_init( CONNECT, session->thread_trace, 1 );
499         osrf_app_session_reset_remote( session );
500         session->state = OSRF_SESSION_CONNECTING;
501         int ret = _osrf_app_session_send( session, con_msg );
502         osrf_message_free(con_msg);
503         if(ret) return 0;
504
505         time_t start = time(NULL);      
506         time_t remaining = (time_t) timeout;
507
508         while( session->state != OSRF_SESSION_CONNECTED && remaining >= 0 ) {
509                 osrf_app_session_queue_wait( session, remaining, NULL );
510                 remaining -= (int) (time(NULL) - start);
511         }
512
513         if(session->state == OSRF_SESSION_CONNECTED)
514                 osrfLogDebug( OSRF_LOG_MARK, " * Connected Successfully to %s", session->remote_service );
515
516         if(session->state != OSRF_SESSION_CONNECTED)
517                 return 0;
518
519         return 1;
520 }
521
522
523
524 /** Disconnects from the remote service */
525 int osrf_app_session_disconnect( osrf_app_session* session){
526         if(session == NULL)
527                 return 1;
528
529         if(session->state == OSRF_SESSION_DISCONNECTED)
530                 return 1;
531
532         if(session->stateless && session->state != OSRF_SESSION_CONNECTED) {
533                 osrfLogDebug( OSRF_LOG_MARK,  
534                                 "Exiting disconnect on stateless session %s", 
535                                 session->session_id);
536                 return 1;
537         }
538
539         osrfLogDebug(OSRF_LOG_MARK,  "AppSession disconnecting from %s", session->remote_id );
540
541         osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
542         _osrf_app_session_send( session, dis_msg );
543         session->state = OSRF_SESSION_DISCONNECTED;
544
545         osrf_message_free( dis_msg );
546         osrf_app_session_reset_remote( session );
547         return 1;
548 }
549
550 int osrf_app_session_request_resend( osrf_app_session* session, int req_id ) {
551         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
552         return _osrf_app_request_resend( req );
553 }
554
555
556 int osrfAppSessionSendBatch( osrfAppSession* session, osrf_message* msgs[], int size ) {
557
558         if( !(session && msgs && size > 0) ) return 0;
559         int retval = 0;
560
561         osrfMessage* msg = msgs[0];
562
563         if(msg) {
564
565                 osrf_app_session_queue_wait( session, 0, NULL );
566
567                 if(session->state != OSRF_SESSION_CONNECTED)  {
568
569                         if(session->stateless) { /* stateless session always send to the root listener */
570                                 osrf_app_session_reset_remote(session);
571
572                         } else { 
573
574                                 /* do an auto-connect if necessary */
575                                 if( ! session->stateless &&
576                                         (msg->m_type != CONNECT) && 
577                                         (msg->m_type != DISCONNECT) &&
578                                         (session->state != OSRF_SESSION_CONNECTED) ) {
579
580                                         if(!osrf_app_session_connect( session )) 
581                                                 return 0;
582                                 }
583                         }
584                 }
585         }
586
587         char* string = osrfMessageSerializeBatch(msgs, size);
588
589         if( string ) {
590
591                 transport_message* t_msg = message_init( 
592                                 string, "", session->session_id, session->remote_id, NULL );
593       message_set_osrf_xid( t_msg, osrfLogGetXid() );
594
595                 retval = client_send_message( session->transport_handle, t_msg );
596
597                 if( retval ) osrfLogError(OSRF_LOG_MARK, "client_send_message failed");
598
599                 osrfLogInfo(OSRF_LOG_MARK, "[%s] sent %d bytes of data to %s",
600                         session->remote_service, strlen(string), t_msg->recipient );
601
602                 osrfLogDebug(OSRF_LOG_MARK, "Sent: %s", string );
603
604                 free(string);
605                 message_free( t_msg );
606         }
607
608         return retval; 
609 }
610
611
612
613 int _osrf_app_session_send( osrf_app_session* session, osrf_message* msg ){
614         if( !(session && msg) ) return 0;
615         osrfMessage* a[1];
616         a[0] = msg;
617         return osrfAppSessionSendBatch( session, a, 1 );
618 }
619
620
621
622
623 /**  Waits up to 'timeout' seconds for some data to arrive.
624   * Any data that arrives will be processed according to its
625   * payload and message type.  This method will return after
626   * any data has arrived.
627   */
628 int osrf_app_session_queue_wait( osrf_app_session* session, int timeout, int* recvd ){
629         if(session == NULL) return 0;
630         osrfLogDebug(OSRF_LOG_MARK,  "AppSession in queue_wait with timeout %d", timeout );
631         return osrf_stack_entry_point(session->transport_handle, timeout, recvd);
632 }
633
634 /** Disconnects (if client) and removes the given session from the global session cache 
635   * ! This free's all attached app_requests ! 
636   */
637 void osrfAppSessionFree( osrfAppSession* ses ) {
638         osrf_app_session_destroy( ses );
639 }
640
641
642 void osrf_app_session_destroy( osrf_app_session* session ){
643         if(session == NULL) return;
644
645         osrfLogDebug(OSRF_LOG_MARK,  "AppSession [%s] [%s] destroying self and deleting requests", 
646                         session->remote_service, session->session_id );
647         if(session->type == OSRF_SESSION_CLIENT 
648                         && session->state != OSRF_SESSION_DISCONNECTED ) { /* disconnect if we're a client */
649                 osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
650                 _osrf_app_session_send( session, dis_msg ); 
651                 osrf_message_free(dis_msg);
652         }
653
654         osrfHashRemove( osrfAppSessionCache, session->session_id );
655         _osrf_app_session_free( session );
656 }
657
658 osrf_message* osrfAppSessionRequestRecv(
659                 osrf_app_session* session, int req_id, int timeout ) {
660         return osrf_app_session_request_recv( session, req_id, timeout );
661 }
662 osrf_message* osrf_app_session_request_recv( 
663                 osrf_app_session* session, int req_id, int timeout ) {
664         if(req_id < 0 || session == NULL)
665                 return NULL;
666         osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
667         return _osrf_app_request_recv( req, timeout );
668 }
669
670
671
672 int osrfAppRequestRespond( osrfAppSession* ses, int requestId, const jsonObject* data ) {
673         if(!ses || ! data ) return -1;
674
675         osrf_message* msg = osrf_message_init( RESULT, requestId, 1 );
676         osrf_message_set_status_info( msg, NULL, "OK", OSRF_STATUS_OK );
677         char* json = jsonObjectToJSON( data );
678
679         osrf_message_set_result_content( msg, json );
680         _osrf_app_session_send( ses, msg ); 
681
682         free(json);
683         osrf_message_free( msg );
684
685         return 0;
686 }
687
688
689 int osrfAppRequestRespondComplete( 
690                 osrfAppSession* ses, int requestId, const jsonObject* data ) {
691
692         osrf_message* payload = osrf_message_init( RESULT, requestId, 1 );
693         osrf_message_set_status_info( payload, NULL, "OK", OSRF_STATUS_OK );
694
695         osrf_message* status = osrf_message_init( STATUS, requestId, 1);
696         osrf_message_set_status_info( status, "osrfConnectStatus", "Request Complete", OSRF_STATUS_COMPLETE );
697         
698         if (data) {
699                 char* json = jsonObjectToJSON( data );
700                 osrf_message_set_result_content( payload, json );
701                 free(json);
702
703                 osrfMessage* ms[2];
704                 ms[0] = payload;
705                 ms[1] = status;
706
707                 osrfAppSessionSendBatch( ses, ms, 2 );
708
709                 osrf_message_free( payload );
710         } else {
711                 osrfAppSessionSendBatch( ses, &status, 1 );
712         }
713
714         osrf_message_free( status );
715
716         return 0;
717 }
718
719 int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, char* message ) {
720
721         if(ses) {
722                 osrf_message* msg = osrf_message_init( STATUS, reqId, 1);
723                 osrf_message_set_status_info( msg, name, message, type );
724                 _osrf_app_session_send( ses, msg ); 
725                 osrf_message_free( msg );
726                 return 0;
727         }
728         return -1;
729 }
730
731
732
733
734
735