1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "hril_base.h"
17
18#include <sstream>
19#include <string_ex.h>
20
21#include "hril_manager.h"
22
23namespace OHOS {
24namespace Telephony {
25static constexpr uint8_t HEX_OFFSET = 4;
26static constexpr char HEX_TABLE[] = "0123456789ABCDEF";
27
28int32_t HRilBase::ConvertHexStringToInt(char **response, int32_t index, int32_t length)
29{
30    const int32_t hexBase = HRIL_INVALID_HEX_CHAR;
31    if ((response == nullptr) || (length <= index) || (response[index] == nullptr)) {
32        return HRIL_ERR_GENERIC_FAILURE;
33    }
34    return strtol(response[index], nullptr, hexBase);
35}
36
37HRilNotiType HRilBase::ConvertIntToRadioNoticeType(int32_t indicationType)
38{
39    return (indicationType == (int32_t)ReportType::HRIL_NOTIFICATION) ? (HRilNotiType::HRIL_NOTIFICATION) :
40                                                                        (HRilNotiType::HRIL_NO_DEFINE);
41}
42
43uint8_t HRilBase::ConvertHexCharToInt(uint8_t ch)
44{
45    if ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
46        return ((ch - 'A') % HRIL_UPPER_CASE_LETTERS_OFFSET + HRIL_DEC);
47    } else if (ch >= '0' && ch <= '9') {
48        return (ch - '0');
49    } else {
50        return HRIL_INVALID_HEX_CHAR;
51    }
52}
53
54uint8_t *HRilBase::ConvertHexStringToBytes(const void *response, size_t length)
55{
56    const int32_t SIZE_VALUE = 2;
57    const int32_t BIT_NUM = 4;
58
59    if (response == nullptr) {
60        TELEPHONY_LOGE("response is null!!!");
61        return nullptr;
62    }
63
64    size_t bytesLen = length / SIZE_VALUE;
65    if (length % SIZE_VALUE != 0 || bytesLen <= 0) {
66        TELEPHONY_LOGE("invalid length: %{public}zu", length);
67        return nullptr;
68    }
69    uint8_t *bytes = (uint8_t *)calloc(bytesLen, sizeof(uint8_t));
70    if (bytes == nullptr) {
71        TELEPHONY_LOGE("ConvertHexStringToBytes: cannot allocate memory for bytes string");
72        return nullptr;
73    }
74
75    uint8_t *hexStr = (uint8_t *)response;
76    size_t i = 0;
77    while (i < length) {
78        uint8_t hexCh1 = ConvertHexCharToInt(hexStr[i]);
79        uint8_t hexCh2 = ConvertHexCharToInt(hexStr[i + 1]);
80        if (hexCh1 == HRIL_INVALID_HEX_CHAR || hexCh2 == HRIL_INVALID_HEX_CHAR) {
81            free(bytes);
82            return nullptr;
83        }
84        bytes[i / SIZE_VALUE] = ((hexCh1 << BIT_NUM) | hexCh2);
85        i += SIZE_VALUE;
86    }
87    return bytes;
88}
89
90bool HRilBase::ConvertToString(char **dest, const std::string &srcStr)
91{
92    if (dest == nullptr) {
93        TELEPHONY_LOGE("ConvertToString dest is null");
94        return false;
95    }
96    size_t size = srcStr.size();
97    if (size == 0) {
98        *dest = nullptr;
99        return true;
100    }
101    size_t len = size + 1;
102    if (len <= 0) {
103        return false;
104    }
105
106    *dest = (char *)calloc(len, sizeof(char));
107    if (*dest == nullptr) {
108        TELEPHONY_LOGE("ConvertToString malloc fail");
109        return false;
110    }
111    if (strncpy_s(*dest, len, reinterpret_cast<const char *>(srcStr.c_str()), size) != EOK) {
112        return false;
113    }
114    return true;
115}
116
117void HRilBase::CopyToCharPoint(char **dest, const std::string &src)
118{
119    size_t size = src.size();
120    if (size <= 0) {
121        TELEPHONY_LOGD("CopyToCharPoint src is null");
122        return;
123    }
124    *dest = (char *)malloc((size + 1) * sizeof(char));
125    if (*dest == nullptr) {
126        TELEPHONY_LOGE("CopyToCharPoint malloc content fail!");
127        return;
128    }
129    if (memset_s(*dest, size + 1, 0, size + 1) != EOK) {
130        TELEPHONY_LOGE("CopyToCharPoint memset_s failed");
131        SafeFrees(*dest);
132        return;
133    }
134    if (strcpy_s(*dest, size + 1, src.c_str()) != EOK) {
135        TELEPHONY_LOGE("CopyToCharPoint strcpy_s error");
136        SafeFrees(*dest);
137    }
138}
139
140ReqDataInfo *HRilBase::CreateHRilRequest(int32_t serial, int32_t request)
141{
142    if (HRilManager::manager_ == nullptr) {
143        TELEPHONY_LOGE("manager_ is nullptr");
144        return nullptr;
145    }
146    return HRilManager::manager_->CreateHRilRequest(serial, slotId_, request);
147}
148
149HDI::Ril::V1_1::RilRadioResponseInfo HRilBase::BuildIHRilRadioResponseInfo(
150    const HDI::Ril::V1_1::RilRadioResponseInfo &responseInfo)
151{
152    HDI::Ril::V1_1::RilRadioResponseInfo iResponseInfo = { 0 };
153    iResponseInfo.slotId = GetSlotId();
154    iResponseInfo.flag = responseInfo.flag;
155    iResponseInfo.serial = responseInfo.serial;
156    iResponseInfo.error = (HDI::Ril::V1_1::RilErrType)responseInfo.error;
157    iResponseInfo.type = (HDI::Ril::V1_1::RilResponseTypes)responseInfo.type;
158    return iResponseInfo;
159}
160
161void HRilBase::SetRilCallback(const sptr<HDI::Ril::V1_3::IRilCallback> &callback)
162{
163    std::lock_guard<std::mutex> mutexLock(mutex_);
164    callback_ = callback;
165}
166
167std::string HRilBase::StringToHex(const char *data, int byteLength)
168{
169    std::stringstream ss;
170    for (int i = 0; i < byteLength; ++i) {
171        unsigned char temp = static_cast<unsigned char>(data[i]) >> HEX_OFFSET;
172        ss << HEX_TABLE[temp] << HEX_TABLE[static_cast<unsigned char>(data[i]) & 0xf];
173    }
174    return ss.str();
175}
176} // namespace Telephony
177} // namespace OHOS