Re: [PATCH BlueZ 1/6] AVCTP: Add support to register pass-through handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Fri, Apr 19, 2013 at 3:31 PM, Luiz Augusto von Dentz
<luiz.dentz@xxxxxxxxx> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>
> Pass-through handler can be used to capture AV/C Panel commands before
> they are sent to uinput.
> ---
>  profiles/audio/avctp.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  profiles/audio/avctp.h |  8 ++++++
>  2 files changed, 80 insertions(+)
>
> diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
> index 21aeb6f..705bf71 100644
> --- a/profiles/audio/avctp.c
> +++ b/profiles/audio/avctp.c
> @@ -192,10 +192,18 @@ struct avctp {
>         struct avctp_channel *control;
>         struct avctp_channel *browsing;
>
> +       struct avctp_passthrough_handler *handler;
> +
>         uint8_t key_quirks[256];
>         struct key_pressed *key;
>  };
>
> +struct avctp_passthrough_handler {
> +       avctp_passthrough_cb cb;
> +       void *user_data;
> +       unsigned int id;
> +};
> +
>  struct avctp_pdu_handler {
>         uint8_t opcode;
>         avctp_control_pdu_cb cb;
> @@ -280,6 +288,8 @@ static size_t handle_panel_passthrough(struct avctp *session,
>                                         uint8_t *subunit, uint8_t *operands,
>                                         size_t operand_count, void *user_data)
>  {
> +       struct key_pressed *key = session->key;
> +       struct avctp_passthrough_handler *handler = session->handler;
>         const char *status;
>         int pressed, i;
>
> @@ -299,6 +309,12 @@ static size_t handle_panel_passthrough(struct avctp *session,
>                 pressed = 1;
>         }
>
> +       if (key == NULL && handler != NULL) {
> +               if (handler->cb(session, operands[0] & 0x7F,
> +                                               pressed, handler->user_data))
> +                       goto done;
> +       }
> +
>         for (i = 0; key_map[i].name != NULL; i++) {
>                 uint8_t key_quirks;
>
> @@ -321,6 +337,16 @@ static size_t handle_panel_passthrough(struct avctp *session,
>                         break;
>                 }
>
> +               if (pressed) {
> +                       if (key == NULL)
> +                               key = g_new0(struct key_pressed, 1);
> +                       key->op = key_map[i].avc;
> +                       session->key = key;
> +               } else if (key && key->op == key_map[i].avc) {
> +                       g_free(key);
> +                       session->key = NULL;
> +               }
> +
>                 send_key(session->uinput, key_map[i].uinput, pressed);
>                 break;
>         }
> @@ -1692,6 +1718,52 @@ gboolean avctp_remove_state_cb(unsigned int id)
>         return FALSE;
>  }
>
> +unsigned int avctp_register_passthrough_handler(struct avctp *session,
> +                                               avctp_passthrough_cb cb,
> +                                               void *user_data)
> +{
> +       struct avctp_channel *control = session->control;
> +       struct avctp_passthrough_handler *handler;
> +       static unsigned int id = 0;
> +
> +       if (control == NULL || session->handler != NULL)
> +               return 0;
> +
> +       handler = g_new(struct avctp_passthrough_handler, 1);
> +       handler->cb = cb;
> +       handler->user_data = user_data;
> +       handler->id = ++id;
> +
> +       session->handler = handler;
> +
> +       return handler->id;
> +}
> +
> +bool avctp_unregister_passthrough_handler(unsigned int id)
> +{
> +       GSList *l;
> +
> +       for (l = servers; l; l = l->next) {
> +               struct avctp_server *server = l->data;
> +               GSList *s;
> +
> +               for (s = server->sessions; s; s = s->next) {
> +                       struct avctp *session = s->data;
> +
> +                       if (session->handler == NULL)
> +                               continue;
> +
> +                       if (session->handler->id == id) {
> +                               g_free(session->handler);
> +                               session->handler = NULL;
> +                               return true;
> +                       }
> +               }
> +       }
> +
> +       return false;
> +}
> +
>  unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
>                                                 avctp_control_pdu_cb cb,
>                                                 void *user_data)
> diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
> index 648e982..0a414af 100644
> --- a/profiles/audio/avctp.h
> +++ b/profiles/audio/avctp.h
> @@ -94,6 +94,9 @@ typedef void (*avctp_state_cb) (struct audio_device *dev,
>                                 avctp_state_t old_state,
>                                 avctp_state_t new_state);
>
> +typedef bool (*avctp_passthrough_cb) (struct avctp *session,
> +                                       uint8_t op, bool pressed,
> +                                       void *user_data);
>  typedef size_t (*avctp_control_pdu_cb) (struct avctp *session,
>                                         uint8_t transaction, uint8_t *code,
>                                         uint8_t *subunit, uint8_t *operands,
> @@ -120,6 +123,11 @@ struct avctp *avctp_get(struct audio_device *device);
>  int avctp_connect_browsing(struct avctp *session);
>  void avctp_disconnect(struct avctp *session);
>
> +unsigned int avctp_register_passthrough_handler(struct avctp *session,
> +                                               avctp_passthrough_cb cb,
> +                                               void *user_data);
> +bool avctp_unregister_passthrough_handler(unsigned int id);
> +
>  unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
>                                                 avctp_control_pdu_cb cb,
>                                                 void *user_data);
> --
> 1.8.1.4

It seems this did not get into upstream, can I go ahead and apply this set?


--
Luiz Augusto von Dentz
--
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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux