1 /*
2  * Copyright 2024 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 <base/functional/bind.h>
18 
19 #include <cstdint>
20 #include <cstring>
21 #include <string>
22 
23 #include "bluetooth/log.h"
24 #include "bta/ras/ras_types.h"
25 #include "types/bluetooth/uuid.h"
26 
27 using namespace bluetooth;
28 using namespace ::ras;
29 using namespace ::ras::uuid;
30 
31 namespace ras {
getUuidName(const bluetooth::Uuid & uuid)32 std::string uuid::getUuidName(const bluetooth::Uuid& uuid) {
33   switch (uuid.As16Bit()) {
34     case kRangingService16Bit:
35       return "Ranging Service";
36     case kRasFeaturesCharacteristic16bit:
37       return "RAS Features";
38     case kRasRealTimeRangingDataCharacteristic16bit:
39       return "Real-time Ranging Data";
40     case kRasOnDemandDataCharacteristic16bit:
41       return "On-demand Ranging Data";
42     case kRasControlPointCharacteristic16bit:
43       return "RAS Control Point (RAS-CP)";
44     case kRasRangingDataReadyCharacteristic16bit:
45       return "Ranging Data Ready";
46     case kRasRangingDataOverWrittenCharacteristic16bit:
47       return "Ranging Data Overwritten";
48     case kClientCharacteristicConfiguration16bit:
49       return "Client Characteristic Configuration";
50     default:
51       return "Unknown UUID";
52   }
53 }
54 
ParseControlPointCommand(ControlPointCommand * command,const uint8_t * value,uint16_t len)55 bool ParseControlPointCommand(ControlPointCommand* command, const uint8_t* value, uint16_t len) {
56   command->opcode_ = static_cast<Opcode>(value[0]);
57   // Check for minimum expected length
58   switch (value[0]) {
59     case (uint8_t)Opcode::ABORT_OPERATION:
60       if (len != 1) {
61         return false;
62       }
63       break;
64     case (uint8_t)Opcode::GET_RANGING_DATA:
65     case (uint8_t)Opcode::ACK_RANGING_DATA:
66     case (uint8_t)Opcode::FILTER:
67       if (len != 3) {
68         return false;
69       }
70       break;
71     case (uint8_t)Opcode::RETRIEVE_LOST_RANGING_DATA_SEGMENTS:
72       if (len != 5) {
73         return false;
74       }
75       break;
76     default:
77       log::warn("unknown opcode 0x{:02x}", value[0]);
78       return false;
79   }
80   std::memcpy(command->parameter_, value + 1, len - 1);
81   command->isValid_ = true;
82   return true;
83 }
84 
GetOpcodeText(Opcode opcode)85 std::string GetOpcodeText(Opcode opcode) {
86   switch (opcode) {
87     case Opcode::GET_RANGING_DATA:
88       return "GET_RANGING_DATA";
89     case Opcode::ACK_RANGING_DATA:
90       return "ACK_RANGING_DATA";
91     case Opcode::RETRIEVE_LOST_RANGING_DATA_SEGMENTS:
92       return "RETRIEVE_LOST_RANGING_DATA_SEGMENTS";
93     case Opcode::ABORT_OPERATION:
94       return "ABORT_OPERATION";
95     case Opcode::FILTER:
96       return "FILTER";
97     default:
98       return "Unknown Opcode";
99   }
100 }
101 
GetResponseOpcodeValueText(ResponseCodeValue response_code_value)102 std::string GetResponseOpcodeValueText(ResponseCodeValue response_code_value) {
103   switch (response_code_value) {
104     case ResponseCodeValue::RESERVED_FOR_FUTURE_USE:
105       return "RESERVED_FOR_FUTURE_USE";
106     case ResponseCodeValue::SUCCESS:
107       return "SUCCESS";
108     case ResponseCodeValue::OP_CODE_NOT_SUPPORTED:
109       return "OP_CODE_NOT_SUPPORTED";
110     case ResponseCodeValue::INVALID_PARAMETER:
111       return "INVALID_PARAMETER";
112     case ResponseCodeValue::PERSISTED:
113       return "PERSISTED";
114     case ResponseCodeValue::ABORT_UNSUCCESSFUL:
115       return "ABORT_UNSUCCESSFUL";
116     case ResponseCodeValue::PROCEDURE_NOT_COMPLETED:
117       return "PROCEDURE_NOT_COMPLETED";
118     case ResponseCodeValue::SERVER_BUSY:
119       return "SERVER_BUSY";
120     case ResponseCodeValue::NO_RECORDS_FOUND:
121       return "NO_RECORDS_FOUND";
122     default:
123       return "Reserved for Future Use";
124   }
125 }
126 
IsRangingServiceCharacteristic(const bluetooth::Uuid & uuid)127 bool IsRangingServiceCharacteristic(const bluetooth::Uuid& uuid) {
128   if (!uuid.Is16Bit()) {
129     return false;
130   }
131   switch (uuid.As16Bit()) {
132     case kRangingService16Bit:
133     case kRasFeaturesCharacteristic16bit:
134     case kRasRealTimeRangingDataCharacteristic16bit:
135     case kRasOnDemandDataCharacteristic16bit:
136     case kRasControlPointCharacteristic16bit:
137     case kRasRangingDataReadyCharacteristic16bit:
138     case kRasRangingDataOverWrittenCharacteristic16bit:
139       return true;
140     default:
141       return false;
142   }
143 }
144 
145 }  // namespace ras
146