avrcp_controller.c (b28a301e4cb410ef409cc073c79f2d0b866d3387) | avrcp_controller.c (8b631c133ad1de27895b59950abcd1500898b447) |
---|---|
1/* 2 * Copyright (C) 2016 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 1242 unchanged lines hidden (view full) --- 1251 1252 // trigger pending notification reqistrations 1253 if ((connection->state == AVCTP_CONNECTION_OPENED) && connection->controller_notifications_to_register){ 1254 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1255 } 1256} 1257 1258static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ | 1/* 2 * Copyright (C) 2016 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 1242 unchanged lines hidden (view full) --- 1251 1252 // trigger pending notification reqistrations 1253 if ((connection->state == AVCTP_CONNECTION_OPENED) && connection->controller_notifications_to_register){ 1254 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1255 } 1256} 1257 1258static void avrcp_controller_handle_can_send_now(avrcp_connection_t * connection){ |
1259 // identifier (9) + num attributes (1) + attributes (4 * num attributes) 1260 uint8_t get_element_attributes_command[9+8*((AVRCP_MEDIA_ATTR_RESERVED-AVRCP_MEDIA_ATTR_TITLE) + 1)]; 1261 uint16_t pos; 1262 uint16_t num_attributes_index; 1263 uint8_t i; 1264 |
|
1259 switch (connection->state){ 1260 case AVCTP_W2_SEND_PRESS_COMMAND: 1261 avrcp_send_cmd_with_avctp_fragmentation(connection); 1262 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 1263 return; 1264 1265 case AVCTP_W2_SEND_RELEASE_COMMAND: 1266 avrcp_send_cmd_with_avctp_fragmentation(connection); --- 4 unchanged lines hidden (view full) --- 1271 avrcp_send_cmd_with_avctp_fragmentation(connection); 1272 if (connection->data_offset < connection->data_len){ 1273 // continue AVCTP fragmentation 1274 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1275 return; 1276 } 1277 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 1278 return; | 1265 switch (connection->state){ 1266 case AVCTP_W2_SEND_PRESS_COMMAND: 1267 avrcp_send_cmd_with_avctp_fragmentation(connection); 1268 connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE; 1269 return; 1270 1271 case AVCTP_W2_SEND_RELEASE_COMMAND: 1272 avrcp_send_cmd_with_avctp_fragmentation(connection); --- 4 unchanged lines hidden (view full) --- 1277 avrcp_send_cmd_with_avctp_fragmentation(connection); 1278 if (connection->data_offset < connection->data_len){ 1279 // continue AVCTP fragmentation 1280 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1281 return; 1282 } 1283 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 1284 return; |
1285 case AVCTP_W2_SEND_GET_ELEMENT_ATTRIBUTES_REQUEST: 1286 // build command in local buffer 1287 pos = 0; 1288 connection->data = get_element_attributes_command; 1289 // write identifier 1290 memset(connection->data, 0, 8); 1291 pos += 8; 1292 num_attributes_index = pos; 1293 // If num_attributes is set to zero, all attribute information shall be returned, 1294 // and the AttributeID field is omitted 1295 connection->data[num_attributes_index] = 0; 1296 pos++; 1297 for (i = 0; i < AVRCP_MEDIA_ATTR_RESERVED-AVRCP_MEDIA_ATTR_TITLE; i++){ 1298 if ((connection->controller_element_attributes & (1<<i)) != 0){ 1299 // every attribute is 4 bytes long 1300 big_endian_store_32(connection->data, pos, AVRCP_MEDIA_ATTR_TITLE + i); 1301 pos += 4; 1302 connection->data[num_attributes_index]++; 1303 } 1304 } 1305 1306 // Parameter Length 1307 connection->data_len = pos; 1308 1309 log_info("AVCTP_W2_SEND_GET_ELEMENT_ATTRIBUTES_REQUEST, len %u", connection->data_len); 1310 1311 // send data - assume it will fit into one packet 1312 avrcp_send_cmd_with_avctp_fragmentation(connection); 1313 connection->state = AVCTP_W2_RECEIVE_RESPONSE; 1314 return; |
|
1279 default: 1280 break; 1281 } 1282 1283 // send register notification if queued, 1284 // avrcp_handle_l2cap_data_packet_for_signaling_connection will trigger next one 1285 if (connection->controller_notifications_to_register != 0){ 1286 uint8_t event_id; --- 303 unchanged lines hidden (view full) --- 1590 } 1591 1592 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1593 1594 if (num_attributes >= AVRCP_MEDIA_ATTR_RESERVED) { 1595 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 1596 } 1597 | 1315 default: 1316 break; 1317 } 1318 1319 // send register notification if queued, 1320 // avrcp_handle_l2cap_data_packet_for_signaling_connection will trigger next one 1321 if (connection->controller_notifications_to_register != 0){ 1322 uint8_t event_id; --- 303 unchanged lines hidden (view full) --- 1626 } 1627 1628 if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED; 1629 1630 if (num_attributes >= AVRCP_MEDIA_ATTR_RESERVED) { 1631 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 1632 } 1633 |
1598 connection->state = AVCTP_W2_SEND_COMMAND; | 1634 connection->state = AVCTP_W2_SEND_GET_ELEMENT_ATTRIBUTES_REQUEST; |
1599 avrcp_controller_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES, true); 1600 | 1635 avrcp_controller_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES, true); 1636 |
1601 uint8_t pos = 0; 1602 // write 8 bytes value 1603 memset(connection->data, pos, 8); // identifier: PLAYING 1604 pos += 8; 1605 1606 uint8_t num_attributes_index = pos; 1607 pos++; 1608 1609 // If num_attributes is set to zero, all attribute information shall be returned, 1610 // and the AttributeID field is omitted 1611 connection->data[num_attributes_index] = 0; | 1637 // collect element attributes |
1612 uint8_t i; | 1638 uint8_t i; |
1639 uint16_t attributes_set = 0; |
|
1613 for (i = 0; i < num_attributes; i++){ 1614 // ignore invalid attribute ID and "get all attributes" 1615 if (AVRCP_MEDIA_ATTR_ALL < attributes[i] && attributes[i] < AVRCP_MEDIA_ATTR_RESERVED){ | 1640 for (i = 0; i < num_attributes; i++){ 1641 // ignore invalid attribute ID and "get all attributes" 1642 if (AVRCP_MEDIA_ATTR_ALL < attributes[i] && attributes[i] < AVRCP_MEDIA_ATTR_RESERVED){ |
1616 // every attribute is 4 bytes long 1617 big_endian_store_32(connection->data, pos, attributes[i]); 1618 pos += 4; 1619 connection->data[num_attributes_index]++; | 1643 attributes_set |= 1 << (attributes[i] - AVRCP_MEDIA_ATTR_TITLE); |
1620 } 1621 } | 1644 } 1645 } |
1646 connection->controller_element_attributes = attributes_set; |
|
1622 | 1647 |
1623 // Parameter Length 1624 connection->data_len = pos; 1625 | |
1626 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1627 return ERROR_CODE_SUCCESS; 1628} 1629 1630uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 1631 return avrcp_controller_get_element_attributes(avrcp_cid, 0, NULL); 1632} 1633 --- 200 unchanged lines hidden --- | 1648 avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid); 1649 return ERROR_CODE_SUCCESS; 1650} 1651 1652uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){ 1653 return avrcp_controller_get_element_attributes(avrcp_cid, 0, NULL); 1654} 1655 --- 200 unchanged lines hidden --- |