Simplify encode/decode for PLDM bios commands

The encode/decode for PLDM bios commands was implemented
using extensive pointer arithmetic and memcpys. To reduce
the pointer usage and also for the simple assignments,
structures have been created for each of the PLDM bios commands.

Change-Id: I34aff3ee817c6c09a28556bd2fd8b60d07374ad2
Signed-off-by: Priyanga <priyram1@in.ibm.com>
diff --git a/libpldm/bios.c b/libpldm/bios.c
index 021c680..358fb38 100644
--- a/libpldm/bios.c
+++ b/libpldm/bios.c
@@ -30,33 +30,28 @@
 		return PLDM_ERROR_INVALID_DATA;
 	}
 
-	msg->payload[0] = completion_code;
 	header.msg_type = PLDM_RESPONSE;
 	header.instance = instance_id;
 	header.pldm_type = PLDM_BIOS;
 	header.command = PLDM_GET_DATE_TIME;
 
+	struct pldm_get_date_time_resp *response =
+	    (struct pldm_get_date_time_resp *)msg->payload;
+
 	if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
 		return rc;
 	}
 
-	if (msg->payload[0] == PLDM_SUCCESS) {
-		uint8_t *dst = msg->payload + sizeof(msg->payload[0]);
-
-		memcpy(dst, &seconds, sizeof(seconds));
-		dst += sizeof(seconds);
-		memcpy(dst, &minutes, sizeof(minutes));
-		dst += sizeof(minutes);
-		memcpy(dst, &hours, sizeof(hours));
-		dst += sizeof(hours);
-		memcpy(dst, &day, sizeof(day));
-		dst += sizeof(day);
-		memcpy(dst, &month, sizeof(month));
-		dst += sizeof(month);
-		uint16_t local_year = htole16(year);
-		memcpy(dst, &local_year, sizeof(local_year));
+	response->completion_code = completion_code;
+	if (response->completion_code == PLDM_SUCCESS) {
+		response->completion_code = completion_code;
+		response->seconds = seconds;
+		response->minutes = minutes;
+		response->hours = hours;
+		response->day = day;
+		response->month = month;
+		response->year = htole16(year);
 	}
-
 	return PLDM_SUCCESS;
 }
 
@@ -75,22 +70,19 @@
 		return PLDM_ERROR_INVALID_LENGTH;
 	}
 
-	*completion_code = msg[0];
+	struct pldm_get_date_time_resp *response =
+	    (struct pldm_get_date_time_resp *)msg;
+	*completion_code = response->completion_code;
+
 	if (PLDM_SUCCESS != *completion_code) {
 		return PLDM_SUCCESS;
 	}
-	*seconds = *(msg + sizeof(*completion_code));
-	*minutes = *(msg + sizeof(*completion_code) + sizeof(*seconds));
-	*hours = *(msg + sizeof(*completion_code) + sizeof(*seconds) +
-		   sizeof(*minutes));
-	*day = *(msg + sizeof(*completion_code) + sizeof(*seconds) +
-		 sizeof(*minutes) + sizeof(*hours));
-	*month = *(msg + sizeof(*completion_code) + sizeof(*seconds) +
-		   sizeof(*minutes) + sizeof(*hours) + sizeof(*day));
-	*year = le16toh(
-	    *((uint16_t *)(msg + sizeof(*completion_code) + sizeof(*seconds) +
-			   sizeof(*minutes) + sizeof(*hours) + sizeof(*day) +
-			   sizeof(*month))));
+	*seconds = response->seconds;
+	*minutes = response->minutes;
+	*hours = response->hours;
+	*day = response->day;
+	*month = response->month;
+	*year = le16toh(response->year);
 
 	return PLDM_SUCCESS;
 }
diff --git a/libpldm/bios.h b/libpldm/bios.h
index 4bc00ed..cd35651 100644
--- a/libpldm/bios.h
+++ b/libpldm/bios.h
@@ -16,6 +16,20 @@
 
 enum pldm_bios_commands { PLDM_GET_DATE_TIME = 0x0c };
 
+/** @struct pldm_get_date_time_resp
+ *
+ *  Structure representing PLDM get date time response
+ */
+struct pldm_get_date_time_resp {
+	uint8_t completion_code; //!< completion code
+	uint8_t seconds;	 //!< Seconds in BCD format
+	uint8_t minutes;	 //!< Minutes in BCD format
+	uint8_t hours;		 //!< Hours in BCD format
+	uint8_t day;		 //!< Day of the month in BCD format
+	uint8_t month;		 //!< Month in BCD format
+	uint16_t year;		 //!< Year in BCD format
+} __attribute__((packed));
+
 /* Requester */
 
 /* GetDateTime */