| /* |
| * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & |
| * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "base.h" |
| #include "debug-token.h" |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| TEST(provideToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE]; |
| for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) { |
| token[i] = i; |
| } |
| |
| auto rc = encode_nsm_provide_token_req( |
| 0, token, NSM_DEBUG_TOKEN_DATA_MAX_SIZE, request); |
| |
| nsm_provide_token_req *req = (nsm_provide_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_PROVIDE_TOKEN, req->hdr.command); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_DATA_MAX_SIZE, req->hdr.data_size); |
| EXPECT_EQ( |
| 0, memcmp(token, req->token_data, NSM_DEBUG_TOKEN_DATA_MAX_SIZE)); |
| } |
| |
| TEST(provideToken, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE]; |
| for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) { |
| token[i] = i; |
| } |
| |
| auto rc = encode_nsm_provide_token_req(0, token, 0, request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(provideToken, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x8A, // OCP_TYPE=8, OCP_VER=10 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_PROVIDE_TOKEN, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 0, |
| 0, // data size |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| auto rc = |
| decode_nsm_provide_token_resp(response, msg_len, &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| } |
| |
| TEST(disableTokens, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_disable_tokens_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| auto rc = encode_nsm_disable_tokens_req(0, request); |
| |
| nsm_disable_tokens_req *req = |
| (nsm_disable_tokens_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_DISABLE_TOKENS, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(disableTokens, testBadEncodeRequest) |
| { |
| auto rc = encode_nsm_disable_tokens_req(0, nullptr); |
| |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(disableTokens, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_DISABLE_TOKENS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 0, |
| 0, // data size |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| auto rc = decode_nsm_disable_tokens_resp(response, msg_len, &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| } |
| |
| TEST(queryTokenStatus, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_FRC; |
| |
| auto rc = encode_nsm_query_token_status_req(0, token_type, request); |
| |
| nsm_query_token_status_req *req = |
| (nsm_query_token_status_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, req->hdr.command); |
| EXPECT_EQ(1, req->hdr.data_size); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_FRC, req->token_type); |
| } |
| |
| TEST(queryTokenStatus, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token_type = 0xFF; |
| |
| auto rc = encode_nsm_query_token_status_req( |
| 0, static_cast<nsm_debug_token_type>(token_type), request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(queryTokenStatus, testGoodDecodeResponse) |
| { |
| uint16_t data_size = |
| sizeof(nsm_query_token_status_resp) - sizeof(nsm_common_resp); |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_TOKEN_STATUS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| (uint8_t)(data_size & 0x00FF), // data size |
| (uint8_t)((data_size & 0xFF00) >> 8), // data size |
| NSM_DEBUG_TOKEN_TYPE_CRCS, // token type |
| 0, // reserved |
| NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, // additional info |
| NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED, // status |
| 0x12, // time left |
| 0x34, // time left |
| 0x56, // time left |
| 0x78 // time left |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| nsm_debug_token_status status; |
| nsm_debug_token_status_additional_info additional_info; |
| nsm_debug_token_type token_type; |
| uint32_t time_left; |
| |
| auto rc = decode_nsm_query_token_status_resp( |
| response, msg_len, &cc, &reason_code, &status, &additional_info, |
| &token_type, &time_left); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED, status); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, additional_info); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_CRCS, token_type); |
| EXPECT_EQ(0x78563412, time_left); |
| } |
| |
| TEST(queryTokenParameters, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| nsm_debug_token_opcode token_opcode = NSM_DEBUG_TOKEN_OPCODE_CRCS; |
| |
| auto rc = |
| encode_nsm_query_token_parameters_req(0, token_opcode, request); |
| |
| nsm_query_token_parameters_req *req = |
| (nsm_query_token_parameters_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, req->hdr.command); |
| EXPECT_EQ(1, req->hdr.data_size); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRCS, req->token_opcode); |
| } |
| |
| TEST(queryTokenParameters, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token_opcode = 0xFF; |
| |
| auto rc = encode_nsm_query_token_parameters_req( |
| 0, static_cast<nsm_debug_token_opcode>(token_opcode), request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(queryTokenParameters, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, 0xde, 0x00, 0x89, 0x04, 0x54, 0x00, 0x00, 0x00, 0x8c, 0x00, |
| 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x03, |
| 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x59, 0xbf, 0x4a, 0x04, |
| 0x3d, 0xdd, 0x11, 0xef, 0xb9, 0x4f, 0xac, 0x1f, 0x6b, 0x01, 0xe5, |
| 0xae, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x4e, 0x56, |
| 0x44, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x07, 0xde, 0x04, 0x48, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xfe, |
| 0x66, 0xd4, 0xb4, 0x5c, 0x4e, 0xae, 0xdc, 0x42, 0xdc, 0x25, 0xc7, |
| 0xc6, 0x8c, 0xcf, 0x7c, 0x1d, 0x85, 0x7d, 0x6f, 0x63, 0x66, 0x7b, |
| 0xaa, 0xdf, 0xb3, 0xcb, 0x4b, 0x37, 0x8d, 0x38}; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| nsm_debug_token_request token_request; |
| memset(&token_request, 0, sizeof(nsm_debug_token_request)); |
| |
| auto rc = decode_nsm_query_token_parameters_resp( |
| response, msg_len, &cc, &reason_code, &token_request); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(sizeof(nsm_debug_token_request), |
| token_request.token_request_size); |
| EXPECT_EQ(0, token_request.token_request_version); |
| EXPECT_EQ(0x1C, token_request.device_uuid[0]); |
| EXPECT_EQ(0x76, token_request.device_uuid[1]); |
| EXPECT_EQ(0xC0, token_request.device_uuid[2]); |
| EXPECT_EQ(0xC4, token_request.device_uuid[3]); |
| EXPECT_EQ(0xFC, token_request.device_uuid[4]); |
| EXPECT_EQ(0xAF, token_request.device_uuid[5]); |
| EXPECT_EQ(0x17, token_request.device_uuid[6]); |
| EXPECT_EQ(0x24, token_request.device_uuid[7]); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_DEVICE_TYPE_ID_NVSWITCH, |
| token_request.device_type); |
| EXPECT_EQ(0, token_request.device_index); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_CHALLENGE_QUERY_STATUS_OK, |
| token_request.status); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRDT, token_request.token_opcode); |
| EXPECT_EQ(0x23, token_request.fw_version[0]); |
| EXPECT_EQ(0x07, token_request.fw_version[1]); |
| EXPECT_EQ(0xDE, token_request.fw_version[2]); |
| EXPECT_EQ(0x04, token_request.fw_version[3]); |
| EXPECT_EQ(0x48, token_request.fw_version[4]); |
| EXPECT_EQ(0, token_request.session_id); |
| EXPECT_EQ(0, token_request.challenge_version); |
| } |
| |
| TEST(queryDeviceIDs, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| auto rc = encode_nsm_query_device_ids_req(0, request); |
| |
| nsm_query_device_ids_req *req = |
| (nsm_query_device_ids_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDS, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(queryDeviceIDs, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code, |
| device_id, 8, response); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| |
| nsm_query_device_ids_resp *resp = |
| (nsm_query_device_ids_resp *)response->payload; |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDS, resp->hdr.command); |
| EXPECT_EQ(cc, resp->hdr.completion_code); |
| EXPECT_EQ(8, le16toh(resp->hdr.data_size)); |
| EXPECT_EQ(0, memcmp(device_id, resp->data, 8)); |
| } |
| |
| TEST(queryDeviceIDs, testBadEncodeResponse) |
| { |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| // null message |
| auto rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, |
| device_id, 8, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null device_id |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, nullptr, |
| 8, response); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // zero device_id_len |
| rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, |
| device_id, 0, response); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(queryDeviceIDs, testEncodeResponseWithError) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = NSM_ERR_INVALID_DATA; |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code, |
| device_id, 8, response); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| } |
| |
| TEST(queryDeviceIDs, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 8, // data size (little endian) |
| 0, // data size |
| 0x01, // ID |
| 0x02, // ID |
| 0x03, // ID |
| 0x04, // ID |
| 0x05, // ID |
| 0x06, // ID |
| 0x07, // ID |
| 0x08, // ID |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8]; |
| size_t device_id_len = 0; |
| |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, device_id, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(8, device_id_len); |
| EXPECT_EQ(0x01, device_id[0]); |
| EXPECT_EQ(0x02, device_id[1]); |
| EXPECT_EQ(0x03, device_id[2]); |
| EXPECT_EQ(0x04, device_id[3]); |
| EXPECT_EQ(0x05, device_id[4]); |
| EXPECT_EQ(0x06, device_id[5]); |
| EXPECT_EQ(0x07, device_id[6]); |
| EXPECT_EQ(0x08, device_id[7]); |
| } |
| |
| TEST(queryDeviceIDs, testDecodeResponseWithNullDeviceId) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 8, // data size (little endian) |
| 0, // data size |
| 0x01, // ID |
| 0x02, // ID |
| 0x03, // ID |
| 0x04, // ID |
| 0x05, // ID |
| 0x06, // ID |
| 0x07, // ID |
| 0x08, // ID |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| size_t device_id_len = 0; |
| |
| // Test with null device_id pointer (should still work) |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, nullptr, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(8, device_id_len); |
| } |
| |
| TEST(queryDeviceIDs, testBadDecodeResponse) |
| { |
| uint8_t cc; |
| uint16_t reason_code; |
| uint8_t device_id[8]; |
| size_t device_id_len; |
| |
| // null message |
| auto rc = decode_nsm_query_device_ids_resp( |
| nullptr, 100, &cc, &reason_code, device_id, &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), |
| nullptr, &reason_code, device_id, |
| &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc, |
| nullptr, device_id, |
| &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc, |
| &reason_code, device_id, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_query_device_ids_resp(response, 10, &cc, &reason_code, |
| device_id, &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(queryDeviceIDs, testDecodeResponseWithError) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_ERROR, // completion code |
| ERR_TIMEOUT, // reason code |
| 0, |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8]; |
| size_t device_id_len = 0; |
| |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, device_id, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERROR, cc); |
| EXPECT_EQ(ERR_TIMEOUT, reason_code); |
| } |
| |
| TEST(installToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t chunk_offset = 0x12345678; |
| uint32_t chunk_length = 64; |
| uint32_t length_remaining = 1024; |
| uint8_t data[64]; |
| for (uint32_t i = 0; i < chunk_length; ++i) { |
| data[i] = i & 0xFF; |
| } |
| |
| auto rc = encode_nsm_install_token_req(0, chunk_offset, chunk_length, |
| length_remaining, data, request); |
| nsm_install_token_req *req = (nsm_install_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_INSTALL_TOKEN, req->hdr.command); |
| EXPECT_EQ(sizeof(chunk_offset) + sizeof(chunk_length) + |
| sizeof(length_remaining) + chunk_length, |
| le16toh(req->hdr.data_size)); |
| EXPECT_EQ(chunk_offset, le32toh(req->chunk_offset)); |
| EXPECT_EQ(chunk_length, le32toh(req->chunk_length)); |
| EXPECT_EQ(length_remaining, le32toh(req->length_remaining)); |
| EXPECT_EQ(0, memcmp(data, req->data, chunk_length)); |
| } |
| |
| TEST(installToken, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t data[64]; |
| |
| // null message |
| auto rc = encode_nsm_install_token_req(0, 0, 64, 1024, data, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null data |
| rc = encode_nsm_install_token_req(0, 0, 64, 1024, nullptr, request); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(installToken, testGoodDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t expected_chunk_offset = 0x12345678; |
| uint32_t expected_chunk_length = 64; |
| uint32_t expected_length_remaining = 1024; |
| uint8_t expected_data[64]; |
| for (uint32_t i = 0; i < expected_chunk_length; ++i) { |
| expected_data[i] = i & 0xFF; |
| } |
| auto rc = encode_nsm_install_token_req( |
| 0, expected_chunk_offset, expected_chunk_length, |
| expected_length_remaining, expected_data, request); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| uint32_t chunk_offset; |
| uint32_t chunk_length; |
| uint32_t length_remaining; |
| uint8_t data[64]; |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, &chunk_length, |
| &length_remaining, data); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(expected_chunk_offset, chunk_offset); |
| EXPECT_EQ(expected_chunk_length, chunk_length); |
| EXPECT_EQ(expected_length_remaining, length_remaining); |
| EXPECT_EQ(0, memcmp(expected_data, data, expected_chunk_length)); |
| } |
| |
| TEST(installToken, testBadDecodeRequest) |
| { |
| uint32_t chunk_offset; |
| uint32_t chunk_length; |
| uint32_t length_remaining; |
| uint8_t data[64]; |
| |
| // null message |
| auto rc = decode_nsm_install_token_req(nullptr, 100, &chunk_offset, |
| &chunk_length, &length_remaining, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), nullptr, |
| &chunk_length, &length_remaining, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, nullptr, |
| &length_remaining, data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, &chunk_length, nullptr, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_install_token_req( |
| request, 10, &chunk_offset, &chunk_length, &length_remaining, data); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(eraseToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t token_type = 0x12345678; |
| auto rc = encode_nsm_erase_token_req(0, token_type, request); |
| nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_ERASE_TOKEN, req->hdr.command); |
| EXPECT_EQ(sizeof(token_type), req->hdr.data_size); |
| EXPECT_EQ(token_type, le32toh(req->token_type)); |
| } |
| |
| TEST(eraseToken, testBadEncodeRequest) |
| { |
| auto rc = encode_nsm_erase_token_req(0, 0x12345678, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(eraseToken, testGoodDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t expected_token_type = 0x87654321; |
| auto rc = encode_nsm_erase_token_req(0, expected_token_type, request); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| uint32_t token_type; |
| rc = |
| decode_nsm_erase_token_req(request, requestMsg.size(), &token_type); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(expected_token_type, token_type); |
| } |
| |
| TEST(eraseToken, testBadDecodeRequest) |
| { |
| uint32_t token_type; |
| |
| // null message |
| auto rc = decode_nsm_erase_token_req(nullptr, 100, &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameter |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| rc = decode_nsm_erase_token_req(request, requestMsg.size(), nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_erase_token_req(request, 10, &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| |
| // invalid data size |
| nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload; |
| req->hdr.data_size = 10; // Invalid size |
| rc = |
| decode_nsm_erase_token_req(request, requestMsg.size(), &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryToken, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_resp) + 100); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len = 32; |
| for (size_t i = 0; i < tlv_payload_len; ++i) { |
| tlv_payload[i] = i & 0xFF; |
| } |
| |
| auto rc = encode_nsm_query_token_resp(0, cc, reason_code, tlv_payload, |
| tlv_payload_len, response); |
| nsm_query_token_resp *resp = (nsm_query_token_resp *)response->payload; |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_QUERY_TOKEN, resp->hdr.command); |
| EXPECT_EQ(cc, resp->hdr.completion_code); |
| EXPECT_EQ(tlv_payload_len, le16toh(resp->hdr.data_size)); |
| EXPECT_EQ(0, memcmp(tlv_payload, resp->tlv_payload, tlv_payload_len)); |
| } |
| |
| TEST(queryToken, testBadEncodeResponse) |
| { |
| uint8_t tlv_payload[64] = {0}; |
| |
| auto rc = encode_nsm_query_token_resp(0, NSM_SUCCESS, ERR_NULL, |
| tlv_payload, 32, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(queryToken, testGoodDecodeResponse) |
| { |
| uint16_t data_size = 32; |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_TOKEN, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| (uint8_t)(data_size & 0x00FF), // data size |
| (uint8_t)((data_size & 0xFF00) >> 8) // data size |
| }; |
| for (uint16_t i = 0; i < data_size; ++i) { |
| responseMsg.push_back(i & 0xFF); |
| } |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len = sizeof(tlv_payload); |
| auto rc = |
| decode_nsm_query_token_resp(response, msg_len, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(data_size, tlv_payload_len); |
| for (uint16_t i = 0; i < data_size; ++i) { |
| EXPECT_EQ(i & 0xFF, tlv_payload[i]); |
| } |
| } |
| |
| TEST(queryToken, testBadDecodeResponse) |
| { |
| uint8_t cc; |
| uint16_t reason_code; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len; |
| |
| // null message |
| auto rc = decode_nsm_query_token_resp(nullptr, 100, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| rc = decode_nsm_query_token_resp(response, responseMsg.size(), nullptr, |
| &reason_code, tlv_payload, |
| &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = |
| decode_nsm_query_token_resp(response, responseMsg.size(), &cc, |
| nullptr, tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_token_resp(response, responseMsg.size(), &cc, |
| &reason_code, tlv_payload, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_query_token_resp(response, 10, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |