bool PubSubClient::publish(MQTT::Publish &pub) {
  if (!connected())
    return false;

  switch (pub.qos()) {
  case 0:
    pub.send(*_client);
    lastOutActivity = millis();
    break;

  case 1:
    if (!_send_reliably(&pub))
      return false;
    break;

  case 2:
    {
      if (!_send_reliably(&pub))
	return false;

      MQTT::PublishRel pubrel(pub.packet_id());
      if (!_send_reliably(&pubrel))
	return false;
    }
    break;
  }
  return true;
}
void PubSubClient::_process_message(MQTT::Message* msg) {
  switch (msg->type()) {
  case MQTT::PUBLISH:
    {
      MQTT::Publish *pub = static_cast<MQTT::Publish*>(msg);	// RTTI is disabled on embedded, so no dynamic_cast<>()

      if (_callback)
	_callback(*pub);

      if (pub->qos() == 1) {
	MQTT::PublishAck puback(pub->packet_id());
	puback.send(*_client);
	lastOutActivity = millis();

      } else if (pub->qos() == 2) {
	uint8_t retries = 0;

	{
	  MQTT::PublishRec pubrec(pub->packet_id());
	  if (!_send_reliably(&pubrec))
	    return;
	}

	{
	  MQTT::PublishComp pubcomp(pub->packet_id());
	  pubcomp.send(*_client);
	  lastOutActivity = millis();
	}
      }
    }
    break;

  case MQTT::PINGREQ:
    {
      MQTT::PingResp pr;
      pr.send(*_client);
      lastOutActivity = millis();
    }
    break;

  case MQTT::PINGRESP:
    pingOutstanding = false;
  }
}