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 ); |