Example #1
0
/** @brief Send RAW response frame.
 *  @param opcode uint8_t, Operation code.
 *  @param frame uint8_t*, Command for this operation code.
 *  @param length const uint8_t, Length of the payload.
 *  @return Void.
 */
void send_raw_response(uint8_t opcode, uint8_t status, uint8_t * payload, const uint8_t length) {

	const int FrameLengthL = length + FRAME_STATIC_FIELD_LENGTH + FRAME_RESPONSE_PAYLOAD_OFFSET;

	uint8_t FrameL[(const int)FrameLengthL];

	FrameL[FrameIndexes::Begin] = FRAME_SENTINEL;
	FrameL[FrameIndexes::FrmType] = FrameType::Response;
	FrameL[FrameIndexes::Length] = length + FRAME_RESPONSE_PAYLOAD_OFFSET;
	FrameL[FrameIndexes::OperationCode] = opcode;
	FrameL[FrameIndexes::StatusCode] = status;
	for (uint8_t index = 0; index < length; index++)
	{
		FrameL[index + FRAME_STATIC_FIELD_OFFSET + 1] = payload[index];
	}

	uint8_t CRCL[FRAME_CRC_LEN] = { 0, 0 };
	calculate_CRC(FrameL, (uint8_t)(FrameLengthL - FRAME_CRC_LEN), CRCL);

	for (uint8_t index = 0; index < FRAME_CRC_LEN; index++)
	{
		uint8_t FrmaeIndexL = index + FRAME_STATIC_FIELD_OFFSET + length + 1;
		FrameL[FrmaeIndexL] = CRCL[index];
	}

	COM_PORT.write(FrameL, FrameLengthL);
}
Example #2
0
void add_crc(char *message)
{
  int  length;

  length = strlen(message);
  message[length] = calculate_CRC(message, length);
  message[length + 1] = '\0';
}
Example #3
0
/** @brief Validate the CRC.
*  @param frame The frame string.
*  @return True if successful; or False if failed.
*/
bool validate_CRC(uint8_t * frame, uint8_t length)
{
	uint8_t PayloadLen = length - FRAME_CRC_LEN;
	uint8_t CRCL[FRAME_CRC_LEN] = { 0, 0 };

	calculate_CRC(frame, PayloadLen, CRCL);

	// Check odd byte and even bytes.
	return (frame[PayloadLen] == CRCL[0]) && (frame[PayloadLen + 1] == CRCL[1]);
}
Example #4
0
void send_command(t_serial_request *prq, t_shared_data *pshared)
{
  char             byte;
  char             message[MAX_MSG_SIZE];
  int              sz, ctn;
  //
  enum eserial_state
    {
      ser_nothing,
      ser_waiting_response
    };
  eserial_state ser_state;

  ser_state = ser_nothing;
  switch (prq->type)
    {
    case enothing:
      break;
    case eping:
      {
	while (pshared->pserial->read_next_byte(&byte)); // Empty the buffer
	snprintf(message, MAX_MSG_SIZE, "ping\n");
	add_crc(message);
	pshared->pserial->write_serial_port(message, 1 + strlen(message));
	ser_state = ser_waiting_response;
      }
      break;
    case einformation:
      {
	while (pshared->pserial->read_next_byte(&byte)); // Empty the buffer
	snprintf(message, MAX_MSG_SIZE, "get_params\n");
	add_crc(message);
	pshared->pserial->write_serial_port(message, 1 + strlen(message));
	ser_state = ser_waiting_response;
      }
      break;
    case ereport:
      {
	while (pshared->pserial->read_next_byte(&byte)); // Empty the buffer
	snprintf(message, MAX_MSG_SIZE, "get_report\n");
	add_crc(message);
	pshared->pserial->write_serial_port(message, 1 + strlen(message));
	ser_state = ser_waiting_response;
      }
      break;
    case eprogram:
      {
	snprintf(message, MAX_MSG_SIZE, "set_param %s\n", prq->command);
	add_crc(message);
	pshared->pserial->write_serial_port(message, 1 + strlen(message));
	usleep(500000);
	ser_state = ser_nothing;
      }
      break;
    case eupdategui:
    default:
      break;
    }
  if (ser_state == ser_waiting_response)
    {
      // Get the bytes from the serial line. Wait a little if nothing is found.
      sz = 0;
      for (ctn = 0; !pshared->pserial->read_next_byte(&byte) && ctn < 10; ctn++)
	usleep(10000);
      while (sz < MAX_MSG_SIZE && byte != 0 && ctn < 10) // Is the end of the message
	{
	  message[sz++] = byte;
	  for (ctn = 0; !pshared->pserial->read_next_byte(&byte) && ctn < 10; ctn++)
	    usleep(1000);
	}
      if (byte == 0 && sz > 0)
	{
	  message[sz] = '\0';
	  if (!check_crc(message, sz))
	    {
	      printf("Wrong CRC: %x / %x.\n", calculate_CRC(message, sz - 1), message[sz - 1]);
	      return;
	    }
	  message[sz - 1] = '\0'; // Erase the CRC
	  printf("<- Received a serial message: \"%s\".\n", message);
	  LOCK;
	  // Process the shit, like if it was a sewer pipe.
	  switch (prq->type)
	    {
	    case enothing:
	      break;
	    case eping:
	      {
		strncpy(pshared->bms_version, message, MAX_MSG_SIZE);
	      }
	      break;
	    case einformation:
	      {
		strncpy(pshared->param_msg, message, MAX_MSG_SIZE);
		pshared->pBMS->parse_BMS_params_string(&pshared->pBMS->m_params, pshared->param_msg);
	      }
	      break;
	    case ereport:
	      {
		strncpy(pshared->report_msg, message, MAX_MSG_SIZE);
		pshared->pBMS->parse_BMS_report_string(&pshared->pBMS->m_report, pshared->report_msg);
	      }
	      break;
	    case eprogram:
	    case eupdategui:
	    default:
	      break;
	    }
	  // This will trigger a screen refresh
	  add_command_in_locked_area(eupdategui, " ", pshared);
	  UNLOCK;
	}
    }
}
Example #5
0
bool check_crc(char *pmessage, int sz)
{
  return (calculate_CRC(pmessage, sz - 1) == pmessage[sz - 1]);
}