1 /******************************************************************************* 2 * Copyright (C) 2004-2008 Intel Corp. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * - Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * - Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * - Neither the name of Intel Corp. nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 *******************************************************************************/ 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 #include <cstdio> 35 #include <cstdlib> 36 37 #ifdef __sun 38 #include <stdio.h> 39 #include <stdlib.h> 40 #endif // __sun 41 42 #include "FWULCommand.h" 43 44 FWULCommand::FWULCommand(bool verbose) : 45 FWULClient(FW_UPDATE_GUID, verbose) 46 { 47 _verbose = verbose; 48 } 49 50 FWULCommand::~FWULCommand(void) 51 { 52 } 53 54 HECI_STATUS FWULCommand::_call(const unsigned char *command, UINT32 command_size, UINT8 **readBuffer, UINT32 *outBuffSize) 55 { 56 UINT32 inBuffSize; 57 *outBuffSize = 0; 58 59 inBuffSize = FWULClient.GetBufferSize(); 60 if (NULL == *readBuffer) 61 { 62 *readBuffer = (UINT8 *)malloc(sizeof(UINT8) * inBuffSize); 63 if (NULL == *readBuffer) 64 { 65 if (_verbose) 66 { 67 fprintf(stderr, "Error: Malloc failed\n"); 68 } 69 return HECI_STATUS_MEMORY_ALLOCATION_ERROR; 70 } 71 } 72 memset(*readBuffer, 0, inBuffSize); 73 74 int bytesWritten = FWULClient.SendMessage(command, command_size); 75 if ((UINT32)bytesWritten != command_size) 76 { 77 if (_verbose) 78 { 79 fprintf(stderr, "Error: Could not send data to FWUpdate client through MEI\n"); 80 } 81 return HECI_STATUS_MSG_TRANSMISSION_ERROR; 82 } 83 *outBuffSize = FWULClient.ReceiveMessage(*readBuffer, inBuffSize, 15000); 84 if (0 == *outBuffSize) 85 { 86 if (_verbose) 87 { 88 fprintf(stderr, "Error: Could not read data from FWUpdate client through MEI\n"); 89 } 90 return HECI_STATUS_UNEXPECTED_RESPONSE; 91 } 92 if (_verbose) 93 { 94 fprintf(stdout, "Data received from FWUpdate Client. %d bytes read\n", *outBuffSize); 95 } 96 return HECI_STATUS_OK; 97 } 98 99 100 /* 101 * Get ME data information from FW update client using AMTCommunication class 102 */ 103 HECI_STATUS 104 FWULCommand::GetFWUVersionAndInfo(FWU_GET_VERSION_MSG_REPLY &verMsg, FWU_GET_INFO_MSG_REPLY &infoMsg) 105 { 106 UINT8 *readBuffer = NULL; 107 UINT32 command_size = sizeof(ME_GET_FW_UPDATE_INFO_REQUEST); 108 UINT32 replySize = 0; 109 ME_GET_FW_UPDATE_INFO_REQUEST msg; 110 HECI_STATUS status; 111 112 msg.MessageID = FWU_GET_VERSION; 113 status = _call((const unsigned char *)&msg, command_size, 114 &readBuffer, &replySize); 115 if (status != HECI_STATUS_OK) 116 { 117 goto fwuvend; 118 } 119 if (replySize == sizeof(FWU_GET_VERSION_MSG_REPLY)) 120 { 121 if (((FWU_MSG_REPLY_HEADER *)readBuffer)->MessageType != FWU_GET_VERSION_REPLY) 122 { 123 if (_verbose) 124 { 125 fprintf(stderr, "Error: MessageType in MEI response is not as expected\n"); 126 } 127 status = HECI_STATUS_UNEXPECTED_RESPONSE; 128 goto fwuvend; 129 } 130 if (((FWU_MSG_REPLY_HEADER *)readBuffer)->Status != PT_STATUS_SUCCESS) 131 { 132 if (_verbose) 133 { 134 fprintf(stderr, "Error: Status in MEI response is not as expected\n"); 135 } 136 status = HECI_STATUS_UNEXPECTED_RESPONSE; 137 goto fwuvend; 138 } 139 140 memcpy(&verMsg, readBuffer, sizeof(FWU_GET_VERSION_MSG_REPLY)); 141 142 msg.MessageID = FWU_GET_INFO; 143 status = _call((const unsigned char *)&msg, command_size, 144 &readBuffer, &replySize); 145 if (status != HECI_STATUS_OK) 146 { 147 goto fwuvend; 148 } 149 if (replySize != sizeof(FWU_GET_INFO_MSG_REPLY)) 150 { 151 if (_verbose) 152 { 153 fprintf(stderr, "Error: MEI response size is not as expected\n"); 154 } 155 status = HECI_STATUS_UNEXPECTED_RESPONSE; 156 goto fwuvend; 157 } 158 if (((FWU_MSG_REPLY_HEADER *)readBuffer)->MessageType != FWU_GET_INFO_REPLY) 159 { 160 if (_verbose) 161 { 162 fprintf(stderr, "Error: MessageType in MEI response is not as expected\n"); 163 } 164 status = HECI_STATUS_UNEXPECTED_RESPONSE; 165 goto fwuvend; 166 } 167 if (((FWU_MSG_REPLY_HEADER *)readBuffer)->Status != PT_STATUS_SUCCESS) 168 { 169 if (_verbose) 170 { 171 fprintf(stderr, "Error: Status in MEI response is not as expected\n"); 172 } 173 status = HECI_STATUS_UNEXPECTED_RESPONSE; 174 goto fwuvend; 175 } 176 177 memcpy(&infoMsg, readBuffer, sizeof(FWU_GET_INFO_MSG_REPLY)); 178 179 } 180 else if (replySize == sizeof(FWU_GET_VERSION_MSG_REPLY_V3)) 181 { 182 if (((FWU_MSG_REPLY_HEADER_V3 *)readBuffer)->MessageType != FWU_GET_VERSION_REPLY) 183 { 184 if (_verbose) 185 { 186 fprintf(stderr, "Error: MessageType in MEI response is not as expected\n"); 187 } 188 status = HECI_STATUS_UNEXPECTED_RESPONSE; 189 goto fwuvend; 190 } 191 if (((FWU_MSG_REPLY_HEADER_V3 *)readBuffer)->Status != PT_STATUS_SUCCESS) 192 { 193 if (_verbose) 194 { 195 fprintf(stderr, "Error: Status in MEI response is not as expected\n"); 196 } 197 status = HECI_STATUS_UNEXPECTED_RESPONSE; 198 goto fwuvend; 199 } 200 201 FWU_GET_VERSION_MSG_REPLY_V3 *rep = (FWU_GET_VERSION_MSG_REPLY_V3 *)readBuffer; 202 verMsg.MessageType = FWU_GET_VERSION_REPLY; 203 verMsg.Status = rep->Status; 204 verMsg.Sku = rep->Sku; 205 verMsg.ICHVer = rep->ICHVer; 206 verMsg.MCHVer = rep->MCHVer; 207 verMsg.Vendor = rep->Vendor; 208 verMsg.LastFwUpdateStatus = rep->LastFwUpdateStatus; 209 verMsg.HwSku = rep->Sku; 210 memcpy(&verMsg.CodeVersion, &(rep->CodeVersion), sizeof(verMsg.CodeVersion)); 211 memset(&verMsg.AMTVersion, 0, sizeof(verMsg.AMTVersion)); 212 verMsg.EnabledUpdateInterfaces = rep->EnabledUpdateInterfaces; 213 verMsg.Reserved = 0; 214 215 memset(&infoMsg, 0, sizeof(infoMsg)); 216 } else { 217 if (_verbose) 218 { 219 fprintf(stderr, "Error: MEI response size is not as expected\n"); 220 } 221 status = HECI_STATUS_UNEXPECTED_RESPONSE; 222 goto fwuvend; 223 } 224 225 fwuvend: 226 227 if (readBuffer != NULL) 228 { 229 free(readBuffer); 230 } 231 232 return status; 233 } 234