54 make_fixed_header(control_packet_type::connack, 0b0000)
60 connect_acknowledge_flags_(
61 session_present ? 1 : 0
64 property_length_{async_mqtt::
size(
props)},
65 props_(force_move(
props))
67 using namespace std::literals;
68 auto pb = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(property_length_));
70 property_length_buf_.push_back(
e);
73 for (
auto const&
prop : props_) {
75 if (!validate_property(property_location::connack,
id)) {
78 "v5::connack_packet property "s + id_to_str(
id) +
" is not allowed"
83 remaining_length_ += property_length_buf_.size() + property_length_;
84 auto rb = val_to_variable_bytes(boost::numeric_cast<std::uint32_t>(remaining_length_));
86 remaining_length_buf_.push_back(e);
95 "v5::connack_packet fixed_header doesn't exist"
98 fixed_header_ =
static_cast<std::uint8_t
>(buf.front());
100 auto cpt_opt = get_control_packet_type_with_check(fixed_header_);
101 if (!cpt_opt || *cpt_opt != control_packet_type::connack) {
104 "v5::connack_packet fixed_header is invalid"
109 if (
auto vl_opt = insert_advance_variable_length(buf, remaining_length_buf_)) {
110 remaining_length_ = *vl_opt;
113 throw make_error(errc::bad_message,
"v5::connack_packet remaining length is invalid");
115 if (remaining_length_ != buf.size()) {
116 throw make_error(errc::bad_message,
"v5::connack_packet remaining length doesn't match buf.size()");
120 if (buf.size() < 1) {
123 "v5::connack_packet connect acknowledge flags don't exist"
126 connect_acknowledge_flags_ =
static_cast<std::uint8_t
>(buf.front());
127 buf.remove_prefix(1);
128 if ((connect_acknowledge_flags_ & 0b11111110)!= 0) {
131 "v5::connack_packet connect acknowledge flags is invalid"
135 reason_code_ =
static_cast<connect_reason_code
>(buf.front());
136 buf.remove_prefix(1);
137 switch (reason_code_) {
138 case connect_reason_code::success:
139 case connect_reason_code::unspecified_error:
140 case connect_reason_code::malformed_packet:
141 case connect_reason_code::protocol_error:
142 case connect_reason_code::implementation_specific_error:
143 case connect_reason_code::unsupported_protocol_version:
144 case connect_reason_code::client_identifier_not_valid:
145 case connect_reason_code::bad_user_name_or_password:
146 case connect_reason_code::not_authorized:
147 case connect_reason_code::server_unavailable:
148 case connect_reason_code::server_busy:
149 case connect_reason_code::banned:
150 case connect_reason_code::server_shutting_down:
151 case connect_reason_code::bad_authentication_method:
152 case connect_reason_code::topic_name_invalid:
153 case connect_reason_code::packet_too_large:
154 case connect_reason_code::quota_exceeded:
155 case connect_reason_code::payload_format_invalid:
156 case connect_reason_code::retain_not_supported:
157 case connect_reason_code::qos_not_supported:
158 case connect_reason_code::use_another_server:
159 case connect_reason_code::server_moved:
160 case connect_reason_code::connection_rate_exceeded:
165 "v5::connack_packet connect reason_code is invalid"
171 auto it = buf.begin();
172 if (
auto pl_opt = variable_bytes_to_val(it, buf.end())) {
173 property_length_ = *pl_opt;
174 std::copy(buf.begin(), it, std::back_inserter(property_length_buf_));
175 buf.remove_prefix(std::size_t(std::distance(buf.begin(), it)));
176 if (buf.size() < property_length_) {
179 "v5::connack_packet properties_don't match its length"
182 auto prop_buf = buf.substr(0, property_length_);
183 props_ = make_properties(prop_buf, property_location::connack);
184 buf.remove_prefix(property_length_);
189 "v5::connack_packet property_length is invalid"
196 "v5::connack_packet properties don't match its length"
201 constexpr control_packet_type type()
const {
202 return control_packet_type::connack;
211 std::vector<as::const_buffer>
ret;
214 ret.emplace_back(as::buffer(&fixed_header_, 1));
215 ret.emplace_back(as::buffer(remaining_length_buf_.data(), remaining_length_buf_.size()));
216 ret.emplace_back(as::buffer(&connect_acknowledge_flags_, 1));
217 ret.emplace_back(as::buffer(&reason_code_, 1));
219 ret.emplace_back(as::buffer(property_length_buf_.data(), property_length_buf_.size()));
220 auto props_cbs = async_mqtt::const_buffer_sequence(props_);
233 remaining_length_buf_.size() +
248 async_mqtt::num_of_const_buffer_sequence(props_);
251 bool session_present()
const {
252 return is_session_present(
static_cast<char>(connect_acknowledge_flags_));
259 connect_reason_code
code()
const {
272 std::uint8_t fixed_header_;
274 std::size_t remaining_length_;
275 boost::container::static_vector<char, 4> remaining_length_buf_;
277 std::uint8_t connect_acknowledge_flags_;
279 connect_reason_code reason_code_;
281 std::size_t property_length_;
282 boost::container::static_vector<char, 4> property_length_buf_;