1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <arpa/inet.h>  // htons
18 #include <dlfcn.h>
19 #include <gtest/gtest.h>
20 
21 #include "stack/include/avrc_api.h"
22 
23 class StackAvrcpTest : public ::testing::Test {
24  protected:
25   StackAvrcpTest() = default;
26 
27   virtual ~StackAvrcpTest() = default;
28 };
29 
TEST_F(StackAvrcpTest,test_avrcp_parse_browse_cmd)30 TEST_F(StackAvrcpTest, test_avrcp_parse_browse_cmd) {
31   uint8_t scratch_buf[512]{};
32   tAVRC_MSG msg{};
33   tAVRC_COMMAND result{};
34   uint8_t browse_cmd_buf[512]{};
35 
36   msg.hdr.opcode = AVRC_OP_BROWSE;
37   msg.browse.p_browse_data = browse_cmd_buf;
38   msg.browse.browse_len = 2;
39   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
40             AVRC_STS_BAD_CMD);
41 
42   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
43   browse_cmd_buf[0] = AVRC_PDU_SET_BROWSED_PLAYER;
44   msg.browse.browse_len = 3;
45   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
46             AVRC_STS_BAD_CMD);
47 
48   msg.browse.browse_len = 5;
49   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
50             AVRC_STS_NO_ERROR);
51 
52   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
53   browse_cmd_buf[0] = AVRC_PDU_GET_FOLDER_ITEMS;
54   msg.browse.browse_len = 3;
55   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
56             AVRC_STS_BAD_CMD);
57 
58   msg.browse.browse_len = 13;
59   uint8_t* p = &browse_cmd_buf[3];
60   UINT8_TO_STREAM(p, AVRC_SCOPE_NOW_PLAYING);  // scope
61   UINT32_TO_STREAM(p, 0x00000001);             // start_item
62   UINT32_TO_STREAM(p, 0x00000002);             // end_item
63   browse_cmd_buf[12] = 0;                      // attr_count
64   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
65             AVRC_STS_NO_ERROR);
66 
67   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
68   browse_cmd_buf[0] = AVRC_PDU_CHANGE_PATH;
69   msg.browse.browse_len = 3;
70   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
71             AVRC_STS_BAD_CMD);
72 
73   msg.browse.browse_len = 14;
74   p = &browse_cmd_buf[3];
75   UINT16_TO_STREAM(p, 0x1234);      // uid_counter
76   UINT8_TO_STREAM(p, AVRC_DIR_UP);  // direction
77   UINT8_TO_STREAM(p, 0);            // attr_count
78   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
79             AVRC_STS_NO_ERROR);
80 
81   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
82   browse_cmd_buf[0] = AVRC_PDU_GET_ITEM_ATTRIBUTES;
83   msg.browse.browse_len = 3;
84   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
85             AVRC_STS_BAD_CMD);
86 
87   msg.browse.browse_len = 15;
88   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
89             AVRC_STS_NO_ERROR);
90 
91   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
92   browse_cmd_buf[0] = AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS;
93   msg.browse.browse_len = 3;
94   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
95             AVRC_STS_BAD_CMD);
96 
97   msg.browse.browse_len = 4;
98   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
99             AVRC_STS_NO_ERROR);
100 
101   memset(browse_cmd_buf, 0, sizeof(browse_cmd_buf));
102   browse_cmd_buf[0] = AVRC_PDU_SEARCH;
103   msg.browse.browse_len = 3;
104   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
105             AVRC_STS_BAD_CMD);
106 
107   p = &browse_cmd_buf[3];
108   UINT16_TO_STREAM(p, 0x0000);  // charset_id
109   UINT16_TO_STREAM(p, 0x0000);  // str_len
110   msg.browse.browse_len = 7;
111   EXPECT_EQ(AVRC_ParsCommand(&msg, &result, scratch_buf, sizeof(scratch_buf)),
112             AVRC_STS_NO_ERROR);
113 }
114 
TEST_F(StackAvrcpTest,test_avrcp_pdu_register_notification)115 TEST_F(StackAvrcpTest, test_avrcp_pdu_register_notification) {
116   ASSERT_EQ(htons(0x500), 5);
117 
118   struct {
119     uint8_t pdu;
120     uint8_t reserved;
121     uint16_t len;
122     struct {
123       uint8_t event_id;
124       uint32_t param;
125     } payload;
126   } data = {
127       AVRC_PDU_REGISTER_NOTIFICATION,
128       0,  // reserved
129       htons(sizeof(data.payload)),
130       .payload =
131           {
132               .event_id = 0,
133               .param = 0x1234,
134           },
135   };
136 
137   tAVRC_MSG msg = {
138       .vendor =
139           {
140               .hdr =
141                   {
142                       .ctype = AVRC_CMD_NOTIF,
143                       .opcode = AVRC_OP_VENDOR,
144                   },
145               .p_vendor_data = (uint8_t*)&data,
146               .vendor_len = sizeof(data),
147           },
148   };
149   tAVRC_COMMAND result{};
150 
151   // Run through all possible event ids
152   uint8_t id = 0;
153   do {
154     data.payload.event_id = id;
155     ASSERT_EQ((id == 0 || id > AVRC_NUM_NOTIF_EVENTS) ? AVRC_STS_BAD_PARAM
156                                                       : AVRC_STS_NO_ERROR,
157               AVRC_Ctrl_ParsCommand(&msg, &result));
158   } while (++id != 0);
159 }
160