| /* |
| * 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 "common-tests.hpp" |
| #include "device-capability-discovery.h" |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| using ::testing::ElementsAre; |
| |
| TEST(PackNSMMessage, BadPathTest) |
| { |
| struct nsm_header_info hdr; |
| struct nsm_header_info *hdr_ptr = NULL; |
| |
| struct nsm_msg_hdr msg{}; |
| |
| // header information pointer is NULL |
| auto rc = pack_nsm_header(hdr_ptr, &msg); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| // message pointer is NULL |
| rc = pack_nsm_header(&hdr, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| // header information pointer and message pointer is NULL |
| rc = pack_nsm_header(hdr_ptr, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| // Instance ID out of range |
| hdr.nsm_msg_type = NSM_REQUEST; |
| hdr.instance_id = 32; |
| rc = pack_nsm_header(&hdr, &msg); |
| EXPECT_EQ(rc, NSM_SW_ERROR_DATA); |
| } |
| |
| TEST(UnpackNSMMessage, BadPathTest) |
| { |
| struct nsm_header_info hdr; |
| |
| // message pointer is NULL |
| auto rc = unpack_nsm_header(nullptr, &hdr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| struct nsm_msg_hdr msg{}; |
| |
| // hdr pointer is NULL |
| rc = unpack_nsm_header(&msg, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(ping, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| auto rc = encode_ping_req(0, request); |
| |
| struct nsm_common_req *req = |
| reinterpret_cast<struct nsm_common_req *>(request->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_PING, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(ping, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t instance_id = 0x12; |
| uint16_t reason_code = 0; |
| auto rc = encode_ping_resp(instance_id, reason_code, response); |
| |
| struct nsm_common_resp *resp = |
| reinterpret_cast<struct nsm_common_resp *>(response->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(instance_id, response->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| response->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_PING, resp->command); |
| EXPECT_EQ(0, le16toh(resp->data_size)); |
| } |
| |
| TEST(ping, 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_PING, // command |
| 0, // completion code |
| 0, |
| 0, |
| 0, |
| 0 // data size |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| auto rc = decode_ping_resp(response, msg_len, &cc, &reason_code); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| } |
| |
| TEST(getSupportedNvidiaMessageTypes, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| auto rc = encode_get_supported_nvidia_message_types_req(0, request); |
| |
| struct nsm_common_req *req = |
| reinterpret_cast<struct nsm_common_req *>(request->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_SUPPORTED_NVIDIA_MESSAGE_TYPES, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(getSupportedNvidiaMessageTypes, testGoodEncodeResponse) |
| { |
| |
| std::vector<uint8_t> responseMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_get_supported_nvidia_message_types_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t instance_id = 0x12; |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| std::vector<uint8_t> types{0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; |
| |
| auto rc = encode_get_supported_nvidia_message_types_resp( |
| instance_id, cc, reason_code, (bitfield8_t *)types.data(), |
| response); |
| |
| struct nsm_get_supported_nvidia_message_types_resp *resp = |
| reinterpret_cast< |
| struct nsm_get_supported_nvidia_message_types_resp *>( |
| response->payload); |
| |
| EXPECT_EQ(rc, NSM_SUCCESS); |
| |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(instance_id, response->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| response->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_SUPPORTED_NVIDIA_MESSAGE_TYPES, resp->hdr.command); |
| EXPECT_EQ(32, le16toh(resp->hdr.data_size)); |
| |
| uint8_t responseTypes[SUPPORTED_MSG_TYPE_DATA_SIZE]; |
| memcpy(responseTypes, resp->supported_nvidia_message_types, |
| SUPPORTED_MSG_TYPE_DATA_SIZE); |
| EXPECT_THAT(responseTypes, |
| ElementsAre(0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0)); |
| } |
| |
| TEST(getSupportedNvidiaMessageTypes, 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_SUPPORTED_NVIDIA_MESSAGE_TYPES, // command |
| 0, // completion code |
| 0, |
| 0, |
| 32, |
| 0, // data size |
| 0xf, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0 // types |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t responseTypes[SUPPORTED_MSG_TYPE_DATA_SIZE]; |
| |
| auto rc = decode_get_supported_nvidia_message_types_resp( |
| response, msg_len, &cc, &reason_code, (bitfield8_t *)responseTypes); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| EXPECT_THAT(responseTypes, |
| ElementsAre(0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0)); |
| } |
| |
| TEST(getSupportedNvidiaMessageTypes, testBadDecodeResponse) |
| { |
| 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_SUPPORTED_NVIDIA_MESSAGE_TYPES, // command |
| 0, // completion code |
| 0, |
| 0, |
| 32, |
| 0, // data size |
| 0xf, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0 // types |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t responseTypes[SUPPORTED_MSG_TYPE_DATA_SIZE]; |
| |
| auto rc = decode_get_supported_nvidia_message_types_resp( |
| nullptr, msg_len, &cc, &reason_code, (bitfield8_t *)responseTypes); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_get_supported_nvidia_message_types_resp( |
| response, msg_len, nullptr, &reason_code, |
| (bitfield8_t *)responseTypes); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_get_supported_nvidia_message_types_resp( |
| response, msg_len, &cc, nullptr, (bitfield8_t *)responseTypes); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_get_supported_nvidia_message_types_resp( |
| response, msg_len, &cc, &reason_code, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_get_supported_nvidia_message_types_resp( |
| response, msg_len - 4, &cc, &reason_code, |
| (bitfield8_t *)responseTypes); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(getSupportedCommandCodes, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_supported_command_codes_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t instance_id = 0x12; |
| uint8_t msg_type = NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY; |
| auto rc = encode_get_supported_command_codes_req(instance_id, msg_type, |
| request); |
| |
| struct nsm_get_supported_command_codes_req *req = |
| reinterpret_cast<struct nsm_get_supported_command_codes_req *>( |
| request->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(instance_id, request->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_SUPPORTED_COMMAND_CODES, req->hdr.command); |
| EXPECT_EQ(1, req->hdr.data_size); |
| EXPECT_EQ(msg_type, req->nvidia_message_type); |
| } |
| |
| TEST(getSupportedCommandCodes, testGoodEncodeResponse) |
| { |
| |
| std::vector<uint8_t> responseMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_supported_command_codes_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t instance_id = 0x12; |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| std::vector<uint8_t> command_codes{ |
| 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; |
| |
| auto rc = encode_get_supported_command_codes_resp( |
| instance_id, cc, reason_code, (bitfield8_t *)command_codes.data(), |
| response); |
| |
| struct nsm_get_supported_command_codes_resp *resp = |
| reinterpret_cast<struct nsm_get_supported_command_codes_resp *>( |
| response->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(instance_id, response->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| response->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_SUPPORTED_COMMAND_CODES, resp->hdr.command); |
| EXPECT_EQ(32, le16toh(resp->hdr.data_size)); |
| |
| uint8_t responseCodes[SUPPORTED_COMMAND_CODE_DATA_SIZE]; |
| memcpy(responseCodes, resp->supported_command_codes, |
| SUPPORTED_COMMAND_CODE_DATA_SIZE); |
| EXPECT_THAT(responseCodes, |
| ElementsAre(0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0)); |
| } |
| |
| TEST(getSupportedCommandCodes, 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_SUPPORTED_COMMAND_CODES, // command |
| 0, // completion code |
| 0, |
| 0, |
| 32, |
| 0, // data size |
| 0xf, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0, |
| 0x0 // codes |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t responseCodes[SUPPORTED_COMMAND_CODE_DATA_SIZE]; |
| |
| auto rc = decode_get_supported_command_codes_resp( |
| response, msg_len, &cc, &reason_code, (bitfield8_t *)responseCodes); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| EXPECT_THAT(responseCodes, |
| ElementsAre(0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
| 0x0, 0x0, 0x0, 0x0, 0x0)); |
| } |
| |
| TEST(queryDeviceIdentification, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_supported_command_codes_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t instance_id = 0x12; |
| auto rc = |
| encode_nsm_query_device_identification_req(instance_id, request); |
| |
| struct nsm_common_req *req = |
| reinterpret_cast<struct nsm_common_req *>(request->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(instance_id, request->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDENTIFICATION, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(queryDeviceIdentification, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_get_supported_command_codes_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t instance_id = 0x12; |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_identification = NSM_DEV_ID_GPU; |
| uint8_t device_instance = 1; |
| |
| auto rc = encode_query_device_identification_resp( |
| instance_id, cc, reason_code, device_identification, |
| device_instance, response); |
| |
| struct nsm_query_device_identification_resp *resp = |
| reinterpret_cast<struct nsm_query_device_identification_resp *>( |
| response->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(instance_id, response->hdr.instance_id); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| response->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDENTIFICATION, resp->hdr.command); |
| EXPECT_EQ(2, le16toh(resp->hdr.data_size)); |
| EXPECT_EQ(device_identification, resp->device_identification); |
| EXPECT_EQ(device_instance, resp->instance_id); |
| } |
| |
| TEST(queryDeviceIdentification, 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDENTIFICATION, // command |
| 0, // completion code |
| 0, |
| 0, |
| 2, |
| 0, // data size |
| NSM_DEV_ID_GPU, // device _identification |
| 1 // instance_id |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_identification = 0; |
| uint8_t device_instance = 0; |
| |
| auto rc = decode_query_device_identification_resp( |
| response, msg_len, &cc, &reason_code, &device_identification, |
| &device_instance); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| EXPECT_EQ(NSM_DEV_ID_GPU, device_identification); |
| EXPECT_EQ(1, device_instance); |
| } |
| |
| TEST(encodeReasonCode, testGoodEncodeReasonCode) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| |
| auto rc = encode_reason_code(cc, reasonCode, NSM_PING, response); |
| |
| struct nsm_common_non_success_resp *resp = |
| reinterpret_cast<struct nsm_common_non_success_resp *>( |
| response->payload); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(NSM_ERROR, resp->completion_code); |
| EXPECT_EQ(NSM_PING, resp->command); |
| EXPECT_EQ(ERR_NULL, le16toh(resp->reason_code)); |
| } |
| |
| TEST(encodeReasonCode, testBadEncodeReasonCode) |
| { |
| uint8_t cc = NSM_ERROR; |
| uint16_t reasonCode = ERR_NULL; |
| |
| auto rc = encode_reason_code(cc, reasonCode, NSM_PING, nullptr); |
| |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(decodeReasonCodeCC, testGoodDecodeReasonCode) |
| { |
| 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDENTIFICATION, // command |
| 0x01, // completion code != NSM_SUCCESS |
| 0x00, // reason code |
| 0x00}; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = |
| decode_reason_code_and_cc(response, msg_len, &cc, &reason_code); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_ERROR); |
| EXPECT_EQ(reason_code, 0x0000); |
| } |
| |
| TEST(decodeReasonCodeCC, testGoodDecodeCompletionCode) |
| { |
| 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDENTIFICATION, // command |
| 0x00, // completion code = NSM_SUCCESS |
| 0x00, // reason code |
| 0x02}; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = |
| decode_reason_code_and_cc(response, msg_len, &cc, &reason_code); |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| EXPECT_EQ(reason_code, ERR_NULL); |
| } |
| |
| TEST(decodeReasonCode, testBadDecodeReasonCode) |
| { |
| 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_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDENTIFICATION, // command |
| 0x01, // completion code |
| 0x00, // reason code |
| 0x00}; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = |
| decode_reason_code_and_cc(nullptr, msg_len, &cc, &reason_code); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = |
| decode_reason_code_and_cc(response, msg_len, nullptr, &reason_code); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_reason_code_and_cc(response, msg_len, &cc, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| rc = decode_reason_code_and_cc( |
| response, msg_len - 2, &cc, |
| &reason_code); // sending msg len less then expected |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(commonReq, testCommonRequest) |
| { |
| testEncodeCommonRequest( |
| [](uint8_t instanceId, struct nsm_msg *msg) { |
| return encode_common_req(instanceId, 0, 0, msg); |
| }, |
| 0, 0); |
| testDecodeCommonRequest(&decode_common_req, 0, 0); |
| } |
| |
| TEST(commonResp, testCommonResponse) |
| { |
| testEncodeCommonResponse( |
| [](uint8_t instanceId, uint8_t cc, uint16_t reasonCode, |
| nsm_msg *msg) { |
| return encode_common_resp(instanceId, cc, reasonCode, 0, 0, |
| msg); |
| }, |
| 0, 0); |
| testDecodeCommonResponse( |
| [](const nsm_msg *msg, size_t len, uint8_t *cc, |
| uint16_t *reasonCode) { |
| uint16_t size = 0; |
| auto rc = |
| decode_common_resp(msg, len, cc, &size, reasonCode); |
| EXPECT_EQ(0, size); |
| return rc; |
| }, |
| 0, 0); |
| } |
| |
| TEST(commonReq, testEncodeRawMsg) |
| { |
| auto encodePingRawCmdReq = [](uint8_t instanceId, nsm_msg *msg) { |
| return encode_raw_cmd_req(instanceId, |
| NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| NSM_PING, nullptr, 0, msg); |
| }; |
| testEncodeCommonRequest(encodePingRawCmdReq, |
| NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, NSM_PING); |
| |
| Request responseMsg(sizeof(nsm_msg_hdr) + sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, |
| encode_raw_cmd_req(0, NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| NSM_PING, nullptr, 1, msg)); |
| } |
| |
| TEST(LongRunning, testDecodeEventState) |
| { |
| const uint8_t instanceId = 0; |
| const uint8_t commandCode = 0x4d; |
| Response responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| (instanceId & 0x1f), // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| 0x08, // NSM_EVENT_VERSION=0, ACK=1, RES=0 |
| NSM_LONG_RUNNING_EVENT, // EVENT_ID |
| NSM_NVIDIA_GENERAL_EVENT_CLASS, // EVENT_CLASS |
| NSM_TYPE_PLATFORM_ENVIRONMENTAL, // EVENT_STATE >> 8 |
| commandCode, // EVENT_STATE & 0xFF |
| sizeof(struct nsm_long_running_resp), // data size |
| instanceId, // instance id |
| 0, // completion code |
| 0, // reserved |
| 0, // reserved |
| 0, // data |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| auto len = responseMsg.size(); |
| uint8_t dataSize; |
| uint16_t eventState; |
| EXPECT_EQ(NSM_SW_ERROR_NULL, |
| decode_nsm_event(response, len, NSM_LONG_RUNNING_EVENT, |
| NSM_NVIDIA_GENERAL_EVENT_CLASS, nullptr, |
| &dataSize)); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, |
| decode_nsm_event_with_data( |
| response, sizeof(nsm_msg_hdr) + NSM_EVENT_MIN_LEN, |
| NSM_LONG_RUNNING_EVENT, NSM_NVIDIA_GENERAL_EVENT_CLASS, |
| &eventState, &dataSize, nullptr)); |
| EXPECT_EQ(NSM_SW_SUCCESS, |
| decode_nsm_event(response, len, NSM_LONG_RUNNING_EVENT, |
| NSM_NVIDIA_GENERAL_EVENT_CLASS, &eventState, |
| &dataSize)); |
| nsm_long_running_event_state state; |
| memcpy(&state, &eventState, sizeof(uint16_t)); |
| EXPECT_EQ(0x4d, state.command); |
| EXPECT_EQ(NSM_TYPE_PLATFORM_ENVIRONMENTAL, state.nvidia_message_type); |
| } |
| |
| TEST(LongRunning, testBadEncodeSize) |
| { |
| Response responseMsg(sizeof(struct nsm_msg_hdr) + NSM_EVENT_MIN_LEN + |
| sizeof(struct nsm_long_running_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| auto rc = encode_long_running_resp(0, NSM_SUCCESS, ERR_NULL, |
| NSM_TYPE_PLATFORM_ENVIRONMENTAL, 0, |
| nullptr, 0xFC, response); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| auto event = reinterpret_cast<nsm_event *>(response->payload); |
| EXPECT_EQ(0, event->data_size); |
| } |
| |
| TEST(LongRunning, testGoodEncodeNullData) |
| { |
| Response responseMsg(sizeof(struct nsm_msg_hdr) + NSM_EVENT_MIN_LEN + |
| sizeof(struct nsm_long_running_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| auto rc = encode_long_running_resp(0, NSM_SUCCESS, ERR_NULL, |
| NSM_TYPE_PLATFORM_ENVIRONMENTAL, |
| 0xFC, nullptr, 0, response); |
| EXPECT_EQ(0, rc); |
| auto event = reinterpret_cast<nsm_event *>(response->payload); |
| EXPECT_EQ(NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, |
| response->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_EVENT_VERSION, event->version); |
| EXPECT_EQ(false, event->ackr); |
| EXPECT_EQ(0, event->resvd); |
| EXPECT_EQ(NSM_LONG_RUNNING_EVENT, event->event_id); |
| EXPECT_EQ(NSM_NVIDIA_GENERAL_EVENT_CLASS, event->event_class); |
| EXPECT_EQ(NSM_TYPE_PLATFORM_ENVIRONMENTAL, event->event_state & 0xFF); |
| EXPECT_EQ(0xFC, event->event_state >> 8); |
| EXPECT_EQ(sizeof(nsm_long_running_resp), event->data_size); |
| } |
| |
| TEST(LongRunning, testBadDecode) |
| { |
| const uint8_t instanceId = 0; |
| const uint8_t commandCode = 0x4d; |
| Response responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| (instanceId & 0x1f), // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DEVICE_CAPABILITY_DISCOVERY, // NVIDIA_MSG_TYPE |
| 0x08, // NSM_EVENT_VERSION=0, ACK=1, RES=0 |
| NSM_LONG_RUNNING_EVENT, // EVENT_ID |
| NSM_NVIDIA_GENERAL_EVENT_CLASS, // EVENT_CLASS |
| NSM_TYPE_PLATFORM_ENVIRONMENTAL, // EVENT_STATE >> 8 |
| commandCode, // EVENT_STATE & 0xFF |
| sizeof(struct nsm_long_running_resp), // data size |
| instanceId, // instance id |
| 0, // completion code |
| 0, // reserved |
| 0, // reserved |
| 0, // data |
| }; |
| uint8_t data; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| auto event = reinterpret_cast<nsm_event *>(response->payload); |
| auto longRunning = |
| reinterpret_cast<nsm_long_running_resp *>(event->data); |
| auto len = responseMsg.size(); |
| auto badLen = sizeof(struct nsm_msg_hdr) + NSM_EVENT_MIN_LEN + |
| sizeof(struct nsm_long_running_resp) - 1; |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reasonCode = ERR_NULL; |
| |
| auto rc = decode_long_running_resp_with_data( |
| response, badLen, NSM_TYPE_PLATFORM_ENVIRONMENTAL, commandCode, &cc, |
| &reasonCode, &data, sizeof(bitfield8_t)); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| |
| const auto offset = [response](uint8_t *data) { |
| return size_t(data) - size_t(response); |
| }; |
| |
| responseMsg[offset(&event->data_size)] = |
| sizeof(struct nsm_long_running_resp) - 1; |
| rc = decode_long_running_resp_with_data( |
| response, len, NSM_TYPE_PLATFORM_ENVIRONMENTAL, commandCode, &cc, |
| &reasonCode, &data, sizeof(bitfield8_t)); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| responseMsg[offset(&event->data_size)] = |
| sizeof(struct nsm_long_running_resp); |
| |
| responseMsg[offset(&event->data_size)] = |
| sizeof(struct nsm_long_running_resp) + 1; |
| rc = decode_long_running_resp_with_data( |
| response, badLen, NSM_TYPE_PLATFORM_ENVIRONMENTAL, commandCode, &cc, |
| &reasonCode, &data, sizeof(bitfield8_t)); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| |
| responseMsg[offset(&longRunning->completion_code)] = NSM_ERROR; |
| rc = decode_long_running_resp_with_data( |
| response, len, NSM_TYPE_PLATFORM_ENVIRONMENTAL, commandCode, &cc, |
| &reasonCode, &data, sizeof(bitfield8_t)); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| EXPECT_EQ(cc, NSM_ERROR); |
| responseMsg[offset(&longRunning->completion_code)] = NSM_SUCCESS; |
| } |