mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(bt/bluedroid): fixed issues from AI review in GAP, SPP, HID, L2CAP and HCI
This commit is contained in:
@@ -93,15 +93,15 @@ void btm_dev_init (void)
|
||||
btm_cb.devcb.rln_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RLN;
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 +
|
||||
BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5;
|
||||
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 | BTM_ACL_PKT_TYPES_MASK_DM1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DH3 | BTM_ACL_PKT_TYPES_MASK_DM3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DH5 | BTM_ACL_PKT_TYPES_MASK_DM5;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 +
|
||||
BTM_SCO_PKT_TYPES_MASK_HV2 +
|
||||
BTM_SCO_PKT_TYPES_MASK_HV3 +
|
||||
BTM_SCO_PKT_TYPES_MASK_EV3 +
|
||||
BTM_SCO_PKT_TYPES_MASK_EV4 +
|
||||
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 |
|
||||
BTM_SCO_PKT_TYPES_MASK_HV2 |
|
||||
BTM_SCO_PKT_TYPES_MASK_HV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV4 |
|
||||
BTM_SCO_PKT_TYPES_MASK_EV5;
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
}
|
||||
@@ -132,6 +132,17 @@ static void btm_db_reset (void)
|
||||
(*p_cb)((void *) NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_page_to_set_cmpl_cb;
|
||||
tBTM_SET_PAGE_TIMEOUT_RESULTS results = {0};
|
||||
|
||||
results.status = BTM_DEV_RESET;
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
|
||||
btu_free_timer(&btm_cb.devcb.page_timeout_set_timer);
|
||||
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
#endif // (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
if (btm_cb.devcb.p_rssi_cmpl_cb) {
|
||||
@@ -188,7 +199,7 @@ static void reset_complete(void)
|
||||
btm_pm_reset();
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic());
|
||||
l2c_link_process_num_bufs(controller->get_acl_buffer_count_classic());
|
||||
#if BTM_SCO_HCI_INCLUDED == TRUE
|
||||
btm_sco_process_num_bufs(controller->get_sco_buffer_count());
|
||||
#endif
|
||||
@@ -297,29 +308,29 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
case HCI_EXT_FEATURES_PAGE_0:
|
||||
|
||||
/* Create ACL supported packet types mask */
|
||||
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 +
|
||||
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM1);
|
||||
|
||||
if (HCI_3_SLOT_PACKETS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM3);
|
||||
}
|
||||
|
||||
if (HCI_5_SLOT_PACKETS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 |
|
||||
BTM_ACL_PKT_TYPES_MASK_DM5);
|
||||
}
|
||||
|
||||
/* Add in EDR related ACL types */
|
||||
if (!HCI_EDR_ACL_2MPS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
|
||||
}
|
||||
|
||||
if (!HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 +
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
|
||||
@@ -327,12 +338,12 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
if (HCI_EDR_ACL_2MPS_SUPPORTED(p_features) ||
|
||||
HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
|
||||
if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
|
||||
}
|
||||
|
||||
if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p_features)) {
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 +
|
||||
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 |
|
||||
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
|
||||
}
|
||||
}
|
||||
@@ -378,7 +389,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_2_EV5;
|
||||
}
|
||||
} else {
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 +
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5);
|
||||
}
|
||||
|
||||
@@ -387,7 +398,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
|
||||
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_3_EV5;
|
||||
}
|
||||
} else {
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 +
|
||||
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
|
||||
}
|
||||
}
|
||||
@@ -635,8 +646,6 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
|
||||
return (BTM_SUCCESS);
|
||||
}
|
||||
|
||||
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
|
||||
|
||||
if (!controller_get_interface()->get_is_ready()) {
|
||||
return (BTM_DEV_RESET);
|
||||
}
|
||||
@@ -645,6 +654,8 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
|
||||
|
||||
return (BTM_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -691,7 +702,7 @@ UINT8 *BTM_ReadLocalFeatures (void)
|
||||
** save the pointer to the function that is return and
|
||||
** call it when processing of the event is complete
|
||||
**
|
||||
** Returns status of the operation
|
||||
** Returns original device status callback
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif (tBTM_DEV_STATUS_CB *p_cb)
|
||||
@@ -725,6 +736,10 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len,
|
||||
BTM_TRACE_EVENT ("BTM: BTM_VendorSpecificCommand: Opcode: 0x%04X, ParamLen: %i.",
|
||||
opcode, param_len);
|
||||
|
||||
if ((param_len > 0) && (p_param_buf == NULL)) {
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
/* Allocate a buffer to hold HCI command plus the callback function */
|
||||
if ((p_buf = HCI_GET_CMD_BUF(param_len)) != NULL) {
|
||||
/* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */
|
||||
@@ -769,51 +784,68 @@ tBTM_STATUS BTM_ConfigCoexStatus(tBTM_COEX_OPERATION op, tBTM_COEX_TYPE type, UI
|
||||
void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
tBTM_CMPL_CB *p_vsc_cplt_cback)
|
||||
{
|
||||
UINT8 *p_orig = p;
|
||||
UINT16 remain_len = evt_len;
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
switch(opcode) {
|
||||
case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: {
|
||||
#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
|
||||
uint8_t subcode, status; uint32_t length;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
STREAM_TO_UINT8(subcode, p);
|
||||
STREAM_TO_UINT32(length, p);
|
||||
if (remain_len >= 6) {
|
||||
uint8_t subcode, status; uint32_t length;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
STREAM_TO_UINT8(subcode, p);
|
||||
STREAM_TO_UINT32(length, p);
|
||||
remain_len -= 6;
|
||||
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.exception_list_up.status = status;
|
||||
cb_params.exception_list_up.subcode = subcode;
|
||||
cb_params.exception_list_up.length = length;
|
||||
cb_params.exception_list_up.device_info = p;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.exception_list_up.status = status;
|
||||
cb_params.exception_list_up.subcode = subcode;
|
||||
cb_params.exception_list_up.length = length;
|
||||
cb_params.exception_list_up.device_info = p;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
|
||||
}
|
||||
#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_CLEAR_ADV: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_SET_CSA_SUPPORT: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_VENDOR_BLE_SET_EVT_MASK: {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
|
||||
if (remain_len >= 1) {
|
||||
uint8_t status;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
remain_len -= 1;
|
||||
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
|
||||
cb_params.status = status;
|
||||
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
UNUSED(remain_len);
|
||||
#endif // (BLE_INCLUDED == TRUE)
|
||||
tBTM_VSC_CMPL vcs_cplt_params;
|
||||
|
||||
@@ -822,7 +854,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
/* Pass parameters to the callback function */
|
||||
vcs_cplt_params.opcode = opcode; /* Number of bytes in return info */
|
||||
vcs_cplt_params.param_len = evt_len; /* Number of bytes in return info */
|
||||
vcs_cplt_params.p_param_buf = p;
|
||||
vcs_cplt_params.p_param_buf = p_orig;
|
||||
(*p_vsc_cplt_cback)(&vcs_cplt_params); /* Call the VSC complete callback function */
|
||||
}
|
||||
|
||||
@@ -897,16 +929,29 @@ void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len)
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
UINT8 sub_event;
|
||||
UINT8 remain_len = evt_len;
|
||||
UINT8 *p_evt = p;
|
||||
|
||||
if (remain_len < 1) {
|
||||
goto exit;
|
||||
}
|
||||
STREAM_TO_UINT8(sub_event, p_evt);
|
||||
remain_len -= 1;
|
||||
|
||||
/* Check in subevent if authentication is through Legacy Authentication. */
|
||||
if (sub_event == HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE) {
|
||||
if (remain_len < 2) {
|
||||
goto exit;
|
||||
}
|
||||
UINT16 hci_handle;
|
||||
STREAM_TO_UINT16(hci_handle, p_evt);
|
||||
remain_len -= 2;
|
||||
btm_sec_handle_remote_legacy_auth_cmp(hci_handle);
|
||||
}
|
||||
|
||||
exit:
|
||||
#endif /// (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) {
|
||||
if (btm_cb.devcb.p_vend_spec_cb[i]) {
|
||||
(*btm_cb.devcb.p_vend_spec_cb[i])(evt_len, p);
|
||||
@@ -932,16 +977,22 @@ tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout, tBTM_CMPL_CB *p_cb)
|
||||
{
|
||||
BTM_TRACE_EVENT ("BTM: BTM_WritePageTimeout: Timeout: %d.", timeout);
|
||||
|
||||
if (timeout >= HCI_MIN_PAGE_TOUT) {
|
||||
btm_cb.btm_inq_vars.page_timeout = timeout;
|
||||
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
|
||||
return BTM_BUSY;
|
||||
}
|
||||
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = p_cb;
|
||||
|
||||
/* Send the HCI command */
|
||||
if (!btsnd_hcic_write_page_tout (timeout)) {
|
||||
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
if (timeout >= HCI_MIN_PAGE_TOUT) {
|
||||
btm_cb.btm_inq_vars.page_timeout = timeout;
|
||||
}
|
||||
|
||||
if (p_cb) {
|
||||
btu_start_timer(&btm_cb.devcb.page_timeout_set_timer, BTU_TTYPE_BTM_SET_PAGE_TO, BTM_DEV_REPLY_TIMEOUT);
|
||||
}
|
||||
@@ -981,6 +1032,14 @@ tBTM_STATUS BTM_SetMinEncKeySize(UINT8 key_size, tBTM_CMPL_CB *p_cb)
|
||||
status = BTM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
if (status != BTM_SUCCESS) {
|
||||
if (p_cb) {
|
||||
btm_cb.devcb.p_set_min_enc_key_size_cmpl_cb = NULL;
|
||||
tBTM_SET_MIN_ENC_KEY_SIZE_RESULTS results = {0};
|
||||
results.hci_status = HCI_ERR_MEMORY_FULL;
|
||||
(*p_cb)(&results);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
@@ -1065,7 +1124,7 @@ tBTM_STATUS BTM_ReadPageTimeout(tBTM_CMPL_CB *p_cb)
|
||||
BTM_TRACE_EVENT ("BTM: BTM_ReadPageTimeout");
|
||||
|
||||
/* Get the page timeout */
|
||||
tBTM_GET_PAGE_TIMEOUT_RESULTS results;
|
||||
tBTM_GET_PAGE_TIMEOUT_RESULTS results = {0};
|
||||
|
||||
if (p_cb) {
|
||||
results.hci_status = HCI_SUCCESS;
|
||||
@@ -1142,6 +1201,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
|
||||
/* Send the HCI command */
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = p_cb;
|
||||
if (!btsnd_hcic_delete_stored_key (bd_addr, delete_all_flag)) {
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
} else {
|
||||
return (BTM_SUCCESS);
|
||||
@@ -1161,7 +1221,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
|
||||
void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb;
|
||||
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result;
|
||||
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result = {0};
|
||||
|
||||
/* If there was a callback registered for read stored link key, call it */
|
||||
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
|
||||
@@ -1232,6 +1292,7 @@ tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_chann
|
||||
btm_cb.devcb.p_afh_channels_cmpl_cb = p_afh_channels_cmpl_cback;
|
||||
|
||||
if (!btsnd_hcic_set_afh_channels (channels)) {
|
||||
btm_cb.devcb.p_afh_channels_cmpl_cb = NULL;
|
||||
return (BTM_NO_RESOURCES);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user