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