Hi Marcel, On 1 March 2014 04:20, Marcel Holtmann <marcel@xxxxxxxxxxxx> wrote: > Hi Marcin, > >> Add two functions: hfp_gw_register_prefix_handler() and >> hfp_gw_unregister_prefix_handler(). It will allow user to register for >> specific command. Current implementation just put/remove handler data >> from queue. >> --- >> Makefile.tools | 1 + >> src/shared/hfp.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> src/shared/hfp.h | 19 +++++++++++ >> 3 files changed, 120 insertions(+) >> >> diff --git a/Makefile.tools b/Makefile.tools >> index 9f7ba9f..31e1093 100644 >> --- a/Makefile.tools >> +++ b/Makefile.tools >> @@ -63,6 +63,7 @@ emulator_hfp_SOURCES = emulator/hfp.c \ >> monitor/mainloop.h monitor/mainloop.c \ >> src/shared/io.h src/shared/io-mainloop.c \ >> src/shared/util.h src/shared/util.c \ >> + src/shared/queue.h src/shared/queue.c \ >> src/shared/ringbuf.h src/shared/ringbuf.c \ >> src/shared/hfp.h src/shared/hfp.c >> >> diff --git a/src/shared/hfp.c b/src/shared/hfp.c >> index 854cf46..aecd246 100644 >> --- a/src/shared/hfp.c >> +++ b/src/shared/hfp.c >> @@ -32,6 +32,7 @@ >> >> #include "src/shared/util.h" >> #include "src/shared/ringbuf.h" >> +#include "src/shared/queue.h" >> #include "src/shared/io.h" >> #include "src/shared/hfp.h" >> >> @@ -42,6 +43,7 @@ struct hfp_gw { >> struct io *io; >> struct ringbuf *read_buf; >> struct ringbuf *write_buf; >> + struct queue *prefix_handlers; > > call this cmd_handlers. > >> bool writer_active; >> bool permissive_syntax; >> bool result_pending; >> @@ -60,6 +62,37 @@ struct hfp_gw { >> bool destroyed; >> }; >> >> +struct prefix_handler_data { > > Same here. Just cmd_handler should be fine. > >> + char *prefix; >> + void *user_data; >> + hfp_destroy_func_t destroy; >> + hfp_result_func_t callback; >> +}; >> + >> +static void destroy_prefix_handler_data(void *data) >> +{ > > Use destroy_cmd_handler here. > >> + struct prefix_handler_data *handler = data; >> + >> + if (handler->destroy) >> + handler->destroy(handler->user_data); >> + >> + free(handler); >> +} >> + >> +static bool match_handler_prefix(const void *a, const void *b) >> +{ >> + const struct prefix_handler_data *handler = a; >> + const char *prefix = b; >> + >> + if (strlen(handler->prefix) != strlen(prefix)) >> + return false; >> + >> + if (memcmp(handler->prefix, prefix, strlen(prefix))) >> + return false; >> + >> + return true; >> +} >> + >> static void write_watch_destroy(void *user_data) >> { >> struct hfp_gw *hfp = user_data; >> @@ -196,8 +229,19 @@ struct hfp_gw *hfp_gw_new(int fd) >> return NULL; >> } >> >> + hfp->prefix_handlers = queue_new(); >> + if (!hfp->prefix_handlers) { >> + io_destroy(hfp->io); >> + ringbuf_free(hfp->write_buf); >> + ringbuf_free(hfp->read_buf); >> + free(hfp); >> + return NULL; >> + } >> + >> if (!io_set_read_handler(hfp->io, can_read_data, >> hfp, read_watch_destroy)) { >> + queue_destroy(hfp->prefix_handlers, >> + destroy_prefix_handler_data); >> io_destroy(hfp->io); >> ringbuf_free(hfp->write_buf); >> ringbuf_free(hfp->read_buf); >> @@ -250,6 +294,9 @@ void hfp_gw_unref(struct hfp_gw *hfp) >> ringbuf_free(hfp->write_buf); >> hfp->write_buf = NULL; >> >> + queue_destroy(hfp->prefix_handlers, destroy_prefix_handler_data); >> + hfp->prefix_handlers = NULL; >> + >> if (!hfp->in_disconnect) { >> free(hfp); >> return; >> @@ -405,6 +452,59 @@ bool hfp_gw_set_command_handler(struct hfp_gw *hfp, >> return true; >> } >> >> +bool hfp_gw_register_prefix_handler(struct hfp_gw *hfp, >> + hfp_result_func_t callback, >> + const char *prefix, >> + void *user_data, >> + hfp_destroy_func_t destroy) >> +{ >> + struct prefix_handler_data *handler; >> + >> + handler = new0(struct prefix_handler_data, 1); >> + if (!handler) >> + return false; >> + >> + handler->callback = callback; >> + handler->user_data = user_data; >> + >> + handler->prefix = strdup(prefix); >> + if (!handler->prefix) { >> + free(handler); >> + return false; >> + } >> + >> + if (queue_find(hfp->prefix_handlers, match_handler_prefix, >> + handler->prefix)) { >> + destroy_prefix_handler_data(handler); >> + return false; >> + } >> + >> + handler->destroy = destroy; >> + >> + return queue_push_tail(hfp->prefix_handlers, handler); >> +} >> + >> +bool hfp_gw_unregister_prefix_handler(struct hfp_gw *hfp, const char *prefix) >> +{ >> + struct prefix_handler_data *handler; >> + char *lookup_prefix; >> + >> + lookup_prefix = strdup(prefix); >> + if (!lookup_prefix) >> + return false; >> + >> + handler = queue_remove_if(hfp->prefix_handlers, match_handler_prefix, >> + lookup_prefix); >> + free(lookup_prefix); >> + >> + if (!handler) >> + return false; >> + >> + destroy_prefix_handler_data(handler); >> + >> + return true; >> +} >> + >> static void disconnect_watch_destroy(void *user_data) >> { >> struct hfp_gw *hfp = user_data; >> diff --git a/src/shared/hfp.h b/src/shared/hfp.h >> index b0bd934..dee80d9 100644 >> --- a/src/shared/hfp.h >> +++ b/src/shared/hfp.h >> @@ -60,6 +60,18 @@ enum hfp_error { >> HFP_ERROR_NETWORK_NOT_ALLOWED = 32, >> }; >> >> +enum hfp_cmd_type { >> + HFP_AT_READ, >> + HFP_AT_SET, >> + HFP_AT_TEST, >> + HFP_AT_COMMAND >> +}; >> + >> +struct hfp_gw_result; > > At this moment, lets use hfp_gw_cmd_type and HFP_GW_CMD_TYPE_READ etc. > >> + >> +typedef void (*hfp_result_func_t)(struct hfp_gw_result *result, >> + enum hfp_cmd_type type, void *user_data); >> + >> typedef void (*hfp_destroy_func_t)(void *user_data); >> typedef void (*hfp_debug_func_t)(const char *str, void *user_data); >> >> @@ -94,3 +106,10 @@ bool hfp_gw_set_disconnect_handler(struct hfp_gw *hfp, >> hfp_destroy_func_t destroy); >> >> bool hfp_gw_disconnect(struct hfp_gw *hfp); >> + >> +bool hfp_gw_register_prefix_handler(struct hfp_gw *hfp, >> + hfp_result_func_t callback, >> + const char *prefix, >> + void *user_data, >> + hfp_destroy_func_t destroy); >> +bool hfp_gw_unregister_prefix_handler(struct hfp_gw *hfp, const char *prefix); > > Just hfp_gw_register and hfp_gw_unregister are enough. That is what we do within the other code that provides similar functionality. > > Regards > > Marcel > I'll change it in next version BR Marcin -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html