source: mainline/uspace/lib/socket/generic/net_modules.c@ 74c5a1ca

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 74c5a1ca was 14f1db0, checked in by Martin Decky <martin@…>, 16 years ago

networking overhaul:

  • separation of conserns
  • removal of (almost all) overlaping symbols, libnetif is not needed anymore
  • again, it is possible to build the networking in multiple architecture configurations (however, currently only the bundling netif and nil layers is supported, more to come)
  • code style updates and fixes (still a huge amount of work to do)
  • Property mode set to 100644
File size: 6.4 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 <net_err.h>
46#include <net_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
79/** Create bidirectional connection with the needed module service and registers the message receiver.
80 *
81 * @param[in] need The needed module service.
82 * @param[in] arg1 The first parameter.
83 * @param[in] arg2 The second parameter.
84 * @param[in] arg3 The third parameter.
85 * @param[in] client_receiver The message receiver.
86 *
87 * @return The phone of the needed service.
88 * @return Other error codes as defined for the ipc_connect_to_me() function.
89 *
90 */
91int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3,
92 async_client_conn_t client_receiver)
93{
94 return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
95}
96
97/** Create bidirectional connection with the needed module service and registers the message receiver.
98 *
99 * @param[in] need The needed module service.
100 * @param[in] arg1 The first parameter.
101 * @param[in] arg2 The second parameter.
102 * @param[in] arg3 The third parameter.
103 * @param[in] client_receiver The message receiver.
104 * @param[in] timeout The connection timeout in microseconds.
105 * No timeout if set to zero (0).
106 *
107 * @return The phone of the needed service.
108 * @return ETIMEOUT if the connection timeouted.
109 * @return Other error codes as defined for the ipc_connect_to_me() function.
110 *
111 */
112int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2,
113 ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
114{
115 ERROR_DECLARE;
116
117 /* Connect to the needed service */
118 int phone = connect_to_service_timeout(need, timeout);
119 if (phone >= 0) {
120 /* Request the bidirectional connection */
121 ipcarg_t phonehash;
122 if (ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3,
123 &phonehash))) {
124 ipc_hangup(phone);
125 return ERROR_CODE;
126 }
127 async_new_connection(phonehash, 0, NULL, client_receiver);
128 }
129
130 return phone;
131}
132
133int connect_to_service(services_t need){
134 return connect_to_service_timeout(need, 0);
135}
136
137int connect_to_service_timeout(services_t need, suseconds_t timeout){
138 int phone;
139
140 // if no timeout is set
141 if (timeout <= 0){
142 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
143 }
144
145 while(true){
146 phone = async_connect_me_to(PHONE_NS, need, 0, 0);
147 if((phone >= 0) || (phone != ENOENT)){
148 return phone;
149 }
150
151 // end if no time is left
152 if(timeout <= 0){
153 return ETIMEOUT;
154 }
155
156 // wait the minimum of the module wait time and the timeout
157 usleep((timeout <= MODULE_WAIT_TIME) ? timeout : MODULE_WAIT_TIME);
158 timeout -= MODULE_WAIT_TIME;
159 }
160}
161
162int data_receive(void ** data, size_t * length){
163 ERROR_DECLARE;
164
165 ipc_callid_t callid;
166
167 if(!(data && length)){
168 return EBADMEM;
169 }
170
171 // fetch the request
172 if(! async_data_write_receive(&callid, length)){
173 return EINVAL;
174 }
175
176 // allocate the buffer
177 *data = malloc(*length);
178 if(!(*data)){
179 return ENOMEM;
180 }
181
182 // fetch the data
183 if(ERROR_OCCURRED(async_data_write_finalize(callid, * data, * length))){
184 free(data);
185 return ERROR_CODE;
186 }
187 return EOK;
188}
189
190int data_reply(void * data, size_t data_length){
191 size_t length;
192 ipc_callid_t callid;
193
194 // fetch the request
195 if(! async_data_read_receive(&callid, &length)){
196 return EINVAL;
197 }
198
199 // check the requested data size
200 if(length < data_length){
201 async_data_read_finalize(callid, data, length);
202 return EOVERFLOW;
203 }
204
205 // send the data
206 return async_data_read_finalize(callid, data, data_length);
207}
208
209void refresh_answer(ipc_call_t * answer, int * answer_count){
210
211 if(answer_count){
212 *answer_count = 0;
213 }
214
215 if(answer){
216 IPC_SET_RETVAL(*answer, 0);
217 // just to be precize
218 IPC_SET_METHOD(*answer, 0);
219 IPC_SET_ARG1(*answer, 0);
220 IPC_SET_ARG2(*answer, 0);
221 IPC_SET_ARG3(*answer, 0);
222 IPC_SET_ARG4(*answer, 0);
223 IPC_SET_ARG5(*answer, 0);
224 }
225}
226
227/** @}
228 */
Note: See TracBrowser for help on using the repository browser.