void KineticController_HandleResult(bus_msg_result_t *res, void *udata) { KineticOperation* op = udata; KINETIC_ASSERT(op); KINETIC_ASSERT(op->session); KineticStatus status = bus_to_kinetic_status(res->status); if (status == KINETIC_STATUS_SUCCESS) { KineticResponse * response = res->u.response.opaque_msg; status = KineticResponse_GetStatus(response); LOGF2("[PDU RX] pdu: %p, session: %p, bus: %p, " "fd: %6d, seq: %8lld, protoLen: %8u, valueLen: %8u, op: %p, status: %s", (void*)response, (void*)op->session, (void*)op->session->messageBus, op->session->socket, response->command->header->acksequence, KineticResponse_GetProtobufLength(response), KineticResponse_GetValueLength(response), (void*)op, Kinetic_GetStatusDescription(status)); KineticLogger_LogHeader(3, &response->header); KineticLogger_LogProtobuf(3, response->proto); if (op->response == NULL) { op->response = response; } } else { LOGF0("Error receiving response, got message bus error: %s", bus_error_string(res->status)); if (res->status == BUS_SEND_RX_TIMEOUT) { LOG0("RX_TIMEOUT"); } } // Call operation-specific callback, if configured if (op->opCallback != NULL) { status = op->opCallback(op, status); } KineticOperation_Complete(op, status); }
KineticStatus KineticPDU_ReceiveMain(KineticPDU* const response) { assert(response != NULL); assert(response->connection != NULL); const int fd = response->connection->socket; assert(fd >= 0); LOGF1("\nReceiving PDU via fd=%d", fd); KineticStatus status; KineticMessage* msg = &response->protoData.message; // Receive the PDU header ByteBuffer rawHeader = ByteBuffer_Create(&response->headerNBO, sizeof(KineticPDUHeader), 0); status = KineticSocket_Read(fd, &rawHeader, rawHeader.array.len); if (status != KINETIC_STATUS_SUCCESS) { LOG0("Failed to receive PDU header!"); return status; } else { LOG3("PDU header received successfully"); KineticPDUHeader* headerNBO = &response->headerNBO; response->header = (KineticPDUHeader) { .versionPrefix = headerNBO->versionPrefix, .protobufLength = KineticNBO_ToHostU32(headerNBO->protobufLength), .valueLength = KineticNBO_ToHostU32(headerNBO->valueLength), }; KineticLogger_LogHeader(1, &response->header); } // Receive the protobuf message status = KineticSocket_ReadProtobuf(fd, response); if (status != KINETIC_STATUS_SUCCESS) { LOG0("Failed to receive PDU protobuf message!"); return status; } else { LOG3("Received PDU protobuf"); KineticLogger_LogProtobuf(2, response->proto); } // Validate the HMAC for the recevied protobuf message if (response->proto->authType == KINETIC_PROTO_MESSAGE_AUTH_TYPE_HMACAUTH) { if(!KineticHMAC_Validate( response->proto, response->connection->session.hmacKey)) { LOG0("Received PDU protobuf message has invalid HMAC!"); msg->has_command = true; msg->command.status = &msg->status; msg->status.code = KINETIC_PROTO_COMMAND_STATUS_STATUS_CODE_DATA_ERROR; return KINETIC_STATUS_DATA_ERROR; } else { LOG3("Received protobuf HMAC validation succeeded"); } } else if (response->proto->authType == KINETIC_PROTO_MESSAGE_AUTH_TYPE_PINAUTH) { LOG0("PIN-based authentication not yet supported!"); return KINETIC_STATUS_DATA_ERROR; } else if (response->proto->authType == KINETIC_PROTO_MESSAGE_AUTH_TYPE_UNSOLICITEDSTATUS) { LOG3("Unsolicited status message is not authenticated"); } // Extract embedded command, if supplied KineticProto_Message* pMsg = response->proto; if (pMsg->has_commandBytes && pMsg->commandBytes.data != NULL && pMsg->commandBytes.len > 0) { response->command = KineticProto_command__unpack( NULL, pMsg->commandBytes.len, pMsg->commandBytes.data); } status = KineticPDU_GetStatus(response); if (status == KINETIC_STATUS_SUCCESS) { LOG2("PDU received successfully!"); } return status; } KineticStatus KineticPDU_ReceiveValue(int socket_desc, ByteBuffer* value, size_t value_length) { assert(socket_desc >= 0); assert(value != NULL); assert(value->array.data != NULL); // Receive value payload LOGF1("Receiving value payload (%lld bytes)...", value_length); ByteBuffer_Reset(value); KineticStatus status = KineticSocket_Read(socket_desc, value, value_length); if (status != KINETIC_STATUS_SUCCESS) { LOG0("Failed to receive PDU value payload!"); return status; } LOG1("Received value payload successfully"); KineticLogger_LogByteBuffer(3, "Value Buffer", *value); return status; }