Rev 4743 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4743 | Rev 4756 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright (c) 2009 Lukas Mejdrech |
2 | * Copyright (c) 2009 Lukas Mejdrech |
3 | * All rights reserved. |
3 | * All rights reserved. |
4 | * |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
7 | * are met: |
8 | * |
8 | * |
9 | * - Redistributions of source code must retain the above copyright |
9 | * - Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * - Redistributions in binary form must reproduce the above copyright |
11 | * - Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
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 |
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. |
15 | * derived from this software without specific prior written permission. |
16 | * |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
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 |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
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 |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
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 |
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. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | /** @addtogroup nildummy |
29 | /** @addtogroup nildummy |
30 | * @{ |
30 | * @{ |
31 | */ |
31 | */ |
32 | 32 | ||
33 | /** @file |
33 | /** @file |
34 | * Dummy network interface layer module implementation. |
34 | * Dummy network interface layer module implementation. |
35 | * @see nildummy.h |
35 | * @see nildummy.h |
36 | */ |
36 | */ |
37 | 37 | ||
38 | #include <async.h> |
38 | #include <async.h> |
39 | #include <malloc.h> |
39 | #include <malloc.h> |
40 | #include <mem.h> |
40 | #include <mem.h> |
41 | #include <stdio.h> |
41 | #include <stdio.h> |
42 | #include <string.h> |
42 | #include <string.h> |
43 | 43 | ||
44 | #include <ipc/ipc.h> |
44 | #include <ipc/ipc.h> |
45 | #include <ipc/services.h> |
45 | #include <ipc/services.h> |
46 | 46 | ||
47 | #include "../../err.h" |
47 | #include "../../err.h" |
48 | #include "../../messages.h" |
48 | #include "../../messages.h" |
49 | #include "../../modules.h" |
49 | #include "../../modules.h" |
50 | 50 | ||
51 | #include "../../include/device.h" |
51 | #include "../../include/device.h" |
52 | #include "../../include/netif_interface.h" |
52 | #include "../../include/netif_interface.h" |
53 | #include "../../include/nil_interface.h" |
53 | #include "../../include/nil_interface.h" |
54 | #include "../../include/il_interface.h" |
54 | #include "../../include/il_interface.h" |
55 | 55 | ||
56 | #include "../../structures/measured_strings.h" |
56 | #include "../../structures/measured_strings.h" |
57 | #include "../../structures/packet/packet.h" |
57 | #include "../../structures/packet/packet.h" |
58 | 58 | ||
59 | #include "../nil_module.h" |
59 | #include "../nil_module.h" |
60 | 60 | ||
61 | #include "nildummy.h" |
61 | #include "nildummy.h" |
62 | 62 | ||
63 | /** Default maximum transmission unit. |
63 | /** Default maximum transmission unit. |
64 | */ |
64 | */ |
65 | #define NET_DEFAULT_MTU 1500 |
65 | #define NET_DEFAULT_MTU 1500 |
66 | 66 | ||
67 | /** Network interface layer module global data. |
67 | /** Network interface layer module global data. |
68 | */ |
68 | */ |
69 | nildummy_globals_t nildummy_globals; |
69 | nildummy_globals_t nildummy_globals; |
70 | 70 | ||
71 | /** @name Message processing functions |
71 | /** @name Message processing functions |
72 | */ |
72 | */ |
73 | /*@{*/ |
73 | /*@{*/ |
74 | 74 | ||
75 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
75 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
76 | * @param iid The message identifier. Input parameter. |
76 | * @param[in] iid The message identifier. |
77 | * @param icall The message parameters. Input/output parameter. |
77 | * @param[in,out] icall The message parameters. |
78 | */ |
78 | */ |
79 | void nildummy_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
79 | void nildummy_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
80 | 80 | ||
81 | /** Registers new device or updates the MTU of an existing one. |
81 | /** Registers new device or updates the MTU of an existing one. |
82 | * Determines the device local hardware address. |
82 | * Determines the device local hardware address. |
83 | * @param device_id The new device identifier. Input parameter. |
83 | * @param[in] device_id The new device identifier. |
84 | * @param service The device driver service. Input parameter. |
84 | * @param[in] service The device driver service. |
85 | * @param mtu The device maximum transmission unit. Input parameter. |
85 | * @param[in] mtu The device maximum transmission unit. |
86 | * @returns EOK on success. |
86 | * @returns EOK on success. |
87 | * @returns EEXIST if the device with the different service exists. |
87 | * @returns EEXIST if the device with the different service exists. |
88 | * @returns ENOMEM if there is not enough memory left. |
88 | * @returns ENOMEM if there is not enough memory left. |
89 | * @returns Other error codes as defined for the netif_bind_service() function. |
89 | * @returns Other error codes as defined for the netif_bind_service() function. |
90 | * @returns Other error codes as defined for the netif_get_addr_req() function. |
90 | * @returns Other error codes as defined for the netif_get_addr_req() function. |
91 | */ |
91 | */ |
92 | int nildummy_device_message( device_id_t device_id, services_t service, size_t mtu ); |
92 | int nildummy_device_message( device_id_t device_id, services_t service, size_t mtu ); |
93 | 93 | ||
94 | /** Returns the device packet dimensions for sending. |
94 | /** Returns the device packet dimensions for sending. |
95 | * @param device_id The device identifier. Input parameter. |
95 | * @param[in] device_id The device identifier. |
96 | * @param addr_len The minimum reserved address length. Output parameter. |
96 | * @param[out] addr_len The minimum reserved address length. |
97 | * @param prefix The minimum reserved prefix size. Output parameter. |
97 | * @param[out] prefix The minimum reserved prefix size. |
98 | * @param content The maximum content size. Output parameter. |
98 | * @param[out] content The maximum content size. |
99 | * @param suffix The minimum reserved suffix size. Output parameter. |
99 | * @param[out] suffix The minimum reserved suffix size. |
100 | * @returns EOK on success. |
100 | * @returns EOK on success. |
101 | * @returns EBADMEM if either one of the parameters is NULL. |
101 | * @returns EBADMEM if either one of the parameters is NULL. |
102 | * @returns ENOENT if there is no such device. |
102 | * @returns ENOENT if there is no such device. |
103 | */ |
103 | */ |
104 | int nildummy_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
104 | int nildummy_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
105 | 105 | ||
106 | /** Registers receiving module service. |
106 | /** Registers receiving module service. |
107 | * Passes received packets for this service. |
107 | * Passes received packets for this service. |
108 | * @param service The module service. Input parameter. |
108 | * @param[in] service The module service. |
109 | * @param phone The service phone. Input parameter. |
109 | * @param[in] phone The service phone. |
110 | * @returns EOK on success. |
110 | * @returns EOK on success. |
111 | * @returns ENOENT if the service is not known. |
111 | * @returns ENOENT if the service is not known. |
112 | * @returns ENOMEM if there is not enough memory left. |
112 | * @returns ENOMEM if there is not enough memory left. |
113 | */ |
113 | */ |
114 | int nildummy_register_message( services_t service, int phone ); |
114 | int nildummy_register_message( services_t service, int phone ); |
115 | 115 | ||
116 | /** Sends the packet queue. |
116 | /** Sends the packet queue. |
117 | * @param device_id The device identifier. Input parameter. |
117 | * @param[in] device_id The device identifier. |
118 | * @param packet The packet queue. Input parameter. |
118 | * @param[in] packet The packet queue. |
119 | * @param sender The sending module service. Input parameter. |
119 | * @param[in] sender The sending module service. |
120 | * @returns EOK on success. |
120 | * @returns EOK on success. |
121 | * @returns ENOENT if there no such device. |
121 | * @returns ENOENT if there no such device. |
122 | * @returns EINVAL if the service parameter is not known. |
122 | * @returns EINVAL if the service parameter is not known. |
123 | */ |
123 | */ |
124 | int nildummy_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
124 | int nildummy_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
125 | 125 | ||
126 | /** Returns the device hardware address. |
126 | /** Returns the device hardware address. |
127 | * @param device_id The device identifier. Input parameter. |
127 | * @param[in] device_id The device identifier. |
128 | * @param address The device hardware address. Output parameter. |
128 | * @param[out] address The device hardware address. |
129 | * @returns EOK on success. |
129 | * @returns EOK on success. |
130 | * @returns EBADMEM if the address parameter is NULL. |
130 | * @returns EBADMEM if the address parameter is NULL. |
131 | * @returns ENOENT if there no such device. |
131 | * @returns ENOENT if there no such device. |
132 | */ |
132 | */ |
133 | int nildummy_addr_message( device_id_t device_id, measured_string_ref * address ); |
133 | int nildummy_addr_message( device_id_t device_id, measured_string_ref * address ); |
134 | 134 | ||
135 | /*@}*/ |
135 | /*@}*/ |
136 | 136 | ||
137 | DEVICE_MAP_IMPLEMENT( nildummy_devices, nildummy_device_t ) |
137 | DEVICE_MAP_IMPLEMENT( nildummy_devices, nildummy_device_t ) |
138 | 138 | ||
139 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
139 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
140 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
140 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
141 | if( nildummy_globals.proto.phone ) il_device_state_msg( nildummy_globals.proto.phone, device_id, state, nildummy_globals.proto.service ); |
141 | if( nildummy_globals.proto.phone ) il_device_state_msg( nildummy_globals.proto.phone, device_id, state, nildummy_globals.proto.service ); |
142 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
142 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
143 | return EOK; |
143 | return EOK; |
144 | } |
144 | } |
145 | 145 | ||
146 | int nil_initialize( int net_phone ){ |
146 | int nil_initialize( int net_phone ){ |
147 | ERROR_DECLARE; |
147 | ERROR_DECLARE; |
148 | 148 | ||
149 | fibril_rwlock_initialize( & nildummy_globals.devices_lock ); |
149 | fibril_rwlock_initialize( & nildummy_globals.devices_lock ); |
150 | fibril_rwlock_initialize( & nildummy_globals.protos_lock ); |
150 | fibril_rwlock_initialize( & nildummy_globals.protos_lock ); |
151 | fibril_rwlock_write_lock( & nildummy_globals.devices_lock ); |
151 | fibril_rwlock_write_lock( & nildummy_globals.devices_lock ); |
152 | fibril_rwlock_write_lock( & nildummy_globals.protos_lock ); |
152 | fibril_rwlock_write_lock( & nildummy_globals.protos_lock ); |
153 | nildummy_globals.net_phone = net_phone; |
153 | nildummy_globals.net_phone = net_phone; |
154 | nildummy_globals.proto.phone = 0; |
154 | nildummy_globals.proto.phone = 0; |
155 | ERROR_PROPAGATE( nildummy_devices_initialize( & nildummy_globals.devices )); |
155 | ERROR_PROPAGATE( nildummy_devices_initialize( & nildummy_globals.devices )); |
156 | fibril_rwlock_write_unlock( & nildummy_globals.protos_lock ); |
156 | fibril_rwlock_write_unlock( & nildummy_globals.protos_lock ); |
157 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
157 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
158 | return EOK; |
158 | return EOK; |
159 | } |
159 | } |
160 | 160 | ||
161 | int nildummy_device_message( device_id_t device_id, services_t service, size_t mtu ){ |
161 | int nildummy_device_message( device_id_t device_id, services_t service, size_t mtu ){ |
162 | ERROR_DECLARE; |
162 | ERROR_DECLARE; |
163 | 163 | ||
164 | nildummy_device_ref device; |
164 | nildummy_device_ref device; |
165 | int index; |
165 | int index; |
166 | 166 | ||
167 | fibril_rwlock_write_lock( & nildummy_globals.devices_lock ); |
167 | fibril_rwlock_write_lock( & nildummy_globals.devices_lock ); |
168 | // an existing device? |
168 | // an existing device? |
169 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
169 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
170 | if( device ){ |
170 | if( device ){ |
171 | if( device->service != service ){ |
171 | if( device->service != service ){ |
172 | printf( "Device %d already exists\n", device->device_id ); |
172 | printf( "Device %d already exists\n", device->device_id ); |
173 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
173 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
174 | return EEXIST; |
174 | return EEXIST; |
175 | }else{ |
175 | }else{ |
176 | // update mtu |
176 | // update mtu |
177 | if( mtu > 0 ){ |
177 | if( mtu > 0 ){ |
178 | device->mtu = mtu; |
178 | device->mtu = mtu; |
179 | }else{ |
179 | }else{ |
180 | device->mtu = NET_DEFAULT_MTU; |
180 | device->mtu = NET_DEFAULT_MTU; |
181 | } |
181 | } |
182 | printf( "Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu ); |
182 | printf( "Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu ); |
183 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
183 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
184 | // notify the upper layer module |
184 | // notify the upper layer module |
185 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
185 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
186 | if( nildummy_globals.proto.phone ){ |
186 | if( nildummy_globals.proto.phone ){ |
187 | il_mtu_changed_msg( nildummy_globals.proto.phone, device->device_id, device->mtu, nildummy_globals.proto.service ); |
187 | il_mtu_changed_msg( nildummy_globals.proto.phone, device->device_id, device->mtu, nildummy_globals.proto.service ); |
188 | } |
188 | } |
189 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
189 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
190 | return EOK; |
190 | return EOK; |
191 | } |
191 | } |
192 | }else{ |
192 | }else{ |
193 | // create a new device |
193 | // create a new device |
194 | device = ( nildummy_device_ref ) malloc( sizeof( nildummy_device_t )); |
194 | device = ( nildummy_device_ref ) malloc( sizeof( nildummy_device_t )); |
195 | if( ! device ) return ENOMEM; |
195 | if( ! device ) return ENOMEM; |
196 | device->device_id = device_id; |
196 | device->device_id = device_id; |
197 | device->service = service; |
197 | device->service = service; |
198 | if( mtu > 0 ){ |
198 | if( mtu > 0 ){ |
199 | device->mtu = mtu; |
199 | device->mtu = mtu; |
200 | }else{ |
200 | }else{ |
201 | device->mtu = NET_DEFAULT_MTU; |
201 | device->mtu = NET_DEFAULT_MTU; |
202 | } |
202 | } |
203 | // bind the device driver |
203 | // bind the device driver |
204 | device->phone = netif_bind_service( device->service, device->device_id, SERVICE_ETHERNET, nildummy_receiver ); |
204 | device->phone = netif_bind_service( device->service, device->device_id, SERVICE_ETHERNET, nildummy_receiver ); |
205 | if( device->phone < 0 ){ |
205 | if( device->phone < 0 ){ |
206 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
206 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
207 | free( device ); |
207 | free( device ); |
208 | return device->phone; |
208 | return device->phone; |
209 | } |
209 | } |
210 | // get hardware address |
210 | // get hardware address |
211 | if( ERROR_OCCURRED( netif_get_addr_req( device->phone, device->device_id, & device->addr, & device->addr_data ))){ |
211 | if( ERROR_OCCURRED( netif_get_addr_req( device->phone, device->device_id, & device->addr, & device->addr_data ))){ |
212 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
212 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
213 | free( device ); |
213 | free( device ); |
214 | return ERROR_CODE; |
214 | return ERROR_CODE; |
215 | } |
215 | } |
216 | // add to the cache |
216 | // add to the cache |
217 | index = nildummy_devices_add( & nildummy_globals.devices, device->device_id, device ); |
217 | index = nildummy_devices_add( & nildummy_globals.devices, device->device_id, device ); |
218 | if( index < 0 ){ |
218 | if( index < 0 ){ |
219 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
219 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
220 | free( device->addr ); |
220 | free( device->addr ); |
221 | free( device->addr_data ); |
221 | free( device->addr_data ); |
222 | free( device ); |
222 | free( device ); |
223 | return index; |
223 | return index; |
224 | } |
224 | } |
225 | printf( "New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n", device->device_id, device->service, device->mtu ); |
225 | printf( "New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n", device->device_id, device->service, device->mtu ); |
226 | } |
226 | } |
227 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
227 | fibril_rwlock_write_unlock( & nildummy_globals.devices_lock ); |
228 | return EOK; |
228 | return EOK; |
229 | } |
229 | } |
230 | 230 | ||
231 | int nildummy_addr_message( device_id_t device_id, measured_string_ref * address ){ |
231 | int nildummy_addr_message( device_id_t device_id, measured_string_ref * address ){ |
232 | nildummy_device_ref device; |
232 | nildummy_device_ref device; |
233 | 233 | ||
234 | if( ! address ) return EBADMEM; |
234 | if( ! address ) return EBADMEM; |
235 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
235 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
236 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
236 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
237 | if( ! device ){ |
237 | if( ! device ){ |
238 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
238 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
239 | return ENOENT; |
239 | return ENOENT; |
240 | } |
240 | } |
241 | * address = device->addr; |
241 | * address = device->addr; |
242 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
242 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
243 | return ( * address ) ? EOK : ENOENT; |
243 | return ( * address ) ? EOK : ENOENT; |
244 | } |
244 | } |
245 | 245 | ||
246 | int nildummy_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
246 | int nildummy_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
247 | nildummy_device_ref device; |
247 | nildummy_device_ref device; |
248 | 248 | ||
249 | if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
249 | if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
250 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
250 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
251 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
251 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
252 | if( ! device ){ |
252 | if( ! device ){ |
253 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
253 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
254 | return ENOENT; |
254 | return ENOENT; |
255 | } |
255 | } |
256 | * content = device->mtu; |
256 | * content = device->mtu; |
257 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
257 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
258 | * addr_len = 0; |
258 | * addr_len = 0; |
259 | * prefix = 0; |
259 | * prefix = 0; |
260 | * suffix = 0; |
260 | * suffix = 0; |
261 | return EOK; |
261 | return EOK; |
262 | } |
262 | } |
263 | 263 | ||
264 | int nil_received_msg( int nil_phone, device_id_t device_id, packet_t packet, services_t target ){ |
264 | int nil_received_msg( int nil_phone, device_id_t device_id, packet_t packet, services_t target ){ |
265 | packet_t next; |
265 | packet_t next; |
266 | 266 | ||
267 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
267 | fibril_rwlock_read_lock( & nildummy_globals.protos_lock ); |
268 | if( nildummy_globals.proto.phone ){ |
268 | if( nildummy_globals.proto.phone ){ |
269 | do{ |
269 | do{ |
270 | next = pq_detach( packet ); |
270 | next = pq_detach( packet ); |
271 | il_received_msg( nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service ); |
271 | il_received_msg( nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service ); |
272 | packet = next; |
272 | packet = next; |
273 | }while( packet ); |
273 | }while( packet ); |
274 | } |
274 | } |
275 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
275 | fibril_rwlock_read_unlock( & nildummy_globals.protos_lock ); |
276 | return EOK; |
276 | return EOK; |
277 | } |
277 | } |
278 | 278 | ||
279 | int nildummy_register_message( services_t service, int phone ){ |
279 | int nildummy_register_message( services_t service, int phone ){ |
280 | fibril_rwlock_write_lock( & nildummy_globals.protos_lock ); |
280 | fibril_rwlock_write_lock( & nildummy_globals.protos_lock ); |
281 | nildummy_globals.proto.service = service; |
281 | nildummy_globals.proto.service = service; |
282 | nildummy_globals.proto.phone = phone; |
282 | nildummy_globals.proto.phone = phone; |
283 | printf( "New protocol registered:\n\tservice\t= %d\n\tphone\t= %d\n", nildummy_globals.proto.service, nildummy_globals.proto.phone ); |
283 | printf( "New protocol registered:\n\tservice\t= %d\n\tphone\t= %d\n", nildummy_globals.proto.service, nildummy_globals.proto.phone ); |
284 | fibril_rwlock_write_unlock( & nildummy_globals.protos_lock ); |
284 | fibril_rwlock_write_unlock( & nildummy_globals.protos_lock ); |
285 | return EOK; |
285 | return EOK; |
286 | } |
286 | } |
287 | 287 | ||
288 | int nildummy_send_message( device_id_t device_id, packet_t packet, services_t sender ){ |
288 | int nildummy_send_message( device_id_t device_id, packet_t packet, services_t sender ){ |
289 | nildummy_device_ref device; |
289 | nildummy_device_ref device; |
290 | 290 | ||
291 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
291 | fibril_rwlock_read_lock( & nildummy_globals.devices_lock ); |
292 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
292 | device = nildummy_devices_find( & nildummy_globals.devices, device_id ); |
293 | if( ! device ){ |
293 | if( ! device ){ |
294 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
294 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
295 | return ENOENT; |
295 | return ENOENT; |
296 | } |
296 | } |
297 | // send packet queue |
297 | // send packet queue |
298 | if( packet ){ |
298 | if( packet ){ |
299 | netif_send_msg( device->phone, device_id, packet, SERVICE_NILDUMMY ); |
299 | netif_send_msg( device->phone, device_id, packet, SERVICE_NILDUMMY ); |
300 | } |
300 | } |
301 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
301 | fibril_rwlock_read_unlock( & nildummy_globals.devices_lock ); |
302 | return EOK; |
302 | return EOK; |
303 | } |
303 | } |
304 | 304 | ||
305 | int nil_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
305 | int nil_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
306 | ERROR_DECLARE; |
306 | ERROR_DECLARE; |
307 | 307 | ||
308 | measured_string_ref address; |
308 | measured_string_ref address; |
309 | packet_t packet; |
309 | packet_t packet; |
310 | 310 | ||
311 | // printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_NIL_FIRST ); |
311 | // printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_NIL_FIRST ); |
312 | * answer_count = 0; |
312 | * answer_count = 0; |
313 | switch( IPC_GET_METHOD( * call )){ |
313 | switch( IPC_GET_METHOD( * call )){ |
314 | case IPC_M_PHONE_HUNGUP: |
314 | case IPC_M_PHONE_HUNGUP: |
315 | return EOK; |
315 | return EOK; |
316 | case NET_NIL_DEVICE: |
316 | case NET_NIL_DEVICE: |
317 | return nildummy_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), IPC_GET_MTU( call )); |
317 | return nildummy_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), IPC_GET_MTU( call )); |
318 | case NET_NIL_SEND: |
318 | case NET_NIL_SEND: |
319 | ERROR_PROPAGATE( packet_translate( nildummy_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
319 | ERROR_PROPAGATE( packet_translate( nildummy_globals.net_phone, & packet, IPC_GET_PACKET( call ))); |
320 | return nildummy_send_message( IPC_GET_DEVICE( call ), packet, IPC_GET_SERVICE( call )); |
320 | return nildummy_send_message( IPC_GET_DEVICE( call ), packet, IPC_GET_SERVICE( call )); |
321 | case NET_NIL_PACKET_SPACE: |
321 | case NET_NIL_PACKET_SPACE: |
322 | ERROR_PROPAGATE( nildummy_packet_space_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer ))); |
322 | ERROR_PROPAGATE( nildummy_packet_space_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer ))); |
323 | * answer_count = 4; |
323 | * answer_count = 4; |
324 | return EOK; |
324 | return EOK; |
325 | case NET_NIL_ADDR: |
325 | case NET_NIL_ADDR: |
326 | ERROR_PROPAGATE( nildummy_addr_message( IPC_GET_DEVICE( call ), & address )); |
326 | ERROR_PROPAGATE( nildummy_addr_message( IPC_GET_DEVICE( call ), & address )); |
327 | return measured_strings_reply( address, 1 ); |
327 | return measured_strings_reply( address, 1 ); |
328 | case IPC_M_CONNECT_TO_ME: |
328 | case IPC_M_CONNECT_TO_ME: |
329 | return nildummy_register_message( NIL_GET_PROTO( call ), IPC_GET_PHONE( call )); |
329 | return nildummy_register_message( NIL_GET_PROTO( call ), IPC_GET_PHONE( call )); |
330 | } |
330 | } |
331 | return ENOTSUP; |
331 | return ENOTSUP; |
332 | } |
332 | } |
333 | 333 | ||
334 | void nildummy_receiver( ipc_callid_t iid, ipc_call_t * icall ){ |
334 | void nildummy_receiver( ipc_callid_t iid, ipc_call_t * icall ){ |
335 | ERROR_DECLARE; |
335 | ERROR_DECLARE; |
336 | 336 | ||
337 | packet_t packet; |
337 | packet_t packet; |
338 | 338 | ||
339 | while( true ){ |
339 | while( true ){ |
340 | // printf( "message %d - %d\n", IPC_GET_METHOD( * icall ), NET_NIL_FIRST ); |
340 | // printf( "message %d - %d\n", IPC_GET_METHOD( * icall ), NET_NIL_FIRST ); |
341 | switch( IPC_GET_METHOD( * icall )){ |
341 | switch( IPC_GET_METHOD( * icall )){ |
342 | case NET_NIL_DEVICE_STATE: |
342 | case NET_NIL_DEVICE_STATE: |
343 | ERROR_CODE = nil_device_state_msg( 0, IPC_GET_DEVICE( icall ), IPC_GET_STATE( icall )); |
343 | ERROR_CODE = nil_device_state_msg( 0, IPC_GET_DEVICE( icall ), IPC_GET_STATE( icall )); |
344 | ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); |
344 | ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); |
345 | break; |
345 | break; |
346 | case NET_NIL_RECEIVED: |
346 | case NET_NIL_RECEIVED: |
347 | if( ! ERROR_OCCURRED( packet_translate( nildummy_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){ |
347 | if( ! ERROR_OCCURRED( packet_translate( nildummy_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){ |
348 | ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 ); |
348 | ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 ); |
349 | } |
349 | } |
350 | ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); |
350 | ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); |
351 | break; |
351 | break; |
352 | default: |
352 | default: |
353 | ipc_answer_0( iid, ( ipcarg_t ) ENOTSUP ); |
353 | ipc_answer_0( iid, ( ipcarg_t ) ENOTSUP ); |
354 | } |
354 | } |
355 | iid = async_get_call( icall ); |
355 | iid = async_get_call( icall ); |
356 | } |
356 | } |
357 | } |
357 | } |
358 | 358 | ||
359 | /** @} |
359 | /** @} |
360 | */ |
360 | */ |
361 | 361 |