Re: [PATCH BlueZ 5/5] AVRCP: Add handler for browsing pdu

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

 



Hi Vani,

On Tue, Jul 10, 2012 at 12:37 PM, Vani-dineshbhai PATEL
<vani.patel@xxxxxxxxxxxxxx> wrote:
> +void avctp_send_browsing(struct avctp *session, uint8_t transaction,
> +                                       uint8_t *operands, size_t operand_count)
> +{
> +       struct avctp_header *avctp_header;
> +       uint8_t *buf;
> +       uint16_t length = 0;
> +       int sock;
> +
> +       length = AVCTP_HEADER_LENGTH + operand_count;
> +       buf = g_malloc0(length);
> +
> +       avctp_header = (void *) buf;
> +
> +       avctp_header->cr = AVCTP_RESPONSE;
> +       avctp_header->ipid = FALSE;
> +       avctp_header->packet_type = AVCTP_PACKET_SINGLE;
> +       avctp_header->pid = htons(AV_REMOTE_PROFILE_ID);
> +       avctp_header->transaction = transaction;
> +
> +       memcpy(&buf[AVCTP_HEADER_LENGTH], operands,
> +                                                       operand_count);
> +
> +       sock = g_io_channel_unix_get_fd(session->browsing_io);
> +       if (write(sock, buf, length) < 0)
> +               DBG("Write failed\n");
> +}

We can probably avoid using memcpy by using sendmsg, actually we
should do this for avctp_send as well.

> +static struct pdu_browsing_handler {
> +       uint8_t browsing_pdu;
> +       void (*func) (struct avrcp_player *player,
> +                                       struct avrcp_browsing_header *pdu);
> +       } browsing_handlers[] = {
> +               {},
> +};

What is the reason to have an empty array here? Is this just a place
holder for upcoming patches?

> +static void handle_browsing_pdu(struct avctp *session, uint8_t transaction,
> +                                       uint8_t *operands, size_t operand_count,
> +                                       void *user_data)
> +{
> +       struct avrcp_player *player = user_data;
> +       struct pdu_browsing_handler *b_handler;
> +       struct avrcp_browsing_header *avrcp_browsing = (void *) operands;
> +       uint8_t status, length;
> +
> +       if ((avrcp_browsing->browsing_pdu != AVRCP_SET_BROWSED_PLAYER) &&
> +                       (avrcp_browsing->browsing_pdu != AVRCP_GET_FOLDER_ITEMS) &&
> +                       (avrcp_browsing->browsing_pdu != AVRCP_CHANGE_PATH) &&
> +                       (avrcp_browsing->browsing_pdu != AVRCP_GET_ITEM_ATTRIBUTES)) {
> +
> +               avrcp_browsing->browsing_pdu = AVRCP_GENERAL_REJECT;
> +               status = AVRCP_STATUS_INVALID_COMMAND;
> +               goto err;
> +       }

This is over 80 columns and is inefficient since you are doing
basically the same bellow.

> +       for (b_handler = browsing_handlers; b_handler; b_handler++) {
> +               if (b_handler->browsing_pdu == avrcp_browsing->browsing_pdu)
> +                       break;
> +       }
> +

Where you should do the check if an handler was found e.g:

if (b_handler == NULL) {
        avrcp_browsing->browsing_pdu = AVRCP_GENERAL_REJECT;
        status = AVRCP_STATUS_INVALID_COMMAND;
        goto err;
}

> +       if (!b_handler->func) {
> +               status = AVRCP_STATUS_INVALID_PARAM;
> +               goto err;
> +       }
> +
> +       player->transaction = transaction;
> +       b_handler->func(player, avrcp_browsing);
> +       return;
> +
> +err:
> +       avrcp_browsing->param_len = htons(sizeof(status));
> +       length = AVRCP_BROWSING_HEADER_LENGTH + sizeof(status);
> +       memcpy(&operands[AVRCP_BROWSING_HEADER_LENGTH], &status,
> +                                               sizeof(status));
> +       avctp_send_browsing(session, player->transaction, operands,
> +                                                                       length);

If you gonna response immediately it is better to return the packet
size an write from the session_cb as done for control pdus, if nothing
should be written because the response will be asynchronous we can
just have it the handler return 0 and handle that in session_cb as no
response.

> +}
> +
>  size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands)
>  {
>         struct avrcp_header *pdu = (void *) operands;
> @@ -1233,6 +1299,11 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
>                         avctp_unregister_pdu_handler(player->control_handler);
>                         player->control_handler = 0;
>                 }
> +               if (player->browsing_handler) {
> +                       avctp_unregister_browsing_pdu_handler(
> +                                               player->browsing_handler);
> +                       player->browsing_handler = 0;
> +               }

The indentation above looks wrong, add a empty line before the if
statement, avctp_unregister_browsing_pdu_handler too long name.

>                 break;
>         case AVCTP_STATE_CONNECTING:
> @@ -1244,6 +1315,12 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
>                                                         AVC_OP_VENDORDEP,
>                                                         handle_vendordep_pdu,
>                                                         player);
> +               if (!player->browsing_handler)
> +                       player->browsing_handler =
> +                                       avctp_register_browsing_pdu_handler(
> +                                                       handle_browsing_pdu,
> +                                                       player);
> +

avctp_register_browsing_pdu_handler is also too long, in fact this is
another that we should probably just reuse avctp_register_pdu_handler
and maybe create an opcode for browsing just so that it be can
registered using avctp_register_pdu_handler.

>                 break;
>         case AVCTP_STATE_CONNECTED:
>                 rec = btd_device_get_record(dev->btd_dev, AVRCP_TARGET_UUID);
> diff --git a/audio/avrcp.h b/audio/avrcp.h
> index bf11a6c..7e2f018 100644
> --- a/audio/avrcp.h
> +++ b/audio/avrcp.h
> @@ -75,6 +75,8 @@
>  #define AVRCP_EVENT_TRACK_REACHED_START        0x04
>  #define AVRCP_EVENT_VOLUME_CHANGED     0x0d
>  #define AVRCP_EVENT_LAST               AVRCP_EVENT_VOLUME_CHANGED
> +struct avrcp_browsing_header;
> +#define AVRCP_BROWSING_HEADER_LENGTH 3

This is probably not necessary as the header should only be needed
inside avrcp.c you don't need to make it public.


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