Part of hfp_gw members are going to be common between gw and hf roles. Let's extract them into separate struct which will be a member of hfp_gw and future hfp_hf --- src/shared/hfp.c | 177 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 92 insertions(+), 85 deletions(-) diff --git a/src/shared/hfp.c b/src/shared/hfp.c index efc981f..6176514 100644 --- a/src/shared/hfp.c +++ b/src/shared/hfp.c @@ -37,19 +37,15 @@ #include "src/shared/io.h" #include "src/shared/hfp.h" -struct hfp_gw { +struct hfp { int ref_count; int fd; bool close_on_unref; struct io *io; struct ringbuf *read_buf; struct ringbuf *write_buf; - struct queue *cmd_handlers; bool writer_active; - bool result_pending; - hfp_command_func_t command_callback; - hfp_destroy_func_t command_destroy; - void *command_data; + hfp_debug_func_t debug_callback; hfp_destroy_func_t debug_destroy; void *debug_data; @@ -62,6 +58,15 @@ struct hfp_gw { bool destroyed; }; +struct hfp_gw { + struct hfp hfp; /* Shall be first in the wrapping struct */ + bool result_pending; + struct queue *cmd_handlers; + hfp_command_func_t command_callback; + hfp_destroy_func_t command_destroy; + void *command_data; +}; + struct cmd_handler { char *prefix; void *user_data; @@ -104,7 +109,7 @@ static void write_watch_destroy(void *user_data) { struct hfp_gw *hfp = user_data; - hfp->writer_active = false; + hfp->hfp.writer_active = false; } static bool can_write_data(struct io *io, void *user_data) @@ -112,11 +117,11 @@ static bool can_write_data(struct io *io, void *user_data) struct hfp_gw *hfp = user_data; ssize_t bytes_written; - bytes_written = ringbuf_write(hfp->write_buf, hfp->fd); + bytes_written = ringbuf_write(hfp->hfp.write_buf, hfp->hfp.fd); if (bytes_written < 0) return false; - if (ringbuf_len(hfp->write_buf) > 0) + if (ringbuf_len(hfp->hfp.write_buf) > 0) return true; return false; @@ -124,17 +129,17 @@ static bool can_write_data(struct io *io, void *user_data) static void wakeup_writer(struct hfp_gw *hfp) { - if (hfp->writer_active) + if (hfp->hfp.writer_active) return; - if (!ringbuf_len(hfp->write_buf)) + if (!ringbuf_len(hfp->hfp.write_buf)) return; - if (!io_set_write_handler(hfp->io, can_write_data, + if (!io_set_write_handler(hfp->hfp.io, can_write_data, hfp, write_watch_destroy)) return; - hfp->writer_active = true; + hfp->hfp.writer_active = true; } static void skip_whitespace(struct hfp_gw_result *result) @@ -382,7 +387,7 @@ static void process_input(struct hfp_gw *hfp) size_t len, count; bool free_ptr = false; - str = ringbuf_peek(hfp->read_buf, 0, &len); + str = ringbuf_peek(hfp->hfp.read_buf, 0, &len); if (!str) return; @@ -394,10 +399,10 @@ static void process_input(struct hfp_gw *hfp) /* If there is no more data in ringbuffer, * it's just an incomplete command. */ - if (len == ringbuf_len(hfp->read_buf)) + if (len == ringbuf_len(hfp->hfp.read_buf)) return; - str2 = ringbuf_peek(hfp->read_buf, len, &len2); + str2 = ringbuf_peek(hfp->hfp.read_buf, len, &len2); if (!str2) return; @@ -423,7 +428,7 @@ static void process_input(struct hfp_gw *hfp) hfp_gw_send_result(hfp, HFP_RESULT_ERROR); } - len = ringbuf_drain(hfp->read_buf, count + 1); + len = ringbuf_drain(hfp->hfp.read_buf, count + 1); if (free_ptr) free(ptr); @@ -438,7 +443,7 @@ static bool can_read_data(struct io *io, void *user_data) struct hfp_gw *hfp = user_data; ssize_t bytes_read; - bytes_read = ringbuf_read(hfp->read_buf, hfp->fd); + bytes_read = ringbuf_read(hfp->hfp.read_buf, hfp->hfp.fd); if (bytes_read < 0) return false; @@ -461,51 +466,51 @@ struct hfp_gw *hfp_gw_new(int fd) if (!hfp) return NULL; - hfp->fd = fd; - hfp->close_on_unref = false; + hfp->hfp.fd = fd; + hfp->hfp.close_on_unref = false; - hfp->read_buf = ringbuf_new(4096); - if (!hfp->read_buf) { + hfp->hfp.read_buf = ringbuf_new(4096); + if (!hfp->hfp.read_buf) { free(hfp); return NULL; } - hfp->write_buf = ringbuf_new(4096); - if (!hfp->write_buf) { - ringbuf_free(hfp->read_buf); + hfp->hfp.write_buf = ringbuf_new(4096); + if (!hfp->hfp.write_buf) { + ringbuf_free(hfp->hfp.read_buf); free(hfp); return NULL; } - hfp->io = io_new(fd); - if (!hfp->io) { - ringbuf_free(hfp->write_buf); - ringbuf_free(hfp->read_buf); + hfp->hfp.io = io_new(fd); + if (!hfp->hfp.io) { + ringbuf_free(hfp->hfp.write_buf); + ringbuf_free(hfp->hfp.read_buf); free(hfp); return NULL; } hfp->cmd_handlers = queue_new(); if (!hfp->cmd_handlers) { - io_destroy(hfp->io); - ringbuf_free(hfp->write_buf); - ringbuf_free(hfp->read_buf); + io_destroy(hfp->hfp.io); + ringbuf_free(hfp->hfp.write_buf); + ringbuf_free(hfp->hfp.read_buf); free(hfp); return NULL; } - if (!io_set_read_handler(hfp->io, can_read_data, + if (!io_set_read_handler(hfp->hfp.io, can_read_data, hfp, read_watch_destroy)) { queue_destroy(hfp->cmd_handlers, destroy_cmd_handler); - io_destroy(hfp->io); - ringbuf_free(hfp->write_buf); - ringbuf_free(hfp->read_buf); + io_destroy(hfp->hfp.io); + ringbuf_free(hfp->hfp.write_buf); + ringbuf_free(hfp->hfp.read_buf); free(hfp); return NULL; } - hfp->writer_active = false; + hfp->hfp.writer_active = false; hfp->result_pending = false; return hfp_gw_ref(hfp); @@ -516,7 +521,7 @@ struct hfp_gw *hfp_gw_ref(struct hfp_gw *hfp) if (!hfp) return NULL; - __sync_fetch_and_add(&hfp->ref_count, 1); + __sync_fetch_and_add(&hfp->hfp.ref_count, 1); return hfp; } @@ -526,52 +531,54 @@ void hfp_gw_unref(struct hfp_gw *hfp) if (!hfp) return; - if (__sync_sub_and_fetch(&hfp->ref_count, 1)) + if (__sync_sub_and_fetch(&hfp->hfp.ref_count, 1)) return; hfp_gw_set_command_handler(hfp, NULL, NULL, NULL); - io_set_write_handler(hfp->io, NULL, NULL, NULL); - io_set_read_handler(hfp->io, NULL, NULL, NULL); - io_set_disconnect_handler(hfp->io, NULL, NULL, NULL); + io_set_write_handler(hfp->hfp.io, NULL, NULL, NULL); + io_set_read_handler(hfp->hfp.io, NULL, NULL, NULL); + io_set_disconnect_handler(hfp->hfp.io, NULL, NULL, NULL); - io_destroy(hfp->io); - hfp->io = NULL; + io_destroy(hfp->hfp.io); + hfp->hfp.io = NULL; - if (hfp->close_on_unref) - close(hfp->fd); + if (hfp->hfp.close_on_unref) + close(hfp->hfp.fd); hfp_gw_set_debug(hfp, NULL, NULL, NULL); - ringbuf_free(hfp->read_buf); - hfp->read_buf = NULL; + ringbuf_free(hfp->hfp.read_buf); + hfp->hfp.read_buf = NULL; - ringbuf_free(hfp->write_buf); - hfp->write_buf = NULL; + ringbuf_free(hfp->hfp.write_buf); + hfp->hfp.write_buf = NULL; queue_destroy(hfp->cmd_handlers, destroy_cmd_handler); hfp->cmd_handlers = NULL; - if (!hfp->in_disconnect) { + if (!hfp->hfp.in_disconnect) { free(hfp); return; } - hfp->destroyed = true; + hfp->hfp.destroyed = true; } static void read_tracing(const void *buf, size_t count, void *user_data) { struct hfp_gw *hfp = user_data; - util_hexdump('>', buf, count, hfp->debug_callback, hfp->debug_data); + util_hexdump('>', buf, count, hfp->hfp.debug_callback, + hfp->hfp.debug_data); } static void write_tracing(const void *buf, size_t count, void *user_data) { struct hfp_gw *hfp = user_data; - util_hexdump('<', buf, count, hfp->debug_callback, hfp->debug_data); + util_hexdump('<', buf, count, hfp->hfp.debug_callback, + hfp->hfp.debug_data); } bool hfp_gw_set_debug(struct hfp_gw *hfp, hfp_debug_func_t callback, @@ -580,19 +587,19 @@ bool hfp_gw_set_debug(struct hfp_gw *hfp, hfp_debug_func_t callback, if (!hfp) return false; - if (hfp->debug_destroy) - hfp->debug_destroy(hfp->debug_data); + if (hfp->hfp.debug_destroy) + hfp->hfp.debug_destroy(hfp->hfp.debug_data); - hfp->debug_callback = callback; - hfp->debug_destroy = destroy; - hfp->debug_data = user_data; + hfp->hfp.debug_callback = callback; + hfp->hfp.debug_destroy = destroy; + hfp->hfp.debug_data = user_data; - if (hfp->debug_callback) { - ringbuf_set_input_tracing(hfp->read_buf, read_tracing, hfp); - ringbuf_set_input_tracing(hfp->write_buf, write_tracing, hfp); + if (hfp->hfp.debug_callback) { + ringbuf_set_input_tracing(hfp->hfp.read_buf, read_tracing, hfp); + ringbuf_set_input_tracing(hfp->hfp.write_buf, write_tracing, hfp); } else { - ringbuf_set_input_tracing(hfp->read_buf, NULL, NULL); - ringbuf_set_input_tracing(hfp->write_buf, NULL, NULL); + ringbuf_set_input_tracing(hfp->hfp.read_buf, NULL, NULL); + ringbuf_set_input_tracing(hfp->hfp.write_buf, NULL, NULL); } return true; @@ -603,7 +610,7 @@ bool hfp_gw_set_close_on_unref(struct hfp_gw *hfp, bool do_close) if (!hfp) return false; - hfp->close_on_unref = do_close; + hfp->hfp.close_on_unref = do_close; return true; } @@ -626,7 +633,7 @@ bool hfp_gw_send_result(struct hfp_gw *hfp, enum hfp_result result) return false; } - if (ringbuf_printf(hfp->write_buf, "\r\n%s\r\n", str) < 0) + if (ringbuf_printf(hfp->hfp.write_buf, "\r\n%s\r\n", str) < 0) return false; wakeup_writer(hfp); @@ -641,7 +648,7 @@ bool hfp_gw_send_error(struct hfp_gw *hfp, enum hfp_error error) if (!hfp) return false; - if (ringbuf_printf(hfp->write_buf, "\r\n+CME ERROR: %u\r\n", error) < 0) + if (ringbuf_printf(hfp->hfp.write_buf, "\r\n+CME ERROR: %u\r\n", error) < 0) return false; wakeup_writer(hfp); @@ -664,7 +671,7 @@ bool hfp_gw_send_info(struct hfp_gw *hfp, const char *format, ...) return false; va_start(ap, format); - len = ringbuf_vprintf(hfp->write_buf, fmt, ap); + len = ringbuf_vprintf(hfp->hfp.write_buf, fmt, ap); va_end(ap); free(fmt); @@ -753,10 +760,10 @@ static void disconnect_watch_destroy(void *user_data) { struct hfp_gw *hfp = user_data; - if (hfp->disconnect_destroy) - hfp->disconnect_destroy(hfp->disconnect_data); + if (hfp->hfp.disconnect_destroy) + hfp->hfp.disconnect_destroy(hfp->hfp.disconnect_data); - if (hfp->destroyed) + if (hfp->hfp.destroyed) free(hfp); } @@ -764,12 +771,12 @@ static bool io_disconnected(struct io *io, void *user_data) { struct hfp_gw *hfp = user_data; - hfp->in_disconnect = true; + hfp->hfp.in_disconnect = true; - if (hfp->disconnect_callback) - hfp->disconnect_callback(hfp->disconnect_data); + if (hfp->hfp.disconnect_callback) + hfp->hfp.disconnect_callback(hfp->hfp.disconnect_data); - hfp->in_disconnect = false; + hfp->hfp.in_disconnect = false; return false; } @@ -782,20 +789,20 @@ bool hfp_gw_set_disconnect_handler(struct hfp_gw *hfp, if (!hfp) return false; - if (hfp->disconnect_destroy) - hfp->disconnect_destroy(hfp->disconnect_data); + if (hfp->hfp.disconnect_destroy) + hfp->hfp.disconnect_destroy(hfp->hfp.disconnect_data); - if (!io_set_disconnect_handler(hfp->io, io_disconnected, hfp, + if (!io_set_disconnect_handler(hfp->hfp.io, io_disconnected, hfp, disconnect_watch_destroy)) { - hfp->disconnect_callback = NULL; - hfp->disconnect_destroy = NULL; - hfp->disconnect_data = NULL; + hfp->hfp.disconnect_callback = NULL; + hfp->hfp.disconnect_destroy = NULL; + hfp->hfp.disconnect_data = NULL; return false; } - hfp->disconnect_callback = callback; - hfp->disconnect_destroy = destroy; - hfp->disconnect_data = user_data; + hfp->hfp.disconnect_callback = callback; + hfp->hfp.disconnect_destroy = destroy; + hfp->hfp.disconnect_data = user_data; return true; } @@ -805,5 +812,5 @@ bool hfp_gw_disconnect(struct hfp_gw *hfp) if (!hfp) return false; - return io_shutdown(hfp->io); + return io_shutdown(hfp->hfp.io); } -- 1.8.4 -- 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