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 | } |