Declare and Implement generic ICMPv6 handler management

This commit is contained in:
George Oikonomou 2014-03-08 21:24:50 +00:00
parent d387f27a65
commit b6978b30e8
2 changed files with 95 additions and 0 deletions

View file

@ -74,7 +74,50 @@
static uip_ipaddr_t tmp_ipaddr; static uip_ipaddr_t tmp_ipaddr;
LIST(echo_reply_callback_list); LIST(echo_reply_callback_list);
/*---------------------------------------------------------------------------*/
/* List of input handlers */
LIST(input_handler_list);
/*---------------------------------------------------------------------------*/
static uip_icmp6_input_handler_t *
input_handler_lookup(uint8_t type, uint8_t icode)
{
uip_icmp6_input_handler_t *handler = NULL;
for(handler = list_head(input_handler_list);
handler != NULL;
handler = list_item_next(handler)) {
if(handler->type == type &&
(handler->icode == icode ||
handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
return handler;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_icmp6_input(uint8_t type, uint8_t icode)
{
uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
if(handler == NULL) {
return UIP_ICMP6_INPUT_ERROR;
}
if(handler->handler == NULL) {
return UIP_ICMP6_INPUT_ERROR;
}
handler->handler();
return UIP_ICMP6_INPUT_SUCCESS;
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
{
list_add(input_handler_list, handler);
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uip_icmp6_echo_request_input(void) uip_icmp6_echo_request_input(void)

View file

@ -192,8 +192,60 @@ uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
void void
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n); uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
/* Generic ICMPv6 input handers */
typedef struct uip_icmp6_input_handler {
struct uip_icmp6_input_handler *next;
uint8_t type;
uint8_t icode;
void (*handler)(void);
} uip_icmp6_input_handler_t;
#define UIP_ICMP6_INPUT_SUCCESS 0
#define UIP_ICMP6_INPUT_ERROR 1
#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */
/*
* Initialise a variable of type uip_icmp6_input_handler, to be used later as
* the argument to uip_icmp6_register_input_handler
*
* The function pointer stored in this variable will get called and will be
* expected to handle incoming ICMPv6 datagrams of the specified type/code
*
* If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function
* will handle all codes for this type. In other words, the ICMPv6
* message's code is "don't care"
*/
#define UIP_ICMP6_HANDLER(name, type, code, func) \
static uip_icmp6_input_handler_t name = { NULL, type, code, func }
/**
* \brief Handle an incoming ICMPv6 message
* \param type The ICMPv6 message type
* \param icode The ICMPv6 message code
* \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR
*
* Generic handler for unknown ICMPv6 types. It will lookup for a registered
* function capable of handing this message type. The function must have first
* been registered with uip_icmp6_register_input_handler. The function is in
* charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to
* send whatever remains in the UIP_IP_BUF.
*
* A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be
* invoked. This is most likely because the ICMPv6 type does not have a valid
* handler associated with it.
* UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6
* type and that it was invoked. It does NOT provide any indication whatsoever
* regarding whether the handler itself succeeded.
*/
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode);
/**
* \brief Register a handler which can handle a specific ICMPv6 message type
* \param handler A pointer to the handler
*/
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler);
/** @} */ /** @} */