Rev 4558 | Rev 4695 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4558 | Rev 4582 | ||
---|---|---|---|
Line 36... | Line 36... | ||
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 <rwlock.h> |
41 | #include <fibril_sync.h> |
42 | #include <stdio.h> |
42 | #include <stdio.h> |
43 | #include <string.h> |
43 | #include <string.h> |
44 | #include <task.h> |
44 | #include <task.h> |
45 | 45 | ||
46 | #include <ipc/ipc.h> |
46 | #include <ipc/ipc.h> |
Line 138... | Line 138... | ||
138 | } |
138 | } |
139 | 139 | ||
140 | int arp_clear_device_req( int arp_phone, device_id_t device_id ){ |
140 | int arp_clear_device_req( int arp_phone, device_id_t device_id ){ |
141 | arp_device_ref device; |
141 | arp_device_ref device; |
142 | 142 | ||
143 | rwlock_write_lock( & arp_globals.lock ); |
143 | fibril_rwlock_write_lock( & arp_globals.lock ); |
144 | device = arp_cache_find( & arp_globals.cache, device_id ); |
144 | device = arp_cache_find( & arp_globals.cache, device_id ); |
145 | if( ! device ){ |
145 | if( ! device ){ |
146 | rwlock_write_unlock( & arp_globals.lock ); |
146 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
147 | return ENOENT; |
147 | return ENOENT; |
148 | } |
148 | } |
149 | clear_device( device ); |
149 | clear_device( device ); |
150 | printf( "Device %d cleared\n", device_id ); |
150 | printf( "Device %d cleared\n", device_id ); |
151 | rwlock_write_unlock( & arp_globals.lock ); |
151 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
152 | return EOK; |
152 | return EOK; |
153 | } |
153 | } |
154 | 154 | ||
155 | int arp_clean_cache_req( int arp_phone ){ |
155 | int arp_clean_cache_req( int arp_phone ){ |
156 | int count; |
156 | int count; |
157 | arp_device_ref device; |
157 | arp_device_ref device; |
158 | 158 | ||
159 | rwlock_write_lock( & arp_globals.lock ); |
159 | fibril_rwlock_write_lock( & arp_globals.lock ); |
160 | for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){ |
160 | for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){ |
161 | device = arp_cache_get_index( & arp_globals.cache, count ); |
161 | device = arp_cache_get_index( & arp_globals.cache, count ); |
162 | if( device ){ |
162 | if( device ){ |
163 | clear_device( device ); |
163 | clear_device( device ); |
164 | if( device->addr_data ) free( device->addr_data ); |
164 | if( device->addr_data ) free( device->addr_data ); |
165 | if( device->broadcast_data ) free( device->broadcast_data ); |
165 | if( device->broadcast_data ) free( device->broadcast_data ); |
166 | } |
166 | } |
167 | } |
167 | } |
168 | arp_cache_clear( & arp_globals.cache ); |
168 | arp_cache_clear( & arp_globals.cache ); |
169 | rwlock_write_unlock( & arp_globals.lock ); |
169 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
170 | printf( "Cache cleaned\n" ); |
170 | printf( "Cache cleaned\n" ); |
171 | return EOK; |
171 | return EOK; |
172 | } |
172 | } |
173 | 173 | ||
174 | int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){ |
174 | int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){ |
Line 185... | Line 185... | ||
185 | } |
185 | } |
186 | 186 | ||
187 | int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data ){ |
187 | int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data ){ |
188 | measured_string_ref tmp; |
188 | measured_string_ref tmp; |
189 | 189 | ||
190 | rwlock_read_lock( & arp_globals.lock ); |
190 | fibril_rwlock_read_lock( & arp_globals.lock ); |
191 | tmp = arp_translate_message( device_id, protocol, address ); |
191 | tmp = arp_translate_message( device_id, protocol, address ); |
192 | if( tmp ){ |
192 | if( tmp ){ |
193 | * translation = measured_string_copy( tmp ); |
193 | * translation = measured_string_copy( tmp ); |
194 | rwlock_read_unlock( & arp_globals.lock ); |
194 | fibril_rwlock_read_unlock( & arp_globals.lock ); |
195 | if( * translation ){ |
195 | if( * translation ){ |
196 | * data = ( ** translation ).value; |
196 | * data = ( ** translation ).value; |
197 | return EOK; |
197 | return EOK; |
198 | }else{ |
198 | }else{ |
199 | return ENOMEM; |
199 | return ENOMEM; |
200 | } |
200 | } |
201 | }else{ |
201 | }else{ |
202 | rwlock_read_unlock( & arp_globals.lock ); |
202 | fibril_rwlock_read_unlock( & arp_globals.lock ); |
203 | return ENOENT; |
203 | return ENOENT; |
204 | } |
204 | } |
205 | } |
205 | } |
206 | 206 | ||
207 | int arp_initialize( async_client_conn_t client_connection ){ |
207 | int arp_initialize( async_client_conn_t client_connection ){ |
208 | ERROR_DECLARE; |
208 | ERROR_DECLARE; |
209 | 209 | ||
210 | rwlock_initialize( & arp_globals.lock ); |
210 | fibril_rwlock_initialize( & arp_globals.lock ); |
211 | rwlock_write_lock( & arp_globals.lock ); |
211 | fibril_rwlock_write_lock( & arp_globals.lock ); |
212 | arp_globals.client_connection = client_connection; |
212 | arp_globals.client_connection = client_connection; |
213 | ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache )); |
213 | ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache )); |
214 | rwlock_write_unlock( & arp_globals.lock ); |
214 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
215 | return EOK; |
215 | return EOK; |
216 | } |
216 | } |
217 | 217 | ||
218 | int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){ |
218 | int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){ |
219 | ERROR_DECLARE; |
219 | ERROR_DECLARE; |
Line 236... | Line 236... | ||
236 | arp_device_ref device; |
236 | arp_device_ref device; |
237 | arp_proto_ref proto; |
237 | arp_proto_ref proto; |
238 | int index; |
238 | int index; |
239 | hw_type_t hardware; |
239 | hw_type_t hardware; |
240 | 240 | ||
241 | rwlock_write_lock( & arp_globals.lock ); |
241 | fibril_rwlock_write_lock( & arp_globals.lock ); |
242 | // an existing device? |
242 | // an existing device? |
243 | device = arp_cache_find( & arp_globals.cache, device_id ); |
243 | device = arp_cache_find( & arp_globals.cache, device_id ); |
244 | if( device ){ |
244 | if( device ){ |
245 | if( device->service != service ){ |
245 | if( device->service != service ){ |
246 | printf( "Device %d already exists\n", device->device_id ); |
246 | printf( "Device %d already exists\n", device->device_id ); |
247 | rwlock_write_unlock( & arp_globals.lock ); |
247 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
248 | return EEXIST; |
248 | return EEXIST; |
249 | } |
249 | } |
250 | proto = arp_protos_find( & device->protos, protocol ); |
250 | proto = arp_protos_find( & device->protos, protocol ); |
251 | if( proto ){ |
251 | if( proto ){ |
252 | free( proto->addr ); |
252 | free( proto->addr ); |
253 | free( proto->addr_data ); |
253 | free( proto->addr_data ); |
254 | proto->addr = address; |
254 | proto->addr = address; |
255 | proto->addr_data = address->value; |
255 | proto->addr_data = address->value; |
256 | }else{ |
256 | }else{ |
257 | if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
257 | if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
258 | rwlock_write_unlock( & arp_globals.lock ); |
258 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
259 | return ERROR_CODE; |
259 | return ERROR_CODE; |
260 | } |
260 | } |
261 | index = arp_protos_add( & device->protos, proto->service, proto ); |
261 | index = arp_protos_add( & device->protos, proto->service, proto ); |
262 | if( index < 0 ){ |
262 | if( index < 0 ){ |
263 | rwlock_write_unlock( & arp_globals.lock ); |
263 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
264 | free( proto ); |
264 | free( proto ); |
265 | return index; |
265 | return index; |
266 | } |
266 | } |
267 | printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol ); |
267 | printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol ); |
268 | } |
268 | } |
Line 270... | Line 270... | ||
270 | hardware = hardware_map( service ); |
270 | hardware = hardware_map( service ); |
271 | if( ! hardware ) return ENOENT; |
271 | if( ! hardware ) return ENOENT; |
272 | // create a new device |
272 | // create a new device |
273 | device = ( arp_device_ref ) malloc( sizeof( arp_device_t )); |
273 | device = ( arp_device_ref ) malloc( sizeof( arp_device_t )); |
274 | if( ! device ){ |
274 | if( ! device ){ |
275 | rwlock_write_unlock( & arp_globals.lock ); |
275 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
276 | return ENOMEM; |
276 | return ENOMEM; |
277 | } |
277 | } |
278 | device->hardware = hardware; |
278 | device->hardware = hardware; |
279 | device->device_id = device_id; |
279 | device->device_id = device_id; |
280 | if( ERROR_OCCURRED( arp_protos_initialize( & device->protos )) |
280 | if( ERROR_OCCURRED( arp_protos_initialize( & device->protos )) |
281 | || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
281 | || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
282 | rwlock_write_unlock( & arp_globals.lock ); |
282 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
283 | free( device ); |
283 | free( device ); |
284 | return ERROR_CODE; |
284 | return ERROR_CODE; |
285 | } |
285 | } |
286 | index = arp_protos_add( & device->protos, proto->service, proto ); |
286 | index = arp_protos_add( & device->protos, proto->service, proto ); |
287 | if( index < 0 ){ |
287 | if( index < 0 ){ |
288 | rwlock_write_unlock( & arp_globals.lock ); |
288 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
289 | arp_protos_destroy( & device->protos ); |
289 | arp_protos_destroy( & device->protos ); |
290 | free( device ); |
290 | free( device ); |
291 | return index; |
291 | return index; |
292 | } |
292 | } |
293 | device->service = service; |
293 | device->service = service; |
294 | // bind the new one |
294 | // bind the new one |
295 | device->phone = bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, 0, arp_globals.client_connection ); |
295 | device->phone = bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, 0, arp_globals.client_connection ); |
296 | if( device->phone < 0 ){ |
296 | if( device->phone < 0 ){ |
297 | rwlock_write_unlock( & arp_globals.lock ); |
297 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
298 | arp_protos_destroy( & device->protos ); |
298 | arp_protos_destroy( & device->protos ); |
299 | free( device ); |
299 | free( device ); |
300 | return EREFUSED; |
300 | return EREFUSED; |
301 | } |
301 | } |
302 | // get packet dimensions |
302 | // get packet dimensions |
303 | if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){ |
303 | if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){ |
304 | rwlock_write_unlock( & arp_globals.lock ); |
304 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
305 | arp_protos_destroy( & device->protos ); |
305 | arp_protos_destroy( & device->protos ); |
306 | free( device ); |
306 | free( device ); |
307 | return ERROR_CODE; |
307 | return ERROR_CODE; |
308 | } |
308 | } |
309 | // get hardware address |
309 | // get hardware address |
310 | if( ERROR_OCCURRED( nil_get_addr( device->phone, device_id, & device->addr, & device->addr_data ))){ |
310 | if( ERROR_OCCURRED( nil_get_addr( device->phone, device_id, & device->addr, & device->addr_data ))){ |
311 | rwlock_write_unlock( & arp_globals.lock ); |
311 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
312 | arp_protos_destroy( & device->protos ); |
312 | arp_protos_destroy( & device->protos ); |
313 | free( device ); |
313 | free( device ); |
314 | return ERROR_CODE; |
314 | return ERROR_CODE; |
315 | } |
315 | } |
316 | // get broadcast address |
316 | // get broadcast address |
317 | if( ERROR_OCCURRED( nil_get_broadcast_addr( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){ |
317 | if( ERROR_OCCURRED( nil_get_broadcast_addr( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){ |
318 | rwlock_write_unlock( & arp_globals.lock ); |
318 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
319 | free( device->addr ); |
319 | free( device->addr ); |
320 | free( device->addr_data ); |
320 | free( device->addr_data ); |
321 | arp_protos_destroy( & device->protos ); |
321 | arp_protos_destroy( & device->protos ); |
322 | free( device ); |
322 | free( device ); |
323 | return ERROR_CODE; |
323 | return ERROR_CODE; |
324 | } |
324 | } |
325 | if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ |
325 | if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ |
326 | rwlock_write_unlock( & arp_globals.lock ); |
326 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
327 | free( device->addr ); |
327 | free( device->addr ); |
328 | free( device->addr_data ); |
328 | free( device->addr_data ); |
329 | free( device->broadcast_addr ); |
329 | free( device->broadcast_addr ); |
330 | free( device->broadcast_data ); |
330 | free( device->broadcast_data ); |
331 | arp_protos_destroy( & device->protos ); |
331 | arp_protos_destroy( & device->protos ); |
332 | free( device ); |
332 | free( device ); |
333 | return ERROR_CODE; |
333 | return ERROR_CODE; |
334 | } |
334 | } |
335 | printf( "New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol ); |
335 | printf( "New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol ); |
336 | } |
336 | } |
337 | rwlock_write_unlock( & arp_globals.lock ); |
337 | fibril_rwlock_write_unlock( & arp_globals.lock ); |
338 | return EOK; |
338 | return EOK; |
339 | } |
339 | } |
340 | 340 | ||
341 | measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ |
341 | measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ |
342 | arp_device_ref device; |
342 | arp_device_ref device; |
Line 486... | Line 486... | ||
486 | free( data ); |
486 | free( data ); |
487 | } |
487 | } |
488 | return ERROR_CODE; |
488 | return ERROR_CODE; |
489 | case NET_ARP_TRANSLATE: |
489 | case NET_ARP_TRANSLATE: |
490 | ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 )); |
490 | ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 )); |
491 | rwlock_read_lock( & arp_globals.lock ); |
491 | fibril_rwlock_read_lock( & arp_globals.lock ); |
492 | translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address ); |
492 | translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address ); |
493 | free( address ); |
493 | free( address ); |
494 | free( data ); |
494 | free( data ); |
495 | if( ! translation ){ |
495 | if( ! translation ){ |
496 | rwlock_read_unlock( & arp_globals.lock ); |
496 | fibril_rwlock_read_unlock( & arp_globals.lock ); |
497 | return ENOENT; |
497 | return ENOENT; |
498 | } |
498 | } |
499 | ERROR_CODE = measured_strings_reply( translation, 1 ); |
499 | ERROR_CODE = measured_strings_reply( translation, 1 ); |
500 | rwlock_read_unlock( & arp_globals.lock ); |
500 | fibril_rwlock_read_unlock( & arp_globals.lock ); |
501 | return ERROR_CODE; |
501 | return ERROR_CODE; |
502 | case NET_ARP_CLEAR_DEVICE: |
502 | case NET_ARP_CLEAR_DEVICE: |
503 | return arp_clear_device_req( 0, IPC_GET_DEVICE( call )); |
503 | return arp_clear_device_req( 0, IPC_GET_DEVICE( call )); |
504 | case NET_ARP_CLEAN_CACHE: |
504 | case NET_ARP_CLEAN_CACHE: |
505 | return arp_clean_cache_req( 0 ); |
505 | return arp_clean_cache_req( 0 ); |
506 | case NET_IL_DEVICE_STATE: |
506 | case NET_IL_DEVICE_STATE: |
507 | // do nothing - keep the cache |
507 | // do nothing - keep the cache |
508 | return EOK; |
508 | return EOK; |
509 | case NET_IL_RECEIVED: |
509 | case NET_IL_RECEIVED: |
510 | if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){ |
510 | if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){ |
511 | rwlock_read_lock( & arp_globals.lock ); |
511 | fibril_rwlock_read_lock( & arp_globals.lock ); |
512 | do{ |
512 | do{ |
513 | next = pq_detach( packet ); |
513 | next = pq_detach( packet ); |
514 | ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet ); |
514 | ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet ); |
515 | if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet )); |
515 | if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet )); |
516 | packet = next; |
516 | packet = next; |
517 | }while( packet ); |
517 | }while( packet ); |
518 | rwlock_read_unlock( & arp_globals.lock ); |
518 | fibril_rwlock_read_unlock( & arp_globals.lock ); |
519 | } |
519 | } |
520 | return ERROR_CODE; |
520 | return ERROR_CODE; |
521 | } |
521 | } |
522 | return ENOTSUP; |
522 | return ENOTSUP; |
523 | } |
523 | } |