source: mainline/uspace/srv/net/modules.c@ 5d2e976

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5d2e976 was a64c64d, checked in by Lukas Mejdrech <lukasmejdrech@…>, 15 years ago
  • code reorganization (no functional change)
  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net
30 * @{
31 */
32
33/** @file
34 * Generic module functions implementation.
35 */
36
37#include <async.h>
38#include <malloc.h>
39
40#include <ipc/ipc.h>
41#include <ipc/services.h>
42
43#include <sys/time.h>
44
45#include "err.h"
46#include "modules.h"
47
48/** The time between connect requests in microseconds.
49 */
50#define MODULE_WAIT_TIME (10 * 1000)
51
52void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count){
53 // choose the most efficient answer function
54 if(answer || (! answer_count)){
55 switch(answer_count){
56 case 0:
57 ipc_answer_0(callid, (ipcarg_t) result);
58 break;
59 case 1:
60 ipc_answer_1(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer));
61 break;
62 case 2:
63 ipc_answer_2(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
64 break;
65 case 3:
66 ipc_answer_3(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer));
67 break;
68 case 4:
69 ipc_answer_4(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
70 break;
71 case 5:
72 default:
73 ipc_answer_5(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
74 break;
75 }
76 }
77}
78
79int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver){
80 return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
81}
82
83int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout){
84 ERROR_DECLARE;
85
86 int phone;
87 ipcarg_t phonehash;
88
89 // connect to the needed service
90 phone = connect_to_service_timeout(need, timeout);
91 // if connected
92 if(phone >= 0){
93 // request the bidirectional connection
94 if(ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash))){
95 ipc_hangup(phone);
96 return ERROR_CODE;
97 }
98 async_new_connection(phonehash, 0, NULL, client_receiver);
99 }
100 return phone;
101}
102
103int connect_to_service(services_t need){
104 return connect_to_service_timeout(need, 0);
105}
106
107int connect_to_service_timeout(services_t need, suseconds_t timeout){
108 int phone;
109
110 // if no timeout is set
111 if (timeout <= 0){
112 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
113 }
114
115 while(true){
116 phone = async_connect_me_to(PHONE_NS, need, 0, 0);
117 if((phone >= 0) || (phone != ENOENT)){
118 return phone;
119 }
120
121 // end if no time is left
122 if(timeout <= 0){
123 return ETIMEOUT;
124 }
125
126 // wait the minimum of the module wait time and the timeout
127 usleep((timeout <= MODULE_WAIT_TIME) ? timeout : MODULE_WAIT_TIME);
128 timeout -= MODULE_WAIT_TIME;
129 }
130}
131
132int data_receive(void ** data, size_t * length){
133 ERROR_DECLARE;
134
135 ipc_callid_t callid;
136
137 if(!(data && length)){
138 return EBADMEM;
139 }
140
141 // fetch the request
142 if(! async_data_write_receive(&callid, length)){
143 return EINVAL;
144 }
145
146 // allocate the buffer
147 *data = malloc(*length);
148 if(!(*data)){
149 return ENOMEM;
150 }
151
152 // fetch the data
153 if(ERROR_OCCURRED(async_data_write_finalize(callid, * data, * length))){
154 free(data);
155 return ERROR_CODE;
156 }
157 return EOK;
158}
159
160int data_reply(void * data, size_t data_length){
161 size_t length;
162 ipc_callid_t callid;
163
164 // fetch the request
165 if(! async_data_read_receive(&callid, &length)){
166 return EINVAL;
167 }
168
169 // check the requested data size
170 if(length < data_length){
171 async_data_read_finalize(callid, data, length);
172 return EOVERFLOW;
173 }
174
175 // send the data
176 return async_data_read_finalize(callid, data, data_length);
177}
178
179void refresh_answer(ipc_call_t * answer, int * answer_count){
180
181 if(answer_count){
182 *answer_count = 0;
183 }
184
185 if(answer){
186 IPC_SET_RETVAL(*answer, 0);
187 // just to be precize
188 IPC_SET_METHOD(*answer, 0);
189 IPC_SET_ARG1(*answer, 0);
190 IPC_SET_ARG2(*answer, 0);
191 IPC_SET_ARG3(*answer, 0);
192 IPC_SET_ARG4(*answer, 0);
193 IPC_SET_ARG5(*answer, 0);
194 }
195}
196
197/** @}
198 */
Note: See TracBrowser for help on using the repository browser.