/* $Id$ */ /* Copyright (c) 2011-2020 Pierre Pronchery */ /* This file is part of DeforaOS System libApp */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "App/appclient.h" #include "App/appmessage.h" #include "apptransport.h" #include "appinterface.h" /* AppClient */ /* private */ /* types */ struct _AppClient { App * app; AppInterface * interface; Event * event; int event_free; AppTransport * transport; AppTransportHelper helper; }; /* prototypes */ /* helpers */ static int _appclient_helper_message(void * data, AppTransport * transport, AppTransportClient * client, AppMessage * message); /* public */ /* functions */ /* appclient_new */ AppClient * appclient_new(App * self, char const * app, char const * name) { return appclient_new_event(self, app, name, NULL); } /* appclient_new_event */ AppClient * appclient_new_event(App * self, char const * app, char const * name, Event * event) { AppClient * appclient; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\", %p)\n", __func__, app, name, (void *)event); #endif if((appclient = object_new(sizeof(*appclient))) == NULL) return NULL; appclient->app = self; appclient->interface = appinterface_new(ATM_CLIENT, app); appclient->helper.data = appclient; appclient->helper.message = _appclient_helper_message; appclient->event = (event != NULL) ? event : event_new(); appclient->event_free = (event != NULL) ? 0 : 1; appclient->transport = apptransport_new_app(ATM_CLIENT, &appclient->helper, app, name, appclient->event); /* check for errors */ if(appclient->interface == NULL || appclient->transport == NULL || appclient->event == NULL) { appclient_delete(appclient); #ifdef DEBUG fprintf(stderr, "DEBUG: %s() => NULL\n", __func__); #endif return NULL; } #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\", %p) => %p\n", __func__, app, (void *)event, (void *)appclient); #endif return appclient; } /* appclient_delete */ void appclient_delete(AppClient * appclient) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(appclient->interface != NULL) appinterface_delete(appclient->interface); if(appclient->event_free != 0) event_delete(appclient->event); object_delete(appclient); } /* accessors */ /* appclient_get_app */ char const * appclient_get_app(AppClient * appclient) { return appinterface_get_app(appclient->interface); } /* appclient_get_status */ AppStatus * appclient_get_status(AppClient * appclient) { return appinterface_get_status(appclient->interface); } /* useful */ /* appclient_call */ int appclient_call(AppClient * appclient, void ** result, char const * method, ...) { int ret; va_list ap; va_start(ap, method); ret = appclient_callv(appclient, result, method, ap); va_end(ap); return ret; } /* appclient_callv */ int appclient_callv(AppClient * appclient, void ** result, char const * method, va_list ap) { int ret; AppMessage * message; if((message = appinterface_messagev(appclient->interface, method, ap)) == NULL) return -1; /* FIXME obtain the answer (AICD_{,IN}OUT) */ ret = apptransport_client_send(appclient->transport, message, 1); appmessage_delete(message); return ret; } /* appclient_call_variable */ int appclient_call_variable(AppClient * appclient, Variable * result, char const * method, ...) { int ret; va_list ap; va_start(ap, method); ret = appclient_call_variablev(appclient, result, method, ap); va_end(ap); return ret; } /* appclient_call_variables */ int appclient_call_variables(AppClient * appclient, Variable * result, char const * method, Variable ** args) { int ret; AppMessage * message; if((message = appinterface_message_variables(appclient->interface, method, args)) == NULL) return -1; /* FIXME obtain the answer (AICD_{,IN}OUT) */ ret = apptransport_client_send(appclient->transport, message, 1); appmessage_delete(message); return ret; } /* appclient_call_variablev */ int appclient_call_variablev(AppClient * appclient, Variable * result, char const * method, va_list args) { int ret; AppMessage * message; if((message = appinterface_message_variablev(appclient->interface, method, args)) == NULL) return -1; /* FIXME obtain the answer (AICD_{,IN}OUT) */ ret = apptransport_client_send(appclient->transport, message, 1); appmessage_delete(message); return ret; } /* private */ /* appclient_helper_message */ static int _helper_message_call(AppClient * appclient, AppTransport * transport, AppMessage * message); static int _appclient_helper_message(void * data, AppTransport * transport, AppTransportClient * client, AppMessage * message) { AppClient * appclient = data; if(client != NULL) /* XXX report error */ return -1; switch(appmessage_get_type(message)) { case AMT_CALL: return _helper_message_call(appclient, transport, message); } /* FIXME implement */ return -1; } static int _helper_message_call(AppClient * appclient, AppTransport * transport, AppMessage * message) { /* we have received a callback request */ int ret; String const * method; String const * name; Variable * result = NULL; method = appmessage_get_method(message); name = apptransport_get_name(transport); if(!appinterface_can_call(appclient->interface, method, name)) /* XXX report errors */ return -1; ret = appinterface_call_variablev(appclient->interface, appclient->app, NULL, result, method, 0, NULL); if(result != NULL) variable_delete(result); return ret; }