Rev 4728 | Rev 4731 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4728 | Rev 4730 | ||
|---|---|---|---|
| Line 121... | Line 121... | ||
| 121 | /** Type definition of the ICMP reply timeout pointer. |
121 | /** Type definition of the ICMP reply timeout pointer. |
| 122 | * @see icmp_reply_timeout |
122 | * @see icmp_reply_timeout |
| 123 | */ |
123 | */ |
| 124 | typedef icmp_reply_timeout_t * icmp_reply_timeout_ref; |
124 | typedef icmp_reply_timeout_t * icmp_reply_timeout_ref; |
| 125 | 125 | ||
| - | 126 | /** ICMP reply timeout data. |
|
| - | 127 | * Used as a timeouting fibril argument. |
|
| - | 128 | * @see icmp_timeout_for_reply() |
|
| - | 129 | */ |
|
| - | 130 | struct icmp_reply_timeout{ |
|
| - | 131 | /** Reply data key. |
|
| - | 132 | */ |
|
| - | 133 | int reply_key; |
|
| - | 134 | /** Timeout in microseconds. |
|
| - | 135 | */ |
|
| - | 136 | suseconds_t timeout; |
|
| - | 137 | }; |
|
| - | 138 | ||
| 126 | /** Processes the received ICMP packet. |
139 | /** Processes the received ICMP packet. |
| 127 | * Is used as an entry point from the underlying IP module. |
140 | * Is used as an entry point from the underlying IP module. |
| 128 | * Releases the packet on error. |
141 | * Releases the packet on error. |
| 129 | * @param device_id The device identifier. Ignored parameter. |
142 | * @param device_id The device identifier. Ignored parameter. |
| 130 | * @param packet The received packet. Input/output parameter. |
143 | * @param packet The received packet. Input/output parameter. |
| Line 250... | Line 263... | ||
| 250 | * @returns EBADMEM if the echo_data parameter is NULL. |
263 | * @returns EBADMEM if the echo_data parameter is NULL. |
| 251 | * @returns ENOTCONN if no free identifier have been found. |
264 | * @returns ENOTCONN if no free identifier have been found. |
| 252 | */ |
265 | */ |
| 253 | int icmp_bind_free_id( icmp_echo_ref echo_data ); |
266 | int icmp_bind_free_id( icmp_echo_ref echo_data ); |
| 254 | 267 | ||
| 255 | /** ICMP reply timeout data. |
- | |
| 256 | * Used as a timeouting fibril argument. |
- | |
| 257 | * @see icmp_timeout_for_reply() |
- | |
| 258 | */ |
- | |
| 259 | struct icmp_reply_timeout{ |
- | |
| 260 | /** Reply data key. |
- | |
| 261 | */ |
- | |
| 262 | int reply_key; |
- | |
| 263 | /** Timeout in microseconds. |
- | |
| 264 | */ |
- | |
| 265 | suseconds_t timeout; |
- | |
| 266 | }; |
- | |
| 267 | - | ||
| 268 | /** ICMP global data. |
268 | /** ICMP global data. |
| 269 | */ |
269 | */ |
| 270 | icmp_globals_t icmp_globals; |
270 | icmp_globals_t icmp_globals; |
| 271 | 271 | ||
| 272 | INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t ); |
272 | INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t ); |
| Line 377... | Line 377... | ||
| 377 | reply = malloc( sizeof( * reply )); |
377 | reply = malloc( sizeof( * reply )); |
| 378 | if( ! reply ){ |
378 | if( ! reply ){ |
| 379 | free( reply_timeout ); |
379 | free( reply_timeout ); |
| 380 | return icmp_release_and_return( packet, ENOMEM ); |
380 | return icmp_release_and_return( packet, ENOMEM ); |
| 381 | } |
381 | } |
| - | 382 | // prepare the timeouting thread |
|
| - | 383 | fibril = fibril_create( icmp_timeout_for_reply, reply_timeout ); |
|
| - | 384 | if( ! fibril ){ |
|
| - | 385 | free( reply ); |
|
| - | 386 | free( reply_timeout ); |
|
| - | 387 | return icmp_release_and_return( packet, EPARTY ); |
|
| - | 388 | } |
|
| 382 | reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number ); |
389 | reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number ); |
| 383 | // timeout in microseconds |
390 | // timeout in microseconds |
| 384 | reply_timeout->timeout = timeout * 1000; |
391 | reply_timeout->timeout = timeout * 1000; |
| 385 | fibril_mutex_initialize( & reply->mutex ); |
392 | fibril_mutex_initialize( & reply->mutex ); |
| 386 | fibril_mutex_lock( & reply->mutex ); |
393 | fibril_mutex_lock( & reply->mutex ); |
| 387 | fibril_condvar_initialize( & reply->condvar ); |
394 | fibril_condvar_initialize( & reply->condvar ); |
| - | 395 | // start the timeouting fibril |
|
| - | 396 | fibril_add_ready( fibril ); |
|
| 388 | index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply ); |
397 | index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply ); |
| 389 | if( index < 0 ){ |
398 | if( index < 0 ){ |
| 390 | free( reply ); |
399 | free( reply ); |
| 391 | free( reply_timeout ); |
- | |
| 392 | return icmp_release_and_return( packet, index ); |
400 | return icmp_release_and_return( packet, index ); |
| 393 | } |
401 | } |
| 394 | // start the timeouting thread |
- | |
| 395 | fibril = fibril_create( icmp_timeout_for_reply, reply_timeout ); |
- | |
| 396 | if( ! fibril ){ |
- | |
| 397 | return EPARTY; |
- | |
| 398 | } |
- | |
| 399 | fibril_add_ready( fibril ); |
- | |
| 400 | 402 | ||
| 401 | // unlock the globals and wait for a reply |
403 | // unlock the globals and wait for a reply |
| 402 | fibril_rwlock_write_unlock( & icmp_globals.lock ); |
404 | fibril_rwlock_write_unlock( & icmp_globals.lock ); |
| 403 | 405 | ||
| 404 | // send the request |
406 | // send the request |
| 405 | icmp_send_packet( ICMP_ECHO, 0, packet, header, 0 ); |
407 | icmp_send_packet( ICMP_ECHO, 0, packet, header, 0 ); |
| 406 | 408 | ||
| 407 | // wait for a reply |
409 | // wait for a reply |
| 408 | fibril_condvar_wait( & reply->condvar, & reply->mutex ); |
410 | fibril_condvar_wait( & reply->condvar, & reply->mutex ); |
| - | 411 | ||
| 409 | // read the result |
412 | // read the result |
| 410 | result = reply->result; |
413 | result = reply->result; |
| 411 | 414 | ||
| 412 | // destroy the reply structure |
415 | // destroy the reply structure |
| 413 | fibril_mutex_unlock( & reply->mutex ); |
416 | fibril_mutex_unlock( & reply->mutex ); |