modules.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Lukas Mejdrech
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00041 #include <async.h>
00042 #include <malloc.h>
00043 #include <errno.h>
00044 #include <sys/time.h>
00045 #include <ipc/services.h>
00046 #include <net/modules.h>
00047 
00049 #define MODULE_WAIT_TIME        (10 * 1000)
00050 
00059 void answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
00060     size_t count)
00061 {
00062         /* Choose the most efficient function */
00063         if ((answer != NULL) || (count == 0)) {
00064                 switch (count) {
00065                 case 0:
00066                         async_answer_0(callid, (sysarg_t) result);
00067                         break;
00068                 case 1:
00069                         async_answer_1(callid, (sysarg_t) result,
00070                             IPC_GET_ARG1(*answer));
00071                         break;
00072                 case 2:
00073                         async_answer_2(callid, (sysarg_t) result,
00074                             IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
00075                         break;
00076                 case 3:
00077                         async_answer_3(callid, (sysarg_t) result,
00078                             IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
00079                             IPC_GET_ARG3(*answer));
00080                         break;
00081                 case 4:
00082                         async_answer_4(callid, (sysarg_t) result,
00083                             IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
00084                             IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
00085                         break;
00086                 case 5:
00087                 default:
00088                         async_answer_5(callid, (sysarg_t) result,
00089                             IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
00090                             IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer),
00091                             IPC_GET_ARG5(*answer));
00092                         break;
00093                 }
00094         }
00095 }
00096 
00110 int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
00111     async_client_conn_t client_receiver)
00112 {
00113         return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
00114 }
00115 
00133 int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2,
00134     sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
00135 {
00136         /* Connect to the needed service */
00137         int phone = connect_to_service_timeout(need, timeout);
00138         if (phone >= 0) {
00139                 /* Request the bidirectional connection */
00140                 int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
00141                 if (rc != EOK) {
00142                         async_hangup(phone);
00143                         return rc;
00144                 }
00145         }
00146         
00147         return phone;
00148 }
00149 
00155 int connect_to_service(services_t need)
00156 {
00157         return connect_to_service_timeout(need, 0);
00158 }
00159 
00168 int connect_to_service_timeout(services_t need, suseconds_t timeout)
00169 {
00170         int phone;
00171 
00172         /* If no timeout is set */
00173         if (timeout <= 0)
00174                 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
00175 
00176         while (true) {
00177                 phone = async_connect_me_to(PHONE_NS, need, 0, 0);
00178                 if ((phone >= 0) || (phone != ENOENT))
00179                         return phone;
00180 
00181                 /* Abort if no time is left */
00182                 if (timeout <= 0)
00183                         return ETIMEOUT;
00184 
00185                 /* Wait the minimum of the module wait time and the timeout */
00186                 usleep((timeout <= MODULE_WAIT_TIME) ?
00187                     timeout : MODULE_WAIT_TIME);
00188                 timeout -= MODULE_WAIT_TIME;
00189         }
00190 }
00191 
00203 int data_reply(void *data, size_t data_length)
00204 {
00205         size_t length;
00206         ipc_callid_t callid;
00207 
00208         /* Fetch the request */
00209         if (!async_data_read_receive(&callid, &length))
00210                 return EINVAL;
00211 
00212         /* Check the requested data size */
00213         if (length < data_length) {
00214                 async_data_read_finalize(callid, data, length);
00215                 return EOVERFLOW;
00216         }
00217 
00218         /* Send the data */
00219         return async_data_read_finalize(callid, data, data_length);
00220 }
00221 
00230 void refresh_answer(ipc_call_t *answer, size_t *count)
00231 {
00232         if (count != NULL)
00233                 *count = 0;
00234         
00235         if (answer != NULL) {
00236                 IPC_SET_RETVAL(*answer, 0);
00237                 IPC_SET_IMETHOD(*answer, 0);
00238                 IPC_SET_ARG1(*answer, 0);
00239                 IPC_SET_ARG2(*answer, 0);
00240                 IPC_SET_ARG3(*answer, 0);
00241                 IPC_SET_ARG4(*answer, 0);
00242                 IPC_SET_ARG5(*answer, 0);
00243         }
00244 }
00245 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7