_ZN7fuzzing10datasource4Base3GetIbEET_m:
   49|  11.8k|{
   50|  11.8k|    uint8_t ret;
   51|  11.8k|    const auto v = get(sizeof(ret), sizeof(ret), id);
   52|  11.8k|    memcpy(&ret, v.data(), sizeof(ret));
   53|  11.8k|    return (ret % 2) ? true : false;
  ------------------
  |  Branch (53:12): [True: 2.00k, False: 9.81k]
  ------------------
   54|  11.8k|}
_ZN7fuzzing10datasource4Base3GetINSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEET_m:
   57|  7.24k|{
   58|  7.24k|    auto data = GetData(id);
   59|  7.24k|    return std::string(data.data(), data.data() + data.size());
   60|  7.24k|}
_ZN7fuzzing10datasource4Base7GetDataEmmm:
   81|  16.5k|{
   82|  16.5k|    return get(min, max, id);
   83|  16.5k|}
_ZN7fuzzing10datasource10DatasourceC2EPKhm:
  124|  2.79k|    Base(), data(_data), size(_size), idx(0), left(size)
  125|  2.79k|{
  126|  2.79k|}
_ZN7fuzzing10datasource10Datasource3getEmmm:
  128|  59.8k|std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
  129|  59.8k|    (void)id;
  130|       |
  131|  59.8k|    uint32_t getSize;
  132|  59.8k|    if ( left < sizeof(getSize) ) {
  ------------------
  |  Branch (132:10): [True: 2.72k, False: 57.0k]
  ------------------
  133|  2.72k|        throw OutOfData();
  134|  2.72k|    }
  135|  57.0k|    memcpy(&getSize, data + idx, sizeof(getSize));
  136|  57.0k|    idx += sizeof(getSize);
  137|  57.0k|    left -= sizeof(getSize);
  138|       |
  139|  57.0k|    if ( getSize < min ) {
  ------------------
  |  Branch (139:10): [True: 5.97k, False: 51.1k]
  ------------------
  140|  5.97k|        getSize = min;
  141|  5.97k|    }
  142|  57.0k|    if ( max && getSize > max ) {
  ------------------
  |  Branch (142:10): [True: 41.1k, False: 15.9k]
  |  Branch (142:17): [True: 34.8k, False: 6.34k]
  ------------------
  143|  34.8k|        getSize = max;
  144|  34.8k|    }
  145|       |
  146|  57.0k|    if ( left < getSize ) {
  ------------------
  |  Branch (146:10): [True: 2.83k, False: 54.2k]
  ------------------
  147|  2.83k|        throw OutOfData();
  148|  2.83k|    }
  149|       |
  150|  54.2k|    std::vector<uint8_t> ret(getSize);
  151|       |
  152|  54.2k|    if ( getSize > 0 ) {
  ------------------
  |  Branch (152:10): [True: 48.2k, False: 5.98k]
  ------------------
  153|  48.2k|        memcpy(ret.data(), data + idx, getSize);
  154|  48.2k|    }
  155|  54.2k|    idx += getSize;
  156|  54.2k|    left -= getSize;
  157|       |
  158|  54.2k|    return ret;
  159|  57.0k|}
_ZN7fuzzing10datasource4BaseC2Ev:
   20|  2.79k|        Base(void) = default;
_ZN7fuzzing10datasource4BaseD2Ev:
   21|  2.79k|        virtual ~Base(void) = default;
_ZN7fuzzing10datasource4Base9OutOfDataC2Ev:
   30|  5.55k|                OutOfData() = default;
_ZN7fuzzing10datasource4Base3GetItEET_m:
   41|  11.6k|{
   42|  11.6k|    T ret;
   43|  11.6k|    const auto v = get(sizeof(ret), sizeof(ret), id);
   44|  11.6k|    memcpy(&ret, v.data(), sizeof(ret));
   45|  11.6k|    return ret;
   46|  11.6k|}
_ZN7fuzzing10datasource4Base3GetIhEET_m:
   41|  15.7k|{
   42|  15.7k|    T ret;
   43|  15.7k|    const auto v = get(sizeof(ret), sizeof(ret), id);
   44|  15.7k|    memcpy(&ret, v.data(), sizeof(ret));
   45|  15.7k|    return ret;
   46|  15.7k|}
_ZN7fuzzing10datasource4Base3GetIjEET_m:
   41|  3.99k|{
   42|  3.99k|    T ret;
   43|  3.99k|    const auto v = get(sizeof(ret), sizeof(ret), id);
   44|  3.99k|    memcpy(&ret, v.data(), sizeof(ret));
   45|  3.99k|    return ret;
   46|  3.99k|}

_ZN7fuzzing9exception13FlowExceptionC2Ev:
   18|  5.55k|        FlowException(void) : ExceptionBase() { }
_ZN7fuzzing9exception13ExceptionBaseC2Ev:
   11|  5.55k|        ExceptionBase(void) = default;

_ZN4BaseC2ERN7fuzzing10datasource10DatasourceE:
   38|  9.17k|    ds(ds)
   39|  9.17k|{ }
_ZN4BaseD2Ev:
   41|  9.17k|Base::~Base() { }
_ZNK4Base6GetQoSEv:
   43|  3.66k|MqttQoS Base::GetQoS(void) const {
   44|  3.66k|    switch ( ds.Get<uint8_t>() % 3 ) {
   45|  2.73k|        case    0:
  ------------------
  |  Branch (45:9): [True: 2.73k, False: 924]
  ------------------
   46|  2.73k|            return MQTT_QOS_0;
   47|    427|        case    1:
  ------------------
  |  Branch (47:9): [True: 427, False: 3.23k]
  ------------------
   48|    427|            return MQTT_QOS_1;
   49|    449|        case    2:
  ------------------
  |  Branch (49:9): [True: 449, False: 3.21k]
  ------------------
   50|    449|            return MQTT_QOS_2;
   51|      0|        default:
  ------------------
  |  Branch (51:9): [True: 0, False: 3.66k]
  ------------------
   52|       |            /* Silence compiler warning */
   53|      0|            abort();
   54|  3.66k|    }
   55|  3.66k|}
_ZN5TopicC2ERN7fuzzing10datasource10DatasourceE:
   69|  3.63k|    Base(ds)
   70|  3.63k|{ }
_ZN5TopicD2Ev:
   72|  3.63k|Topic::~Topic() { }
_ZN5Topic8GenerateEv:
   74|  3.63k|bool Topic::Generate(void) {
   75|  3.63k|    bool ret;
   76|       |
   77|  3.63k|    memset(&topic, 0, sizeof(topic));
   78|       |
   79|  3.63k|    strings.push_back( ds.Get<std::string>() );
   80|  3.63k|    topic.topic_filter = strings.back().c_str();
   81|       |
   82|  3.63k|    topic.qos = GetQoS();
   83|       |
   84|  3.63k|    ret = true;
   85|  3.63k|end:
   86|  2.75k|    return ret;
   87|  3.63k|}
_ZN5Topic3GetEv:
   89|  2.69k|MqttTopic Topic::Get(void) {
   90|  2.69k|    return topic;
   91|  2.69k|}
_ZN6TopicsC2ERN7fuzzing10datasource10DatasourceE:
  105|  2.74k|    Base(ds)
  106|  2.74k|{ }
_ZN6TopicsD2Ev:
  108|  2.74k|Topics::~Topics() {
  109|  3.63k|    for (auto& t : topics) {
  ------------------
  |  Branch (109:18): [True: 3.63k, False: 2.74k]
  ------------------
  110|  3.63k|        delete t;
  111|  3.63k|    }
  112|  2.74k|}
_ZN6Topics8GenerateEv:
  114|  2.74k|bool Topics::Generate(void) {
  115|  2.74k|    bool ret;
  116|       |
  117|  2.74k|    try {
  118|  2.74k|        const auto numTopics = ds.Get<uint16_t>() % (MAX_TOPICS+1);
  ------------------
  |  |   24|  2.74k|#define MAX_TOPICS 50
  ------------------
  119|       |
  120|  6.38k|        for (size_t i = 0; i < numTopics; i++) {
  ------------------
  |  Branch (120:28): [True: 3.63k, False: 2.74k]
  ------------------
  121|  3.63k|            topics.push_back(new Topic(ds));
  122|  3.63k|            CHECK_EQ(topics.back()->Generate(), true);
  ------------------
  |  |   20|  3.63k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 0, False: 3.63k]
  |  |  ------------------
  ------------------
  123|  3.63k|        }
  124|       |
  125|  2.74k|        ret = true;
  126|  2.74k|    } catch ( ... ) { }
  127|       |
  128|  2.74k|end:
  129|  2.74k|    return ret;
  130|  2.74k|}
_ZN6Topics7ToArrayEv:
  132|  2.44k|MqttTopic* Topics::ToArray(void) {
  133|  2.44k|    auto ret = new MqttTopic[topics.size()];
  134|       |
  135|  5.14k|    for (size_t i = 0; i < Size(); i++) {
  ------------------
  |  Branch (135:24): [True: 2.69k, False: 2.44k]
  ------------------
  136|  2.69k|        ret[i] = topics[i]->Get();
  137|  2.69k|    }
  138|  2.44k|    return ret;
  139|  2.44k|}
_ZNK6Topics4SizeEv:
  141|  7.58k|size_t Topics::Size(void) const {
  142|  7.58k|    return topics.size();
  143|  7.58k|}
_ZN14wolfMQTTFuzzer6mallocEm:
  217|  5.50k|void* wolfMQTTFuzzer::malloc(const size_t n) {
  218|  5.50k|    return n == 0 ? BADPTR : ::malloc(n);
  ------------------
  |  |   23|      0|#define BADPTR ((void*)0x12)
  ------------------
  |  Branch (218:12): [True: 0, False: 5.50k]
  ------------------
  219|  5.50k|}
_ZN14wolfMQTTFuzzer4freeEPv:
  221|  5.59k|void wolfMQTTFuzzer::free(void* ptr) {
  222|  5.59k|    if ( ptr == BADPTR ) {
  ------------------
  |  |   23|  5.59k|#define BADPTR ((void*)0x12)
  ------------------
  |  Branch (222:10): [True: 0, False: 5.59k]
  ------------------
  223|      0|        return;
  224|      0|    }
  225|       |
  226|  5.59k|    ::free(ptr);
  227|  5.59k|}
_ZNK14wolfMQTTFuzzer11GetPacketIdEv:
  239|  3.38k|word16 wolfMQTTFuzzer::GetPacketId(void) const {
  240|  3.38k|    return ds.Get<word16>();
  241|  3.38k|}
_ZN14wolfMQTTFuzzer9subscribeEv:
  243|  2.25k|bool wolfMQTTFuzzer::subscribe(void) {
  244|  2.25k|    MqttTopic* topicsArray = nullptr;
  245|       |
  246|  2.25k|    bool ret = false;
  247|       |
  248|  2.25k|    try {
  249|  2.25k|        Topics topics(ds);
  250|  2.25k|        CHECK_EQ(topics.Generate(), true);
  ------------------
  |  |   20|  2.25k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 0, False: 2.25k]
  |  |  ------------------
  ------------------
  251|       |
  252|  2.25k|        MqttSubscribe subscribe;
  253|       |
  254|  2.25k|        memset(&subscribe, 0, sizeof(subscribe));
  255|       |
  256|  2.25k|        subscribe.packet_id = GetPacketId();
  257|  2.25k|        topicsArray = topics.ToArray();
  258|  2.25k|        subscribe.topic_count = topics.Size();
  259|  2.25k|        subscribe.topics = topicsArray;
  260|       |
  261|  2.25k|        CHECK_EQ(MqttClient_Subscribe(&client, &subscribe), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|  2.25k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 1.91k, False: 338]
  |  |  ------------------
  ------------------
  262|       |
  263|    338|        ret = true;
  264|    338|    } catch ( ... ) { }
  265|       |
  266|  2.25k|end:
  267|  2.25k|    if ( topicsArray ) {
  ------------------
  |  Branch (267:10): [True: 2.00k, False: 248]
  ------------------
  268|  2.00k|        delete[] topicsArray;
  269|  2.00k|    }
  270|  2.25k|    return ret;
  271|  2.25k|}
_ZN14wolfMQTTFuzzer11unsubscribeEv:
  273|    494|bool wolfMQTTFuzzer::unsubscribe(void) {
  274|    494|    MqttTopic* topicsArray = nullptr;
  275|       |
  276|    494|    bool ret = false;
  277|       |
  278|    494|    try {
  279|    494|        Topics topics(ds);
  280|    494|        CHECK_EQ(topics.Generate(), true);
  ------------------
  |  |   20|    494|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 0, False: 494]
  |  |  ------------------
  ------------------
  281|       |
  282|    494|        MqttUnsubscribe unsubscribe;
  283|       |
  284|    494|        memset(&unsubscribe, 0, sizeof(unsubscribe));
  285|       |
  286|    494|        unsubscribe.packet_id = GetPacketId();
  287|    494|        topicsArray = topics.ToArray();
  288|    494|        unsubscribe.topic_count = topics.Size();
  289|    494|        unsubscribe.topics = topicsArray;
  290|       |
  291|    494|        CHECK_EQ(MqttClient_Unsubscribe(&client, &unsubscribe), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|    494|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 421, False: 73]
  |  |  ------------------
  ------------------
  292|       |
  293|     73|        ret = true;
  294|     73|    } catch ( ... ) { }
  295|       |
  296|    494|end:
  297|    494|    if ( topicsArray ) {
  ------------------
  |  Branch (297:10): [True: 445, False: 49]
  ------------------
  298|    445|        delete[] topicsArray;
  299|    445|    }
  300|    494|    return ret;
  301|    494|}
_ZN14wolfMQTTFuzzer7publishEv:
  303|    861|bool wolfMQTTFuzzer::publish(void) {
  304|    861|    bool ret = false;
  305|       |
  306|    861|    try {
  307|    861|        MqttPublish publish;
  308|       |
  309|    861|        memset(&publish, 0, sizeof(publish));
  310|       |
  311|    861|        publish.retain = ds.Get<bool>() ? 1 : 0;
  ------------------
  |  Branch (311:26): [True: 193, False: 668]
  ------------------
  312|    861|        publish.qos = GetQoS();
  313|    861|        publish.duplicate = ds.Get<bool>() ? 1 : 0;
  ------------------
  |  Branch (313:29): [True: 326, False: 535]
  ------------------
  314|       |
  315|    861|        const auto topic_str = ds.Get<std::string>();
  316|    861|        publish.topic_name = topic_str.c_str();
  317|       |
  318|    861|        publish.packet_id = GetPacketId();
  319|       |
  320|    861|        auto buffer = ds.GetData(0);
  321|    861|        publish.buffer = buffer.data();
  322|    861|        publish.total_len = buffer.size();
  323|       |
  324|    861|        if ( DEBUG ) {
  ------------------
  |  |   26|    861|#define DEBUG 0
  |  |  ------------------
  |  |  |  Branch (26:15): [Folded, False: 861]
  |  |  ------------------
  ------------------
  325|      0|            printf("publish: topic name size: %zu\n", strlen(topic_str.c_str()));
  326|      0|        }
  327|       |
  328|    861|        CHECK_EQ(MqttClient_Publish(&client, &publish), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|    861|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 495, False: 366]
  |  |  ------------------
  ------------------
  329|       |
  330|    366|        ret = true;
  331|    366|    } catch ( ... ) { }
  332|       |
  333|    861|end:
  334|    861|    return ret;
  335|    861|}
_ZN14wolfMQTTFuzzer4pingEv:
  337|    910|bool wolfMQTTFuzzer::ping(void) {
  338|    910|    bool ret = false;
  339|       |
  340|    910|    MqttPing ping;
  341|       |
  342|    910|    memset(&ping, 0, sizeof(ping));
  343|       |
  344|    910|    CHECK_EQ(MqttClient_Ping_ex(&client, &ping), true);
  ------------------
  |  |   20|    910|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 910, False: 0]
  |  |  ------------------
  ------------------
  345|       |
  346|      0|    ret = true;
  347|       |
  348|    910|end:
  349|    910|    return ret;
  350|      0|}
_ZN14wolfMQTTFuzzer4waitEv:
  352|  2.66k|bool wolfMQTTFuzzer::wait(void) {
  353|  2.66k|    bool ret = false;
  354|       |
  355|  2.66k|    CHECK_EQ(MqttClient_WaitMessage(&client, 1000), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|  2.66k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 2.65k, False: 15]
  |  |  ------------------
  ------------------
  356|       |
  357|     15|    ret = true;
  358|       |
  359|  2.66k|end:
  360|  2.66k|    return ret;
  361|     15|}
_ZN14wolfMQTTFuzzerC2ERN7fuzzing10datasource10DatasourceE:
  364|  2.79k|    Base(ds)
  365|  2.79k|{ }
_ZN14wolfMQTTFuzzerD2Ev:
  367|  2.79k|wolfMQTTFuzzer::~wolfMQTTFuzzer() {
  368|  2.79k|    this->free(tx_buf);
  369|  2.79k|    this->free(rx_buf);
  370|  2.79k|}
_ZN14wolfMQTTFuzzer10InitializeEv:
  372|  2.79k|bool wolfMQTTFuzzer::Initialize(void) {
  373|  2.79k|    bool ret = false;
  374|       |
  375|  2.79k|    try {
  376|       |        /* net */
  377|  2.79k|        {
  378|  2.79k|            memset(&net, 0, sizeof(net));
  379|       |
  380|  2.79k|            net.connect = mqtt_connect;
  381|  2.79k|            net.read = mqtt_recv;
  382|  2.79k|            net.write = mqtt_write;
  383|  2.79k|            net.disconnect = mqtt_disconnect;
  384|  2.79k|            net.context = this;
  385|  2.79k|        }
  386|       |
  387|       |        /* client */
  388|  2.79k|        {
  389|  2.79k|            memset(&client, 0, sizeof(client));
  390|       |
  391|  2.79k|            tx_size = ds.Get<uint16_t>();
  392|  2.79k|            tx_size = 4096;
  393|  2.79k|            tx_buf = (uint8_t*)this->malloc(tx_size);
  394|  2.79k|            rx_size = ds.Get<uint16_t>();
  395|  2.79k|            rx_size = 4096;
  396|  2.79k|            rx_buf = (uint8_t*)this->malloc(rx_size);
  397|  2.79k|            memset(tx_buf, 0, tx_size);
  398|  2.79k|            memset(rx_buf, 0, rx_size);
  399|       |
  400|  2.79k|            client.msg_cb = mqtt_message_cb;
  401|  2.79k|            client.tx_buf = tx_buf;
  402|  2.79k|            client.tx_buf_len = tx_size;
  403|  2.79k|            client.rx_buf = rx_buf;
  404|  2.79k|            client.rx_buf_len = rx_size;
  405|  2.79k|            client.cmd_timeout_ms = 1000;
  406|  2.79k|        }
  407|       |
  408|       |        /* connect */
  409|  2.79k|        MqttMessage lwt_msg;
  410|  2.79k|        {
  411|  2.79k|            memset(&connect, 0, sizeof(connect));
  412|       |
  413|  2.79k|            connect.keep_alive_sec = 1;
  414|  2.79k|            connect.clean_session = ds.Get<bool>() ? 1 : 0;
  ------------------
  |  Branch (414:37): [True: 1.02k, False: 1.77k]
  ------------------
  415|  2.79k|            client_id = ds.Get<std::string>();
  416|  2.79k|            connect.client_id = client_id.c_str();
  417|  2.79k|            connect.enable_lwt = ds.Get<bool>() ? 1 : 0;
  ------------------
  |  Branch (417:34): [True: 30, False: 2.76k]
  ------------------
  418|  2.79k|        }
  419|       |            
  420|  2.79k|        std::string lwt_topic_name;
  421|  2.79k|        std::vector<uint8_t> lwt_buffer;
  422|       |
  423|  2.79k|        if ( connect.enable_lwt ) {
  ------------------
  |  Branch (423:14): [True: 30, False: 2.76k]
  ------------------
  424|     30|            lwt_topic_name = ds.Get<std::string>();
  425|     30|            lwt_buffer = ds.GetData(0);
  426|       |
  427|     30|            connect.lwt_msg = &lwt_msg;
  428|     30|            lwt_msg.qos = GetQoS();
  429|     30|            lwt_msg.retain = ds.Get<bool>() ? 1 : 0;
  ------------------
  |  Branch (429:30): [True: 6, False: 24]
  ------------------
  430|     30|            lwt_msg.topic_name = lwt_topic_name.c_str();
  431|     30|            lwt_msg.buffer = lwt_buffer.data();
  432|     30|            lwt_msg.total_len = lwt_buffer.size();
  433|     30|        }
  434|       |
  435|  2.79k|        CHECK_EQ(MqttSocket_Init(&client, &net), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|  2.79k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 0, False: 2.79k]
  |  |  ------------------
  ------------------
  436|       |
  437|       |#if 0
  438|       |        if ( ds.Get<bool>() ) {
  439|       |            //CHECK_EQ(MqttClient_SetPropertyCallback(&client, mqtt_property_cb, NULL);
  440|       |        }
  441|       |#endif
  442|       |
  443|  2.79k|        CHECK_EQ(MqttClient_NetConnect(&client, "dummy", 12345, 1000, 0, NULL), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|  2.79k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 0, False: 2.79k]
  |  |  ------------------
  ------------------
  444|  2.79k|        CHECK_EQ(MqttClient_Connect(&client, &connect), MQTT_CODE_SUCCESS);
  ------------------
  |  |   20|  2.79k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 956, False: 1.83k]
  |  |  ------------------
  ------------------
  445|       |
  446|  1.83k|        ret = true;
  447|       |
  448|  1.83k|    } catch ( ... ) {
  449|    155|        return false;
  450|    155|    }
  451|       |
  452|  2.64k|end:
  453|  2.64k|    return ret;
  454|  2.79k|}
_ZN14wolfMQTTFuzzer3RunEv:
  456|  1.68k|void wolfMQTTFuzzer::Run(void) {
  457|  1.68k|    try {
  458|  1.68k|        const auto numActions = ds.Get<uint8_t>() % 20;
  459|       |
  460|  10.6k|        for (size_t i = 0; i < numActions; i++) {
  ------------------
  |  Branch (460:28): [True: 10.4k, False: 237]
  ------------------
  461|  10.4k|            switch ( ds.Get<uint8_t>() ) {
  ------------------
  |  Branch (461:22): [True: 7.18k, False: 3.23k]
  ------------------
  462|  2.25k|                case    0:
  ------------------
  |  Branch (462:17): [True: 2.25k, False: 8.16k]
  ------------------
  463|  2.25k|                    subscribe();
  464|  2.25k|                    break;
  465|    494|                case    1:
  ------------------
  |  Branch (465:17): [True: 494, False: 9.92k]
  ------------------
  466|    494|                    unsubscribe();
  467|    494|                    break;
  468|    861|                case    2:
  ------------------
  |  Branch (468:17): [True: 861, False: 9.55k]
  ------------------
  469|    861|                    publish();
  470|    861|                    break;
  471|    910|                case    3:
  ------------------
  |  Branch (471:17): [True: 910, False: 9.51k]
  ------------------
  472|    910|                    ping();
  473|    910|                    break;
  474|  2.66k|                case    4:
  ------------------
  |  Branch (474:17): [True: 2.66k, False: 7.75k]
  ------------------
  475|  2.66k|                    wait();
  476|  2.66k|                    break;
  477|  10.4k|            }
  478|  10.4k|        }
  479|       |
  480|    237|        MqttClient_NetDisconnect(&client);
  481|  1.45k|    } catch ( ... ) { }
  482|  1.68k|}
_ZN14wolfMQTTFuzzer4recvEPhi:
  484|  8.63k|int wolfMQTTFuzzer::recv(byte* buf, const int buf_len) {
  485|  8.63k|    try {
  486|  8.63k|        const auto data = ds.GetData(0);
  487|  8.63k|        const size_t copySize = buf_len > data.size() ? data.size() : buf_len;
  ------------------
  |  Branch (487:33): [True: 1.08k, False: 7.55k]
  ------------------
  488|  8.63k|        if ( copySize ) {
  ------------------
  |  Branch (488:14): [True: 5.74k, False: 2.89k]
  ------------------
  489|  5.74k|            memcpy(buf, data.data(), copySize);
  490|  5.74k|        }
  491|  8.63k|        if ( DEBUG )
  ------------------
  |  |   26|  8.63k|#define DEBUG 0
  |  |  ------------------
  |  |  |  Branch (26:15): [Folded, False: 8.63k]
  |  |  ------------------
  ------------------
  492|      0|        {
  493|      0|            printf("Recv: %zu bytes (%d requested)\n", copySize, buf_len);
  494|      0|            for (size_t i = 0; i < copySize; i++) {
  ------------------
  |  Branch (494:32): [True: 0, False: 0]
  ------------------
  495|      0|                printf("%02X ", data[i]);
  496|      0|            }
  497|      0|            printf("\n");
  498|      0|        }
  499|  8.63k|        return copySize;
  500|  8.63k|    } catch ( ... ) {
  501|  2.06k|        if ( DEBUG ) printf("Recv: -1\n");
  ------------------
  |  |   26|  2.06k|#define DEBUG 0
  |  |  ------------------
  |  |  |  Branch (26:15): [Folded, False: 2.06k]
  |  |  ------------------
  ------------------
  502|  2.06k|        return -1;
  503|  2.06k|    }
  504|  8.63k|}
_ZN14wolfMQTTFuzzer5writeEi:
  506|  4.64k|int wolfMQTTFuzzer::write(const int buf_len) {
  507|  4.64k|    try {
  508|  4.64k|        if ( ds.Get<bool>() == true ) {
  ------------------
  |  Branch (508:14): [True: 427, False: 4.21k]
  ------------------
  509|    427|            if ( DEBUG ) printf("write: -1\n");
  ------------------
  |  |   26|    427|#define DEBUG 0
  |  |  ------------------
  |  |  |  Branch (26:15): [Folded, False: 427]
  |  |  ------------------
  ------------------
  510|    427|            return -1;
  511|    427|        }
  512|       |
  513|  4.21k|        const auto ret = (int)(ds.Get<uint32_t>() % (buf_len+1));
  514|  4.21k|        if ( DEBUG ) printf("write: %d bytes (%d requested)\n", ret, buf_len);
  ------------------
  |  |   26|  4.21k|#define DEBUG 0
  |  |  ------------------
  |  |  |  Branch (26:15): [Folded, False: 4.21k]
  |  |  ------------------
  ------------------
  515|  4.21k|        return ret;
  516|  4.64k|    } catch ( ... ) {
  517|    235|        return -1;
  518|    235|    }
  519|  4.64k|}
LLVMFuzzerTestOneInput:
  521|  2.79k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  522|  2.79k|    fuzzing::datasource::Datasource ds(data, size);
  523|  2.79k|    wolfMQTTFuzzer fuzzer(ds);
  524|       |
  525|  2.79k|    CHECK_EQ(fuzzer.Initialize(), true);
  ------------------
  |  |   20|  2.79k|#define CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }
  |  |  ------------------
  |  |  |  Branch (20:34): [True: 1.11k, False: 1.68k]
  |  |  ------------------
  ------------------
  526|       |
  527|  1.68k|    fuzzer.Run();
  528|       |
  529|  2.79k|end:
  530|  2.79k|    return 0;
  531|  1.68k|}
fuzzer.cpp:_ZL12mqtt_connectPvPKcti:
  177|  2.64k|{
  178|  2.64k|    (void)context;
  179|  2.64k|    (void)host;
  180|  2.64k|    (void)port;
  181|  2.64k|    (void)timeout_ms;
  182|       |
  183|  2.64k|    return MQTT_CODE_SUCCESS;
  184|  2.64k|}
fuzzer.cpp:_ZL9mqtt_recvPvPhii:
  187|  8.63k|{
  188|  8.63k|    (void)context;
  189|  8.63k|    (void)timeout_ms;
  190|       |
  191|  8.63k|    auto fuzzer = static_cast<wolfMQTTFuzzer*>(context);
  192|  8.63k|    return fuzzer->recv(buf, buf_len);
  193|  8.63k|}
fuzzer.cpp:_ZL10mqtt_writePvPKhii:
  196|  4.64k|{
  197|  4.64k|    (void)context;
  198|  4.64k|    (void)timeout_ms;
  199|  4.64k|    (void)buf;
  200|       |
  201|  4.64k|    auto fuzzer = static_cast<wolfMQTTFuzzer*>(context);
  202|  4.64k|    return fuzzer->write(buf_len);
  203|  4.64k|}
fuzzer.cpp:_ZL15mqtt_disconnectPv:
  206|    226|{
  207|    226|    (void)context;
  208|       |
  209|    226|    return MQTT_CODE_SUCCESS;
  210|    226|}

MqttReadStart:
  316|  3.49k|{
  317|  3.49k|    int rc = MQTT_CODE_SUCCESS;
  318|       |
  319|  3.49k|#if defined(WOLFMQTT_DEBUG_CLIENT) || !defined(WOLFMQTT_ALLOW_NODATA_UNLOCK)
  320|       |  #ifdef WOLFMQTT_DEBUG_CLIENT
  321|       |    if (stat->isReadActive) {
  322|       |        MQTT_TRACE_MSG("Warning, recv already locked!");
  323|       |        rc = MQTT_CODE_ERROR_SYSTEM;
  324|       |    }
  325|       |  #endif /* WOLFMQTT_DEBUG_CLIENT */
  326|  3.49k|  #ifndef WOLFMQTT_ALLOW_NODATA_UNLOCK
  327|       |    /* detect if a read is already in progress */
  328|       |    #ifdef WOLFMQTT_MULTITHREAD
  329|       |    if (wm_SemLock(&client->lockClient) == 0)
  330|       |    #endif
  331|  3.49k|    {
  332|  3.49k|        if (client->read.isActive) {
  ------------------
  |  Branch (332:13): [True: 0, False: 3.49k]
  ------------------
  333|      0|            MQTT_TRACE_MSG("Partial read in progress!");
  334|      0|            rc = MQTT_CODE_CONTINUE; /* can't read yet */
  335|      0|        }
  336|       |    #ifdef WOLFMQTT_MULTITHREAD
  337|       |        wm_SemUnlock(&client->lockClient);
  338|       |    #endif
  339|  3.49k|    }
  340|  3.49k|  #endif /* WOLFMQTT_ALLOW_NODATA_UNLOCK */
  341|  3.49k|    if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (341:9): [True: 0, False: 3.49k]
  ------------------
  342|      0|        return rc;
  343|      0|    }
  344|  3.49k|#endif /* WOLFMQTT_DEBUG_CLIENT || !WOLFMQTT_ALLOW_NODATA_UNLOCK */
  345|       |
  346|       |#ifdef WOLFMQTT_MULTITHREAD
  347|       |    rc = wm_SemLock(&client->lockRecv);
  348|       |#endif
  349|  3.49k|    if (rc == MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (349:9): [True: 3.49k, False: 0]
  ------------------
  350|  3.49k|        stat->isReadActive = 1;
  351|       |
  352|       |    #ifdef WOLFMQTT_MULTITHREAD
  353|       |        if (wm_SemLock(&client->lockClient) == 0)
  354|       |    #endif
  355|  3.49k|        {
  356|       |            /* mark read active */
  357|  3.49k|            client->read.isActive = 1;
  358|       |
  359|       |            /* reset the packet state used by MqttPacket_Read */
  360|  3.49k|            client->packet.stat = MQTT_PK_BEGIN;
  361|       |
  362|       |        #ifdef WOLFMQTT_MULTITHREAD
  363|       |            wm_SemUnlock(&client->lockClient);
  364|       |        #endif
  365|  3.49k|        }
  366|       |
  367|  3.49k|        MQTT_TRACE_MSG("lockRecv");
  368|  3.49k|    }
  369|       |
  370|  3.49k|    return rc;
  371|  3.49k|}
MqttReadStop:
  373|  5.17k|{
  374|       |#ifdef WOLFMQTT_DEBUG_CLIENT
  375|       |    if (!stat->isReadActive) {
  376|       |        MQTT_TRACE_MSG("Warning, recv not locked!");
  377|       |        return;
  378|       |    }
  379|       |#endif
  380|       |
  381|       |#ifdef WOLFMQTT_MULTITHREAD
  382|       |    if (wm_SemLock(&client->lockClient) == 0)
  383|       |#endif
  384|  5.17k|    {
  385|       |        /* reset read */
  386|  5.17k|        XMEMSET(&client->read, 0, sizeof(client->read));
  ------------------
  |  |  988|  5.17k|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  387|       |    #ifdef WOLFMQTT_MULTITHREAD
  388|       |        wm_SemUnlock(&client->lockClient);
  389|       |    #endif
  390|  5.17k|    }
  391|       |
  392|  5.17k|    if (stat->isReadActive) {
  ------------------
  |  Branch (392:9): [True: 3.49k, False: 1.67k]
  ------------------
  393|  3.49k|        MQTT_TRACE_MSG("unlockRecv");
  394|  3.49k|        stat->isReadActive = 0;
  395|       |    #ifdef WOLFMQTT_MULTITHREAD
  396|       |        wm_SemUnlock(&client->lockRecv);
  397|       |    #endif
  398|  3.49k|    }
  399|  5.17k|}
MqttClient_Connect:
 1739|  2.64k|{
 1740|  2.64k|    int rc;
 1741|       |
 1742|       |    /* Validate required arguments */
 1743|  2.64k|    if (client == NULL || mc_connect == NULL) {
  ------------------
  |  Branch (1743:9): [True: 0, False: 2.64k]
  |  Branch (1743:27): [True: 0, False: 2.64k]
  ------------------
 1744|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1745|      0|    }
 1746|       |
 1747|  2.64k|    if (mc_connect->stat.write == MQTT_MSG_BEGIN) {
  ------------------
  |  Branch (1747:9): [True: 2.64k, False: 0]
  ------------------
 1748|       |    #ifdef DEBUG_WOLFMQTT
 1749|       |        /* Warn if credentials are being sent without TLS */
 1750|       |        if ((mc_connect->username != NULL || mc_connect->password != NULL) &&
 1751|       |            !(MqttClient_Flags(client, 0, 0) & MQTT_CLIENT_FLAG_IS_TLS)) {
 1752|       |            PRINTF("Warning: MQTT credentials are being sent without TLS");
 1753|       |        }
 1754|       |    #endif
 1755|       |
 1756|       |        /* Flag write active / lock mutex */
 1757|  2.64k|        if ((rc = MqttWriteStart(client, &mc_connect->stat)) != 0) {
  ------------------
  |  Branch (1757:13): [True: 0, False: 2.64k]
  ------------------
 1758|      0|            return rc;
 1759|      0|        }
 1760|       |
 1761|  2.64k|    #ifdef WOLFMQTT_V5
 1762|       |        /* Use specified protocol version if set */
 1763|  2.64k|        mc_connect->protocol_level = client->protocol_level;
 1764|       |
 1765|       |        /* Reset server-supplied session limits so stale values from a
 1766|       |         * prior broker do not leak across reconnects. An accepted CONNACK
 1767|       |         * will repopulate these in Handle_ConnectAck_Props. Initialize to
 1768|       |         * this build's Maximum QoS so the runtime guard in MqttPublishMsg
 1769|       |         * caps publishes even before CONNACK is processed. */
 1770|  2.64k|        client->max_qos = (MqttQoS)WOLFMQTT_MAX_QOS;
  ------------------
  |  |   37|  2.64k|#define WOLFMQTT_MAX_QOS 2
  ------------------
 1771|  2.64k|        client->retain_avail = 1;
 1772|  2.64k|        client->packet_sz_max = 0;
 1773|  2.64k|    #endif
 1774|       |
 1775|       |        /* Encode the connect packet */
 1776|  2.64k|        rc = MqttEncode_Connect(client->tx_buf, client->tx_buf_len, mc_connect);
 1777|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 1778|       |        PRINTF("MqttClient_EncodePacket: Len %d, Type %s (%d), ID %d, QoS %d",
 1779|       |            rc, MqttPacket_TypeDesc(MQTT_PACKET_TYPE_CONNECT),
 1780|       |            MQTT_PACKET_TYPE_CONNECT, 0, 0);
 1781|       |    #endif
 1782|  2.64k|        if (rc <= 0) {
  ------------------
  |  Branch (1782:13): [True: 17, False: 2.62k]
  ------------------
 1783|       |            /* Encode failed: tx_buf may hold partial plaintext credentials.
 1784|       |             * Zero the full buffer before MqttWriteStop releases lockSend
 1785|       |             * so no other thread can see residual data. */
 1786|     17|            CLIENT_FORCE_ZERO(client->tx_buf, client->tx_buf_len);
  ------------------
  |  |   41|     17|    MqttClient_ForceZero(mem, (word32)(len))
  ------------------
 1787|     17|            MqttWriteStop(client, &mc_connect->stat);
 1788|     17|            return rc;
 1789|     17|        }
 1790|  2.62k|        client->write.len = rc;
 1791|       |
 1792|       |    #ifdef WOLFMQTT_MULTITHREAD
 1793|       |        rc = wm_SemLock(&client->lockClient);
 1794|       |        if (rc == 0) {
 1795|       |            /* inform other threads of expected response */
 1796|       |            rc = MqttClient_RespList_Add(client, MQTT_PACKET_TYPE_CONNECT_ACK,
 1797|       |                    0, &mc_connect->pendResp, &mc_connect->ack);
 1798|       |            wm_SemUnlock(&client->lockClient);
 1799|       |        }
 1800|       |        if (rc != 0) {
 1801|       |            /* Save write.len before MqttWriteStop zeroes client->write */
 1802|       |            int xfer = client->write.len;
 1803|       |            /* Clear tx_buf to remove plaintext credentials BEFORE
 1804|       |             * MqttWriteStop releases lockSend, so another thread cannot
 1805|       |             * race in and repopulate tx_buf before it is scrubbed. */
 1806|       |            CLIENT_FORCE_ZERO(client->tx_buf, xfer);
 1807|       |            MqttWriteStop(client, &mc_connect->stat);
 1808|       |            return rc; /* Error locking client */
 1809|       |        }
 1810|       |    #endif
 1811|       |
 1812|  2.62k|        mc_connect->stat.write = MQTT_MSG_HEADER;
 1813|  2.62k|    }
 1814|  2.62k|    if (mc_connect->stat.write == MQTT_MSG_HEADER) {
  ------------------
  |  Branch (1814:9): [True: 2.62k, False: 0]
  ------------------
 1815|  2.62k|        int xfer = client->write.len;
 1816|       |
 1817|       |        /* Send connect packet */
 1818|  2.62k|        rc = MqttPacket_Write(client, client->tx_buf, xfer);
 1819|       |    #ifdef WOLFMQTT_NONBLOCK
 1820|       |        if (rc == MQTT_CODE_CONTINUE
 1821|       |        #ifdef WOLFMQTT_ALLOW_NODATA_UNLOCK
 1822|       |            && client->write.total > 0
 1823|       |        #endif
 1824|       |        ) {
 1825|       |            /* keep send locked and return early.
 1826|       |             * Note: tx_buf still contains credentials until write completes */
 1827|       |            return rc;
 1828|       |        }
 1829|       |    #endif
 1830|       |        /* Clear tx_buf to remove any plaintext credentials from memory
 1831|       |         * BEFORE MqttWriteStop releases lockSend, so another thread cannot
 1832|       |         * race in and populate tx_buf before it is scrubbed.
 1833|       |         * Use xfer (saved before MqttWriteStop zeroes client->write). */
 1834|  2.62k|        CLIENT_FORCE_ZERO(client->tx_buf, xfer);
  ------------------
  |  |   41|  2.62k|    MqttClient_ForceZero(mem, (word32)(len))
  ------------------
 1835|  2.62k|        MqttWriteStop(client, &mc_connect->stat);
 1836|       |
 1837|  2.62k|        if (rc != xfer) {
  ------------------
  |  Branch (1837:13): [True: 1.75k, False: 872]
  ------------------
 1838|  1.75k|            MqttClient_CancelMessage(client, (MqttObject*)mc_connect);
 1839|  1.75k|            return rc;
 1840|  1.75k|        }
 1841|       |
 1842|    872|    #ifdef WOLFMQTT_V5
 1843|       |        /* Enhanced authentication */
 1844|    872|        if (client->enable_eauth == 1) {
  ------------------
  |  Branch (1844:13): [True: 0, False: 872]
  ------------------
 1845|      0|            mc_connect->stat.write = MQTT_MSG_AUTH;
 1846|      0|        }
 1847|    872|        else
 1848|    872|    #endif
 1849|    872|        {
 1850|    872|            mc_connect->stat.write = MQTT_MSG_WAIT;
 1851|    872|        }
 1852|    872|    }
 1853|       |
 1854|    872|#ifdef WOLFMQTT_V5
 1855|       |    /* Enhanced authentication */
 1856|    872|    if (mc_connect->protocol_level > MQTT_CONNECT_PROTOCOL_LEVEL_4 &&
  ------------------
  |  |  367|  1.74k|#define MQTT_CONNECT_PROTOCOL_LEVEL_4   4 /* v3.1.1 */
  ------------------
  |  Branch (1856:9): [True: 0, False: 872]
  ------------------
 1857|      0|            mc_connect->stat.write == MQTT_MSG_AUTH)
  ------------------
  |  Branch (1857:13): [True: 0, False: 0]
  ------------------
 1858|      0|    {
 1859|      0|        MqttAuth auth, *p_auth = &auth;
 1860|      0|        MqttProp* prop, *conn_prop;
 1861|       |
 1862|       |        /* Find the AUTH property in the connect structure */
 1863|      0|        for (conn_prop = mc_connect->props;
 1864|      0|             (conn_prop != NULL) && (conn_prop->type != MQTT_PROP_AUTH_METHOD);
  ------------------
  |  Branch (1864:14): [True: 0, False: 0]
  |  Branch (1864:37): [True: 0, False: 0]
  ------------------
 1865|      0|             conn_prop = conn_prop->next) {
 1866|      0|        }
 1867|      0|        if (conn_prop == NULL) {
  ------------------
  |  Branch (1867:13): [True: 0, False: 0]
  ------------------
 1868|       |        #ifdef WOLFMQTT_MULTITHREAD
 1869|       |            if (wm_SemLock(&client->lockClient) == 0) {
 1870|       |                MqttClient_RespList_Remove(client, &mc_connect->pendResp);
 1871|       |                wm_SemUnlock(&client->lockClient);
 1872|       |            }
 1873|       |        #endif
 1874|       |            /* AUTH property was not set in connect structure */
 1875|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1876|      0|        }
 1877|       |
 1878|      0|        XMEMSET((void*)p_auth, 0, sizeof(MqttAuth));
  ------------------
  |  |  988|      0|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
 1879|       |
 1880|       |        /* Set the authentication reason */
 1881|      0|        p_auth->reason_code = MQTT_REASON_CONT_AUTH;
 1882|       |
 1883|       |        /* Use the same authentication method property from connect */
 1884|      0|        prop = MqttProps_Add(&p_auth->props);
 1885|      0|        if (prop == NULL) {
  ------------------
  |  Branch (1885:13): [True: 0, False: 0]
  ------------------
 1886|       |        #ifdef WOLFMQTT_MULTITHREAD
 1887|       |            if (wm_SemLock(&client->lockClient) == 0) {
 1888|       |                MqttClient_RespList_Remove(client, &mc_connect->pendResp);
 1889|       |                wm_SemUnlock(&client->lockClient);
 1890|       |            }
 1891|       |        #endif
 1892|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MEMORY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1893|      0|        }
 1894|      0|        prop->type = MQTT_PROP_AUTH_METHOD;
 1895|      0|        prop->data_str.str = conn_prop->data_str.str;
 1896|      0|        prop->data_str.len = conn_prop->data_str.len;
 1897|       |
 1898|       |        /* Send the AUTH packet */
 1899|      0|        rc = MqttClient_Auth(client, p_auth);
 1900|      0|        MqttClient_PropsFree(p_auth->props);
 1901|       |    #ifdef WOLFMQTT_NONBLOCK
 1902|       |        if (rc == MQTT_CODE_CONTINUE)
 1903|       |            return rc;
 1904|       |    #endif
 1905|      0|        if (rc < 0) {
  ------------------
  |  Branch (1905:13): [True: 0, False: 0]
  ------------------
 1906|       |        #ifdef WOLFMQTT_MULTITHREAD
 1907|       |            if (wm_SemLock(&client->lockClient) == 0) {
 1908|       |                MqttClient_RespList_Remove(client, &mc_connect->pendResp);
 1909|       |                wm_SemUnlock(&client->lockClient);
 1910|       |            }
 1911|       |        #endif
 1912|      0|            return rc;
 1913|      0|        }
 1914|      0|        mc_connect->stat.write = MQTT_MSG_WAIT;
 1915|      0|    }
 1916|    872|#endif /* WOLFMQTT_V5 */
 1917|       |
 1918|       |    /* Wait for connect ack packet */
 1919|    872|    rc = MqttClient_WaitType(client, &mc_connect->ack,
 1920|    872|        MQTT_PACKET_TYPE_CONNECT_ACK, 0, client->cmd_timeout_ms);
 1921|       |#if defined(WOLFMQTT_NONBLOCK) || defined(WOLFMQTT_MULTITHREAD)
 1922|       |    if (rc == MQTT_CODE_CONTINUE)
 1923|       |        return rc;
 1924|       |#endif
 1925|       |
 1926|       |#ifdef WOLFMQTT_MULTITHREAD
 1927|       |    if (wm_SemLock(&client->lockClient) == 0) {
 1928|       |        MqttClient_RespList_Remove(client, &mc_connect->pendResp);
 1929|       |        wm_SemUnlock(&client->lockClient);
 1930|       |    }
 1931|       |#endif
 1932|       |
 1933|       |    /* reset state */
 1934|    872|    mc_connect->stat.write = MQTT_MSG_BEGIN;
 1935|       |
 1936|       |    /* CONNACK was received and decoded, but the broker refused the
 1937|       |     * connection. The specific reason is in mc_connect->ack.return_code
 1938|       |     * (MqttConnectAckReturnCodes for v3.1.1, MqttReasonCodes for v5). */
 1939|    872|    if (rc == MQTT_CODE_SUCCESS &&
  ------------------
  |  Branch (1939:9): [True: 0, False: 872]
  ------------------
 1940|      0|            mc_connect->ack.return_code != MQTT_CONNECT_ACK_CODE_ACCEPTED) {
  ------------------
  |  Branch (1940:13): [True: 0, False: 0]
  ------------------
 1941|      0|        rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_CONNECT_REFUSED);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1942|      0|    }
 1943|       |
 1944|    872|    return rc;
 1945|    872|}
MqttClient_Publish:
 2372|    499|{
 2373|       |    return MqttPublishMsg(client, publish, NULL, 0);
 2374|    499|}
MqttClient_Subscribe:
 2392|  2.00k|{
 2393|  2.00k|    int rc, i;
 2394|  2.00k|    MqttTopic* topic;
 2395|       |
 2396|       |    /* Validate required arguments */
 2397|  2.00k|    if (client == NULL || subscribe == NULL) {
  ------------------
  |  Branch (2397:9): [True: 0, False: 2.00k]
  |  Branch (2397:27): [True: 0, False: 2.00k]
  ------------------
 2398|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2399|      0|    }
 2400|       |
 2401|  2.00k|#ifdef WOLFMQTT_V5
 2402|       |    /* Use specified protocol version if set */
 2403|  2.00k|    subscribe->protocol_level = client->protocol_level;
 2404|  2.00k|#endif
 2405|       |
 2406|  2.00k|    if (subscribe->stat.write == MQTT_MSG_BEGIN) {
  ------------------
  |  Branch (2406:9): [True: 2.00k, False: 0]
  ------------------
 2407|       |        /* Flag write active / lock mutex */
 2408|  2.00k|        if ((rc = MqttWriteStart(client, &subscribe->stat)) != 0) {
  ------------------
  |  Branch (2408:13): [True: 0, False: 2.00k]
  ------------------
 2409|      0|            return rc;
 2410|      0|        }
 2411|       |
 2412|       |        /* Encode the subscribe packet */
 2413|  2.00k|        rc = MqttEncode_Subscribe(client->tx_buf, client->tx_buf_len,
 2414|  2.00k|                subscribe);
 2415|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2416|       |        PRINTF("MqttClient_EncodePacket: Len %d, Type %s (%d), ID %d",
 2417|       |            rc, MqttPacket_TypeDesc(MQTT_PACKET_TYPE_SUBSCRIBE),
 2418|       |            MQTT_PACKET_TYPE_SUBSCRIBE, subscribe->packet_id);
 2419|       |    #endif
 2420|  2.00k|        if (rc <= 0) {
  ------------------
  |  Branch (2420:13): [True: 1.51k, False: 487]
  ------------------
 2421|  1.51k|            MqttWriteStop(client, &subscribe->stat);
 2422|  1.51k|            return rc;
 2423|  1.51k|        }
 2424|    487|        client->write.len = rc;
 2425|       |
 2426|       |    #ifdef WOLFMQTT_MULTITHREAD
 2427|       |        rc = wm_SemLock(&client->lockClient);
 2428|       |        if (rc == 0) {
 2429|       |            /* inform other threads of expected response */
 2430|       |            rc = MqttClient_RespList_Add(client, MQTT_PACKET_TYPE_SUBSCRIBE_ACK,
 2431|       |                subscribe->packet_id, &subscribe->pendResp, &subscribe->ack);
 2432|       |            wm_SemUnlock(&client->lockClient);
 2433|       |        }
 2434|       |        if (rc != 0) {
 2435|       |            MqttWriteStop(client, &subscribe->stat);
 2436|       |            return rc; /* Error locking client */
 2437|       |        }
 2438|       |    #endif
 2439|       |
 2440|    487|        subscribe->stat.write = MQTT_MSG_HEADER;
 2441|    487|    }
 2442|    487|    if (subscribe->stat.write == MQTT_MSG_HEADER) {
  ------------------
  |  Branch (2442:9): [True: 487, False: 0]
  ------------------
 2443|    487|        int xfer = client->write.len;
 2444|       |
 2445|       |        /* Send subscribe packet */
 2446|    487|        rc = MqttPacket_Write(client, client->tx_buf, xfer);
 2447|       |    #ifdef WOLFMQTT_NONBLOCK
 2448|       |        if (rc == MQTT_CODE_CONTINUE
 2449|       |        #ifdef WOLFMQTT_ALLOW_NODATA_UNLOCK
 2450|       |            && client->write.total > 0
 2451|       |        #endif
 2452|       |        ) {
 2453|       |            /* keep send locked and return early */
 2454|       |            return rc;
 2455|       |        }
 2456|       |    #endif
 2457|    487|        MqttWriteStop(client, &subscribe->stat);
 2458|    487|        if (rc != xfer) {
  ------------------
  |  Branch (2458:13): [True: 329, False: 158]
  ------------------
 2459|    329|            MqttClient_CancelMessage(client, (MqttObject*)subscribe);
 2460|    329|            return rc;
 2461|    329|        }
 2462|       |
 2463|    158|        subscribe->stat.write = MQTT_MSG_WAIT;
 2464|    158|    }
 2465|       |
 2466|       |    /* Wait for subscribe ack packet */
 2467|    158|    rc = MqttClient_WaitType(client, &subscribe->ack,
 2468|    158|        MQTT_PACKET_TYPE_SUBSCRIBE_ACK, subscribe->packet_id,
 2469|    158|        client->cmd_timeout_ms);
 2470|       |#if defined(WOLFMQTT_NONBLOCK) || defined(WOLFMQTT_MULTITHREAD)
 2471|       |    if (rc == MQTT_CODE_CONTINUE)
 2472|       |        return rc;
 2473|       |#endif
 2474|       |
 2475|       |#ifdef WOLFMQTT_MULTITHREAD
 2476|       |    if (wm_SemLock(&client->lockClient) == 0) {
 2477|       |        MqttClient_RespList_Remove(client, &subscribe->pendResp);
 2478|       |        wm_SemUnlock(&client->lockClient);
 2479|       |    }
 2480|       |#endif
 2481|       |
 2482|       |    /* Populate return codes and detect broker rejection. A v3.1.1 SUBACK
 2483|       |     * uses MQTT_SUBSCRIBE_ACK_CODE_FAILURE (0x80) to indicate failure;
 2484|       |     * a v5 SUBACK uses any reason code >= 0x80. In either case, any
 2485|       |     * per-topic code with the high bit set means the broker rejected
 2486|       |     * that filter. */
 2487|    158|    if (rc == MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (2487:9): [True: 0, False: 158]
  ------------------
 2488|      0|        byte any_rejected = 0;
 2489|      0|        for (i = 0; i < subscribe->topic_count && i < MAX_MQTT_TOPICS; i++) {
  ------------------
  |  |   48|      0|#define MAX_MQTT_TOPICS      12
  ------------------
  |  Branch (2489:21): [True: 0, False: 0]
  |  Branch (2489:51): [True: 0, False: 0]
  ------------------
 2490|      0|            topic = &subscribe->topics[i];
 2491|      0|            topic->return_code = subscribe->ack.return_codes[i];
 2492|      0|            if (topic->return_code & MQTT_SUBSCRIBE_ACK_CODE_FAILURE) {
  ------------------
  |  Branch (2492:17): [True: 0, False: 0]
  ------------------
 2493|      0|                any_rejected = 1;
 2494|      0|            }
 2495|      0|        }
 2496|      0|        if (any_rejected) {
  ------------------
  |  Branch (2496:13): [True: 0, False: 0]
  ------------------
 2497|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_SUBSCRIBE_REJECTED);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2498|      0|        }
 2499|      0|    }
 2500|       |
 2501|       |    /* reset state */
 2502|    158|    subscribe->stat.write = MQTT_MSG_BEGIN;
 2503|       |
 2504|    158|    return rc;
 2505|    487|}
MqttClient_Unsubscribe:
 2508|    445|{
 2509|    445|    int rc;
 2510|       |
 2511|       |    /* Validate required arguments */
 2512|    445|    if (client == NULL || unsubscribe == NULL) {
  ------------------
  |  Branch (2512:9): [True: 0, False: 445]
  |  Branch (2512:27): [True: 0, False: 445]
  ------------------
 2513|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2514|      0|    }
 2515|       |
 2516|    445|#ifdef WOLFMQTT_V5
 2517|       |    /* Use specified protocol version if set */
 2518|    445|    unsubscribe->protocol_level = client->protocol_level;
 2519|    445|#endif
 2520|       |
 2521|    445|    if (unsubscribe->stat.write == MQTT_MSG_BEGIN) {
  ------------------
  |  Branch (2521:9): [True: 445, False: 0]
  ------------------
 2522|       |        /* Flag write active / lock mutex */
 2523|    445|        if ((rc = MqttWriteStart(client, &unsubscribe->stat)) != 0) {
  ------------------
  |  Branch (2523:13): [True: 0, False: 445]
  ------------------
 2524|      0|            return rc;
 2525|      0|        }
 2526|       |
 2527|       |        /* Encode the subscribe packet */
 2528|    445|        rc = MqttEncode_Unsubscribe(client->tx_buf, client->tx_buf_len,
 2529|    445|            unsubscribe);
 2530|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2531|       |        PRINTF("MqttClient_EncodePacket: Len %d, Type %s (%d), ID %d, QoS %d",
 2532|       |            rc, MqttPacket_TypeDesc(MQTT_PACKET_TYPE_UNSUBSCRIBE),
 2533|       |            MQTT_PACKET_TYPE_UNSUBSCRIBE, unsubscribe->packet_id, 0);
 2534|       |    #endif
 2535|    445|        if (rc <= 0) {
  ------------------
  |  Branch (2535:13): [True: 196, False: 249]
  ------------------
 2536|    196|            MqttWriteStop(client, &unsubscribe->stat);
 2537|    196|            return rc;
 2538|    196|        }
 2539|    249|        client->write.len = rc;
 2540|       |
 2541|       |    #ifdef WOLFMQTT_MULTITHREAD
 2542|       |        rc = wm_SemLock(&client->lockClient);
 2543|       |        if (rc == 0) {
 2544|       |            /* inform other threads of expected response */
 2545|       |            rc = MqttClient_RespList_Add(client,
 2546|       |                MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK, unsubscribe->packet_id,
 2547|       |                &unsubscribe->pendResp, &unsubscribe->ack);
 2548|       |            wm_SemUnlock(&client->lockClient);
 2549|       |        }
 2550|       |        if (rc != 0) {
 2551|       |            MqttWriteStop(client, &unsubscribe->stat);
 2552|       |            return rc;
 2553|       |        }
 2554|       |    #endif
 2555|       |
 2556|    249|        unsubscribe->stat.write = MQTT_MSG_HEADER;
 2557|    249|    }
 2558|    249|    if (unsubscribe->stat.write == MQTT_MSG_HEADER) {
  ------------------
  |  Branch (2558:9): [True: 249, False: 0]
  ------------------
 2559|    249|        int xfer = client->write.len;
 2560|       |
 2561|       |        /* Send unsubscribe packet */
 2562|    249|        rc = MqttPacket_Write(client, client->tx_buf, xfer);
 2563|       |    #ifdef WOLFMQTT_NONBLOCK
 2564|       |        if (rc == MQTT_CODE_CONTINUE
 2565|       |        #ifdef WOLFMQTT_ALLOW_NODATA_UNLOCK
 2566|       |            && client->write.total > 0
 2567|       |        #endif
 2568|       |        ) {
 2569|       |            /* keep send locked and return early */
 2570|       |            return rc;
 2571|       |        }
 2572|       |    #endif
 2573|    249|        MqttWriteStop(client, &unsubscribe->stat);
 2574|    249|        if (rc != xfer) {
  ------------------
  |  Branch (2574:13): [True: 184, False: 65]
  ------------------
 2575|    184|            MqttClient_CancelMessage(client, (MqttObject*)unsubscribe);
 2576|    184|            return rc;
 2577|    184|        }
 2578|       |
 2579|     65|        unsubscribe->stat.write = MQTT_MSG_WAIT;
 2580|     65|    }
 2581|       |
 2582|       |    /* Wait for unsubscribe ack packet */
 2583|     65|    rc = MqttClient_WaitType(client, &unsubscribe->ack,
 2584|     65|        MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK, unsubscribe->packet_id,
 2585|     65|        client->cmd_timeout_ms);
 2586|       |#if defined(WOLFMQTT_NONBLOCK) || defined(WOLFMQTT_MULTITHREAD)
 2587|       |    if (rc == MQTT_CODE_CONTINUE)
 2588|       |        return rc;
 2589|       |#endif
 2590|       |
 2591|       |#ifdef WOLFMQTT_MULTITHREAD
 2592|       |    if (wm_SemLock(&client->lockClient) == 0) {
 2593|       |        MqttClient_RespList_Remove(client, &unsubscribe->pendResp);
 2594|       |        wm_SemUnlock(&client->lockClient);
 2595|       |    }
 2596|       |#endif
 2597|       |
 2598|     65|#ifdef WOLFMQTT_V5
 2599|     65|    if (unsubscribe->ack.props != NULL) {
  ------------------
  |  Branch (2599:9): [True: 0, False: 65]
  ------------------
 2600|       |        /* Release the allocated properties */
 2601|      0|        MqttClient_PropsFree(unsubscribe->ack.props);
 2602|      0|    }
 2603|     65|#endif
 2604|       |
 2605|       |    /* reset state */
 2606|     65|    unsubscribe->stat.write = MQTT_MSG_BEGIN;
 2607|       |
 2608|     65|    return rc;
 2609|    249|}
MqttClient_Ping_ex:
 2612|    910|{
 2613|    910|    int rc;
 2614|       |
 2615|       |    /* Validate required arguments */
 2616|    910|    if (client == NULL || ping == NULL) {
  ------------------
  |  Branch (2616:9): [True: 0, False: 910]
  |  Branch (2616:27): [True: 0, False: 910]
  ------------------
 2617|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2618|      0|    }
 2619|       |
 2620|    910|    if (ping->stat.write == MQTT_MSG_BEGIN) {
  ------------------
  |  Branch (2620:9): [True: 910, False: 0]
  ------------------
 2621|       |        /* Flag write active / lock mutex */
 2622|    910|        if ((rc = MqttWriteStart(client, &ping->stat)) != 0) {
  ------------------
  |  Branch (2622:13): [True: 0, False: 910]
  ------------------
 2623|      0|            return rc;
 2624|      0|        }
 2625|       |
 2626|       |        /* Encode the subscribe packet */
 2627|    910|        rc = MqttEncode_Ping(client->tx_buf, client->tx_buf_len, ping);
 2628|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2629|       |        PRINTF("MqttClient_EncodePacket: Len %d, Type %s (%d), ID %d, QoS %d",
 2630|       |            rc, MqttPacket_TypeDesc(MQTT_PACKET_TYPE_PING_REQ),
 2631|       |            MQTT_PACKET_TYPE_PING_REQ, 0, 0);
 2632|       |    #endif
 2633|    910|        if (rc <= 0) {
  ------------------
  |  Branch (2633:13): [True: 0, False: 910]
  ------------------
 2634|      0|            MqttWriteStop(client, &ping->stat);
 2635|      0|            return rc;
 2636|      0|        }
 2637|    910|        client->write.len = rc;
 2638|       |
 2639|       |    #ifdef WOLFMQTT_MULTITHREAD
 2640|       |        rc = wm_SemLock(&client->lockClient);
 2641|       |        if (rc == 0) {
 2642|       |            /* inform other threads of expected response */
 2643|       |            rc = MqttClient_RespList_Add(client, MQTT_PACKET_TYPE_PING_RESP, 0,
 2644|       |                &ping->pendResp, ping);
 2645|       |            wm_SemUnlock(&client->lockClient);
 2646|       |        }
 2647|       |        if (rc != 0) {
 2648|       |            MqttWriteStop(client, &ping->stat);
 2649|       |            return rc; /* Error locking client */
 2650|       |        }
 2651|       |    #endif
 2652|       |
 2653|    910|        ping->stat.write = MQTT_MSG_HEADER;
 2654|    910|    }
 2655|    910|    if (ping->stat.write == MQTT_MSG_HEADER) {
  ------------------
  |  Branch (2655:9): [True: 910, False: 0]
  ------------------
 2656|    910|        int xfer = client->write.len;
 2657|       |
 2658|       |        /* Send ping req packet */
 2659|    910|        rc = MqttPacket_Write(client, client->tx_buf, xfer);
 2660|       |    #ifdef WOLFMQTT_NONBLOCK
 2661|       |        if (rc == MQTT_CODE_CONTINUE
 2662|       |        #ifdef WOLFMQTT_ALLOW_NODATA_UNLOCK
 2663|       |            && client->write.total > 0
 2664|       |        #endif
 2665|       |        ) {
 2666|       |            /* keep send locked and return early */
 2667|       |            return rc;
 2668|       |        }
 2669|       |    #endif
 2670|    910|        MqttWriteStop(client, &ping->stat);
 2671|    910|        if (rc != xfer) {
  ------------------
  |  Branch (2671:13): [True: 153, False: 757]
  ------------------
 2672|    153|            MqttClient_CancelMessage(client, (MqttObject*)ping);
 2673|    153|            return rc;
 2674|    153|        }
 2675|       |
 2676|    757|        ping->stat.write = MQTT_MSG_WAIT;
 2677|    757|    }
 2678|       |
 2679|       |    /* Wait for ping resp packet */
 2680|    757|    rc = MqttClient_WaitType(client, ping, MQTT_PACKET_TYPE_PING_RESP, 0,
 2681|    757|        client->cmd_timeout_ms);
 2682|       |#if defined(WOLFMQTT_NONBLOCK) || defined(WOLFMQTT_MULTITHREAD)
 2683|       |    if (rc == MQTT_CODE_CONTINUE)
 2684|       |        return rc;
 2685|       |#endif
 2686|       |
 2687|       |#ifdef WOLFMQTT_MULTITHREAD
 2688|       |    if (wm_SemLock(&client->lockClient) == 0) {
 2689|       |        MqttClient_RespList_Remove(client, &ping->pendResp);
 2690|       |        wm_SemUnlock(&client->lockClient);
 2691|       |    }
 2692|       |#endif
 2693|       |
 2694|       |    /* reset state */
 2695|    757|    ping->stat.write = MQTT_MSG_BEGIN;
 2696|       |
 2697|    757|    return rc;
 2698|    910|}
MqttClient_WaitMessage_ex:
 2915|  2.66k|{
 2916|  2.66k|    return MqttClient_WaitType(client, msg, MQTT_PACKET_TYPE_ANY, 0,
 2917|  2.66k|        timeout_ms);
 2918|  2.66k|}
MqttClient_WaitMessage:
 2920|  2.66k|{
 2921|  2.66k|    if (client == NULL)
  ------------------
  |  Branch (2921:9): [True: 0, False: 2.66k]
  ------------------
 2922|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2923|  2.66k|    return MqttClient_WaitMessage_ex(client, &client->msg, timeout_ms);
 2924|  2.66k|}
MqttClient_NetConnect:
 3047|  2.64k|{
 3048|  2.64k|    return MqttSocket_Connect(client, host, port, timeout_ms, use_tls, cb);
 3049|  2.64k|}
MqttClient_NetDisconnect:
 3052|    226|{
 3053|       |#ifdef WOLFMQTT_MULTITHREAD
 3054|       |    MqttPendResp *tmpResp;
 3055|       |    MqttPendResp *nextResp;
 3056|       |    int rc;
 3057|       |#endif
 3058|       |
 3059|    226|    if (client == NULL) {
  ------------------
  |  Branch (3059:9): [True: 0, False: 226]
  ------------------
 3060|      0|        return MQTT_CODE_ERROR_BAD_ARG;
 3061|      0|    }
 3062|       |
 3063|       |#ifdef WOLFMQTT_MULTITHREAD
 3064|       |    /* Get client lock on to ensure no other threads are active */
 3065|       |    rc = wm_SemLock(&client->lockClient);
 3066|       |    if (rc == 0) {
 3067|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 3068|       |        PRINTF("Net Disconnect: Removing pending responses");
 3069|       |    #endif
 3070|       |        for (tmpResp = client->firstPendResp;
 3071|       |             tmpResp != NULL;
 3072|       |             tmpResp = nextResp) {
 3073|       |            nextResp = tmpResp->next;
 3074|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 3075|       |            PRINTF("\tPendResp: %p (obj %p), Type %s (%d), ID %d, InProc %d, Done %d",
 3076|       |                tmpResp, tmpResp->packet_obj,
 3077|       |                MqttPacket_TypeDesc(tmpResp->packet_type),
 3078|       |                tmpResp->packet_type, tmpResp->packet_id,
 3079|       |                tmpResp->packetProcessing, tmpResp->packetDone);
 3080|       |        #endif
 3081|       |            MqttClient_RespList_Remove(client, tmpResp);
 3082|       |        }
 3083|       |        wm_SemUnlock(&client->lockClient);
 3084|       |    }
 3085|       |    else {
 3086|       |        return rc;
 3087|       |    }
 3088|       |#endif
 3089|       |
 3090|    226|    return MqttSocket_Disconnect(client);
 3091|    226|}
MqttClient_Flags:
 3250|  21.6k|{
 3251|  21.6k|    word32 ret = 0;
 3252|  21.6k|    if (client != NULL) {
  ------------------
  |  Branch (3252:9): [True: 21.6k, False: 0]
  ------------------
 3253|       |#ifdef WOLFMQTT_MULTITHREAD
 3254|       |        /* Get client lock on to ensure no other threads are active */
 3255|       |        if (wm_SemLock(&client->lockClient) == 0)
 3256|       |#endif
 3257|  21.6k|        {
 3258|  21.6k|            client->flags &= ~mask;
 3259|  21.6k|            client->flags |= flags;
 3260|  21.6k|            ret = client->flags;
 3261|       |#ifdef WOLFMQTT_MULTITHREAD
 3262|       |            wm_SemUnlock(&client->lockClient);
 3263|       |#endif
 3264|  21.6k|        }
 3265|  21.6k|    }
 3266|  21.6k|    return ret;
 3267|  21.6k|}
mqtt_client.c:MqttWriteStart:
  235|  6.50k|{
  236|  6.50k|    int rc = MQTT_CODE_SUCCESS;
  237|       |
  238|  6.50k|#if defined(WOLFMQTT_DEBUG_CLIENT) || !defined(WOLFMQTT_ALLOW_NODATA_UNLOCK)
  239|       |  #ifdef WOLFMQTT_DEBUG_CLIENT
  240|       |    if (stat->isWriteActive) {
  241|       |        MQTT_TRACE_MSG("Warning, send already locked!");
  242|       |        rc = MQTT_CODE_ERROR_SYSTEM;
  243|       |    }
  244|       |  #endif
  245|  6.50k|  #ifndef WOLFMQTT_ALLOW_NODATA_UNLOCK
  246|       |    /* detect if a write is already in progress */
  247|       |    #ifdef WOLFMQTT_MULTITHREAD
  248|       |    if (wm_SemLock(&client->lockClient) == 0)
  249|       |    #endif
  250|  6.50k|    {
  251|  6.50k|        if (client->write.isActive) {
  ------------------
  |  Branch (251:13): [True: 0, False: 6.50k]
  ------------------
  252|      0|            MQTT_TRACE_MSG("Partial write in progress!");
  253|      0|            rc = MQTT_CODE_CONTINUE; /* can't write yet */
  254|      0|        }
  255|       |    #ifdef WOLFMQTT_MULTITHREAD
  256|       |        wm_SemUnlock(&client->lockClient);
  257|       |    #endif
  258|  6.50k|    }
  259|  6.50k|  #endif /* WOLFMQTT_ALLOW_NODATA_UNLOCK */
  260|  6.50k|    if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (260:9): [True: 0, False: 6.50k]
  ------------------
  261|      0|        return rc;
  262|      0|    }
  263|  6.50k|#endif
  264|       |
  265|       |#ifdef WOLFMQTT_MULTITHREAD
  266|       |    rc = wm_SemLock(&client->lockSend);
  267|       |#endif
  268|  6.50k|    if (rc == MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (268:9): [True: 6.50k, False: 0]
  ------------------
  269|  6.50k|        stat->isWriteActive = 1;
  270|       |
  271|       |    #ifdef WOLFMQTT_MULTITHREAD
  272|       |        if (wm_SemLock(&client->lockClient) == 0)
  273|       |    #endif
  274|  6.50k|        {
  275|  6.50k|            client->write.isActive = 1;
  276|       |        #ifdef WOLFMQTT_MULTITHREAD
  277|       |            wm_SemUnlock(&client->lockClient);
  278|       |        #endif
  279|  6.50k|        }
  280|       |
  281|  6.50k|        MQTT_TRACE_MSG("lockSend");
  282|  6.50k|    }
  283|       |
  284|  6.50k|    return rc;
  285|  6.50k|}
mqtt_client.c:MqttClient_ForceZero:
   32|  2.64k|{
   33|  2.64k|    volatile byte* p = (volatile byte*)mem;
   34|  2.64k|    word32 i;
   35|   184k|    for (i = 0; i < len; i++) {
  ------------------
  |  Branch (35:17): [True: 181k, False: 2.64k]
  ------------------
   36|   181k|        p[i] = 0;
   37|   181k|    }
   38|  2.64k|}
mqtt_client.c:MqttWriteStop:
  287|  6.50k|{
  288|       |#ifdef WOLFMQTT_DEBUG_CLIENT
  289|       |    if (!stat->isWriteActive) {
  290|       |        MQTT_TRACE_MSG("Warning, send not locked!");
  291|       |        return;
  292|       |    }
  293|       |#endif
  294|       |
  295|       |#ifdef WOLFMQTT_MULTITHREAD
  296|       |    if (wm_SemLock(&client->lockClient) == 0)
  297|       |#endif
  298|  6.50k|    {
  299|       |        /* reset write */
  300|  6.50k|        XMEMSET(&client->write, 0, sizeof(client->write));
  ------------------
  |  |  988|  6.50k|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  301|       |    #ifdef WOLFMQTT_MULTITHREAD
  302|       |        wm_SemUnlock(&client->lockClient);
  303|       |    #endif
  304|  6.50k|    }
  305|       |
  306|  6.50k|    if (stat->isWriteActive) {
  ------------------
  |  Branch (306:9): [True: 6.50k, False: 0]
  ------------------
  307|  6.50k|        MQTT_TRACE_MSG("unlockSend");
  308|  6.50k|        stat->isWriteActive = 0;
  309|       |    #ifdef WOLFMQTT_MULTITHREAD
  310|       |        wm_SemUnlock(&client->lockSend);
  311|       |    #endif
  312|  6.50k|    }
  313|  6.50k|}
mqtt_client.c:MqttClient_WaitType:
 1218|  4.51k|{
 1219|  4.51k|    int rc = MQTT_CODE_SUCCESS;
 1220|  4.51k|    word16         packet_id;
 1221|  4.51k|    MqttPacketType packet_type;
 1222|  4.51k|    MqttQoS        packet_qos = MQTT_QOS_0;
 1223|       |#ifdef WOLFMQTT_MULTITHREAD
 1224|       |    MqttPendResp *pendResp;
 1225|       |#endif
 1226|  4.51k|    MqttMsgStat* mms_stat;
 1227|  4.51k|    int waitMatchFound;
 1228|  4.51k|    void* use_packet_obj = NULL;
 1229|       |
 1230|  4.51k|    if (client == NULL || packet_obj == NULL) {
  ------------------
  |  Branch (1230:9): [True: 0, False: 4.51k]
  |  Branch (1230:27): [True: 0, False: 4.51k]
  ------------------
 1231|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1232|      0|    }
 1233|       |
 1234|       |    /* all packet type structures must have MqttMsgStat at top */
 1235|  4.51k|    mms_stat = (MqttMsgStat*)packet_obj;
 1236|       |
 1237|  5.14k|wait_again:
 1238|       |
 1239|       |    /* initialize variables */
 1240|  5.14k|    packet_id = 0;
 1241|  5.14k|    packet_type = MQTT_PACKET_TYPE_RESERVED;
 1242|       |#ifdef WOLFMQTT_MULTITHREAD
 1243|       |    pendResp = NULL;
 1244|       |#endif
 1245|  5.14k|    waitMatchFound = 0;
 1246|       |
 1247|       |#ifdef WOLFMQTT_DEBUG_CLIENT
 1248|       |    #ifdef WOLFMQTT_NONBLOCK
 1249|       |    if (client->lastRc != MQTT_CODE_CONTINUE)
 1250|       |    #endif
 1251|       |    {
 1252|       |        PRINTF("MqttClient_WaitType: Type %s (%d), ID %d, State %d-%d",
 1253|       |            MqttPacket_TypeDesc((MqttPacketType)wait_type),
 1254|       |                wait_type, wait_packet_id, mms_stat->read, mms_stat->write);
 1255|       |    }
 1256|       |#endif
 1257|       |
 1258|  5.14k|    switch (mms_stat->read)
 1259|  5.14k|    {
 1260|  3.49k|        case MQTT_MSG_BEGIN:
  ------------------
  |  Branch (1260:9): [True: 3.49k, False: 1.65k]
  ------------------
 1261|  3.49k|        {
 1262|       |        #ifdef WOLFMQTT_MULTITHREAD
 1263|       |            /* Check to see if packet type and id have already completed */
 1264|       |            rc = MqttClient_CheckPendResp(client, wait_type, wait_packet_id);
 1265|       |            if (rc != MQTT_CODE_ERROR_NOT_FOUND && rc != MQTT_CODE_CONTINUE) {
 1266|       |                return rc;
 1267|       |            }
 1268|       |        #endif
 1269|       |
 1270|  3.49k|            if ((rc = MqttReadStart(client, mms_stat)) != 0) {
  ------------------
  |  Branch (1270:17): [True: 0, False: 3.49k]
  ------------------
 1271|      0|                return rc;
 1272|      0|            }
 1273|       |
 1274|  3.49k|            mms_stat->read = MQTT_MSG_WAIT;
 1275|  3.49k|        }
 1276|  3.49k|        FALL_THROUGH;
  ------------------
  |  |  472|  3.49k|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 1277|       |
 1278|  3.49k|        case MQTT_MSG_WAIT:
  ------------------
  |  Branch (1278:9): [True: 0, False: 5.14k]
  ------------------
 1279|  5.12k|        case MQTT_MSG_HEADER:
  ------------------
  |  Branch (1279:9): [True: 1.62k, False: 3.52k]
  ------------------
 1280|  5.12k|        {
 1281|       |            /* Wait for packet */
 1282|  5.12k|            rc = MqttPacket_Read(client, client->rx_buf, client->rx_buf_len,
 1283|  5.12k|                    timeout_ms);
 1284|       |            /* handle failure */
 1285|  5.12k|            if (rc <= 0) {
  ------------------
  |  Branch (1285:17): [True: 3.07k, False: 2.05k]
  ------------------
 1286|       |            #ifdef WOLFMQTT_NONBLOCK
 1287|       |                if (rc == MQTT_CODE_CONTINUE &&
 1288|       |                    (client->packet.stat > MQTT_PK_BEGIN ||
 1289|       |                     client->read.total > 0)
 1290|       |                ) {
 1291|       |                    /* advance state, since we received some data */
 1292|       |                    mms_stat->read = MQTT_MSG_HEADER;
 1293|       |                }
 1294|       |            #endif
 1295|  3.07k|                break;
 1296|  3.07k|            }
 1297|       |
 1298|       |            /* advance state, since we received some data */
 1299|  2.05k|            mms_stat->read = MQTT_MSG_HEADER;
 1300|       |
 1301|       |            /* capture length read */
 1302|  2.05k|            client->packet.buf_len = rc;
 1303|       |
 1304|       |            /* Decode Packet - get type, qos and id */
 1305|  2.05k|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1306|  2.05k|                client->packet.buf_len, NULL, &packet_type, &packet_qos,
 1307|  2.05k|                &packet_id, 1);
 1308|  2.05k|            if (rc < 0) {
  ------------------
  |  Branch (1308:17): [True: 2.03k, False: 17]
  ------------------
 1309|  2.03k|                break;
 1310|  2.03k|            }
 1311|       |
 1312|     17|            MqttClient_PacketReset(packet_type, &client->msg);
 1313|       |
 1314|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 1315|       |            PRINTF("Read Packet: Len %d, Type %d, ID %d",
 1316|       |                client->packet.buf_len, packet_type, packet_id);
 1317|       |        #endif
 1318|       |
 1319|       |            /* Ping response is special case, no payload */
 1320|     17|            if (packet_type != MQTT_PACKET_TYPE_PING_RESP) {
  ------------------
  |  Branch (1320:17): [True: 17, False: 0]
  ------------------
 1321|     17|                mms_stat->read = MQTT_MSG_PAYLOAD;
 1322|     17|            }
 1323|      0|            else {
 1324|      0|                mms_stat->read = MQTT_MSG_WAIT;
 1325|      0|            }
 1326|     17|        }
 1327|     17|        FALL_THROUGH;
  ------------------
  |  |  472|     17|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 1328|       |
 1329|     40|        case MQTT_MSG_PAYLOAD:
  ------------------
  |  Branch (1329:9): [True: 23, False: 5.12k]
  ------------------
 1330|     40|        case MQTT_MSG_PAYLOAD2:
  ------------------
  |  Branch (1330:9): [True: 0, False: 5.14k]
  ------------------
 1331|     40|        {
 1332|     40|            MqttPublishResp resp;
 1333|     40|            MqttPacketType use_packet_type;
 1334|       |
 1335|       |            /* Determine if we received data for this request */
 1336|     40|            if ((wait_type == MQTT_PACKET_TYPE_ANY ||
  ------------------
  |  Branch (1336:18): [True: 36, False: 4]
  ------------------
 1337|      4|                 wait_type == packet_type ||
  ------------------
  |  Branch (1337:18): [True: 0, False: 4]
  ------------------
 1338|      4|                 (MqttIsPubRespPacket(packet_type) &&
  ------------------
  |  Branch (1338:19): [True: 0, False: 4]
  ------------------
 1339|      0|                  MqttIsPubRespPacket(wait_type))) &&
  ------------------
  |  Branch (1339:19): [True: 0, False: 0]
  ------------------
 1340|     36|                (wait_packet_id == 0 || wait_packet_id == packet_id))
  ------------------
  |  Branch (1340:18): [True: 36, False: 0]
  |  Branch (1340:41): [True: 0, False: 0]
  ------------------
 1341|     36|            {
 1342|     36|                use_packet_obj = packet_obj;
 1343|       |            #ifdef WOLFMQTT_DEBUG_CLIENT
 1344|       |                PRINTF("Using INCOMING packet_obj %p", use_packet_obj);
 1345|       |            #endif
 1346|     36|                if (packet_type == wait_type ||
  ------------------
  |  Branch (1346:21): [True: 0, False: 36]
  ------------------
 1347|     36|                        wait_type == MQTT_PACKET_TYPE_ANY) {
  ------------------
  |  Branch (1347:25): [True: 36, False: 0]
  ------------------
 1348|       |                    /* Only stop waiting when matched or waiting for "any" */
 1349|     36|                    waitMatchFound = 1;
 1350|     36|                }
 1351|     36|            }
 1352|      4|            else {
 1353|       |            #ifdef WOLFMQTT_MULTITHREAD
 1354|       |                rc = wm_SemLock(&client->lockClient);
 1355|       |                if (rc != 0) {
 1356|       |                    break; /* error */
 1357|       |                }
 1358|       |            #endif
 1359|       |
 1360|       |                /* use generic packet object */
 1361|      4|                use_packet_obj = &client->msg;
 1362|       |            #ifdef WOLFMQTT_DEBUG_CLIENT
 1363|       |                PRINTF("Using SHARED packet_obj %p", use_packet_obj);
 1364|       |            #endif
 1365|       |
 1366|       |            #ifdef WOLFMQTT_MULTITHREAD
 1367|       |                wm_SemUnlock(&client->lockClient);
 1368|       |            #endif
 1369|      4|            }
 1370|     40|            use_packet_type = packet_type;
 1371|       |
 1372|       |        #ifdef WOLFMQTT_MULTITHREAD
 1373|       |            /* Check to see if we have a pending response for this packet */
 1374|       |            pendResp = NULL;
 1375|       |            rc = wm_SemLock(&client->lockClient);
 1376|       |            if (rc == 0) {
 1377|       |                if (MqttClient_RespList_Find(client, packet_type, packet_id,
 1378|       |                                                               &pendResp)) {
 1379|       |                    /* we found packet match this incoming read packet */
 1380|       |                    pendResp->packetProcessing = 1;
 1381|       |                    if (pendResp->packet_obj != packet_obj) {
 1382|       |                        use_packet_obj = pendResp->packet_obj;
 1383|       |                        use_packet_type = pendResp->packet_type;
 1384|       |                        /* req from another thread... not a match */
 1385|       |                        waitMatchFound = 0;
 1386|       |                    }
 1387|       |                }
 1388|       |                wm_SemUnlock(&client->lockClient);
 1389|       |            }
 1390|       |            else {
 1391|       |                break; /* error */
 1392|       |            }
 1393|       |        #endif /* WOLFMQTT_MULTITHREAD */
 1394|       |
 1395|       |            /* for payload state packet type is always publish */
 1396|     40|            if (use_packet_type == MQTT_PACKET_TYPE_RESERVED &&
  ------------------
  |  Branch (1396:17): [True: 23, False: 17]
  ------------------
 1397|     23|                    (mms_stat->read == MQTT_MSG_PAYLOAD ||
  ------------------
  |  Branch (1397:22): [True: 23, False: 0]
  ------------------
 1398|      0|                     mms_stat->read == MQTT_MSG_PAYLOAD2))
  ------------------
  |  Branch (1398:22): [True: 0, False: 0]
  ------------------
 1399|     23|            {
 1400|     23|                use_packet_type = MQTT_PACKET_TYPE_PUBLISH;
 1401|     23|            }
 1402|       |            /* cache publish packet id and qos for MqttClient_HandlePacket payload */
 1403|     40|            if (use_packet_type == MQTT_PACKET_TYPE_PUBLISH &&
  ------------------
  |  Branch (1403:17): [True: 23, False: 17]
  ------------------
 1404|     23|                  mms_stat->read == MQTT_MSG_PAYLOAD && use_packet_obj != NULL)
  ------------------
  |  Branch (1404:19): [True: 23, False: 0]
  |  Branch (1404:57): [True: 23, False: 0]
  ------------------
 1405|     23|            {
 1406|     23|                MqttObject* obj = (MqttObject*)use_packet_obj;
 1407|     23|                obj->publish.qos = packet_qos;
 1408|     23|                obj->publish.packet_id = packet_id;
 1409|     23|            }
 1410|       |
 1411|       |            /* Perform packet handling for publish callback and QoS */
 1412|     40|            XMEMSET(&resp, 0, sizeof(resp));
  ------------------
  |  |  988|     40|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
 1413|     40|            rc = MqttClient_HandlePacket(client, use_packet_type,
 1414|     40|                use_packet_obj, &resp, timeout_ms);
 1415|       |
 1416|       |            /* if using the shared packet object, make sure the original
 1417|       |             * state is correct for publish payload 2 (continued) */
 1418|     40|            if (use_packet_obj != NULL && use_packet_obj != mms_stat &&
  ------------------
  |  Branch (1418:17): [True: 40, False: 0]
  |  Branch (1418:43): [True: 4, False: 36]
  ------------------
 1419|      4|                    ((MqttMsgStat*)use_packet_obj)->read == MQTT_MSG_PAYLOAD2) {
  ------------------
  |  Branch (1419:21): [True: 0, False: 4]
  ------------------
 1420|      0|                mms_stat->read = MQTT_MSG_PAYLOAD2;
 1421|      0|            }
 1422|       |
 1423|       |        #ifdef WOLFMQTT_NONBLOCK
 1424|       |            if (rc == MQTT_CODE_CONTINUE) {
 1425|       |                break;
 1426|       |            }
 1427|       |        #endif
 1428|       |
 1429|       |            /* handle success case */
 1430|     40|            if (rc >= 0) {
  ------------------
  |  Branch (1430:17): [True: 23, False: 17]
  ------------------
 1431|     23|                rc = MQTT_CODE_SUCCESS;
 1432|     23|            }
 1433|     17|            else {
 1434|       |                /* error, break */
 1435|     17|                break;
 1436|     17|            }
 1437|       |
 1438|       |        #ifdef WOLFMQTT_MULTITHREAD
 1439|       |            if (pendResp) {
 1440|       |                /* Mark pending response entry done */
 1441|       |                if (wm_SemLock(&client->lockClient) == 0) {
 1442|       |                    pendResp->packetDone = 1;
 1443|       |                    pendResp->packet_ret = rc;
 1444|       |                #ifdef WOLFMQTT_DEBUG_CLIENT
 1445|       |                    PRINTF("PendResp Done %p", pendResp);
 1446|       |                #endif
 1447|       |                    pendResp = NULL;
 1448|       |                    wm_SemUnlock(&client->lockClient);
 1449|       |                }
 1450|       |            }
 1451|       |        #endif /* WOLFMQTT_MULTITHREAD */
 1452|       |
 1453|       |            /* Determine if we are sending ACK or done */
 1454|     23|            if (MqttIsPubRespPacket(resp.packet_type)) {
  ------------------
  |  Branch (1454:17): [True: 4, False: 19]
  ------------------
 1455|       |                /* if we get here, then we are sending an ACK */
 1456|      4|                mms_stat->read = MQTT_MSG_ACK;
 1457|      4|                mms_stat->ack = MQTT_MSG_WAIT;
 1458|       |
 1459|       |                /* setup ACK in shared context */
 1460|      4|                XMEMCPY(&client->packetAck, &resp, sizeof(MqttPublishResp));
  ------------------
  |  |  987|      4|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 1461|      4|            #ifdef WOLFMQTT_V5
 1462|      4|                client->packetAck.protocol_level = client->protocol_level;
 1463|      4|            #endif
 1464|      4|            }
 1465|       |
 1466|       |            /* done reading */
 1467|     23|            MqttReadStop(client, mms_stat);
 1468|     23|            break;
 1469|     40|        }
 1470|       |
 1471|      3|        case MQTT_MSG_ACK:
  ------------------
  |  Branch (1471:9): [True: 3, False: 5.14k]
  ------------------
 1472|       |            /* go to write section below */
 1473|      3|            break;
 1474|       |
 1475|      0|        case MQTT_MSG_AUTH:
  ------------------
  |  Branch (1475:9): [True: 0, False: 5.14k]
  ------------------
 1476|      0|        default:
  ------------------
  |  Branch (1476:9): [True: 0, False: 5.14k]
  ------------------
 1477|      0|        {
 1478|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 1479|       |            PRINTF("MqttClient_WaitType: Invalid read state %d!",
 1480|       |                mms_stat->read);
 1481|       |        #endif
 1482|      0|            rc = MQTT_CODE_ERROR_STAT;
 1483|      0|            break;
 1484|      0|        }
 1485|  5.14k|    } /* switch (mms_stat->read) */
 1486|       |
 1487|  5.14k|    switch (mms_stat->ack)
 1488|  5.14k|    {
 1489|  5.14k|        case MQTT_MSG_BEGIN:
  ------------------
  |  Branch (1489:9): [True: 5.14k, False: 4]
  ------------------
 1490|       |            /* wait for read to set ack */
 1491|  5.14k|            break;
 1492|       |
 1493|      4|        case MQTT_MSG_WAIT:
  ------------------
  |  Branch (1493:9): [True: 4, False: 5.14k]
  ------------------
 1494|      4|        {
 1495|       |            /* Flag write active / lock mutex */
 1496|      4|            if ((rc = MqttWriteStart(client, mms_stat)) != 0) {
  ------------------
  |  Branch (1496:17): [True: 0, False: 4]
  ------------------
 1497|      0|                break;
 1498|      0|            }
 1499|      4|            mms_stat->ack = MQTT_MSG_ACK;
 1500|      4|        }
 1501|      4|        FALL_THROUGH;
  ------------------
  |  |  472|      4|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 1502|       |
 1503|      4|        case MQTT_MSG_ACK:
  ------------------
  |  Branch (1503:9): [True: 0, False: 5.14k]
  ------------------
 1504|      4|        {
 1505|       |            /* send ack */
 1506|      4|            rc = MqttEncode_PublishResp(client->tx_buf, client->tx_buf_len,
 1507|      4|                client->packetAck.packet_type, &client->packetAck);
 1508|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 1509|       |            PRINTF("MqttEncode_PublishResp: Len %d, Type %s (%d), ID %d",
 1510|       |                rc, MqttPacket_TypeDesc(client->packetAck.packet_type),
 1511|       |                    client->packetAck.packet_type, client->packetAck.packet_id);
 1512|       |        #endif
 1513|      4|            if (rc < 0) {
  ------------------
  |  Branch (1513:17): [True: 0, False: 4]
  ------------------
 1514|      0|                MqttWriteStop(client, mms_stat);
 1515|      0|                break;
 1516|      0|            }
 1517|       |
 1518|      4|            client->write.len = rc;
 1519|       |            /* Note: static analyzer complains about set, but not used here.
 1520|       |             * Keeping it to ensure no future issues with rc > 0 */
 1521|      4|            rc = MQTT_CODE_SUCCESS;
 1522|      4|            (void)rc; /* inhibit clang-analyzer-deadcode.DeadStores */
 1523|       |
 1524|      4|            mms_stat->ack = MQTT_MSG_HEADER;
 1525|      4|        }
 1526|      4|        FALL_THROUGH;
  ------------------
  |  |  472|      4|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 1527|       |
 1528|      4|        case MQTT_MSG_HEADER:
  ------------------
  |  Branch (1528:9): [True: 0, False: 5.14k]
  ------------------
 1529|      4|        {
 1530|      4|            int xfer = client->write.len;
 1531|       |
 1532|       |            /* Send publish response packet */
 1533|      4|            rc = MqttPacket_Write(client, client->tx_buf, xfer);
 1534|       |        #ifdef WOLFMQTT_NONBLOCK
 1535|       |            if (rc == MQTT_CODE_CONTINUE) {
 1536|       |                /* keep send mutex locked and return to caller */
 1537|       |                /* must keep send locked */
 1538|       |                return rc;
 1539|       |            }
 1540|       |        #endif
 1541|      4|            MqttWriteStop(client, mms_stat);
 1542|      4|            if (rc == xfer) {
  ------------------
  |  Branch (1542:17): [True: 0, False: 4]
  ------------------
 1543|      0|                rc = MQTT_CODE_SUCCESS; /* success */
 1544|      0|            }
 1545|       |
 1546|      4|            mms_stat->ack = MQTT_MSG_BEGIN; /* reset write state */
 1547|      4|            break;
 1548|      4|        }
 1549|       |
 1550|      0|        case MQTT_MSG_AUTH:
  ------------------
  |  Branch (1550:9): [True: 0, False: 5.14k]
  ------------------
 1551|      0|        case MQTT_MSG_PAYLOAD:
  ------------------
  |  Branch (1551:9): [True: 0, False: 5.14k]
  ------------------
 1552|      0|        case MQTT_MSG_PAYLOAD2:
  ------------------
  |  Branch (1552:9): [True: 0, False: 5.14k]
  ------------------
 1553|      0|        default:
  ------------------
  |  Branch (1553:9): [True: 0, False: 5.14k]
  ------------------
 1554|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 1555|       |            PRINTF("MqttClient_WaitType: Invalid ack state %d!",
 1556|       |                mms_stat->ack);
 1557|       |        #endif
 1558|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_STAT);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1559|      0|            break;
 1560|  5.14k|    } /* switch (mms_stat->ack) */
 1561|       |
 1562|       |    /* no data read or ack done, then reset state */
 1563|  5.14k|    if (mms_stat->read == MQTT_MSG_WAIT) {
  ------------------
  |  Branch (1563:9): [True: 1.69k, False: 3.45k]
  ------------------
 1564|  1.69k|        mms_stat->read = MQTT_MSG_BEGIN;
 1565|  1.69k|    }
 1566|       |
 1567|       |#ifdef WOLFMQTT_NONBLOCK
 1568|       |    /* if nonblocking and some data has been read, do not release read lock */
 1569|       |    if (rc == MQTT_CODE_CONTINUE && mms_stat->read > MQTT_MSG_WAIT) {
 1570|       |        return rc;
 1571|       |    }
 1572|       |#endif
 1573|       |
 1574|  5.14k|    MqttReadStop(client, mms_stat);
 1575|       |
 1576|       |#ifdef WOLFMQTT_NONBLOCK
 1577|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 1578|       |    #ifdef WOLFMQTT_MULTITHREAD
 1579|       |    if (wm_SemLock(&client->lockClient) == 0)
 1580|       |    #endif
 1581|       |    {
 1582|       |        client->lastRc = rc;
 1583|       |    #ifdef WOLFMQTT_MULTITHREAD
 1584|       |        wm_SemUnlock(&client->lockClient);
 1585|       |    #endif
 1586|       |    }
 1587|       |    #endif /* WOLFMQTT_DEBUG_CLIENT */
 1588|       |    if (rc == MQTT_CODE_CONTINUE) {
 1589|       |        return rc;
 1590|       |    }
 1591|       |#endif
 1592|       |
 1593|  5.14k|    if (rc < 0) {
  ------------------
  |  Branch (1593:9): [True: 4.50k, False: 644]
  ------------------
 1594|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 1595|       |        if (rc != MQTT_CODE_CONTINUE) {
 1596|       |            PRINTF("MqttClient_WaitType: Failure: %s (%d)",
 1597|       |                MqttClient_ReturnCodeToString(rc), rc);
 1598|       |        }
 1599|       |    #endif
 1600|  4.50k|        return rc;
 1601|  4.50k|    }
 1602|       |
 1603|    644|    if (!waitMatchFound) {
  ------------------
  |  Branch (1603:9): [True: 629, False: 15]
  ------------------
 1604|       |        /* if we get here, then the we are still waiting for a packet */
 1605|    629|        mms_stat->read = MQTT_MSG_BEGIN;
 1606|       |    #ifdef WOLFMQTT_NONBLOCK
 1607|       |        /* for non-blocking return with code continue instead of waiting again
 1608|       |         * if called with packet type and id of 'any' */
 1609|       |        if (wait_type == MQTT_PACKET_TYPE_ANY && wait_packet_id == 0) {
 1610|       |            return MQTT_CODE_CONTINUE;
 1611|       |        }
 1612|       |    #endif
 1613|    629|        MQTT_TRACE_MSG("Wait Again");
 1614|    629|        goto wait_again;
 1615|    629|    }
 1616|       |#ifdef WOLFMQTT_DEBUG_CLIENT
 1617|       |    if (rc != MQTT_CODE_CONTINUE) {
 1618|       |        PRINTF("MqttClient_WaitType: rc %d, state %d-%d-%d",
 1619|       |            rc, mms_stat->read, mms_stat->write, mms_stat->ack);
 1620|       |    }
 1621|       |#endif
 1622|       |
 1623|       |
 1624|     15|    return rc;
 1625|    644|}
mqtt_client.c:MqttClient_DecodePacket:
  655|  2.09k|{
  656|  2.09k|    int rc = MQTT_CODE_SUCCESS;
  657|  2.09k|    MqttPacket* header;
  658|  2.09k|    MqttPacketType packet_type;
  659|  2.09k|    MqttQoS packet_qos;
  660|  2.09k|    word16 packet_id = 0;
  661|       |
  662|       |    /* must have rx buffer with at least 2 byes for header */
  663|  2.09k|    if (rx_buf == NULL || rx_len < MQTT_PACKET_HEADER_MIN_SIZE) {
  ------------------
  |  |  300|  2.09k|#define MQTT_PACKET_HEADER_MIN_SIZE        (2)
  ------------------
  |  Branch (663:9): [True: 0, False: 2.09k]
  |  Branch (663:27): [True: 0, False: 2.09k]
  ------------------
  664|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  665|      0|    }
  666|       |
  667|       |    /* Decode header */
  668|  2.09k|    header = (MqttPacket*)rx_buf;
  669|  2.09k|    packet_type = (MqttPacketType)MQTT_PACKET_TYPE_GET(header->type_flags);
  ------------------
  |  |  244|  2.09k|#define MQTT_PACKET_TYPE_GET(x)  (((x) >> 4) & 0xF)
  ------------------
  670|  2.09k|    if (ppacket_type) {
  ------------------
  |  Branch (670:9): [True: 2.09k, False: 0]
  ------------------
  671|  2.09k|        *ppacket_type = packet_type;
  672|  2.09k|    }
  673|  2.09k|    packet_qos = (MqttQoS)MQTT_PACKET_FLAGS_GET_QOS(header->type_flags);
  ------------------
  |  |  270|  2.09k|    ((MQTT_PACKET_FLAGS_GET((type_flags)) & \
  |  |  ------------------
  |  |  |  |  267|  2.09k|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  |  |  ------------------
  |  |  271|  2.09k|        MQTT_PACKET_FLAG_QOS_MASK) >> MQTT_PACKET_FLAG_QOS_SHIFT)
  ------------------
  674|  2.09k|    if (ppacket_qos) {
  ------------------
  |  Branch (674:9): [True: 2.09k, False: 0]
  ------------------
  675|  2.09k|        *ppacket_qos = packet_qos;
  676|  2.09k|    }
  677|       |
  678|       |    /* Decode packet specific data (if requested) */
  679|  2.09k|    if (ppacket_id || packet_obj) {
  ------------------
  |  Branch (679:9): [True: 2.09k, False: 0]
  |  Branch (679:23): [True: 0, False: 0]
  ------------------
  680|  2.09k|        switch (packet_type) {
  681|    414|        case MQTT_PACKET_TYPE_CONNECT_ACK:
  ------------------
  |  Branch (681:9): [True: 414, False: 1.67k]
  ------------------
  682|    414|        {
  683|    414|            MqttConnectAck connect_ack, *p_connect_ack = &connect_ack;
  684|    414|            if (packet_obj) {
  ------------------
  |  Branch (684:17): [True: 1, False: 413]
  ------------------
  685|      1|                p_connect_ack = (MqttConnectAck*)packet_obj;
  686|      1|            }
  687|    413|            else {
  688|    413|                XMEMSET(p_connect_ack, 0, sizeof(MqttConnectAck));
  ------------------
  |  |  988|    413|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  689|    413|            }
  690|    414|        #ifdef WOLFMQTT_V5
  691|    414|            p_connect_ack->protocol_level = client->protocol_level;
  692|    414|        #endif
  693|    414|            rc = MqttDecode_ConnectAck(rx_buf, rx_len, p_connect_ack);
  694|    414|        #ifdef WOLFMQTT_V5
  695|    414|            if (rc >= 0 && doProps) {
  ------------------
  |  Branch (695:17): [True: 0, False: 414]
  |  Branch (695:28): [True: 0, False: 0]
  ------------------
  696|      0|                int tmp;
  697|       |                /* Only latch server-supplied session limits when the broker
  698|       |                 * accepted the connection. A refused CONNACK must not
  699|       |                 * mutate long-lived MqttClient state. */
  700|      0|                if (p_connect_ack->return_code ==
  ------------------
  |  Branch (700:21): [True: 0, False: 0]
  ------------------
  701|      0|                        MQTT_CONNECT_ACK_CODE_ACCEPTED) {
  702|      0|                    Handle_ConnectAck_Props(client, p_connect_ack->props);
  703|      0|                }
  704|      0|                tmp = Handle_Props(client, p_connect_ack->props,
  705|      0|                                   (packet_obj != NULL), 1);
  706|      0|                p_connect_ack->props = NULL;
  707|      0|                if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (707:21): [True: 0, False: 0]
  ------------------
  708|      0|                    rc = tmp;
  709|      0|                }
  710|      0|            }
  711|    414|        #endif
  712|    414|            break;
  713|      0|        }
  714|    225|        case MQTT_PACKET_TYPE_PUBLISH:
  ------------------
  |  Branch (714:9): [True: 225, False: 1.86k]
  ------------------
  715|    225|        {
  716|    225|            MqttPublish publish, *p_publish;
  717|    225|            if (packet_obj) {
  ------------------
  |  Branch (717:17): [True: 1, False: 224]
  ------------------
  718|      1|                p_publish = (MqttPublish*)packet_obj;
  719|      1|            #ifdef WOLFMQTT_V5
  720|       |                /* setting the protocol level will enable parsing of the
  721|       |                 * properties. The properties are allocated from a list,
  722|       |                 * so only parse if we are using a return packet object */
  723|      1|                p_publish->protocol_level = client->protocol_level;
  724|      1|            #endif
  725|      1|            }
  726|    224|            else {
  727|    224|                p_publish = &publish;
  728|    224|                XMEMSET(p_publish, 0, sizeof(MqttPublish));
  ------------------
  |  |  988|    224|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  729|    224|            }
  730|    225|            rc = MqttDecode_Publish(rx_buf, rx_len, p_publish);
  731|    225|            if (rc >= 0) {
  ------------------
  |  Branch (731:17): [True: 0, False: 225]
  ------------------
  732|      0|                packet_id = p_publish->packet_id;
  733|      0|            #ifdef WOLFMQTT_V5
  734|      0|                if (doProps) {
  ------------------
  |  Branch (734:21): [True: 0, False: 0]
  ------------------
  735|       |                    /* Do not free property list here. It will be freed
  736|       |                       after the message callback. */
  737|      0|                    int tmp = Handle_Props(client, p_publish->props,
  738|      0|                                           (packet_obj != NULL), 0);
  739|      0|                    if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (739:25): [True: 0, False: 0]
  ------------------
  740|      0|                        rc = tmp;
  741|      0|                    }
  742|      0|                }
  743|      0|            #endif
  744|      0|            }
  745|    225|            break;
  746|      0|        }
  747|    198|        case MQTT_PACKET_TYPE_PUBLISH_ACK:
  ------------------
  |  Branch (747:9): [True: 198, False: 1.89k]
  ------------------
  748|    240|        case MQTT_PACKET_TYPE_PUBLISH_REC:
  ------------------
  |  Branch (748:9): [True: 42, False: 2.04k]
  ------------------
  749|    292|        case MQTT_PACKET_TYPE_PUBLISH_REL:
  ------------------
  |  Branch (749:9): [True: 52, False: 2.03k]
  ------------------
  750|    321|        case MQTT_PACKET_TYPE_PUBLISH_COMP:
  ------------------
  |  Branch (750:9): [True: 29, False: 2.06k]
  ------------------
  751|    321|        {
  752|    321|            MqttPublishResp publish_resp, *p_publish_resp = &publish_resp;
  753|    321|            if (packet_obj) {
  ------------------
  |  Branch (753:17): [True: 4, False: 317]
  ------------------
  754|      4|                p_publish_resp = (MqttPublishResp*)packet_obj;
  755|      4|            }
  756|    317|            else {
  757|    317|                XMEMSET(p_publish_resp, 0, sizeof(MqttPublishResp));
  ------------------
  |  |  988|    317|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  758|    317|            }
  759|       |
  760|    321|        #ifdef WOLFMQTT_V5
  761|    321|            p_publish_resp->protocol_level = client->protocol_level;
  762|    321|        #endif
  763|    321|            rc = MqttDecode_PublishResp(rx_buf, rx_len, packet_type,
  764|    321|                p_publish_resp);
  765|    321|            if (rc >= 0) {
  ------------------
  |  Branch (765:17): [True: 8, False: 313]
  ------------------
  766|      8|                packet_id = p_publish_resp->packet_id;
  767|      8|            #ifdef WOLFMQTT_V5
  768|      8|                if (doProps) {
  ------------------
  |  Branch (768:21): [True: 8, False: 0]
  ------------------
  769|      8|                    int tmp = Handle_Props(client, p_publish_resp->props,
  770|      8|                                           (packet_obj != NULL), 1);
  771|      8|                    p_publish_resp->props = NULL;
  772|      8|                    if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (772:25): [True: 0, False: 8]
  ------------------
  773|      0|                        rc = tmp;
  774|      0|                    }
  775|      8|                }
  776|      8|            #endif
  777|      8|            }
  778|    321|            break;
  779|    292|        }
  780|    221|        case MQTT_PACKET_TYPE_SUBSCRIBE_ACK:
  ------------------
  |  Branch (780:9): [True: 221, False: 1.86k]
  ------------------
  781|    221|        {
  782|    221|            MqttSubscribeAck subscribe_ack, *p_subscribe_ack = &subscribe_ack;
  783|    221|            if (packet_obj) {
  ------------------
  |  Branch (783:17): [True: 0, False: 221]
  ------------------
  784|      0|                p_subscribe_ack = (MqttSubscribeAck*)packet_obj;
  785|      0|            }
  786|    221|            else {
  787|    221|                XMEMSET(p_subscribe_ack, 0, sizeof(MqttSubscribeAck));
  ------------------
  |  |  988|    221|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  788|    221|            }
  789|    221|        #ifdef WOLFMQTT_V5
  790|    221|            p_subscribe_ack->protocol_level = client->protocol_level;
  791|    221|        #endif
  792|    221|            rc = MqttDecode_SubscribeAck(rx_buf, rx_len, p_subscribe_ack);
  793|    221|            if (rc >= 0) {
  ------------------
  |  Branch (793:17): [True: 0, False: 221]
  ------------------
  794|      0|                packet_id = p_subscribe_ack->packet_id;
  795|      0|            #ifdef WOLFMQTT_V5
  796|      0|                if (doProps) {
  ------------------
  |  Branch (796:21): [True: 0, False: 0]
  ------------------
  797|      0|                    int tmp = Handle_Props(client, p_subscribe_ack->props,
  798|      0|                                           (packet_obj != NULL), 1);
  799|      0|                    p_subscribe_ack->props = NULL;
  800|      0|                    if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (800:25): [True: 0, False: 0]
  ------------------
  801|      0|                        rc = tmp;
  802|      0|                    }
  803|      0|                }
  804|      0|            #endif
  805|      0|            }
  806|    221|            break;
  807|    292|        }
  808|    147|        case MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK:
  ------------------
  |  Branch (808:9): [True: 147, False: 1.94k]
  ------------------
  809|    147|        {
  810|    147|            MqttUnsubscribeAck unsubscribe_ack,
  811|    147|                               *p_unsubscribe_ack = &unsubscribe_ack;
  812|    147|            if (packet_obj) {
  ------------------
  |  Branch (812:17): [True: 19, False: 128]
  ------------------
  813|     19|                p_unsubscribe_ack = (MqttUnsubscribeAck*)packet_obj;
  814|     19|            }
  815|    128|            else {
  816|    128|                XMEMSET(p_unsubscribe_ack, 0, sizeof(MqttUnsubscribeAck));
  ------------------
  |  |  988|    128|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  817|    128|            }
  818|    147|        #ifdef WOLFMQTT_V5
  819|    147|            p_unsubscribe_ack->protocol_level = client->protocol_level;
  820|    147|        #endif
  821|    147|            rc = MqttDecode_UnsubscribeAck(rx_buf, rx_len, p_unsubscribe_ack);
  822|    147|            if (rc >= 0) {
  ------------------
  |  Branch (822:17): [True: 7, False: 140]
  ------------------
  823|      7|                packet_id = p_unsubscribe_ack->packet_id;
  824|      7|            #ifdef WOLFMQTT_V5
  825|      7|                if (doProps) {
  ------------------
  |  Branch (825:21): [True: 7, False: 0]
  ------------------
  826|      7|                    int tmp = Handle_Props(client, p_unsubscribe_ack->props,
  827|      7|                                           (packet_obj != NULL), 1);
  828|      7|                    p_unsubscribe_ack->props = NULL;
  829|      7|                    if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (829:25): [True: 0, False: 7]
  ------------------
  830|      0|                        rc = tmp;
  831|      0|                    }
  832|      7|                }
  833|      7|            #endif
  834|      7|            }
  835|    147|            break;
  836|    292|        }
  837|     54|        case MQTT_PACKET_TYPE_PING_RESP:
  ------------------
  |  Branch (837:9): [True: 54, False: 2.03k]
  ------------------
  838|     54|        {
  839|     54|            MqttPing ping, *p_ping = &ping;
  840|     54|            if (packet_obj) {
  ------------------
  |  Branch (840:17): [True: 0, False: 54]
  ------------------
  841|      0|                p_ping = (MqttPing*)packet_obj;
  842|      0|            }
  843|     54|            else {
  844|     54|                XMEMSET(p_ping, 0, sizeof(MqttPing));
  ------------------
  |  |  988|     54|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  845|     54|            }
  846|     54|            rc = MqttDecode_Ping(rx_buf, rx_len, p_ping);
  847|     54|            break;
  848|    292|        }
  849|    313|        case MQTT_PACKET_TYPE_AUTH:
  ------------------
  |  Branch (849:9): [True: 313, False: 1.77k]
  ------------------
  850|    313|        {
  851|    313|        #ifdef WOLFMQTT_V5
  852|    313|            MqttAuth auth, *p_auth = &auth;
  853|    313|            if (packet_obj) {
  ------------------
  |  Branch (853:17): [True: 1, False: 312]
  ------------------
  854|      1|                p_auth = (MqttAuth*)packet_obj;
  855|      1|            }
  856|    312|            else {
  857|    312|                XMEMSET(p_auth, 0, sizeof(MqttAuth));
  ------------------
  |  |  988|    312|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  858|    312|            }
  859|    313|            rc = MqttDecode_Auth(rx_buf, rx_len, p_auth);
  860|    313|            if (rc >= 0 && doProps) {
  ------------------
  |  Branch (860:17): [True: 2, False: 311]
  |  Branch (860:28): [True: 2, False: 0]
  ------------------
  861|      2|                int tmp = Handle_Props(client, p_auth->props,
  862|      2|                                       (packet_obj != NULL), 1);
  863|      2|                p_auth->props = NULL;
  864|      2|                if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (864:21): [True: 0, False: 2]
  ------------------
  865|      0|                    rc = tmp;
  866|      0|                }
  867|      2|            }
  868|       |        #else
  869|       |            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
  870|       |        #endif /* WOLFMQTT_V5 */
  871|    313|            break;
  872|    292|        }
  873|    319|        case MQTT_PACKET_TYPE_DISCONNECT:
  ------------------
  |  Branch (873:9): [True: 319, False: 1.77k]
  ------------------
  874|    319|        {
  875|    319|        #ifdef WOLFMQTT_V5
  876|    319|            MqttDisconnect disc, *p_disc = &disc;
  877|    319|            if (packet_obj) {
  ------------------
  |  Branch (877:17): [True: 14, False: 305]
  ------------------
  878|     14|                p_disc = (MqttDisconnect*)packet_obj;
  879|     14|            }
  880|    305|            else {
  881|    305|                XMEMSET(p_disc, 0, sizeof(MqttDisconnect));
  ------------------
  |  |  988|    305|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
  882|    305|            }
  883|    319|            rc = MqttDecode_Disconnect(rx_buf, rx_len, p_disc);
  884|    319|            if (rc >= 0 && doProps) {
  ------------------
  |  Branch (884:17): [True: 23, False: 296]
  |  Branch (884:28): [True: 23, False: 0]
  ------------------
  885|     23|                int tmp = Handle_Props(client, p_disc->props,
  886|     23|                                       (packet_obj != NULL), 1);
  887|     23|                p_disc->props = NULL;
  888|     23|                if (tmp != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (888:21): [True: 0, False: 23]
  ------------------
  889|      0|                    rc = tmp;
  890|      0|                }
  891|     23|            }
  892|    319|            #ifdef WOLFMQTT_DISCONNECT_CB
  893|       |            /* Call disconnect callback with reason code */
  894|    319|            if ((packet_obj != NULL) && client->disconnect_cb) {
  ------------------
  |  Branch (894:17): [True: 14, False: 305]
  |  Branch (894:41): [True: 0, False: 14]
  ------------------
  895|      0|                client->disconnect_cb(client, p_disc->reason_code,
  896|      0|                    client->disconnect_ctx);
  897|      0|            }
  898|    319|            #endif
  899|       |        #else
  900|       |            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
  901|       |        #endif /* WOLFMQTT_V5 */
  902|    319|            break;
  903|    292|        }
  904|      0|        case MQTT_PACKET_TYPE_CONNECT:
  ------------------
  |  Branch (904:9): [True: 0, False: 2.09k]
  ------------------
  905|      1|        case MQTT_PACKET_TYPE_SUBSCRIBE:
  ------------------
  |  Branch (905:9): [True: 1, False: 2.08k]
  ------------------
  906|      1|        case MQTT_PACKET_TYPE_UNSUBSCRIBE:
  ------------------
  |  Branch (906:9): [True: 0, False: 2.09k]
  ------------------
  907|      1|        case MQTT_PACKET_TYPE_PING_REQ:
  ------------------
  |  Branch (907:9): [True: 0, False: 2.09k]
  ------------------
  908|      1|        case MQTT_PACKET_TYPE_ANY:
  ------------------
  |  Branch (908:9): [True: 0, False: 2.09k]
  ------------------
  909|     76|        case MQTT_PACKET_TYPE_RESERVED:
  ------------------
  |  Branch (909:9): [True: 75, False: 2.01k]
  ------------------
  910|     76|        default:
  ------------------
  |  Branch (910:9): [True: 0, False: 2.09k]
  ------------------
  911|       |            /* these type are only encoded by client */
  912|     76|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
  ------------------
  |  |  392|     76|#define MQTT_TRACE_ERROR(err) err
  ------------------
  913|     76|            break;
  914|  2.09k|        } /* switch (packet_type) */
  915|  2.09k|    }
  916|       |
  917|  2.09k|    if (ppacket_id) {
  ------------------
  |  Branch (917:9): [True: 2.09k, False: 0]
  ------------------
  918|  2.09k|        *ppacket_id = packet_id;
  919|  2.09k|    }
  920|       |
  921|  2.09k|    (void)client;
  922|  2.09k|    (void)doProps;
  923|       |
  924|       |#ifdef WOLFMQTT_DEBUG_CLIENT
  925|       |    PRINTF("MqttClient_DecodePacket: Rc %d, Len %d, Type %s (%d), ID %d,"
  926|       |            " QoS %d, doProps %d",
  927|       |        rc, rx_len, MqttPacket_TypeDesc(packet_type), packet_type, packet_id,
  928|       |        packet_qos, doProps);
  929|       |#endif
  930|       |
  931|  2.09k|    return rc;
  932|  2.09k|}
mqtt_client.c:Handle_Props:
  609|     40|{
  610|     40|    int rc = MQTT_CODE_SUCCESS;
  611|       |
  612|       |    /* If no properties, just return */
  613|     40|    if (props != NULL) {
  ------------------
  |  Branch (613:9): [True: 0, False: 40]
  ------------------
  614|      0|    #ifdef WOLFMQTT_PROPERTY_CB
  615|       |        /* Check for properties set by the server */
  616|      0|        if ((use_cb == 1) && (client->property_cb != NULL)) {
  ------------------
  |  Branch (616:13): [True: 0, False: 0]
  |  Branch (616:30): [True: 0, False: 0]
  ------------------
  617|       |            /* capture error if returned */
  618|      0|            int rc_err = client->property_cb(client, props,
  619|      0|                    client->property_ctx);
  620|      0|            if (rc_err < 0) {
  ------------------
  |  Branch (620:17): [True: 0, False: 0]
  ------------------
  621|      0|                rc = rc_err;
  622|      0|            }
  623|      0|        }
  624|       |    #else
  625|       |        (void)client;
  626|       |        (void)use_cb;
  627|       |    #endif
  628|      0|        if (free_props) {
  ------------------
  |  Branch (628:13): [True: 0, False: 0]
  ------------------
  629|       |            /* Free the properties */
  630|      0|            MqttProps_Free(props);
  631|      0|        }
  632|      0|    }
  633|     40|    return rc;
  634|     40|}
mqtt_client.c:MqttClient_PacketReset:
 1158|     17|{
 1159|     17|    size_t objSz = 0;
 1160|     17|    size_t offset = sizeof(MqttMsgStat);
 1161|       |#ifdef WOLFMQTT_MULTITHREAD
 1162|       |    offset += sizeof(MqttPendResp);
 1163|       |#endif
 1164|     17|    switch (packet_type) {
 1165|      0|        case MQTT_PACKET_TYPE_CONNECT:
  ------------------
  |  Branch (1165:9): [True: 0, False: 17]
  ------------------
 1166|      0|            objSz = sizeof(MqttConnect);
 1167|      0|            break;
 1168|      0|        case MQTT_PACKET_TYPE_CONNECT_ACK:
  ------------------
  |  Branch (1168:9): [True: 0, False: 17]
  ------------------
 1169|      0|            objSz = sizeof(MqttConnectAck);
 1170|      0|            break;
 1171|      0|        case MQTT_PACKET_TYPE_PUBLISH:
  ------------------
  |  Branch (1171:9): [True: 0, False: 17]
  ------------------
 1172|      0|            objSz = sizeof(MqttPublish);
 1173|      0|            break;
 1174|      0|        case MQTT_PACKET_TYPE_PUBLISH_ACK:
  ------------------
  |  Branch (1174:9): [True: 0, False: 17]
  ------------------
 1175|      0|        case MQTT_PACKET_TYPE_PUBLISH_REC:
  ------------------
  |  Branch (1175:9): [True: 0, False: 17]
  ------------------
 1176|      4|        case MQTT_PACKET_TYPE_PUBLISH_REL:
  ------------------
  |  Branch (1176:9): [True: 4, False: 13]
  ------------------
 1177|      4|        case MQTT_PACKET_TYPE_PUBLISH_COMP:
  ------------------
  |  Branch (1177:9): [True: 0, False: 17]
  ------------------
 1178|      4|            objSz = sizeof(MqttPublishResp);
 1179|      4|            break;
 1180|      0|        case MQTT_PACKET_TYPE_SUBSCRIBE:
  ------------------
  |  Branch (1180:9): [True: 0, False: 17]
  ------------------
 1181|      0|            objSz = sizeof(MqttSubscribe);
 1182|      0|            break;
 1183|      0|        case MQTT_PACKET_TYPE_SUBSCRIBE_ACK:
  ------------------
  |  Branch (1183:9): [True: 0, False: 17]
  ------------------
 1184|      0|            objSz = sizeof(MqttSubscribeAck);
 1185|      0|            break;
 1186|      0|        case MQTT_PACKET_TYPE_UNSUBSCRIBE:
  ------------------
  |  Branch (1186:9): [True: 0, False: 17]
  ------------------
 1187|      0|            objSz = sizeof(MqttUnsubscribe);
 1188|      0|            break;
 1189|      3|        case MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK:
  ------------------
  |  Branch (1189:9): [True: 3, False: 14]
  ------------------
 1190|      3|            objSz = sizeof(MqttUnsubscribeAck);
 1191|      3|            break;
 1192|      0|        case MQTT_PACKET_TYPE_PING_REQ:
  ------------------
  |  Branch (1192:9): [True: 0, False: 17]
  ------------------
 1193|      0|        case MQTT_PACKET_TYPE_PING_RESP:
  ------------------
  |  Branch (1193:9): [True: 0, False: 17]
  ------------------
 1194|      0|            objSz = sizeof(MqttPing);
 1195|      0|            break;
 1196|      1|        case MQTT_PACKET_TYPE_AUTH:
  ------------------
  |  Branch (1196:9): [True: 1, False: 16]
  ------------------
 1197|      1|        #ifdef WOLFMQTT_V5
 1198|      1|            objSz = sizeof(MqttAuth);
 1199|      1|        #endif
 1200|      1|            break;
 1201|      9|        case MQTT_PACKET_TYPE_DISCONNECT:
  ------------------
  |  Branch (1201:9): [True: 9, False: 8]
  ------------------
 1202|      9|        #ifdef WOLFMQTT_V5
 1203|      9|            objSz = sizeof(MqttDisconnect);
 1204|      9|        #endif
 1205|      9|            break;
 1206|      0|        case MQTT_PACKET_TYPE_ANY:
  ------------------
  |  Branch (1206:9): [True: 0, False: 17]
  ------------------
 1207|      0|        case MQTT_PACKET_TYPE_RESERVED:
  ------------------
  |  Branch (1207:9): [True: 0, False: 17]
  ------------------
 1208|      0|        default:
  ------------------
  |  Branch (1208:9): [True: 0, False: 17]
  ------------------
 1209|      0|            break;
 1210|     17|    } /* switch (packet_type) */
 1211|     17|    if (objSz > offset) {
  ------------------
  |  Branch (1211:9): [True: 17, False: 0]
  ------------------
 1212|     17|        XMEMSET((byte*)packet_obj + offset, 0, objSz - offset);
  ------------------
  |  |  988|     17|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
 1213|     17|    }
 1214|     17|}
mqtt_client.c:MqttIsPubRespPacket:
 1108|     27|{
 1109|     27|    return (packet_type == MQTT_PACKET_TYPE_PUBLISH_ACK /* Acknowledgment */ ||
  ------------------
  |  Branch (1109:13): [True: 0, False: 27]
  ------------------
 1110|     27|            packet_type == MQTT_PACKET_TYPE_PUBLISH_REC /* Received */ ||
  ------------------
  |  Branch (1110:13): [True: 0, False: 27]
  ------------------
 1111|     27|            packet_type == MQTT_PACKET_TYPE_PUBLISH_REL /* Release */ ||
  ------------------
  |  Branch (1111:13): [True: 0, False: 27]
  ------------------
 1112|     27|            packet_type == MQTT_PACKET_TYPE_PUBLISH_COMP /* Complete */);
  ------------------
  |  Branch (1112:13): [True: 4, False: 23]
  ------------------
 1113|     27|}
mqtt_client.c:MqttClient_HandlePacket:
  937|     40|{
  938|     40|    int rc = MQTT_CODE_SUCCESS;
  939|     40|    MqttQoS packet_qos = MQTT_QOS_0;
  940|     40|    word16 packet_id = 0;
  941|       |
  942|     40|    if (client == NULL || packet_obj == NULL) {
  ------------------
  |  Branch (942:9): [True: 0, False: 40]
  |  Branch (942:27): [True: 0, False: 40]
  ------------------
  943|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  944|      0|    }
  945|       |
  946|       |    /* make sure the response defaults to no ACK */
  947|     40|    resp->packet_type = MQTT_PACKET_TYPE_RESERVED;
  948|       |
  949|     40|    switch (packet_type)
  950|     40|    {
  951|      0|        case MQTT_PACKET_TYPE_CONNECT_ACK:
  ------------------
  |  Branch (951:9): [True: 0, False: 40]
  ------------------
  952|      0|        {
  953|      0|            rc = MqttClient_DecodePacket(client, client->rx_buf,
  954|      0|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
  955|      0|                &packet_id, 1);
  956|      0|            break;
  957|      0|        }
  958|     23|        case MQTT_PACKET_TYPE_PUBLISH:
  ------------------
  |  Branch (958:9): [True: 23, False: 17]
  ------------------
  959|     23|        {
  960|     23|            MqttPublish* publish = (MqttPublish*)packet_obj;
  961|     23|            if (publish->stat.read != MQTT_MSG_PAYLOAD2) {
  ------------------
  |  Branch (961:17): [True: 23, False: 0]
  ------------------
  962|     23|                rc = MqttClient_DecodePacket(client, client->rx_buf,
  963|     23|                    client->packet.buf_len, packet_obj, &packet_type,
  964|     23|                    &packet_qos, &packet_id, 1);
  965|     23|                if (rc <= 0) {
  ------------------
  |  Branch (965:21): [True: 17, False: 6]
  ------------------
  966|     17|                    return rc;
  967|     17|                }
  968|     23|            }
  969|      0|            else {
  970|       |                /* packet ID and QoS were already established */
  971|      0|                packet_id =  publish->packet_id;
  972|      0|                packet_qos = publish->qos;
  973|      0|            }
  974|       |
  975|      6|            rc = MqttClient_Publish_ReadPayload(client, publish, timeout_ms);
  976|      6|            if (rc < 0) {
  ------------------
  |  Branch (976:17): [True: 0, False: 6]
  ------------------
  977|      0|                break;
  978|      0|            }
  979|       |            /* Note: Getting here means the Publish Read is done */
  980|      6|            publish->stat.read = MQTT_MSG_BEGIN; /* reset state */
  981|       |
  982|      6|        #ifdef WOLFMQTT_V5
  983|       |            /* Free the properties */
  984|      6|            MqttProps_Free(publish->props);
  985|      6|            publish->props = NULL;
  986|      6|        #endif
  987|       |
  988|       |            /* Handle QoS */
  989|      6|            if (packet_qos == MQTT_QOS_0) {
  ------------------
  |  Branch (989:17): [True: 6, False: 0]
  ------------------
  990|       |                /* we are done, no QoS response */
  991|      6|                break;
  992|      6|            }
  993|       |
  994|      0|        #ifdef WOLFMQTT_V5
  995|       |            /* Copy response code in case changed by callback */
  996|      0|            resp->reason_code = publish->resp.reason_code;
  997|      0|        #endif
  998|       |            /* Populate information needed for ack */
  999|      0|            resp->packet_type = (packet_qos == MQTT_QOS_1) ?
  ------------------
  |  Branch (999:33): [True: 0, False: 0]
  ------------------
 1000|      0|                MQTT_PACKET_TYPE_PUBLISH_ACK :
 1001|      0|                MQTT_PACKET_TYPE_PUBLISH_REC;
 1002|      0|            resp->packet_id = packet_id;
 1003|      0|            break;
 1004|      6|        }
 1005|      0|        case MQTT_PACKET_TYPE_PUBLISH_ACK:
  ------------------
  |  Branch (1005:9): [True: 0, False: 40]
  ------------------
 1006|      0|        case MQTT_PACKET_TYPE_PUBLISH_REC:
  ------------------
  |  Branch (1006:9): [True: 0, False: 40]
  ------------------
 1007|      4|        case MQTT_PACKET_TYPE_PUBLISH_REL:
  ------------------
  |  Branch (1007:9): [True: 4, False: 36]
  ------------------
 1008|      4|        case MQTT_PACKET_TYPE_PUBLISH_COMP:
  ------------------
  |  Branch (1008:9): [True: 0, False: 40]
  ------------------
 1009|      4|        {
 1010|       |        #if defined(WOLFMQTT_V5) && defined(WOLFMQTT_DEBUG_CLIENT)
 1011|       |            MqttPublishResp* publish_resp = (MqttPublishResp*)packet_obj;
 1012|       |        #endif
 1013|      4|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1014|      4|                client->packet.buf_len, packet_obj, &packet_type,
 1015|      4|                &packet_qos, &packet_id, 1);
 1016|      4|            if (rc <= 0) {
  ------------------
  |  Branch (1016:17): [True: 0, False: 4]
  ------------------
 1017|      0|                return rc;
 1018|      0|            }
 1019|       |
 1020|       |        #if defined(WOLFMQTT_V5) && defined(WOLFMQTT_DEBUG_CLIENT)
 1021|       |            PRINTF("\tPublish response: reason code %d, Type %s (%d),"
 1022|       |                    " ID %d, QoS %d",
 1023|       |                    publish_resp->reason_code,
 1024|       |                    MqttPacket_TypeDesc(packet_type),
 1025|       |                    packet_type, packet_id, packet_qos);
 1026|       |        #endif
 1027|       |
 1028|       |            /* Only ACK publish Received or Release QoS levels */
 1029|      4|            if (packet_type != MQTT_PACKET_TYPE_PUBLISH_REC &&
  ------------------
  |  Branch (1029:17): [True: 4, False: 0]
  ------------------
 1030|      4|                packet_type != MQTT_PACKET_TYPE_PUBLISH_REL) {
  ------------------
  |  Branch (1030:17): [True: 0, False: 4]
  ------------------
 1031|      0|                break;
 1032|      0|            }
 1033|       |
 1034|       |            /* Populate information needed for ack */
 1035|      4|            resp->packet_type = packet_type+1; /* next ack */
 1036|      4|            resp->packet_id = packet_id;
 1037|      4|            break;
 1038|      4|        }
 1039|      0|        case MQTT_PACKET_TYPE_SUBSCRIBE_ACK:
  ------------------
  |  Branch (1039:9): [True: 0, False: 40]
  ------------------
 1040|      0|        {
 1041|      0|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1042|      0|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
 1043|      0|                &packet_id, 1);
 1044|      0|            break;
 1045|      4|        }
 1046|      3|        case MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK:
  ------------------
  |  Branch (1046:9): [True: 3, False: 37]
  ------------------
 1047|      3|        {
 1048|      3|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1049|      3|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
 1050|      3|                &packet_id, 1);
 1051|      3|            break;
 1052|      4|        }
 1053|      0|        case MQTT_PACKET_TYPE_PING_RESP:
  ------------------
  |  Branch (1053:9): [True: 0, False: 40]
  ------------------
 1054|      0|        {
 1055|      0|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1056|      0|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
 1057|      0|                &packet_id, 1);
 1058|      0|            break;
 1059|      4|        }
 1060|      1|        case MQTT_PACKET_TYPE_AUTH:
  ------------------
  |  Branch (1060:9): [True: 1, False: 39]
  ------------------
 1061|      1|        {
 1062|      1|        #ifdef WOLFMQTT_V5
 1063|      1|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1064|      1|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
 1065|      1|                &packet_id, 1);
 1066|       |        #else
 1067|       |            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
 1068|       |        #endif
 1069|      1|            break;
 1070|      4|        }
 1071|       |
 1072|      9|        case MQTT_PACKET_TYPE_DISCONNECT:
  ------------------
  |  Branch (1072:9): [True: 9, False: 31]
  ------------------
 1073|      9|        {
 1074|      9|        #ifdef WOLFMQTT_V5
 1075|      9|            rc = MqttClient_DecodePacket(client, client->rx_buf,
 1076|      9|                client->packet.buf_len, packet_obj, &packet_type, &packet_qos,
 1077|      9|                &packet_id, 1);
 1078|       |        #else
 1079|       |            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
 1080|       |        #endif
 1081|      9|            break;
 1082|      4|        }
 1083|      0|        case MQTT_PACKET_TYPE_CONNECT:
  ------------------
  |  Branch (1083:9): [True: 0, False: 40]
  ------------------
 1084|      0|        case MQTT_PACKET_TYPE_SUBSCRIBE:
  ------------------
  |  Branch (1084:9): [True: 0, False: 40]
  ------------------
 1085|      0|        case MQTT_PACKET_TYPE_UNSUBSCRIBE:
  ------------------
  |  Branch (1085:9): [True: 0, False: 40]
  ------------------
 1086|      0|        case MQTT_PACKET_TYPE_PING_REQ:
  ------------------
  |  Branch (1086:9): [True: 0, False: 40]
  ------------------
 1087|      0|        case MQTT_PACKET_TYPE_ANY:
  ------------------
  |  Branch (1087:9): [True: 0, False: 40]
  ------------------
 1088|      0|        case MQTT_PACKET_TYPE_RESERVED:
  ------------------
  |  Branch (1088:9): [True: 0, False: 40]
  ------------------
 1089|      0|        default:
  ------------------
  |  Branch (1089:9): [True: 0, False: 40]
  ------------------
 1090|       |            /* these types are only sent from client and should not be sent
 1091|       |             * by broker */
 1092|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1093|      0|            break;
 1094|     40|    } /* switch (packet_type) */
 1095|       |
 1096|       |#ifdef WOLFMQTT_DEBUG_CLIENT
 1097|       |    if (rc < 0) {
 1098|       |        PRINTF("MqttClient_HandlePacket: Rc %d, Type %s (%d), QoS %d, ID %d",
 1099|       |            rc, MqttPacket_TypeDesc(packet_type), packet_type, packet_qos,
 1100|       |            packet_id);
 1101|       |    }
 1102|       |#endif
 1103|       |
 1104|     23|    return rc;
 1105|     40|}
mqtt_client.c:MqttClient_Publish_ReadPayload:
 1949|      6|{
 1950|      6|    int rc = MQTT_CODE_SUCCESS;
 1951|      6|    byte msg_done;
 1952|       |
 1953|       |    /* Handle packet callback and read remaining payload */
 1954|      6|    do {
 1955|       |        /* Determine if message is done */
 1956|      6|        msg_done = ((publish->buffer_pos + publish->buffer_len) >=
  ------------------
  |  Branch (1956:20): [True: 6, False: 0]
  ------------------
 1957|      6|                    publish->total_len) ? 1 : 0;
 1958|       |
 1959|      6|        if (publish->buffer_new) {
  ------------------
  |  Branch (1959:13): [True: 0, False: 6]
  ------------------
 1960|       |            /* Issue callback for new message (first time only) */
 1961|      0|            if (client->msg_cb) {
  ------------------
  |  Branch (1961:17): [True: 0, False: 0]
  ------------------
 1962|       |                /* if using the temp publish message buffer,
 1963|       |                   then populate message context with client context */
 1964|      0|                if (publish->ctx == NULL && &client->msg.publish == publish) {
  ------------------
  |  Branch (1964:21): [True: 0, False: 0]
  |  Branch (1964:45): [True: 0, False: 0]
  ------------------
 1965|      0|                    publish->ctx = client->ctx;
 1966|      0|                }
 1967|      0|                rc = client->msg_cb(client, publish, publish->buffer_new,
 1968|      0|                                    msg_done);
 1969|      0|                if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (1969:21): [True: 0, False: 0]
  ------------------
 1970|      0|                    return rc;
 1971|      0|                };
 1972|      0|            }
 1973|       |
 1974|       |            /* Reset topic name since valid on new message only */
 1975|      0|            publish->topic_name = NULL;
 1976|      0|            publish->topic_name_len = 0;
 1977|       |
 1978|      0|            publish->buffer_new = 0;
 1979|      0|        }
 1980|       |
 1981|       |        /* Read payload */
 1982|      6|        if (!msg_done) {
  ------------------
  |  Branch (1982:13): [True: 0, False: 6]
  ------------------
 1983|      0|            int msg_len;
 1984|       |
 1985|       |            /* add last length to position and reset len */
 1986|      0|            publish->buffer_pos += publish->buffer_len;
 1987|      0|            publish->buffer_len = 0;
 1988|       |
 1989|       |            /* set state to reading payload */
 1990|      0|            publish->stat.read = MQTT_MSG_PAYLOAD2;
 1991|       |
 1992|      0|            msg_len = (publish->total_len - publish->buffer_pos);
 1993|      0|            if (msg_len > client->rx_buf_len) {
  ------------------
  |  Branch (1993:17): [True: 0, False: 0]
  ------------------
 1994|      0|                msg_len = client->rx_buf_len;
 1995|      0|            }
 1996|       |
 1997|       |            /* make sure there is something to read */
 1998|      0|            if (msg_len > 0) {
  ------------------
  |  Branch (1998:17): [True: 0, False: 0]
  ------------------
 1999|      0|                rc = MqttSocket_Read(client, client->rx_buf, msg_len,
 2000|      0|                        timeout_ms);
 2001|      0|                if (rc < 0) {
  ------------------
  |  Branch (2001:21): [True: 0, False: 0]
  ------------------
 2002|      0|                    break;
 2003|      0|                }
 2004|       |
 2005|       |                /* Update message */
 2006|      0|                publish->buffer = client->rx_buf;
 2007|      0|                publish->buffer_len = rc;
 2008|      0|                rc = MQTT_CODE_SUCCESS; /* mark success */
 2009|       |
 2010|      0|                msg_done = ((publish->buffer_pos + publish->buffer_len) >=
  ------------------
  |  Branch (2010:28): [True: 0, False: 0]
  ------------------
 2011|      0|                    publish->total_len) ? 1 : 0;
 2012|       |
 2013|       |                /* Issue callback for additional publish payload */
 2014|      0|                if (client->msg_cb) {
  ------------------
  |  Branch (2014:21): [True: 0, False: 0]
  ------------------
 2015|      0|                    rc = client->msg_cb(client, publish, publish->buffer_new,
 2016|      0|                                        msg_done);
 2017|      0|                    if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (2017:25): [True: 0, False: 0]
  ------------------
 2018|      0|                        return rc;
 2019|      0|                    };
 2020|      0|                }
 2021|      0|            }
 2022|      0|        }
 2023|      6|    } while (!msg_done);
  ------------------
  |  Branch (2023:14): [True: 0, False: 6]
  ------------------
 2024|       |
 2025|      6|    return rc;
 2026|      6|}
mqtt_client.c:MqttPublishMsg:
 2177|    499|{
 2178|    499|    int rc = MQTT_CODE_SUCCESS;
 2179|    499|    MqttPacketType resp_type;
 2180|       |
 2181|       |    /* Validate required arguments */
 2182|    499|    if (client == NULL || publish == NULL) {
  ------------------
  |  Branch (2182:9): [True: 0, False: 499]
  |  Branch (2182:27): [True: 0, False: 499]
  ------------------
 2183|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2184|      0|    }
 2185|       |
 2186|    499|#ifdef WOLFMQTT_V5
 2187|       |    /* Use specified protocol version if set */
 2188|    499|    publish->protocol_level = client->protocol_level;
 2189|       |
 2190|       |    /* Validate publish request against server properties */
 2191|    499|    if ((publish->qos > client->max_qos) ||
  ------------------
  |  Branch (2191:9): [True: 0, False: 499]
  ------------------
 2192|    499|        ((publish->retain == 1) && (client->retain_avail == 0)))
  ------------------
  |  Branch (2192:10): [True: 89, False: 410]
  |  Branch (2192:36): [True: 0, False: 89]
  ------------------
 2193|      0|    {
 2194|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_SERVER_PROP);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2195|      0|    }
 2196|    499|#endif
 2197|       |
 2198|    499|    switch (publish->stat.write)
  ------------------
  |  Branch (2198:13): [True: 499, False: 0]
  ------------------
 2199|    499|    {
 2200|    499|        case MQTT_MSG_BEGIN:
  ------------------
  |  Branch (2200:9): [True: 499, False: 0]
  ------------------
 2201|    499|        {
 2202|       |            /* Flag write active / lock mutex */
 2203|    499|            if ((rc = MqttWriteStart(client, &publish->stat)) != 0) {
  ------------------
  |  Branch (2203:17): [True: 0, False: 499]
  ------------------
 2204|      0|                return rc;
 2205|      0|            }
 2206|       |
 2207|       |            /* Encode the publish packet */
 2208|    499|            rc = MqttEncode_Publish(client->tx_buf, client->tx_buf_len,
 2209|    499|                    publish, pubCb ? 1 : 0);
  ------------------
  |  Branch (2209:30): [True: 0, False: 499]
  ------------------
 2210|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 2211|       |            PRINTF("MqttClient_EncodePacket: Len %d, Type %s (%d), ID %d,"
 2212|       |                    " QoS %d",
 2213|       |                rc, MqttPacket_TypeDesc(MQTT_PACKET_TYPE_PUBLISH),
 2214|       |                MQTT_PACKET_TYPE_PUBLISH, publish->packet_id,
 2215|       |                publish->qos);
 2216|       |        #endif
 2217|    499|            if (rc <= 0) {
  ------------------
  |  Branch (2217:17): [True: 438, False: 61]
  ------------------
 2218|    438|                MqttWriteStop(client, &publish->stat);
 2219|    438|                return rc;
 2220|    438|            }
 2221|     61|            client->write.len = rc;
 2222|       |
 2223|       |        #ifdef WOLFMQTT_MULTITHREAD
 2224|       |            if (publish->qos > MQTT_QOS_0) {
 2225|       |                resp_type = (publish->qos == MQTT_QOS_1) ?
 2226|       |                        MQTT_PACKET_TYPE_PUBLISH_ACK :
 2227|       |                        MQTT_PACKET_TYPE_PUBLISH_COMP;
 2228|       |
 2229|       |                rc = wm_SemLock(&client->lockClient);
 2230|       |                if (rc == 0) {
 2231|       |                    /* inform other threads of expected response */
 2232|       |                    rc = MqttClient_RespList_Add(client, resp_type,
 2233|       |                        publish->packet_id, &publish->pendResp, &publish->resp);
 2234|       |                    wm_SemUnlock(&client->lockClient);
 2235|       |                }
 2236|       |                if (rc != 0) {
 2237|       |                    MqttWriteStop(client, &publish->stat);
 2238|       |                    return rc; /* Error locking client */
 2239|       |                }
 2240|       |            }
 2241|       |        #endif
 2242|       |
 2243|     61|            publish->stat.write = MQTT_MSG_HEADER;
 2244|     61|        }
 2245|     61|        FALL_THROUGH;
  ------------------
  |  |  472|     61|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 2246|       |
 2247|     61|        case MQTT_MSG_HEADER:
  ------------------
  |  Branch (2247:9): [True: 0, False: 499]
  ------------------
 2248|     61|        {
 2249|     61|            int xfer = client->write.len;
 2250|       |
 2251|       |            /* Send publish packet */
 2252|     61|            rc = MqttPacket_Write(client, client->tx_buf, xfer);
 2253|       |        #ifdef WOLFMQTT_NONBLOCK
 2254|       |            if (rc == MQTT_CODE_CONTINUE
 2255|       |            #ifdef WOLFMQTT_ALLOW_NODATA_UNLOCK
 2256|       |                && client->write.total > 0
 2257|       |            #endif
 2258|       |            ) {
 2259|       |                /* keep send locked and return early */
 2260|       |                return rc;
 2261|       |            }
 2262|       |        #endif
 2263|     61|            client->write.len = 0; /* reset len, so publish chunk resets */
 2264|       |
 2265|       |            /* if failure or no data was written yet */
 2266|     61|            if (rc != xfer) {
  ------------------
  |  Branch (2266:17): [True: 39, False: 22]
  ------------------
 2267|     39|                MqttWriteStop(client, &publish->stat);
 2268|     39|                MqttClient_CancelMessage(client, (MqttObject*)publish);
 2269|     39|                return rc;
 2270|     39|            }
 2271|       |
 2272|       |            /* advance state */
 2273|     22|            publish->stat.write = MQTT_MSG_PAYLOAD;
 2274|     22|        }
 2275|     22|        FALL_THROUGH;
  ------------------
  |  |  472|     22|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 2276|       |
 2277|     22|        case MQTT_MSG_PAYLOAD:
  ------------------
  |  Branch (2277:9): [True: 0, False: 499]
  ------------------
 2278|     22|        {
 2279|     22|            rc = MqttClient_Publish_WritePayload(client, publish, pubCb);
 2280|       |        #ifdef WOLFMQTT_NONBLOCK
 2281|       |            if (rc == MQTT_CODE_CONTINUE || rc == MQTT_CODE_PUB_CONTINUE)
 2282|       |                return rc;
 2283|       |        #endif
 2284|     22|            MqttWriteStop(client, &publish->stat);
 2285|     22|            if (rc < 0) {
  ------------------
  |  Branch (2285:17): [True: 19, False: 3]
  ------------------
 2286|     19|                MqttClient_CancelMessage(client, (MqttObject*)publish);
 2287|     19|                break;
 2288|     19|            }
 2289|       |
 2290|       |            /* if not expecting a reply then we are done */
 2291|      3|            if (publish->qos == MQTT_QOS_0) {
  ------------------
  |  Branch (2291:17): [True: 3, False: 0]
  ------------------
 2292|      3|                break;
 2293|      3|            }
 2294|      0|            publish->stat.write = MQTT_MSG_WAIT;
 2295|      0|        }
 2296|      0|        FALL_THROUGH;
  ------------------
  |  |  472|      0|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 2297|       |
 2298|      0|        case MQTT_MSG_WAIT:
  ------------------
  |  Branch (2298:9): [True: 0, False: 499]
  ------------------
 2299|      0|        {
 2300|       |            /* Handle QoS */
 2301|      0|            if (publish->qos > MQTT_QOS_0) {
  ------------------
  |  Branch (2301:17): [True: 0, False: 0]
  ------------------
 2302|       |                /* Determine packet type to wait for */
 2303|      0|                resp_type = (publish->qos == MQTT_QOS_1) ?
  ------------------
  |  Branch (2303:29): [True: 0, False: 0]
  ------------------
 2304|      0|                    MQTT_PACKET_TYPE_PUBLISH_ACK :
 2305|      0|                    MQTT_PACKET_TYPE_PUBLISH_COMP;
 2306|       |
 2307|       |            #ifdef WOLFMQTT_MULTITHREAD
 2308|       |                if (writeOnly) {
 2309|       |                    /* another thread will handle response */
 2310|       |                    /* check if response already received from other thread */
 2311|       |                    rc = MqttClient_CheckPendResp(client, resp_type,
 2312|       |                        publish->packet_id);
 2313|       |                #ifndef WOLFMQTT_NONBLOCK
 2314|       |                    if (rc == MQTT_CODE_CONTINUE) {
 2315|       |                        /* mark success, let other thread handle response */
 2316|       |                        rc = MQTT_CODE_SUCCESS;
 2317|       |                    }
 2318|       |                #endif
 2319|       |                }
 2320|       |                else
 2321|       |            #endif
 2322|      0|                {
 2323|      0|                    (void)writeOnly; /* not used */
 2324|       |
 2325|       |                    /* Wait for publish response packet */
 2326|      0|                    rc = MqttClient_WaitType(client, &publish->resp, resp_type,
 2327|      0|                        publish->packet_id, client->cmd_timeout_ms);
 2328|      0|                }
 2329|       |
 2330|       |            #if defined(WOLFMQTT_NONBLOCK) || defined(WOLFMQTT_MULTITHREAD)
 2331|       |                if (rc == MQTT_CODE_CONTINUE)
 2332|       |                    break;
 2333|       |            #endif
 2334|       |            #ifdef WOLFMQTT_MULTITHREAD
 2335|       |                if (wm_SemLock(&client->lockClient) == 0) {
 2336|       |                    MqttClient_RespList_Remove(client, &publish->pendResp);
 2337|       |                    wm_SemUnlock(&client->lockClient);
 2338|       |                }
 2339|       |            #endif
 2340|      0|            }
 2341|      0|            break;
 2342|      0|        }
 2343|       |
 2344|      0|        case MQTT_MSG_ACK:
  ------------------
  |  Branch (2344:9): [True: 0, False: 499]
  ------------------
 2345|      0|        case MQTT_MSG_AUTH:
  ------------------
  |  Branch (2345:9): [True: 0, False: 499]
  ------------------
 2346|      0|        case MQTT_MSG_PAYLOAD2:
  ------------------
  |  Branch (2346:9): [True: 0, False: 499]
  ------------------
 2347|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 2348|       |            PRINTF("MqttClient_Publish: Invalid state %d!",
 2349|       |                publish->stat.write);
 2350|       |        #endif
 2351|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_STAT);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2352|      0|            break;
 2353|    499|    } /* switch (publish->stat) */
 2354|       |
 2355|       |    /* reset state */
 2356|     22|    if ((rc != MQTT_CODE_PUB_CONTINUE)
  ------------------
  |  Branch (2356:9): [True: 22, False: 0]
  ------------------
 2357|       |#ifdef WOLFMQTT_NONBLOCK
 2358|       |         && (rc != MQTT_CODE_CONTINUE)
 2359|       |#endif
 2360|     22|        )
 2361|     22|    {
 2362|     22|        publish->stat.write = MQTT_MSG_BEGIN;
 2363|     22|    }
 2364|     22|    if (rc > 0) {
  ------------------
  |  Branch (2364:9): [True: 0, False: 22]
  ------------------
 2365|      0|        rc = MQTT_CODE_SUCCESS;
 2366|      0|    }
 2367|       |
 2368|     22|    return rc;
 2369|    499|}
mqtt_client.c:MqttClient_Publish_WritePayload:
 2030|     22|{
 2031|     22|    int rc = MQTT_CODE_SUCCESS;
 2032|       |
 2033|     22|    if (client == NULL || publish == NULL)
  ------------------
  |  Branch (2033:9): [True: 0, False: 22]
  |  Branch (2033:27): [True: 0, False: 22]
  ------------------
 2034|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2035|       |
 2036|     22|    if (pubCb) { /* use publish callback to get data */
  ------------------
  |  Branch (2036:9): [True: 0, False: 22]
  ------------------
 2037|      0|        word32 tmp_len = publish->buffer_len;
 2038|       |
 2039|      0|        do {
 2040|       |            /* use the client->write.len to handle non-blocking re-entry when
 2041|       |             * new publish callback data is needed */
 2042|      0|            if (client->write.len == 0) {
  ------------------
  |  Branch (2042:17): [True: 0, False: 0]
  ------------------
 2043|       |                /* Use the callback to get payload */
 2044|      0|                if ((client->write.len = pubCb(publish)) < 0) {
  ------------------
  |  Branch (2044:21): [True: 0, False: 0]
  ------------------
 2045|       |                #ifdef WOLFMQTT_DEBUG_CLIENT
 2046|       |                    PRINTF("Publish callback error %d", client->write.len);
 2047|       |                #endif
 2048|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_CALLBACK);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2049|      0|                }
 2050|      0|            }
 2051|       |
 2052|      0|            if ((word32)client->write.len < publish->buffer_len) {
  ------------------
  |  Branch (2052:17): [True: 0, False: 0]
  ------------------
 2053|       |                /* Last read */
 2054|      0|                tmp_len = (word32)client->write.len;
 2055|      0|            }
 2056|       |
 2057|       |            /* Send payload */
 2058|      0|            do {
 2059|      0|                if (client->write.len > client->tx_buf_len) {
  ------------------
  |  Branch (2059:21): [True: 0, False: 0]
  ------------------
 2060|      0|                    client->write.len = client->tx_buf_len;
 2061|      0|                }
 2062|      0|                publish->intBuf_len = client->write.len;
 2063|      0|                XMEMCPY(client->tx_buf, &publish->buffer[publish->intBuf_pos],
  ------------------
  |  |  987|      0|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 2064|      0|                    client->write.len);
 2065|       |
 2066|      0|                rc = MqttPacket_Write(client, client->tx_buf,
 2067|      0|                        client->write.len);
 2068|      0|                if (rc < 0) {
  ------------------
  |  Branch (2068:21): [True: 0, False: 0]
  ------------------
 2069|      0|                    return rc;
 2070|      0|                }
 2071|       |
 2072|      0|                publish->intBuf_pos += publish->intBuf_len;
 2073|      0|                publish->intBuf_len = 0;
 2074|       |
 2075|      0|            } while (publish->intBuf_pos < tmp_len);
  ------------------
  |  Branch (2075:22): [True: 0, False: 0]
  ------------------
 2076|       |
 2077|      0|            publish->buffer_pos += publish->intBuf_pos;
 2078|      0|            publish->intBuf_pos = 0;
 2079|      0|            client->write.len = 0; /* reset current write len */
 2080|       |
 2081|      0|        } while (publish->buffer_pos < publish->total_len);
  ------------------
  |  Branch (2081:18): [True: 0, False: 0]
  ------------------
 2082|      0|    }
 2083|     22|    else if (publish->buffer_pos < publish->total_len) {
  ------------------
  |  Branch (2083:14): [True: 22, False: 0]
  ------------------
 2084|     22|        if (publish->buffer_pos > 0) {
  ------------------
  |  Branch (2084:13): [True: 22, False: 0]
  ------------------
 2085|     22|            client->write.len = (publish->total_len - publish->buffer_pos);
 2086|     22|            if (client->write.len > client->tx_buf_len) {
  ------------------
  |  Branch (2086:17): [True: 17, False: 5]
  ------------------
 2087|     17|                client->write.len = client->tx_buf_len;
 2088|     17|            }
 2089|       |
 2090|     22|            XMEMCPY(client->tx_buf, &publish->buffer[publish->buffer_pos],
  ------------------
  |  |  987|     22|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 2091|     22|                client->write.len);
 2092|       |
 2093|     22|        #ifndef WOLFMQTT_NONBLOCK
 2094|     22|            publish->intBuf_pos += client->write.len;
 2095|     22|        #endif
 2096|     22|        }
 2097|       |
 2098|       |        /* Send packet and payload */
 2099|       |    #ifdef WOLFMQTT_NONBLOCK
 2100|       |            rc = MqttPacket_Write(client, client->tx_buf, client->write.len);
 2101|       |            if (rc < 0) {
 2102|       |                return rc;
 2103|       |            }
 2104|       |
 2105|       |            /* ONLY if send was successful, update buffer position.
 2106|       |             * Otherwise, MqttPacket_Write() will resume where it left off. */
 2107|       |            publish->buffer_pos += client->write.len;
 2108|       |
 2109|       |            /* Check if we are done sending publish message */
 2110|       |            if (publish->buffer_pos < publish->buffer_len) {
 2111|       |            #ifdef WOLFMQTT_DEBUG_CLIENT
 2112|       |                PRINTF("Publish Write: not done (%d remain)",
 2113|       |                    publish->buffer_len - publish->buffer_pos);
 2114|       |            #endif
 2115|       |                return MQTT_CODE_PUB_CONTINUE;
 2116|       |            }
 2117|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 2118|       |            else {
 2119|       |                PRINTF("Publish Write: done");
 2120|       |            }
 2121|       |        #endif
 2122|       |    #else
 2123|     85|        do {
 2124|     85|            rc = MqttPacket_Write(client, client->tx_buf, client->write.len);
 2125|     85|            if (rc < 0) {
  ------------------
  |  Branch (2125:17): [True: 19, False: 66]
  ------------------
 2126|     19|                return rc;
 2127|     19|            }
 2128|       |
 2129|     66|            publish->intBuf_pos += publish->intBuf_len;
 2130|     66|            publish->intBuf_len = 0;
 2131|       |
 2132|       |            /* Check if we are done sending publish message */
 2133|     66|            if (publish->intBuf_pos >= publish->buffer_len) {
  ------------------
  |  Branch (2133:17): [True: 3, False: 63]
  ------------------
 2134|      3|                rc = MQTT_CODE_SUCCESS;
 2135|      3|                break;
 2136|      3|            }
 2137|       |
 2138|       |            /* Build packet payload to send */
 2139|     63|            client->write.len = (publish->buffer_len - publish->intBuf_pos);
 2140|     63|            if (client->write.len > client->tx_buf_len) {
  ------------------
  |  Branch (2140:17): [True: 52, False: 11]
  ------------------
 2141|     52|                client->write.len = client->tx_buf_len;
 2142|     52|            }
 2143|     63|            publish->intBuf_len = client->write.len;
 2144|     63|            XMEMCPY(client->tx_buf, &publish->buffer[publish->intBuf_pos],
  ------------------
  |  |  987|     63|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 2145|     63|                client->write.len);
 2146|     63|        } while (publish->intBuf_pos < publish->buffer_len);
  ------------------
  |  Branch (2146:18): [True: 63, False: 0]
  ------------------
 2147|      3|    #endif
 2148|       |
 2149|      3|        if (rc >= 0) {
  ------------------
  |  Branch (2149:13): [True: 3, False: 0]
  ------------------
 2150|       |            /* If transferring more chunks */
 2151|      3|            publish->buffer_pos += publish->intBuf_pos;
 2152|      3|            if (publish->buffer_pos < publish->total_len) {
  ------------------
  |  Branch (2152:17): [True: 0, False: 3]
  ------------------
 2153|       |            #ifdef WOLFMQTT_DEBUG_CLIENT
 2154|       |                PRINTF("Publish Write: chunk (%d remain)",
 2155|       |                    publish->total_len - publish->buffer_pos);
 2156|       |            #endif
 2157|       |
 2158|       |                /* Build next payload to send */
 2159|      0|                client->write.len = (publish->total_len - publish->buffer_pos);
 2160|      0|                if (client->write.len > client->tx_buf_len) {
  ------------------
  |  Branch (2160:21): [True: 0, False: 0]
  ------------------
 2161|      0|                    client->write.len = client->tx_buf_len;
 2162|      0|                }
 2163|      0|                rc = MQTT_CODE_PUB_CONTINUE;
 2164|      0|            }
 2165|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 2166|       |            else {
 2167|       |                PRINTF("Publish Write: chunked done");
 2168|       |            }
 2169|       |        #endif
 2170|      3|        }
 2171|      3|    }
 2172|      3|    return rc;
 2173|     22|}
mqtt_client.c:MqttClient_CancelMessage:
 2930|  2.47k|{
 2931|  2.47k|    int rc = MQTT_CODE_SUCCESS;
 2932|  2.47k|    MqttMsgStat* mms_stat;
 2933|       |#ifdef WOLFMQTT_MULTITHREAD
 2934|       |    MqttPendResp* tmpResp;
 2935|       |#endif
 2936|       |
 2937|  2.47k|    if (client == NULL || msg == NULL) {
  ------------------
  |  Branch (2937:9): [True: 0, False: 2.47k]
  |  Branch (2937:27): [True: 0, False: 2.47k]
  ------------------
 2938|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2939|      0|    }
 2940|       |
 2941|       |    /* all packet type structures must have MqttMsgStat at top */
 2942|  2.47k|    mms_stat = (MqttMsgStat*)msg;
 2943|       |
 2944|       |#ifdef WOLFMQTT_DEBUG_CLIENT
 2945|       |    PRINTF("Cancel Msg: %p", msg);
 2946|       |#endif
 2947|       |
 2948|       |    /* reset states */
 2949|  2.47k|    mms_stat->write = MQTT_MSG_BEGIN;
 2950|  2.47k|    mms_stat->read = MQTT_MSG_BEGIN;
 2951|       |
 2952|       |#ifdef WOLFMQTT_MULTITHREAD
 2953|       |    /* Remove any pending responses expected */
 2954|       |    rc = wm_SemLock(&client->lockClient);
 2955|       |    if (rc != MQTT_CODE_SUCCESS) {
 2956|       |        return rc;
 2957|       |    }
 2958|       |
 2959|       |    for (tmpResp = client->firstPendResp;
 2960|       |         tmpResp != NULL;
 2961|       |         tmpResp = tmpResp->next)
 2962|       |    {
 2963|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2964|       |        PRINTF("\tMsg: %p (obj %p), Type %s (%d), ID %d, InProc %d, Done %d",
 2965|       |            tmpResp, tmpResp->packet_obj,
 2966|       |            MqttPacket_TypeDesc(tmpResp->packet_type),
 2967|       |            tmpResp->packet_type, tmpResp->packet_id,
 2968|       |            tmpResp->packetProcessing, tmpResp->packetDone);
 2969|       |    #endif
 2970|       |        if ((size_t)tmpResp->packet_obj == (size_t)msg ||
 2971|       |            (size_t)tmpResp - OFFSETOF(MqttMessage, pendResp) == (size_t)msg) {
 2972|       |        #ifdef WOLFMQTT_DEBUG_CLIENT
 2973|       |            PRINTF("Found Cancel Msg: %p (obj %p), Type %s (%d), ID %d, "
 2974|       |                   "InProc %d, Done %d",
 2975|       |                tmpResp, tmpResp->packet_obj,
 2976|       |                MqttPacket_TypeDesc(tmpResp->packet_type),
 2977|       |                tmpResp->packet_type, tmpResp->packet_id,
 2978|       |                tmpResp->packetProcessing, tmpResp->packetDone);
 2979|       |        #endif
 2980|       |            MqttClient_RespList_Remove(client, tmpResp);
 2981|       |            break;
 2982|       |        }
 2983|       |    }
 2984|       |    wm_SemUnlock(&client->lockClient);
 2985|       |#endif /* WOLFMQTT_MULTITHREAD */
 2986|       |
 2987|       |    /* cancel any active flags / locks */
 2988|  2.47k|    if (mms_stat->isReadActive) {
  ------------------
  |  Branch (2988:9): [True: 0, False: 2.47k]
  ------------------
 2989|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2990|       |        PRINTF("Cancel Read Lock");
 2991|       |    #endif
 2992|      0|        MqttReadStop(client, mms_stat);
 2993|      0|    }
 2994|  2.47k|    if (mms_stat->isWriteActive) {
  ------------------
  |  Branch (2994:9): [True: 0, False: 2.47k]
  ------------------
 2995|       |    #ifdef WOLFMQTT_DEBUG_CLIENT
 2996|       |        PRINTF("Cancel Write Lock");
 2997|       |    #endif
 2998|      0|        MqttWriteStop(client, mms_stat);
 2999|      0|    }
 3000|       |
 3001|  2.47k|    return rc;
 3002|  2.47k|}

MqttPacket_TopicNameValid:
  303|    531|{
  304|    531|    word16 i;
  305|    531|    if (topic_name == NULL) {
  ------------------
  |  Branch (305:9): [True: 0, False: 531]
  ------------------
  306|      0|        return 0;
  307|      0|    }
  308|  79.6k|    for (i = 0; i < len; i++) {
  ------------------
  |  Branch (308:17): [True: 79.1k, False: 488]
  ------------------
  309|  79.1k|        if (topic_name[i] == '#' || topic_name[i] == '+') {
  ------------------
  |  Branch (309:13): [True: 15, False: 79.0k]
  |  Branch (309:37): [True: 28, False: 79.0k]
  ------------------
  310|     43|            return 0;
  311|     43|        }
  312|  79.1k|    }
  313|    488|    if (len == 0 && protocol_level < MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|    316|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (313:9): [True: 316, False: 172]
  |  Branch (313:21): [True: 316, False: 0]
  ------------------
  314|    316|        return 0;
  315|    316|    }
  316|    172|    return 1;
  317|    488|}
MqttPacket_FixedHeaderFlagsValid:
  340|  2.01k|{
  341|  2.01k|    byte type = (byte)MQTT_PACKET_TYPE_GET(type_flags);
  ------------------
  |  |  244|  2.01k|#define MQTT_PACKET_TYPE_GET(x)  (((x) >> 4) & 0xF)
  ------------------
  342|  2.01k|    byte flags = (byte)MQTT_PACKET_FLAGS_GET(type_flags);
  ------------------
  |  |  267|  2.01k|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  ------------------
  343|  2.01k|    byte expected;
  344|       |
  345|  2.01k|    if (type == MQTT_PACKET_TYPE_PUBLISH) {
  ------------------
  |  Branch (345:9): [True: 225, False: 1.78k]
  ------------------
  346|    225|        byte qos = (byte)MQTT_PACKET_FLAGS_GET_QOS(type_flags);
  ------------------
  |  |  270|    225|    ((MQTT_PACKET_FLAGS_GET((type_flags)) & \
  |  |  ------------------
  |  |  |  |  267|    225|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  |  |  ------------------
  |  |  271|    225|        MQTT_PACKET_FLAG_QOS_MASK) >> MQTT_PACKET_FLAG_QOS_SHIFT)
  ------------------
  347|    225|        byte dup = (flags & MQTT_PACKET_FLAG_DUPLICATE) ? 1 : 0;
  ------------------
  |  Branch (347:20): [True: 111, False: 114]
  ------------------
  348|    225|        if (qos > MQTT_QOS_2) {
  ------------------
  |  Branch (348:13): [True: 42, False: 183]
  ------------------
  349|     42|            return 0;
  350|     42|        }
  351|    183|        if (qos == MQTT_QOS_0 && dup) {
  ------------------
  |  Branch (351:13): [True: 62, False: 121]
  |  Branch (351:34): [True: 3, False: 59]
  ------------------
  352|      3|            return 0;
  353|      3|        }
  354|    180|        return 1;
  355|    183|    }
  356|  1.78k|    if (FixedHeaderFlagsExpected(type, &expected)) {
  ------------------
  |  Branch (356:9): [True: 1.78k, False: 0]
  ------------------
  357|  1.78k|        return (flags == expected) ? 1 : 0;
  ------------------
  |  Branch (357:16): [True: 114, False: 1.67k]
  ------------------
  358|  1.78k|    }
  359|       |    /* Reserved (type 0) or otherwise unrecognized packet type - reject so
  360|       |     * this helper is safe to use as a protocol-level malformed-packet
  361|       |     * gate. The broker uses it pre-dispatch, so anything it accepts has
  362|       |     * to be a known type. */
  363|      0|    return 0;
  364|  1.78k|}
MqttDecode_Vbi:
  412|  5.02k|{
  413|  5.02k|    word32 rc = 0;
  414|  5.02k|    word32 multiplier = 1;
  415|  5.02k|    byte encodedByte;
  416|       |
  417|  5.02k|    *value = 0;
  418|  5.89k|    do {
  419|  5.89k|        if (buf_len < rc + 1) {
  ------------------
  |  Branch (419:13): [True: 2, False: 5.89k]
  ------------------
  420|      2|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      2|#define MQTT_TRACE_ERROR(err) err
  ------------------
  421|      2|        }
  422|  5.89k|        if (rc >= 4) {
  ------------------
  |  Branch (422:13): [True: 0, False: 5.89k]
  ------------------
  423|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  424|      0|        }
  425|       |
  426|  5.89k|        encodedByte = *(buf++);
  427|  5.89k|        *value += (word32)(encodedByte & ~MQTT_PACKET_LEN_ENCODE_MASK) *
  ------------------
  |  |  284|  5.89k|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  428|  5.89k|                           multiplier;
  429|  5.89k|        multiplier *= MQTT_PACKET_LEN_ENCODE_MASK;
  ------------------
  |  |  284|  5.89k|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  430|  5.89k|        rc++;
  431|  5.89k|    } while ((encodedByte & MQTT_PACKET_LEN_ENCODE_MASK) != 0);
  ------------------
  |  |  284|  5.89k|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  |  Branch (431:14): [True: 876, False: 5.01k]
  ------------------
  432|       |
  433|       |    /* [MQTT-1.5.5-1] Reject non-canonical overlong encodings */
  434|  5.01k|    if (rc > 1 && encodedByte == 0) {
  ------------------
  |  Branch (434:9): [True: 656, False: 4.36k]
  |  Branch (434:19): [True: 75, False: 581]
  ------------------
  435|     75|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|     75|#define MQTT_TRACE_ERROR(err) err
  ------------------
  436|     75|    }
  437|       |
  438|  4.94k|    return (int)rc;
  439|  5.01k|}
MqttEncode_Vbi:
  445|  4.37k|{
  446|  4.37k|    int rc = 0;
  447|  4.37k|    byte encodedByte;
  448|       |
  449|       |    /* [MQTT-2.2.3]: Max value is 268,435,455 (0x0FFFFFFF) */
  450|  4.37k|    if (x > MQTT_PACKET_MAX_REMAIN_LEN) {
  ------------------
  |  |  286|  4.37k|#define MQTT_PACKET_MAX_REMAIN_LEN  0x0FFFFFFFUL /* 268,435,455 */
  ------------------
  |  Branch (450:9): [True: 0, False: 4.37k]
  ------------------
  451|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  452|      0|    }
  453|       |
  454|  4.58k|    do {
  455|  4.58k|        encodedByte = (x & ~MQTT_PACKET_LEN_ENCODE_MASK) & 0xFF;
  ------------------
  |  |  284|  4.58k|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  456|  4.58k|        x >>= 7;
  457|       |        /* if there are more data to encode, set the top bit of this byte */
  458|  4.58k|        if (x > 0) {
  ------------------
  |  Branch (458:13): [True: 218, False: 4.37k]
  ------------------
  459|    218|            encodedByte |= MQTT_PACKET_LEN_ENCODE_MASK;
  ------------------
  |  |  284|    218|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  460|    218|        }
  461|  4.58k|        if (buf != NULL) {
  ------------------
  |  Branch (461:13): [True: 4.58k, False: 0]
  ------------------
  462|  4.58k|            *(buf++) = encodedByte;
  463|  4.58k|        }
  464|  4.58k|        rc++;
  465|  4.58k|    } while (x > 0 && rc < 4);
  ------------------
  |  Branch (465:14): [True: 218, False: 4.37k]
  |  Branch (465:23): [True: 218, False: 0]
  ------------------
  466|       |
  467|  4.37k|    return rc;
  468|  4.37k|}
MqttDecode_Num:
  472|    197|{
  473|    197|    if (buf_len < MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|    197|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (473:9): [True: 89, False: 108]
  ------------------
  474|     89|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|     89|#define MQTT_TRACE_ERROR(err) err
  ------------------
  475|     89|    }
  476|    108|    if (len) {
  ------------------
  |  Branch (476:9): [True: 108, False: 0]
  ------------------
  477|    108|        *len =  (word32)buf[0] << 8;
  478|    108|        *len += buf[1];
  479|    108|    }
  480|    108|    return MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|    108|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  481|    197|}
MqttEncode_Num:
  486|  6.58k|{
  487|  6.58k|    if (buf != NULL) {
  ------------------
  |  Branch (487:9): [True: 6.58k, False: 0]
  ------------------
  488|  6.58k|        buf[0] = len >> 8;
  489|  6.58k|        buf[1] = len & 0xFF;
  490|  6.58k|    }
  491|  6.58k|    return MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|  6.58k|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  492|  6.58k|}
MqttDecode_String:
  605|    182|{
  606|    182|    int len;
  607|    182|    word16 str_len;
  608|    182|    len = MqttDecode_Num(buf, &str_len, buf_len);
  609|    182|    if (len < 0) {
  ------------------
  |  Branch (609:9): [True: 89, False: 93]
  ------------------
  610|     89|        return len;
  611|     89|    }
  612|     93|    if ((word32)str_len > buf_len - (word32)len) {
  ------------------
  |  Branch (612:9): [True: 36, False: 57]
  ------------------
  613|     36|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|     36|#define MQTT_TRACE_ERROR(err) err
  ------------------
  614|     36|    }
  615|     57|    buf += len;
  616|     57|    if (str_len > 0) {
  ------------------
  |  Branch (616:9): [True: 25, False: 32]
  ------------------
  617|     25|    #ifndef WOLFMQTT_NO_UTF8_VALIDATION
  618|       |        /* [MQTT-1.5.3-1] Reject ill-formed UTF-8 (RFC 3629). */
  619|     25|        if (!Utf8WellFormed(buf, str_len)) {
  ------------------
  |  Branch (619:13): [True: 25, False: 0]
  ------------------
  620|     25|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|     25|#define MQTT_TRACE_ERROR(err) err
  ------------------
  621|     25|        }
  622|      0|    #endif
  623|       |        /* [MQTT-1.5.3-2] / [MQTT-1.5.4-2]: an MQTT UTF-8 encoded string
  624|       |         * MUST NOT include the null character (U+0000). Although U+0000
  625|       |         * is well-formed UTF-8, it is forbidden in MQTT string fields -
  626|       |         * downstream C-string handling would otherwise be tricked by an
  627|       |         * embedded NUL truncating the value (e.g., a topic "se\0cret"
  628|       |         * would route to subscribers of "se"). The CONNECT Password
  629|       |         * field is Binary Data per [MQTT-3.1.3.5] and bypasses this
  630|       |         * helper; binary fields tolerate embedded NULs. */
  631|      0|        if (XMEMCHR(buf, 0x00, str_len) != NULL) {
  ------------------
  |  |  276|      0|        #define XMEMCHR(s,c,n)      memchr((s),(c),(n))
  ------------------
  |  Branch (631:13): [True: 0, False: 0]
  ------------------
  632|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  633|      0|        }
  634|      0|    }
  635|     32|    if (pstr_len) {
  ------------------
  |  Branch (635:9): [True: 32, False: 0]
  ------------------
  636|     32|        *pstr_len = str_len;
  637|     32|    }
  638|     32|    if (pstr) {
  ------------------
  |  Branch (638:9): [True: 32, False: 0]
  ------------------
  639|     32|        *pstr = (char*)buf;
  640|     32|    }
  641|     32|    return len + str_len;
  642|     57|}
MqttEncode_String:
  647|  3.20k|{
  648|  3.20k|    int str_len = (int)XSTRLEN(str);
  ------------------
  |  |  992|  3.20k|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
  649|  3.20k|    int len;
  650|       |
  651|       |    /* MQTT UTF-8 strings are limited to 65535 bytes [MQTT-1.5.3] */
  652|  3.20k|    if (str_len > (int)0xFFFF) {
  ------------------
  |  Branch (652:9): [True: 0, False: 3.20k]
  ------------------
  653|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  654|      0|    }
  655|  3.20k|    len = MqttEncode_Num(buf, (word16)str_len);
  656|       |
  657|  3.20k|    if (buf != NULL) {
  ------------------
  |  Branch (657:9): [True: 3.20k, False: 0]
  ------------------
  658|  3.20k|        buf += len;
  659|  3.20k|        XMEMCPY(buf, str, str_len);
  ------------------
  |  |  987|  3.20k|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
  660|  3.20k|    }
  661|  3.20k|    return len + str_len;
  662|  3.20k|}
MqttEncode_Data:
  667|     14|{
  668|     14|    int len = MqttEncode_Num(buf, data_len);
  669|       |
  670|     14|    if ((buf != NULL) && (data != NULL)) {
  ------------------
  |  Branch (670:9): [True: 14, False: 0]
  |  Branch (670:26): [True: 7, False: 7]
  ------------------
  671|      7|        buf += len;
  672|      7|        XMEMCPY(buf, data, data_len);
  ------------------
  |  |  987|      7|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
  673|      7|    }
  674|     14|    return len + data_len;
  675|     14|}
MqttDecode_Props:
  824|     10|{
  825|     10|    int rc = 0;
  826|     10|    int total, tmp;
  827|     10|    MqttProp* cur_prop;
  828|     10|    byte* buf = pbuf;
  829|       |
  830|     10|    total = 0;
  831|       |
  832|     12|    while (((int)prop_len > 0) && (rc >= 0))
  ------------------
  |  Branch (832:12): [True: 12, False: 0]
  |  Branch (832:35): [True: 10, False: 2]
  ------------------
  833|     10|    {
  834|       |        /* Allocate a structure and add to head. */
  835|     10|        cur_prop = MqttProps_Add(props);
  836|     10|        if (cur_prop == NULL) {
  ------------------
  |  Branch (836:13): [True: 0, False: 10]
  ------------------
  837|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MEMORY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  838|      0|            break;
  839|      0|        }
  840|       |
  841|       |        /* Check boundary before VBI decoding */
  842|     10|        if ((buf - pbuf) > (int)buf_len) {
  ------------------
  |  Branch (842:13): [True: 0, False: 10]
  ------------------
  843|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  844|      0|            break;
  845|      0|        }
  846|       |        /* Decode the Identifier */
  847|     10|        rc = MqttDecode_Vbi(buf, (word32*)&cur_prop->type,
  848|     10|                (word32)(buf_len - (buf - pbuf)));
  849|     10|        if (rc < 0) {
  ------------------
  |  Branch (849:13): [True: 1, False: 9]
  ------------------
  850|      1|            break;
  851|      1|        }
  852|      9|        tmp = rc;
  853|      9|        buf += tmp;
  854|      9|        total += tmp;
  855|      9|        prop_len -= tmp;
  856|       |
  857|      9|        if (cur_prop->type >= sizeof(gPropMatrix) / sizeof(gPropMatrix[0])) {
  ------------------
  |  Branch (857:13): [True: 0, False: 9]
  ------------------
  858|      0|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  859|      0|            break;
  860|      0|        }
  861|       |
  862|       |        /* Validate property type is allowed for packet type */
  863|      9|        if (!(gPropMatrix[cur_prop->type].packet_type_mask & (1 << packet))) {
  ------------------
  |  Branch (863:13): [True: 7, False: 2]
  ------------------
  864|      7|            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY_MISMATCH);
  ------------------
  |  |  392|      7|#define MQTT_TRACE_ERROR(err) err
  ------------------
  865|      7|            break;
  866|      7|        }
  867|       |
  868|      2|        switch (gPropMatrix[cur_prop->type].data)
  869|      2|        {
  870|      0|            case MQTT_DATA_TYPE_BYTE:
  ------------------
  |  Branch (870:13): [True: 0, False: 2]
  ------------------
  871|      0|            {
  872|      0|                if ((buf - pbuf) >= (int)buf_len || prop_len < 1) {
  ------------------
  |  Branch (872:21): [True: 0, False: 0]
  |  Branch (872:53): [True: 0, False: 0]
  ------------------
  873|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  874|      0|                    break;
  875|      0|                }
  876|      0|                cur_prop->data_byte = *buf++;
  877|      0|                tmp++;
  878|      0|                total++;
  879|      0|                prop_len--;
  880|      0|                break;
  881|      0|            }
  882|      0|            case MQTT_DATA_TYPE_SHORT:
  ------------------
  |  Branch (882:13): [True: 0, False: 2]
  ------------------
  883|      0|            {
  884|      0|                if ((buf - pbuf) > (int)buf_len) {
  ------------------
  |  Branch (884:21): [True: 0, False: 0]
  ------------------
  885|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  886|      0|                    break;
  887|      0|                }
  888|      0|                tmp = MqttDecode_Num(buf, &cur_prop->data_short,
  889|      0|                        (word32)(buf_len - (buf - pbuf)));
  890|      0|                if (tmp < 0) {
  ------------------
  |  Branch (890:21): [True: 0, False: 0]
  ------------------
  891|      0|                    rc = tmp;
  892|      0|                    break;
  893|      0|                }
  894|      0|                buf += tmp;
  895|      0|                total += tmp;
  896|      0|                prop_len -= (word32)tmp;
  897|      0|                break;
  898|      0|            }
  899|      0|            case MQTT_DATA_TYPE_INT:
  ------------------
  |  Branch (899:13): [True: 0, False: 2]
  ------------------
  900|      0|            {
  901|      0|                if ((buf - pbuf) > (int)buf_len ||
  ------------------
  |  Branch (901:21): [True: 0, False: 0]
  ------------------
  902|      0|                     prop_len < MQTT_DATA_INT_SIZE) {
  ------------------
  |  |   40|      0|#define MQTT_DATA_INT_SIZE   4
  ------------------
  |  Branch (902:22): [True: 0, False: 0]
  ------------------
  903|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  904|      0|                    break;
  905|      0|                }
  906|      0|                tmp = MqttDecode_Int(buf, &cur_prop->data_int,
  907|      0|                        (word32)(buf_len - (buf - pbuf)));
  908|      0|                if (tmp < 0) {
  ------------------
  |  Branch (908:21): [True: 0, False: 0]
  ------------------
  909|      0|                    rc = tmp;
  910|      0|                    break;
  911|      0|                }
  912|      0|                buf += tmp;
  913|      0|                total += tmp;
  914|      0|                prop_len -= tmp;
  915|      0|                break;
  916|      0|            }
  917|      0|            case MQTT_DATA_TYPE_STRING:
  ------------------
  |  Branch (917:13): [True: 0, False: 2]
  ------------------
  918|      0|            {
  919|      0|                if ((buf - pbuf) > (int)buf_len) {
  ------------------
  |  Branch (919:21): [True: 0, False: 0]
  ------------------
  920|       |                    /* Should already be caught earlier, but safe to recheck */
  921|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  922|      0|                    break;
  923|      0|                }
  924|      0|                tmp = MqttDecode_String(buf,
  925|      0|                        (const char**)&cur_prop->data_str.str,
  926|      0|                        &cur_prop->data_str.len,
  927|      0|                        (word32)(buf_len - (buf - pbuf)));
  928|      0|                if (tmp < 0) {
  ------------------
  |  Branch (928:21): [True: 0, False: 0]
  ------------------
  929|       |                    /* Preserve specific error (e.g., MALFORMED_DATA from
  930|       |                     * UTF-8 check) instead of masking as PROPERTY. */
  931|      0|                    rc = tmp;
  932|      0|                }
  933|      0|                else if ((word32)tmp <= (buf_len - (buf - pbuf))) {
  ------------------
  |  Branch (933:26): [True: 0, False: 0]
  ------------------
  934|      0|                    buf += tmp;
  935|      0|                    total += tmp;
  936|      0|                    prop_len -= (word32)tmp;
  937|      0|                }
  938|      0|                else {
  939|       |                    /* Invalid length */
  940|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  941|      0|                }
  942|      0|                break;
  943|      0|            }
  944|      0|            case MQTT_DATA_TYPE_VAR_INT:
  ------------------
  |  Branch (944:13): [True: 0, False: 2]
  ------------------
  945|      0|            {
  946|      0|                if (buf_len < (word32)(buf - pbuf)) {
  ------------------
  |  Branch (946:21): [True: 0, False: 0]
  ------------------
  947|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  948|      0|                    break;
  949|      0|                }
  950|      0|                tmp = MqttDecode_Vbi(buf, &cur_prop->data_int,
  951|      0|                        (word32)(buf_len - (buf - pbuf)));
  952|      0|                if (tmp < 0) {
  ------------------
  |  Branch (952:21): [True: 0, False: 0]
  ------------------
  953|      0|                    rc = tmp;
  954|      0|                    break;
  955|      0|                }
  956|      0|                buf += tmp;
  957|      0|                total += tmp;
  958|      0|                prop_len -= (word32)tmp;
  959|      0|                break;
  960|      0|            }
  961|      0|            case MQTT_DATA_TYPE_BINARY:
  ------------------
  |  Branch (961:13): [True: 0, False: 2]
  ------------------
  962|      0|            {
  963|       |                /* Binary type is a two byte integer "length"
  964|       |                   followed by that number of bytes */
  965|      0|                tmp = MqttDecode_Num(buf, &cur_prop->data_bin.len,
  966|      0|                        (word32)(buf_len - (buf - pbuf)));
  967|      0|                if (tmp < 0) {
  ------------------
  |  Branch (967:21): [True: 0, False: 0]
  ------------------
  968|      0|                    rc = tmp;
  969|      0|                    break;
  970|      0|                }
  971|      0|                buf += tmp;
  972|      0|                total += tmp;
  973|      0|                prop_len -= tmp;
  974|       |
  975|      0|                if (cur_prop->data_bin.len <= (buf_len - (buf - pbuf))) {
  ------------------
  |  Branch (975:21): [True: 0, False: 0]
  ------------------
  976|      0|                    cur_prop->data_bin.data = buf;
  977|      0|                    buf += cur_prop->data_bin.len;
  978|      0|                    total += (int)cur_prop->data_bin.len;
  979|      0|                    prop_len -= cur_prop->data_bin.len;
  980|      0|                }
  981|      0|                else {
  982|       |                    /* Invalid length */
  983|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  984|      0|                }
  985|      0|                break;
  986|      0|            }
  987|      2|            case MQTT_DATA_TYPE_STRING_PAIR:
  ------------------
  |  Branch (987:13): [True: 2, False: 0]
  ------------------
  988|      2|            {
  989|       |                /* String is prefixed with a Two Byte Integer length
  990|       |                   field that gives the number of bytes */
  991|      2|                tmp = MqttDecode_String(buf,
  992|      2|                        (const char**)&cur_prop->data_str.str,
  993|      2|                        &cur_prop->data_str.len,
  994|      2|                        (word32)(buf_len - (buf - pbuf)));
  995|      2|                if (tmp < 0) {
  ------------------
  |  Branch (995:21): [True: 2, False: 0]
  ------------------
  996|      2|                    rc = tmp;
  997|      2|                }
  998|      0|                else if ((word32)tmp <= (buf_len - (buf - pbuf))) {
  ------------------
  |  Branch (998:26): [True: 0, False: 0]
  ------------------
  999|      0|                    buf += tmp;
 1000|      0|                    total += tmp;
 1001|      0|                    prop_len -= (word32)tmp;
 1002|      0|                    if ((buf_len - (buf - pbuf)) > 0) {
  ------------------
  |  Branch (1002:25): [True: 0, False: 0]
  ------------------
 1003|      0|                        tmp = MqttDecode_String(buf,
 1004|      0|                                (const char**)&cur_prop->data_str2.str,
 1005|      0|                                &cur_prop->data_str2.len,
 1006|      0|                                (word32)(buf_len - (buf - pbuf)));
 1007|      0|                        if (tmp < 0) {
  ------------------
  |  Branch (1007:29): [True: 0, False: 0]
  ------------------
 1008|      0|                            rc = tmp;
 1009|      0|                        }
 1010|      0|                        else if ((word32)tmp <=
  ------------------
  |  Branch (1010:34): [True: 0, False: 0]
  ------------------
 1011|      0|                                 (buf_len - (buf - pbuf))) {
 1012|      0|                            buf += tmp;
 1013|      0|                            total += tmp;
 1014|      0|                            prop_len -= (word32)tmp;
 1015|      0|                        }
 1016|      0|                        else {
 1017|       |                            /* Invalid length */
 1018|      0|                            rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1019|      0|                        }
 1020|      0|                    }
 1021|      0|                    else {
 1022|       |                        /* Invalid length */
 1023|      0|                        rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1024|      0|                    }
 1025|      0|                }
 1026|      0|                else {
 1027|       |                    /* Invalid length */
 1028|      0|                    rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1029|      0|                }
 1030|      2|                break;
 1031|      0|            }
 1032|      0|            case MQTT_DATA_TYPE_NONE:
  ------------------
  |  Branch (1032:13): [True: 0, False: 2]
  ------------------
 1033|      0|            default:
  ------------------
  |  Branch (1033:13): [True: 0, False: 2]
  ------------------
 1034|      0|            {
 1035|       |                /* Invalid property data type */
 1036|      0|                rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1037|      0|                break;
 1038|      0|            }
 1039|      2|        }
 1040|     10|    };
 1041|       |
 1042|     10|    if (rc < 0) {
  ------------------
  |  Branch (1042:9): [True: 10, False: 0]
  ------------------
 1043|       |        /* Free the property */
 1044|     10|        MqttProps_Free(*props);
 1045|     10|        *props = NULL;
 1046|     10|    }
 1047|      0|    else {
 1048|      0|        rc = total;
 1049|      0|    }
 1050|       |
 1051|     10|    return rc;
 1052|     10|}
MqttEncode_Connect:
 1057|  2.64k|{
 1058|  2.64k|    int header_len, remain_len;
 1059|  2.64k|#ifdef WOLFMQTT_V5
 1060|  2.64k|    int props_len = 0, lwt_props_len = 0;
 1061|  2.64k|#endif
 1062|  2.64k|    MqttConnectPacket packet = MQTT_CONNECT_INIT;
  ------------------
  |  |  376|  2.64k|    {{0, MQTT_CONNECT_PROTOCOL_NAME_LEN}, {'M', 'Q', 'T', 'T'}, \
  |  |  ------------------
  |  |  |  |  365|  2.64k|#define MQTT_CONNECT_PROTOCOL_NAME_LEN  4
  |  |  ------------------
  |  |  377|  2.64k|        MQTT_CONNECT_PROTOCOL_LEVEL, 0, 0}
  |  |  ------------------
  |  |  |  |  370|  2.64k|#define MQTT_CONNECT_PROTOCOL_LEVEL     MQTT_CONNECT_PROTOCOL_LEVEL_5
  |  |  |  |  ------------------
  |  |  |  |  |  |  368|  2.64k|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1063|  2.64k|    byte *tx_payload;
 1064|       |
 1065|       |    /* Validate required arguments */
 1066|  2.64k|    if (tx_buf == NULL || mc_connect == NULL || mc_connect->client_id == NULL) {
  ------------------
  |  Branch (1066:9): [True: 0, False: 2.64k]
  |  Branch (1066:27): [True: 0, False: 2.64k]
  |  Branch (1066:49): [True: 0, False: 2.64k]
  ------------------
 1067|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1068|      0|    }
 1069|       |
 1070|       |    /* [MQTT-3.1.2-22]: If the User Name Flag is set to 0, the Password Flag
 1071|       |     * MUST be set to 0 */
 1072|  2.64k|    if (mc_connect->password != NULL && mc_connect->username == NULL) {
  ------------------
  |  Branch (1072:9): [True: 0, False: 2.64k]
  |  Branch (1072:41): [True: 0, False: 0]
  ------------------
 1073|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1074|      0|    }
 1075|       |
 1076|       |    /* Determine packet length */
 1077|       |    /* MQTT Version 4/5 header is 10 bytes */
 1078|  2.64k|    remain_len = sizeof(MqttConnectPacket);
 1079|       |
 1080|  2.64k|#ifdef WOLFMQTT_V5
 1081|  2.64k|    if (mc_connect->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|  2.64k|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1081:9): [True: 0, False: 2.64k]
  ------------------
 1082|       |        /* Determine length of properties */
 1083|      0|        props_len = MqttEncode_Props(MQTT_PACKET_TYPE_CONNECT,
 1084|      0|                mc_connect->props, NULL);
 1085|      0|        if (props_len >= 0) {
  ------------------
  |  Branch (1085:13): [True: 0, False: 0]
  ------------------
 1086|      0|            int tmp_len = MqttEncode_Vbi(NULL, props_len);
 1087|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (1087:17): [True: 0, False: 0]
  ------------------
 1088|      0|                return tmp_len;
 1089|      0|            }
 1090|      0|            remain_len += props_len;
 1091|       |
 1092|       |            /* Determine the length of the "property length" */
 1093|      0|            remain_len += tmp_len;
 1094|      0|        }
 1095|      0|        else
 1096|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1097|      0|    }
 1098|  2.64k|#endif
 1099|       |
 1100|       |    /* MQTT UTF-8 strings are limited to 65535 bytes [MQTT-1.5.3]. Check here
 1101|       |     * (before writing the fixed header) so a later MqttEncode_String failure
 1102|       |     * cannot corrupt tx_payload via `tx_payload += -1`. */
 1103|  2.64k|    {
 1104|  2.64k|        size_t str_len = XSTRLEN(mc_connect->client_id);
  ------------------
  |  |  992|  2.64k|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 1105|  2.64k|        if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (1105:13): [True: 5, False: 2.63k]
  ------------------
 1106|      5|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      5|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1107|      5|        }
 1108|  2.63k|        remain_len += (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|  2.63k|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1109|  2.63k|    }
 1110|  2.63k|    if (mc_connect->enable_lwt) {
  ------------------
  |  Branch (1110:9): [True: 21, False: 2.61k]
  ------------------
 1111|     21|        size_t str_len;
 1112|       |        /* Verify all required fields are present */
 1113|     21|        if (mc_connect->lwt_msg == NULL ||
  ------------------
  |  Branch (1113:13): [True: 0, False: 21]
  ------------------
 1114|     21|            mc_connect->lwt_msg->topic_name == NULL ||
  ------------------
  |  Branch (1114:13): [True: 0, False: 21]
  ------------------
 1115|     21|            (mc_connect->lwt_msg->buffer == NULL &&
  ------------------
  |  Branch (1115:14): [True: 7, False: 14]
  ------------------
 1116|      7|             mc_connect->lwt_msg->total_len != 0))
  ------------------
  |  Branch (1116:14): [True: 0, False: 7]
  ------------------
 1117|      0|        {
 1118|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1119|      0|        }
 1120|     21|        str_len = XSTRLEN(mc_connect->lwt_msg->topic_name);
  ------------------
  |  |  992|     21|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 1121|     21|        if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (1121:13): [True: 0, False: 21]
  ------------------
 1122|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1123|      0|        }
 1124|       |
 1125|     21|        remain_len += (int)str_len;
 1126|     21|        remain_len += MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|     21|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1127|       |        /* LWT payload uses word16 length prefix, validate it fits */
 1128|     21|        if (mc_connect->lwt_msg->total_len > (word32)0xFFFF) {
  ------------------
  |  Branch (1128:13): [True: 0, False: 21]
  ------------------
 1129|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1130|      0|        }
 1131|     21|        remain_len += mc_connect->lwt_msg->total_len;
 1132|     21|        remain_len += MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|     21|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1133|     21|#ifdef WOLFMQTT_V5
 1134|     21|    if (mc_connect->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|     21|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1134:9): [True: 0, False: 21]
  ------------------
 1135|       |        /* Determine length of properties */
 1136|      0|        lwt_props_len = MqttEncode_Props(MQTT_PACKET_TYPE_CONNECT,
 1137|      0|                mc_connect->lwt_msg->props, NULL);
 1138|      0|        if (lwt_props_len >= 0) {
  ------------------
  |  Branch (1138:13): [True: 0, False: 0]
  ------------------
 1139|      0|            int tmp_len = MqttEncode_Vbi(NULL, lwt_props_len);
 1140|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (1140:17): [True: 0, False: 0]
  ------------------
 1141|      0|                return tmp_len;
 1142|      0|            }
 1143|      0|            remain_len += lwt_props_len;
 1144|       |
 1145|       |            /* Determine the length of the "lwt property length" */
 1146|      0|            remain_len += tmp_len;
 1147|      0|        }
 1148|      0|        else
 1149|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1150|      0|    }
 1151|     21|#endif
 1152|     21|    }
 1153|  2.63k|    if (mc_connect->username) {
  ------------------
  |  Branch (1153:9): [True: 0, False: 2.63k]
  ------------------
 1154|      0|        size_t str_len = XSTRLEN(mc_connect->username);
  ------------------
  |  |  992|      0|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 1155|      0|        if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (1155:13): [True: 0, False: 0]
  ------------------
 1156|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1157|      0|        }
 1158|      0|        remain_len += (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1159|      0|    }
 1160|  2.63k|    if (mc_connect->password) {
  ------------------
  |  Branch (1160:9): [True: 0, False: 2.63k]
  ------------------
 1161|      0|        size_t str_len = XSTRLEN(mc_connect->password);
  ------------------
  |  |  992|      0|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 1162|      0|        if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (1162:13): [True: 0, False: 0]
  ------------------
 1163|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1164|      0|        }
 1165|      0|        remain_len += (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1166|      0|    }
 1167|       |
 1168|       |    /* Encode fixed header */
 1169|  2.63k|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len, remain_len,
 1170|  2.63k|        MQTT_PACKET_TYPE_CONNECT, 0, 0, 0);
 1171|  2.63k|    if (header_len < 0) {
  ------------------
  |  Branch (1171:9): [True: 0, False: 2.63k]
  ------------------
 1172|      0|        return header_len;
 1173|      0|    }
 1174|       |    /* Check for buffer room */
 1175|  2.63k|    if (tx_buf_len < header_len + remain_len) {
  ------------------
  |  Branch (1175:9): [True: 12, False: 2.62k]
  ------------------
 1176|     12|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|     12|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1177|     12|    }
 1178|  2.62k|    tx_payload = &tx_buf[header_len];
 1179|       |
 1180|       |    /* Encode variable header */
 1181|       |    /* Protocol version */
 1182|  2.62k|    if (mc_connect->protocol_level != 0) {
  ------------------
  |  Branch (1182:9): [True: 0, False: 2.62k]
  ------------------
 1183|      0|        packet.protocol_level = mc_connect->protocol_level;
 1184|      0|    }
 1185|       |
 1186|       |    /* Set connection flags */
 1187|  2.62k|    if (mc_connect->clean_session) {
  ------------------
  |  Branch (1187:9): [True: 960, False: 1.66k]
  ------------------
 1188|    960|        packet.flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
 1189|    960|    }
 1190|  2.62k|    if (mc_connect->enable_lwt) {
  ------------------
  |  Branch (1190:9): [True: 14, False: 2.60k]
  ------------------
 1191|     14|        packet.flags |= MQTT_CONNECT_FLAG_WILL_FLAG;
 1192|       |
 1193|     14|        if (mc_connect->lwt_msg->qos) {
  ------------------
  |  Branch (1193:13): [True: 7, False: 7]
  ------------------
 1194|      7|            packet.flags |= MQTT_CONNECT_FLAG_SET_QOS(mc_connect->lwt_msg->qos);
  ------------------
  |  |  349|      7|    (((qos) << MQTT_CONNECT_FLAG_WILL_QOS_SHIFT) & \
  |  |  350|      7|        MQTT_CONNECT_FLAG_WILL_QOS_MASK)
  ------------------
 1195|      7|        }
 1196|     14|        if (mc_connect->lwt_msg->retain) {
  ------------------
  |  Branch (1196:13): [True: 4, False: 10]
  ------------------
 1197|      4|            packet.flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
 1198|      4|        }
 1199|     14|    }
 1200|  2.62k|    if (mc_connect->username) {
  ------------------
  |  Branch (1200:9): [True: 0, False: 2.62k]
  ------------------
 1201|      0|        packet.flags |= MQTT_CONNECT_FLAG_USERNAME;
 1202|      0|    }
 1203|  2.62k|    if (mc_connect->password) {
  ------------------
  |  Branch (1203:9): [True: 0, False: 2.62k]
  ------------------
 1204|      0|        packet.flags |= MQTT_CONNECT_FLAG_PASSWORD;
 1205|      0|    }
 1206|  2.62k|    MqttEncode_Num((byte*)&packet.keep_alive, mc_connect->keep_alive_sec);
 1207|  2.62k|    XMEMCPY(tx_payload, &packet, sizeof(MqttConnectPacket));
  ------------------
  |  |  987|  2.62k|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 1208|  2.62k|    tx_payload += sizeof(MqttConnectPacket);
 1209|       |
 1210|  2.62k|#ifdef WOLFMQTT_V5
 1211|  2.62k|    if (mc_connect->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|  2.62k|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1211:9): [True: 0, False: 2.62k]
  ------------------
 1212|      0|        int tmp_len = MqttEncode_Vbi(tx_payload, props_len);
 1213|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1213:13): [True: 0, False: 0]
  ------------------
 1214|      0|            return tmp_len;
 1215|      0|        }
 1216|       |        /* Encode the property length */
 1217|      0|        tx_payload += tmp_len;
 1218|       |
 1219|      0|        tmp_len = MqttEncode_Props(MQTT_PACKET_TYPE_CONNECT,
 1220|      0|             mc_connect->props, tx_payload);
 1221|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1221:13): [True: 0, False: 0]
  ------------------
 1222|      0|            return tmp_len;
 1223|      0|        }
 1224|       |        /* Encode properties */
 1225|      0|        tx_payload += tmp_len;
 1226|      0|    }
 1227|  2.62k|#endif
 1228|       |
 1229|       |    /* Encode payload */
 1230|  2.62k|    tx_payload += MqttEncode_String(tx_payload, mc_connect->client_id);
 1231|  2.62k|    if (mc_connect->enable_lwt) {
  ------------------
  |  Branch (1231:9): [True: 14, False: 2.60k]
  ------------------
 1232|     14|#ifdef WOLFMQTT_V5
 1233|     14|    if (mc_connect->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|     14|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1233:9): [True: 0, False: 14]
  ------------------
 1234|      0|        int tmp_len = MqttEncode_Vbi(tx_payload, lwt_props_len);
 1235|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1235:13): [True: 0, False: 0]
  ------------------
 1236|      0|            return tmp_len;
 1237|      0|        }
 1238|       |        /* Encode the lwt property length */
 1239|      0|        tx_payload += tmp_len;
 1240|       |
 1241|      0|        tmp_len = MqttEncode_Props(MQTT_PACKET_TYPE_CONNECT,
 1242|      0|            mc_connect->lwt_msg->props, tx_payload);
 1243|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1243:13): [True: 0, False: 0]
  ------------------
 1244|      0|            return tmp_len;
 1245|      0|        }
 1246|       |        /* Encode lwt properties */
 1247|      0|        tx_payload += tmp_len;
 1248|      0|    }
 1249|     14|#endif
 1250|     14|        tx_payload += MqttEncode_String(tx_payload,
 1251|     14|            mc_connect->lwt_msg->topic_name);
 1252|     14|        tx_payload += MqttEncode_Data(tx_payload,
 1253|     14|            mc_connect->lwt_msg->buffer, (word16)mc_connect->lwt_msg->total_len);
 1254|     14|    }
 1255|  2.62k|    if (mc_connect->username) {
  ------------------
  |  Branch (1255:9): [True: 0, False: 2.62k]
  ------------------
 1256|      0|        tx_payload += MqttEncode_String(tx_payload, mc_connect->username);
 1257|      0|    }
 1258|  2.62k|    if (mc_connect->password) {
  ------------------
  |  Branch (1258:9): [True: 0, False: 2.62k]
  ------------------
 1259|      0|        tx_payload += MqttEncode_String(tx_payload, mc_connect->password);
 1260|      0|    }
 1261|  2.62k|    (void)tx_payload;
 1262|       |
 1263|       |    /* Return total length of packet */
 1264|  2.62k|    return header_len + remain_len;
 1265|  2.62k|}
MqttDecode_ConnectAck:
 1596|    414|{
 1597|    414|    int header_len, remain_len;
 1598|    414|    byte *rx_payload;
 1599|       |
 1600|       |    /* Validate required arguments */
 1601|    414|    if (rx_buf == NULL || rx_buf_len <= 0) {
  ------------------
  |  Branch (1601:9): [True: 0, False: 414]
  |  Branch (1601:27): [True: 0, False: 414]
  ------------------
 1602|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1603|      0|    }
 1604|       |
 1605|       |    /* Decode fixed header */
 1606|    414|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 1607|    414|        MQTT_PACKET_TYPE_CONNECT_ACK, NULL, NULL, NULL);
 1608|    414|    if (header_len < 0) {
  ------------------
  |  Branch (1608:9): [True: 411, False: 3]
  ------------------
 1609|    411|        return header_len;
 1610|    411|    }
 1611|       |
 1612|       |    /* Validate remain_len */
 1613|      3|    if (remain_len < 2) {
  ------------------
  |  Branch (1613:9): [True: 3, False: 0]
  ------------------
 1614|      3|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      3|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1615|      3|    }
 1616|       |
 1617|      0|    rx_payload = &rx_buf[header_len];
 1618|       |
 1619|       |    /* Decode variable header */
 1620|      0|    if (connect_ack) {
  ------------------
  |  Branch (1620:9): [True: 0, False: 0]
  ------------------
 1621|      0|        connect_ack->flags = *rx_payload++;
 1622|      0|        connect_ack->return_code = *rx_payload++;
 1623|       |
 1624|       |        /* [MQTT-3.2.2-1] Bits 7-1 of the Connect Acknowledge Flags byte are
 1625|       |         * reserved and MUST be 0. Any other value is a protocol violation;
 1626|       |         * [MQTT-4.8.0-1] requires the receiver to close the connection. */
 1627|      0|        if ((connect_ack->flags &
  ------------------
  |  Branch (1627:13): [True: 0, False: 0]
  ------------------
 1628|      0|             (byte)~MQTT_CONNECT_ACK_FLAG_SESSION_PRESENT) != 0) {
 1629|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1630|      0|        }
 1631|       |        /* [MQTT-3.2.2-4] If the CONNACK return code is non-zero (CONNECT
 1632|       |         * refused), Session Present MUST be 0. A refused CONNACK that
 1633|       |         * claims an existing session is malformed. */
 1634|      0|        if (connect_ack->return_code != MQTT_CONNECT_ACK_CODE_ACCEPTED &&
  ------------------
  |  Branch (1634:13): [True: 0, False: 0]
  ------------------
 1635|      0|            (connect_ack->flags & MQTT_CONNECT_ACK_FLAG_SESSION_PRESENT)) {
  ------------------
  |  Branch (1635:13): [True: 0, False: 0]
  ------------------
 1636|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1637|      0|        }
 1638|       |
 1639|      0|#ifdef WOLFMQTT_V5
 1640|      0|        connect_ack->props = NULL;
 1641|      0|        if (connect_ack->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|      0|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1641:13): [True: 0, False: 0]
  ------------------
 1642|      0|            word32 props_len = 0;
 1643|      0|            int props_tmp;
 1644|       |            /* Decode Length of Properties */
 1645|      0|            if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (1645:17): [True: 0, False: 0]
  ------------------
 1646|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1647|      0|            }
 1648|      0|            props_tmp = MqttDecode_Vbi(rx_payload, &props_len,
 1649|      0|                    (word32)(rx_buf_len - (rx_payload - rx_buf)));
 1650|      0|            if (props_tmp < 0) {
  ------------------
  |  Branch (1650:17): [True: 0, False: 0]
  ------------------
 1651|      0|                return props_tmp;
 1652|      0|            }
 1653|      0|            rx_payload += props_tmp;
 1654|      0|            if (props_len > 0) {
  ------------------
  |  Branch (1654:17): [True: 0, False: 0]
  ------------------
 1655|       |                /* Decode the Properties */
 1656|      0|                props_tmp = MqttDecode_Props(MQTT_PACKET_TYPE_CONNECT_ACK,
 1657|      0|                               &connect_ack->props, rx_payload,
 1658|      0|                               (word32)(rx_buf_len - (rx_payload - rx_buf)),
 1659|      0|                               props_len);
 1660|      0|                if (props_tmp < 0)
  ------------------
  |  Branch (1660:21): [True: 0, False: 0]
  ------------------
 1661|      0|                    return props_tmp;
 1662|      0|                rx_payload += props_tmp;
 1663|      0|            }
 1664|      0|        }
 1665|      0|#endif
 1666|      0|    }
 1667|       |
 1668|      0|    (void)rx_payload;
 1669|       |
 1670|       |    /* Return total length of packet */
 1671|      0|    return header_len + remain_len;
 1672|      0|}
MqttEncode_Publish:
 1754|    499|{
 1755|    499|    int header_len, variable_len, payload_len = 0;
 1756|    499|    byte *tx_payload;
 1757|    499|#ifdef WOLFMQTT_V5
 1758|    499|    int props_len = 0;
 1759|    499|#endif
 1760|       |
 1761|       |    /* Validate required arguments */
 1762|    499|    if (tx_buf == NULL || publish == NULL) {
  ------------------
  |  Branch (1762:9): [True: 0, False: 499]
  |  Branch (1762:27): [True: 0, False: 499]
  ------------------
 1763|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1764|      0|    }
 1765|       |    /* MQTT UTF-8 strings are limited to 65535 bytes [MQTT-1.5.3]. Check here
 1766|       |     * before writing the fixed header so a later MqttEncode_String failure
 1767|       |     * cannot corrupt tx_payload via `tx_payload += -1`. NULL topic_name
 1768|       |     * is API misuse (BAD_ARG); callers using v5 Topic Alias must pass
 1769|       |     * an empty string "" rather than NULL. */
 1770|    499|    {
 1771|    499|        size_t str_len;
 1772|    499|        byte level = 0;
 1773|    499|        if (publish->topic_name == NULL) {
  ------------------
  |  Branch (1773:13): [True: 0, False: 499]
  ------------------
 1774|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1775|      0|        }
 1776|    499|        str_len = XSTRLEN(publish->topic_name);
  ------------------
  |  |  992|    499|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 1777|    499|        if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (1777:13): [True: 0, False: 499]
  ------------------
 1778|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1779|      0|        }
 1780|    499|    #ifdef WOLFMQTT_V5
 1781|    499|        level = publish->protocol_level;
 1782|    499|    #endif
 1783|       |        /* [MQTT-3.3.2-2] / [MQTT-4.7.1-1] wildcards always forbidden in
 1784|       |         * Topic Names. [MQTT-4.7.3-1] empty Topic Names rejected for
 1785|       |         * v3.1.1; allowed for v5 with caller-managed Topic Alias. */
 1786|    499|        if (!MqttPacket_TopicNameValid(publish->topic_name,
  ------------------
  |  Branch (1786:13): [True: 327, False: 172]
  ------------------
 1787|    499|                                       (word16)str_len, level)) {
 1788|    327|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|    327|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1789|    327|        }
 1790|       |
 1791|       |        /* Determine packet length */
 1792|    172|        variable_len = (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|    172|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1793|    172|    }
 1794|    172|    if (publish->qos > MQTT_QOS_0) {
  ------------------
  |  Branch (1794:9): [True: 11, False: 161]
  ------------------
 1795|     11|        if (publish->packet_id == 0) {
  ------------------
  |  Branch (1795:13): [True: 2, False: 9]
  ------------------
 1796|      2|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_ID);
  ------------------
  |  |  392|      2|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1797|      2|        }
 1798|      9|        variable_len += MQTT_DATA_LEN_SIZE; /* For packet_id */
  ------------------
  |  |   39|      9|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1799|      9|    }
 1800|    161|    else if (publish->duplicate) {
  ------------------
  |  Branch (1800:14): [True: 109, False: 52]
  ------------------
 1801|       |        /* [MQTT-3.3.1-2] DUP MUST be 0 for all QoS 0 PUBLISH messages.
 1802|       |         * The decoder rejects this combination via MqttPacket_FixedHeader
 1803|       |         * FlagsValid; mirror the constraint at the encoder boundary so the
 1804|       |         * library never produces a forbidden wire packet for a caller. */
 1805|    109|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|    109|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1806|    109|    }
 1807|       |
 1808|     61|#ifdef WOLFMQTT_V5
 1809|     61|    if (publish->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|     61|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1809:9): [True: 0, False: 61]
  ------------------
 1810|       |        /* Determine length of properties */
 1811|      0|        props_len = MqttEncode_Props(MQTT_PACKET_TYPE_PUBLISH,
 1812|      0|                          publish->props, NULL);
 1813|      0|        if (props_len >= 0) {
  ------------------
  |  Branch (1813:13): [True: 0, False: 0]
  ------------------
 1814|       |            /* Determine the length of the "property length" */
 1815|      0|            int tmp_len = MqttEncode_Vbi(NULL, props_len);
 1816|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (1816:17): [True: 0, False: 0]
  ------------------
 1817|      0|                return tmp_len;
 1818|      0|            }
 1819|      0|            variable_len += props_len;
 1820|      0|            variable_len += tmp_len;
 1821|      0|        }
 1822|      0|        else
 1823|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1824|      0|    }
 1825|     61|#endif
 1826|       |
 1827|     61|    if (((publish->buffer != NULL) || (use_cb == 1)) &&
  ------------------
  |  Branch (1827:10): [True: 47, False: 14]
  |  Branch (1827:39): [True: 0, False: 14]
  ------------------
 1828|     47|        (publish->total_len > 0)) {
  ------------------
  |  Branch (1828:9): [True: 47, False: 0]
  ------------------
 1829|     47|        payload_len = publish->total_len;
 1830|     47|    }
 1831|       |
 1832|       |    /* Encode fixed header */
 1833|     61|    publish->type = MQTT_PACKET_TYPE_PUBLISH;
 1834|     61|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len,
 1835|     61|        variable_len + payload_len, publish->type,
 1836|     61|        publish->retain, publish->qos, publish->duplicate);
 1837|     61|    if (header_len < 0) {
  ------------------
  |  Branch (1837:9): [True: 0, False: 61]
  ------------------
 1838|      0|        return header_len;
 1839|      0|    }
 1840|       |
 1841|     61|    tx_payload = &tx_buf[header_len];
 1842|       |
 1843|     61|    if (use_cb == 1) {
  ------------------
  |  Branch (1843:9): [True: 0, False: 61]
  ------------------
 1844|       |        /* The callback will encode the payload */
 1845|      0|        payload_len = 0;
 1846|      0|    }
 1847|       |
 1848|       |    /* Check for buffer room */
 1849|     61|    if (tx_buf_len < header_len + variable_len) {
  ------------------
  |  Branch (1849:9): [True: 0, False: 61]
  ------------------
 1850|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1851|      0|    }
 1852|       |
 1853|       |    /* Encode variable header */
 1854|     61|    tx_payload += MqttEncode_String(tx_payload, publish->topic_name);
 1855|     61|    if (publish->qos > MQTT_QOS_0) {
  ------------------
  |  Branch (1855:9): [True: 9, False: 52]
  ------------------
 1856|      9|        tx_payload += MqttEncode_Num(tx_payload, publish->packet_id);
 1857|      9|    }
 1858|       |
 1859|     61|#ifdef WOLFMQTT_V5
 1860|     61|    if (publish->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|     61|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1860:9): [True: 0, False: 61]
  ------------------
 1861|       |        /* Encode the property length */
 1862|      0|        int tmp_len = MqttEncode_Vbi(tx_payload, props_len);
 1863|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1863:13): [True: 0, False: 0]
  ------------------
 1864|      0|            return tmp_len;
 1865|      0|        }
 1866|      0|        tx_payload += tmp_len;
 1867|       |
 1868|       |        /* Encode properties */
 1869|      0|        tmp_len = MqttEncode_Props((MqttPacketType)publish->type,
 1870|      0|            publish->props, tx_payload);
 1871|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (1871:13): [True: 0, False: 0]
  ------------------
 1872|      0|            return tmp_len;
 1873|      0|        }
 1874|      0|        tx_payload += tmp_len;
 1875|      0|    }
 1876|     61|#endif
 1877|       |
 1878|       |    /* Encode payload */
 1879|     61|    if (payload_len > 0) {
  ------------------
  |  Branch (1879:9): [True: 47, False: 14]
  ------------------
 1880|       |        /* Check for buffer room */
 1881|     47|        if (tx_buf_len < header_len + variable_len) {
  ------------------
  |  Branch (1881:13): [True: 0, False: 47]
  ------------------
 1882|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1883|      0|        }
 1884|       |        /* Determine max size to copy into tx_payload */
 1885|     47|        if (payload_len > (tx_buf_len - (header_len + variable_len))) {
  ------------------
  |  Branch (1885:13): [True: 37, False: 10]
  ------------------
 1886|     37|            payload_len = (tx_buf_len - (header_len + variable_len));
 1887|     37|        }
 1888|     47|        if (tx_payload != NULL) {
  ------------------
  |  Branch (1888:13): [True: 47, False: 0]
  ------------------
 1889|     47|            XMEMCPY(tx_payload, publish->buffer, payload_len);
  ------------------
  |  |  987|     47|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 1890|     47|        }
 1891|       |        /* mark how much data was sent */
 1892|     47|        publish->buffer_pos = payload_len;
 1893|       |
 1894|       |        /* Backwards compatibility for chunk transfers */
 1895|     47|        if (publish->buffer_len == 0) {
  ------------------
  |  Branch (1895:13): [True: 47, False: 0]
  ------------------
 1896|     47|            publish->buffer_len = publish->total_len;
 1897|     47|        }
 1898|     47|    }
 1899|     61|    publish->intBuf_pos = 0;
 1900|     61|    publish->intBuf_len = payload_len;
 1901|       |
 1902|       |    /* Return length of packet placed into tx_buf */
 1903|     61|    return header_len + variable_len + payload_len;
 1904|     61|}
MqttDecode_Publish:
 1907|    225|{
 1908|    225|    int header_len, remain_len, variable_len, payload_len;
 1909|    225|    byte *rx_payload;
 1910|    225|    byte level = 0;
 1911|       |
 1912|       |    /* Validate required arguments */
 1913|    225|    if (rx_buf == NULL || rx_buf_len <= 0 || publish == NULL) {
  ------------------
  |  Branch (1913:9): [True: 0, False: 225]
  |  Branch (1913:27): [True: 0, False: 225]
  |  Branch (1913:46): [True: 0, False: 225]
  ------------------
 1914|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1915|      0|    }
 1916|       |
 1917|       |    /* Decode fixed header */
 1918|    225|    publish->type = MQTT_PACKET_TYPE_PUBLISH;
 1919|    225|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len,
 1920|    225|        &remain_len, publish->type, &publish->qos,
 1921|    225|        &publish->retain, &publish->duplicate);
 1922|    225|    if (header_len < 0) {
  ------------------
  |  Branch (1922:9): [True: 45, False: 180]
  ------------------
 1923|     45|        return header_len;
 1924|     45|    }
 1925|    180|    rx_payload = &rx_buf[header_len];
 1926|       |
 1927|       |    /* Decode variable header */
 1928|    180|    variable_len = MqttDecode_String(rx_payload, &publish->topic_name,
 1929|    180|        &publish->topic_name_len, (word32)(rx_buf_len - (rx_payload - rx_buf)));
 1930|    180|    if (variable_len < 0) {
  ------------------
  |  Branch (1930:9): [True: 148, False: 32]
  ------------------
 1931|       |        /* Preserve specific error (e.g., MALFORMED_DATA from UTF-8 check). */
 1932|    148|        return variable_len;
 1933|    148|    }
 1934|     32|    if (variable_len + header_len > rx_buf_len) {
  ------------------
  |  Branch (1934:9): [True: 0, False: 32]
  ------------------
 1935|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1936|      0|    }
 1937|       |    /* [MQTT-3.3.2-2] / [MQTT-4.7.1-1] Reject Topic Names containing
 1938|       |     * wildcards (both versions). [MQTT-4.7.3-1] Reject empty Topic
 1939|       |     * Names for v3.1.1; v5 section 3.3.2.3.4 permits a zero-length Topic Name
 1940|       |     * paired with a Topic Alias property - the alias-empty pairing is
 1941|       |     * left to the caller because the property block is decoded later
 1942|       |     * in this function. */
 1943|     32|#ifdef WOLFMQTT_V5
 1944|     32|    level = publish->protocol_level;
 1945|     32|#endif
 1946|     32|    if (!MqttPacket_TopicNameValid(publish->topic_name,
  ------------------
  |  Branch (1946:9): [True: 32, False: 0]
  ------------------
 1947|     32|                                   publish->topic_name_len, level)) {
 1948|     32|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|     32|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1949|     32|    }
 1950|      0|    rx_payload += variable_len;
 1951|       |
 1952|       |    /* If QoS > 0 then get packet Id */
 1953|      0|    if (publish->qos > MQTT_QOS_0) {
  ------------------
  |  Branch (1953:9): [True: 0, False: 0]
  ------------------
 1954|      0|        int tmp;
 1955|      0|        if (rx_payload - rx_buf + MQTT_DATA_LEN_SIZE > rx_buf_len) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (1955:13): [True: 0, False: 0]
  ------------------
 1956|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1957|      0|        }
 1958|      0|        tmp = MqttDecode_Num(rx_payload, &publish->packet_id,
 1959|      0|                (word32)(rx_buf_len - (rx_payload - rx_buf)));
 1960|      0|        if (tmp < 0) {
  ------------------
  |  Branch (1960:13): [True: 0, False: 0]
  ------------------
 1961|      0|            return tmp;
 1962|      0|        }
 1963|       |        /* [MQTT-2.3.1-1] PUBLISH packets with QoS > 0 must carry a non-zero
 1964|       |         * Packet Identifier. */
 1965|      0|        if (publish->packet_id == 0) {
  ------------------
  |  Branch (1965:13): [True: 0, False: 0]
  ------------------
 1966|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_ID);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1967|      0|        }
 1968|      0|        variable_len += tmp;
 1969|      0|        if (variable_len + header_len <= rx_buf_len) {
  ------------------
  |  Branch (1969:13): [True: 0, False: 0]
  ------------------
 1970|      0|            rx_payload += MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 1971|      0|        }
 1972|      0|        else {
 1973|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1974|      0|        }
 1975|      0|    }
 1976|       |
 1977|      0|#ifdef WOLFMQTT_V5
 1978|      0|    publish->props = NULL;
 1979|      0|    if (publish->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|      0|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (1979:9): [True: 0, False: 0]
  ------------------
 1980|      0|        word32 props_len = 0;
 1981|      0|        int tmp;
 1982|       |
 1983|       |        /* Decode Length of Properties */
 1984|      0|        if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (1984:13): [True: 0, False: 0]
  ------------------
 1985|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 1986|      0|        }
 1987|      0|        tmp = MqttDecode_Vbi(rx_payload, &props_len,
 1988|      0|                (word32)(rx_buf_len - (rx_payload - rx_buf)));
 1989|      0|        if (tmp < 0)
  ------------------
  |  Branch (1989:13): [True: 0, False: 0]
  ------------------
 1990|      0|            return tmp;
 1991|      0|        variable_len += tmp + props_len;
 1992|      0|        if (variable_len + header_len <= rx_buf_len) {
  ------------------
  |  Branch (1992:13): [True: 0, False: 0]
  ------------------
 1993|      0|            rx_payload += tmp;
 1994|      0|            if (props_len > 0) {
  ------------------
  |  Branch (1994:17): [True: 0, False: 0]
  ------------------
 1995|       |                /* Decode the Properties */
 1996|      0|                tmp = MqttDecode_Props((MqttPacketType)publish->type,
 1997|      0|                    &publish->props, rx_payload,
 1998|      0|                    (word32)(rx_buf_len - (rx_payload - rx_buf)), props_len);
 1999|      0|                if (tmp < 0)
  ------------------
  |  Branch (1999:21): [True: 0, False: 0]
  ------------------
 2000|      0|                    return tmp;
 2001|      0|                rx_payload += tmp;
 2002|      0|            }
 2003|      0|        }
 2004|      0|        else {
 2005|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2006|      0|        }
 2007|      0|    }
 2008|      0|#endif
 2009|       |
 2010|       |    /* Decode Payload */
 2011|      0|    if (variable_len > remain_len) {
  ------------------
  |  Branch (2011:9): [True: 0, False: 0]
  ------------------
 2012|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2013|      0|    }
 2014|      0|    payload_len = remain_len - variable_len;
 2015|      0|    publish->buffer = rx_payload;
 2016|      0|    publish->buffer_new = 1;
 2017|      0|    publish->buffer_pos = 0;
 2018|      0|    publish->buffer_len = payload_len;
 2019|      0|    publish->total_len = payload_len;
 2020|       |
 2021|       |    /* Only return the length provided in rx_buf_len */
 2022|      0|    if ((int)publish->buffer_len >
  ------------------
  |  Branch (2022:9): [True: 0, False: 0]
  ------------------
 2023|      0|        (rx_buf_len - (header_len + variable_len)))
 2024|      0|    {
 2025|      0|        publish->buffer_len = (rx_buf_len - (header_len + variable_len));
 2026|      0|    }
 2027|       |
 2028|      0|    return header_len + variable_len + payload_len;
 2029|      0|}
MqttEncode_PublishResp:
 2033|      4|{
 2034|      4|    int header_len, remain_len;
 2035|      4|    byte *tx_payload;
 2036|      4|    MqttQoS qos;
 2037|      4|#ifdef WOLFMQTT_V5
 2038|      4|    int props_len = 0;
 2039|      4|#endif
 2040|       |
 2041|       |    /* Validate required arguments */
 2042|      4|    if (tx_buf == NULL || publish_resp == NULL) {
  ------------------
  |  Branch (2042:9): [True: 0, False: 4]
  |  Branch (2042:27): [True: 0, False: 4]
  ------------------
 2043|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2044|      0|    }
 2045|       |
 2046|       |    /* Determine packet length */
 2047|      4|    remain_len = MQTT_DATA_LEN_SIZE; /* For packet_id */
  ------------------
  |  |   39|      4|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 2048|       |
 2049|      4|#ifdef WOLFMQTT_V5
 2050|      4|    if (publish_resp->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5)
  ------------------
  |  |  368|      4|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2050:9): [True: 0, False: 4]
  ------------------
 2051|      0|    {
 2052|      0|        if (publish_resp->props != NULL) {
  ------------------
  |  Branch (2052:13): [True: 0, False: 0]
  ------------------
 2053|       |            /* Determine length of properties */
 2054|      0|            props_len = MqttEncode_Props((MqttPacketType)type,
 2055|      0|                            publish_resp->props, NULL);
 2056|      0|            if (props_len >= 0) {
  ------------------
  |  Branch (2056:17): [True: 0, False: 0]
  ------------------
 2057|       |                /* Determine the length of the "property length" */
 2058|      0|                int tmp_len = MqttEncode_Vbi(NULL, props_len);
 2059|      0|                if (tmp_len < 0) {
  ------------------
  |  Branch (2059:21): [True: 0, False: 0]
  ------------------
 2060|      0|                    return tmp_len;
 2061|      0|                }
 2062|      0|                remain_len += props_len;
 2063|      0|                remain_len += tmp_len;
 2064|      0|            }
 2065|      0|            else
 2066|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2067|      0|        }
 2068|      0|        if (publish_resp->reason_code != MQTT_REASON_SUCCESS ||
  ------------------
  |  Branch (2068:13): [True: 0, False: 0]
  ------------------
 2069|      0|            publish_resp->props != NULL) {
  ------------------
  |  Branch (2069:13): [True: 0, False: 0]
  ------------------
 2070|       |            /* Reason Code */
 2071|      0|            remain_len++;
 2072|      0|        }
 2073|      0|    }
 2074|      4|#endif
 2075|       |
 2076|       |    /* Determine Qos value */
 2077|      4|    qos = (type == MQTT_PACKET_TYPE_PUBLISH_REL) ? MQTT_QOS_1 : MQTT_QOS_0;
  ------------------
  |  Branch (2077:11): [True: 0, False: 4]
  ------------------
 2078|       |
 2079|       |    /* Encode fixed header */
 2080|      4|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len, remain_len,
 2081|      4|        type, 0, qos, 0);
 2082|      4|    if (header_len < 0) {
  ------------------
  |  Branch (2082:9): [True: 0, False: 4]
  ------------------
 2083|      0|        return header_len;
 2084|      0|    }
 2085|       |    /* Check for buffer room */
 2086|      4|    if (tx_buf_len < header_len + remain_len) {
  ------------------
  |  Branch (2086:9): [True: 0, False: 4]
  ------------------
 2087|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2088|      0|    }
 2089|      4|    tx_payload = &tx_buf[header_len];
 2090|       |
 2091|       |    /* Encode variable header */
 2092|      4|    tx_payload += MqttEncode_Num(&tx_buf[header_len], publish_resp->packet_id);
 2093|       |
 2094|      4|#ifdef WOLFMQTT_V5
 2095|      4|    if (publish_resp->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5)
  ------------------
  |  |  368|      4|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2095:9): [True: 0, False: 4]
  ------------------
 2096|      0|    {
 2097|      0|        if (publish_resp->reason_code != MQTT_REASON_SUCCESS ||
  ------------------
  |  Branch (2097:13): [True: 0, False: 0]
  ------------------
 2098|      0|            publish_resp->props != NULL) {
  ------------------
  |  Branch (2098:13): [True: 0, False: 0]
  ------------------
 2099|       |            /* Encode the Reason Code */
 2100|      0|            *tx_payload++ = publish_resp->reason_code;
 2101|      0|        }
 2102|      0|        if (publish_resp->props != NULL) {
  ------------------
  |  Branch (2102:13): [True: 0, False: 0]
  ------------------
 2103|       |            /* Encode the property length */
 2104|      0|            int tmp_len = MqttEncode_Vbi(tx_payload, props_len);
 2105|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (2105:17): [True: 0, False: 0]
  ------------------
 2106|      0|                return tmp_len;
 2107|      0|            }
 2108|      0|            tx_payload += tmp_len;
 2109|       |
 2110|       |            /* Encode properties */
 2111|      0|            tmp_len = MqttEncode_Props((MqttPacketType)type,
 2112|      0|                            publish_resp->props, tx_payload);
 2113|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (2113:17): [True: 0, False: 0]
  ------------------
 2114|      0|                return tmp_len;
 2115|      0|            }
 2116|      0|            tx_payload += tmp_len;
 2117|      0|        }
 2118|      0|    }
 2119|      4|#endif
 2120|       |
 2121|      4|    (void)tx_payload;
 2122|       |
 2123|       |    /* Return total length of packet */
 2124|      4|    return header_len + remain_len;
 2125|      4|}
MqttDecode_PublishResp:
 2129|    321|{
 2130|    321|    int header_len, remain_len;
 2131|    321|    byte *rx_payload;
 2132|       |
 2133|       |    /* Validate required arguments */
 2134|    321|    if (rx_buf == NULL || rx_buf_len <= 0) {
  ------------------
  |  Branch (2134:9): [True: 0, False: 321]
  |  Branch (2134:27): [True: 0, False: 321]
  ------------------
 2135|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2136|      0|    }
 2137|       |
 2138|       |    /* Decode fixed header */
 2139|    321|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 2140|    321|        type, NULL, NULL, NULL);
 2141|    321|    if (header_len < 0) {
  ------------------
  |  Branch (2141:9): [True: 262, False: 59]
  ------------------
 2142|    262|        return header_len;
 2143|    262|    }
 2144|       |
 2145|       |    /* MQTT 3.1.1 sections 3.4-3.7: PUBACK/PUBREC/PUBREL/PUBCOMP variable header is
 2146|       |     * exactly the two-byte Packet Identifier and there is no payload -
 2147|       |     * Remaining Length is fixed at 2. v5 sections 3.4-3.7 relaxes this to allow
 2148|       |     * an optional Reason Code and Properties block, so the longer form is
 2149|       |     * only valid when the caller has identified the connection as v5.
 2150|       |     * (publish_resp == NULL takes the strict path: with no struct to
 2151|       |     * carry reason_code/props, anything beyond the Packet Identifier
 2152|       |     * cannot be consumed and is therefore extra payload.) */
 2153|     59|#ifdef WOLFMQTT_V5
 2154|     59|    if (publish_resp != NULL &&
  ------------------
  |  Branch (2154:9): [True: 59, False: 0]
  ------------------
 2155|     59|        publish_resp->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|     59|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2155:9): [True: 0, False: 59]
  ------------------
 2156|      0|        if (remain_len < MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2156:13): [True: 0, False: 0]
  ------------------
 2157|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2158|      0|        }
 2159|      0|    }
 2160|     59|    else
 2161|     59|#endif
 2162|     59|    {
 2163|     59|        if (remain_len != MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|     59|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2163:13): [True: 51, False: 8]
  ------------------
 2164|     51|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|     51|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2165|     51|        }
 2166|     59|    }
 2167|       |
 2168|      8|    rx_payload = &rx_buf[header_len];
 2169|       |
 2170|       |    /* Decode variable header */
 2171|      8|    if (publish_resp) {
  ------------------
  |  Branch (2171:9): [True: 8, False: 0]
  ------------------
 2172|      8|        int tmp;
 2173|      8|        tmp = MqttDecode_Num(rx_payload, &publish_resp->packet_id,
 2174|      8|                (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2175|      8|        if (tmp < 0) {
  ------------------
  |  Branch (2175:13): [True: 0, False: 8]
  ------------------
 2176|      0|            return tmp;
 2177|      0|        }
 2178|      8|        rx_payload += tmp;
 2179|       |
 2180|      8|#ifdef WOLFMQTT_V5
 2181|      8|        publish_resp->props = NULL;
 2182|      8|        if (publish_resp->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|      8|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2182:13): [True: 0, False: 8]
  ------------------
 2183|      0|            if (remain_len > MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2183:17): [True: 0, False: 0]
  ------------------
 2184|       |                /* Decode the Reason Code */
 2185|      0|                publish_resp->reason_code = *rx_payload++;
 2186|      0|            }
 2187|      0|            else {
 2188|      0|                publish_resp->reason_code = MQTT_REASON_SUCCESS;
 2189|      0|            }
 2190|       |
 2191|      0|            if (remain_len > MQTT_DATA_LEN_SIZE+1) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2191:17): [True: 0, False: 0]
  ------------------
 2192|      0|                word32 props_len = 0;
 2193|      0|                int props_tmp;
 2194|       |
 2195|       |                /* Decode Length of Properties */
 2196|      0|                if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (2196:21): [True: 0, False: 0]
  ------------------
 2197|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2198|      0|                }
 2199|      0|                props_tmp = MqttDecode_Vbi(rx_payload, &props_len,
 2200|      0|                        (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2201|      0|                if (props_tmp < 0)
  ------------------
  |  Branch (2201:21): [True: 0, False: 0]
  ------------------
 2202|      0|                    return props_tmp;
 2203|       |
 2204|      0|                if (props_len <= (word32)(rx_buf_len - (rx_payload - rx_buf))) {
  ------------------
  |  Branch (2204:21): [True: 0, False: 0]
  ------------------
 2205|      0|                    rx_payload += props_tmp;
 2206|      0|                    if (props_len > 0) {
  ------------------
  |  Branch (2206:25): [True: 0, False: 0]
  ------------------
 2207|       |                        /* Decode the Properties */
 2208|      0|                        props_tmp = MqttDecode_Props((MqttPacketType)type,
 2209|      0|                                &publish_resp->props, rx_payload,
 2210|      0|                                (word32)(rx_buf_len - (rx_payload - rx_buf)),
 2211|      0|                                props_len);
 2212|      0|                        if (props_tmp < 0)
  ------------------
  |  Branch (2212:29): [True: 0, False: 0]
  ------------------
 2213|      0|                            return props_tmp;
 2214|      0|                        rx_payload += props_tmp;
 2215|      0|                    }
 2216|      0|                }
 2217|      0|                else {
 2218|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2219|      0|                }
 2220|      0|            }
 2221|      0|        }
 2222|      8|#endif
 2223|      8|    }
 2224|       |
 2225|      8|    (void)rx_payload;
 2226|       |
 2227|       |    /* Return total length of packet */
 2228|      8|    return header_len + remain_len;
 2229|      8|}
MqttEncode_Subscribe:
 2233|  2.00k|{
 2234|  2.00k|    int header_len, remain_len, i;
 2235|  2.00k|    byte *tx_payload;
 2236|  2.00k|    MqttTopic *topic;
 2237|  2.00k|#ifdef WOLFMQTT_V5
 2238|  2.00k|    int props_len = 0;
 2239|  2.00k|#endif
 2240|       |
 2241|       |    /* Validate required arguments */
 2242|  2.00k|    if (tx_buf == NULL || subscribe == NULL) {
  ------------------
  |  Branch (2242:9): [True: 0, False: 2.00k]
  |  Branch (2242:27): [True: 0, False: 2.00k]
  ------------------
 2243|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2244|      0|    }
 2245|       |
 2246|       |    /* [MQTT-2.3.1-1] SUBSCRIBE packets require a non-zero packet identifier */
 2247|  2.00k|    if (subscribe->packet_id == 0) {
  ------------------
  |  Branch (2247:9): [True: 1.08k, False: 919]
  ------------------
 2248|  1.08k|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_ID);
  ------------------
  |  |  392|  1.08k|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2249|  1.08k|    }
 2250|       |
 2251|       |    /* Determine packet length */
 2252|    919|    remain_len = MQTT_DATA_LEN_SIZE; /* For packet_id */
  ------------------
  |  |   39|    919|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 2253|  1.44k|    for (i = 0; i < subscribe->topic_count; i++) {
  ------------------
  |  Branch (2253:17): [True: 948, False: 500]
  ------------------
 2254|    948|        topic = &subscribe->topics[i];
 2255|    948|        if ((topic != NULL) && (topic->topic_filter != NULL)) {
  ------------------
  |  Branch (2255:13): [True: 948, False: 0]
  |  Branch (2255:32): [True: 533, False: 415]
  ------------------
 2256|       |            /* MQTT UTF-8 strings are limited to 65535 bytes [MQTT-1.5.3] */
 2257|    533|            size_t str_len = XSTRLEN(topic->topic_filter);
  ------------------
  |  |  992|    533|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 2258|    533|            if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (2258:17): [True: 4, False: 529]
  ------------------
 2259|      4|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      4|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2260|      4|            }
 2261|    529|            remain_len += (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|    529|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 2262|    529|            remain_len++; /* For QoS */
 2263|    529|        }
 2264|    415|        else {
 2265|       |            /* Topic count is invalid */
 2266|    415|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|    415|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2267|    415|        }
 2268|    948|    }
 2269|    500|#ifdef WOLFMQTT_V5
 2270|    500|    if (subscribe->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|    500|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2270:9): [True: 0, False: 500]
  ------------------
 2271|       |        /* Determine length of properties */
 2272|      0|        props_len = MqttEncode_Props(MQTT_PACKET_TYPE_SUBSCRIBE,
 2273|      0|                                    subscribe->props, NULL);
 2274|      0|        if (props_len >= 0) {
  ------------------
  |  Branch (2274:13): [True: 0, False: 0]
  ------------------
 2275|       |            /* Determine the length of the "property length" */
 2276|      0|            int tmp_len = MqttEncode_Vbi(NULL, props_len);
 2277|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (2277:17): [True: 0, False: 0]
  ------------------
 2278|      0|                return tmp_len;
 2279|      0|            }
 2280|      0|            remain_len += props_len;
 2281|      0|            remain_len += tmp_len;
 2282|      0|        }
 2283|      0|        else
 2284|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2285|      0|    }
 2286|    500|#endif
 2287|       |
 2288|       |
 2289|       |    /* Encode fixed header */
 2290|    500|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len, remain_len,
 2291|    500|        MQTT_PACKET_TYPE_SUBSCRIBE, 0, MQTT_QOS_1, 0);
 2292|    500|    if (header_len < 0) {
  ------------------
  |  Branch (2292:9): [True: 0, False: 500]
  ------------------
 2293|      0|        return header_len;
 2294|      0|    }
 2295|       |    /* Check for buffer room */
 2296|    500|    if (tx_buf_len < header_len + remain_len) {
  ------------------
  |  Branch (2296:9): [True: 13, False: 487]
  ------------------
 2297|     13|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|     13|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2298|     13|    }
 2299|    487|    tx_payload = &tx_buf[header_len];
 2300|       |
 2301|       |    /* Encode variable header */
 2302|    487|    tx_payload += MqttEncode_Num(&tx_buf[header_len], subscribe->packet_id);
 2303|       |
 2304|    487|#ifdef WOLFMQTT_V5
 2305|    487|    if (subscribe->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|    487|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2305:9): [True: 0, False: 487]
  ------------------
 2306|       |        /* Encode the property length */
 2307|      0|        int tmp_len = MqttEncode_Vbi(tx_payload, props_len);
 2308|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (2308:13): [True: 0, False: 0]
  ------------------
 2309|      0|            return tmp_len;
 2310|      0|        }
 2311|      0|        tx_payload += tmp_len;
 2312|       |
 2313|       |        /* Encode properties */
 2314|      0|        tmp_len = MqttEncode_Props(MQTT_PACKET_TYPE_SUBSCRIBE,
 2315|      0|                        subscribe->props, tx_payload);
 2316|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (2316:13): [True: 0, False: 0]
  ------------------
 2317|      0|            return tmp_len;
 2318|      0|        }
 2319|      0|        tx_payload += tmp_len;
 2320|      0|    }
 2321|    487|#endif
 2322|       |
 2323|       |    /* Encode payload */
 2324|    796|    for (i = 0; i < subscribe->topic_count; i++) {
  ------------------
  |  Branch (2324:17): [True: 309, False: 487]
  ------------------
 2325|    309|        topic = &subscribe->topics[i];
 2326|    309|        tx_payload += MqttEncode_String(tx_payload, topic->topic_filter);
 2327|       |        /* Sanity check for compilers */
 2328|    309|        if (tx_payload != NULL) {
  ------------------
  |  Branch (2328:13): [True: 309, False: 0]
  ------------------
 2329|    309|            *tx_payload = topic->qos;
 2330|    309|        }
 2331|    309|        tx_payload++;
 2332|    309|    }
 2333|       |
 2334|       |    /* Return total length of packet */
 2335|    487|    return header_len + remain_len;
 2336|    487|}
MqttDecode_SubscribeAck:
 2485|    221|{
 2486|    221|    int header_len, remain_len;
 2487|    221|    byte *rx_payload;
 2488|       |
 2489|       |    /* Validate required arguments */
 2490|    221|    if (rx_buf == NULL || rx_buf_len <= 0 || subscribe_ack == NULL) {
  ------------------
  |  Branch (2490:9): [True: 0, False: 221]
  |  Branch (2490:27): [True: 0, False: 221]
  |  Branch (2490:46): [True: 0, False: 221]
  ------------------
 2491|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2492|      0|    }
 2493|       |
 2494|       |    /* Decode fixed header */
 2495|    221|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 2496|    221|        MQTT_PACKET_TYPE_SUBSCRIBE_ACK, NULL, NULL, NULL);
 2497|    221|    if (header_len < 0) {
  ------------------
  |  Branch (2497:9): [True: 221, False: 0]
  ------------------
 2498|    221|        return header_len;
 2499|    221|    }
 2500|       |
 2501|       |    /* Validate remain_len (need at least packet_id) */
 2502|      0|    if (remain_len < MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2502:9): [True: 0, False: 0]
  ------------------
 2503|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2504|      0|    }
 2505|       |
 2506|      0|    rx_payload = &rx_buf[header_len];
 2507|       |
 2508|       |    /* Decode variable header */
 2509|      0|    if (subscribe_ack) {
  ------------------
  |  Branch (2509:9): [True: 0, False: 0]
  ------------------
 2510|      0|        int tmp;
 2511|      0|        tmp = MqttDecode_Num(rx_payload, &subscribe_ack->packet_id,
 2512|      0|                (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2513|      0|        if (tmp < 0) {
  ------------------
  |  Branch (2513:13): [True: 0, False: 0]
  ------------------
 2514|      0|            return tmp;
 2515|      0|        }
 2516|      0|        rx_payload += tmp;
 2517|       |
 2518|      0|#ifdef WOLFMQTT_V5
 2519|      0|        subscribe_ack->props = NULL;
 2520|      0|        if ((subscribe_ack->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) &&
  ------------------
  |  |  368|      0|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2520:13): [True: 0, False: 0]
  ------------------
 2521|      0|            (remain_len > MQTT_DATA_LEN_SIZE)) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2521:13): [True: 0, False: 0]
  ------------------
 2522|      0|            word32 props_len = 0;
 2523|      0|            int props_tmp;
 2524|       |
 2525|       |            /* Decode Length of Properties */
 2526|      0|            if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (2526:17): [True: 0, False: 0]
  ------------------
 2527|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2528|      0|            }
 2529|      0|            props_tmp = MqttDecode_Vbi(rx_payload, &props_len,
 2530|      0|                    (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2531|      0|            if (props_tmp < 0)
  ------------------
  |  Branch (2531:17): [True: 0, False: 0]
  ------------------
 2532|      0|                return props_tmp;
 2533|       |
 2534|      0|            if (props_len <= (word32)(rx_buf_len - (rx_payload - rx_buf))) {
  ------------------
  |  Branch (2534:17): [True: 0, False: 0]
  ------------------
 2535|      0|                rx_payload += props_tmp;
 2536|      0|                if (props_len > 0) {
  ------------------
  |  Branch (2536:21): [True: 0, False: 0]
  ------------------
 2537|       |                    /* Decode the Properties */
 2538|      0|                    props_tmp = MqttDecode_Props(MQTT_PACKET_TYPE_SUBSCRIBE_ACK,
 2539|      0|                                &subscribe_ack->props, rx_payload,
 2540|      0|                                (word32)(rx_buf_len - (rx_payload - rx_buf)),
 2541|      0|                                props_len);
 2542|      0|                    if (props_tmp < 0)
  ------------------
  |  Branch (2542:25): [True: 0, False: 0]
  ------------------
 2543|      0|                        return props_tmp;
 2544|      0|                    rx_payload += props_tmp;
 2545|      0|                }
 2546|      0|            }
 2547|      0|            else {
 2548|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2549|      0|            }
 2550|      0|        }
 2551|      0|#endif
 2552|       |
 2553|       |        /* payload is list of return codes (MqttSubscribeAckReturnCodes) */
 2554|      0|        {
 2555|      0|            int payload_len = remain_len -
 2556|      0|                    (int)(rx_payload - &rx_buf[header_len]);
 2557|      0|            int buf_remain = rx_buf_len - (int)(rx_payload - rx_buf);
 2558|      0|            byte level = 0;
 2559|      0|            int i;
 2560|      0|            if (payload_len < 0 || buf_remain < 0) {
  ------------------
  |  Branch (2560:17): [True: 0, False: 0]
  |  Branch (2560:36): [True: 0, False: 0]
  ------------------
 2561|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2562|      0|            }
 2563|      0|            if (payload_len > buf_remain) {
  ------------------
  |  Branch (2563:17): [True: 0, False: 0]
  ------------------
 2564|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2565|      0|            }
 2566|      0|            if (payload_len > MAX_MQTT_TOPICS)
  ------------------
  |  |   48|      0|#define MAX_MQTT_TOPICS      12
  ------------------
  |  Branch (2566:17): [True: 0, False: 0]
  ------------------
 2567|      0|                payload_len = MAX_MQTT_TOPICS;
  ------------------
  |  |   48|      0|#define MAX_MQTT_TOPICS      12
  ------------------
 2568|      0|        #ifdef WOLFMQTT_V5
 2569|      0|            level = subscribe_ack->protocol_level;
 2570|      0|        #endif
 2571|       |            /* [MQTT-3.9.3-2] Reject reserved SUBACK return codes before
 2572|       |             * the bytes are copied into the caller's struct so a
 2573|       |             * malformed broker response never surfaces to upper-layer
 2574|       |             * subscription handling. Under v5 the property block has
 2575|       |             * already been allocated above; free it before returning so
 2576|       |             * a malformed-broker stream doesn't leak per-SUBACK. */
 2577|      0|            for (i = 0; i < payload_len; i++) {
  ------------------
  |  Branch (2577:25): [True: 0, False: 0]
  ------------------
 2578|      0|                if (!MqttPacket_SubAckReturnCodeValid(rx_payload[i], level)) {
  ------------------
  |  Branch (2578:21): [True: 0, False: 0]
  ------------------
 2579|      0|                #ifdef WOLFMQTT_V5
 2580|      0|                    if (subscribe_ack->props != NULL) {
  ------------------
  |  Branch (2580:25): [True: 0, False: 0]
  ------------------
 2581|      0|                        (void)MqttProps_Free(subscribe_ack->props);
 2582|      0|                        subscribe_ack->props = NULL;
 2583|      0|                    }
 2584|      0|                #endif
 2585|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2586|      0|                }
 2587|      0|            }
 2588|      0|            XMEMSET(subscribe_ack->return_codes, 0, MAX_MQTT_TOPICS);
  ------------------
  |  |  988|      0|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
 2589|      0|            XMEMCPY(subscribe_ack->return_codes, rx_payload, payload_len);
  ------------------
  |  |  987|      0|    #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))
  ------------------
 2590|      0|        }
 2591|      0|    }
 2592|       |
 2593|       |    /* Return total length of packet */
 2594|      0|    return header_len + remain_len;
 2595|      0|}
MqttEncode_Unsubscribe:
 2599|    445|{
 2600|    445|    int header_len, remain_len, i;
 2601|    445|    byte *tx_payload;
 2602|    445|    MqttTopic *topic;
 2603|    445|#ifdef WOLFMQTT_V5
 2604|    445|    int props_len = 0;
 2605|    445|#endif
 2606|       |
 2607|       |    /* Validate required arguments */
 2608|    445|    if (tx_buf == NULL || unsubscribe == NULL) {
  ------------------
  |  Branch (2608:9): [True: 0, False: 445]
  |  Branch (2608:27): [True: 0, False: 445]
  ------------------
 2609|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2610|      0|    }
 2611|       |
 2612|       |    /* [MQTT-2.3.1-1] UNSUBSCRIBE packets require a non-zero packet identifier */
 2613|    445|    if (unsubscribe->packet_id == 0) {
  ------------------
  |  Branch (2613:9): [True: 75, False: 370]
  ------------------
 2614|     75|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_ID);
  ------------------
  |  |  392|     75|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2615|     75|    }
 2616|       |
 2617|       |    /* Determine packet length */
 2618|    370|    remain_len = MQTT_DATA_LEN_SIZE; /* For packet_id */
  ------------------
  |  |   39|    370|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 2619|    735|    for (i = 0; i < unsubscribe->topic_count; i++) {
  ------------------
  |  Branch (2619:17): [True: 475, False: 260]
  ------------------
 2620|    475|        topic = &unsubscribe->topics[i];
 2621|    475|        if ((topic != NULL) && (topic->topic_filter != NULL)) {
  ------------------
  |  Branch (2621:13): [True: 475, False: 0]
  |  Branch (2621:32): [True: 367, False: 108]
  ------------------
 2622|       |            /* MQTT UTF-8 strings are limited to 65535 bytes [MQTT-1.5.3] */
 2623|    367|            size_t str_len = XSTRLEN(topic->topic_filter);
  ------------------
  |  |  992|    367|    #define XSTRLEN(s1)       strlen((s1))
  ------------------
 2624|    367|            if (str_len > (size_t)0xFFFF) {
  ------------------
  |  Branch (2624:17): [True: 2, False: 365]
  ------------------
 2625|      2|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      2|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2626|      2|            }
 2627|    365|            remain_len += (int)str_len + MQTT_DATA_LEN_SIZE;
  ------------------
  |  |   39|    365|#define MQTT_DATA_LEN_SIZE   2
  ------------------
 2628|    365|        }
 2629|    108|        else {
 2630|       |            /* Topic count is invalid */
 2631|    108|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|    108|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2632|    108|        }
 2633|    475|    }
 2634|    260|#ifdef WOLFMQTT_V5
 2635|    260|    if (unsubscribe->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|    260|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2635:9): [True: 0, False: 260]
  ------------------
 2636|       |        /* Determine length of properties */
 2637|      0|        props_len = MqttEncode_Props(MQTT_PACKET_TYPE_UNSUBSCRIBE,
 2638|      0|                                            unsubscribe->props, NULL);
 2639|      0|        if (props_len >= 0) {
  ------------------
  |  Branch (2639:13): [True: 0, False: 0]
  ------------------
 2640|       |            /* Determine the length of the "property length" */
 2641|      0|            int tmp_len = MqttEncode_Vbi(NULL, props_len);
 2642|      0|            if (tmp_len < 0) {
  ------------------
  |  Branch (2642:17): [True: 0, False: 0]
  ------------------
 2643|      0|                return tmp_len;
 2644|      0|            }
 2645|      0|            remain_len += props_len;
 2646|      0|            remain_len += tmp_len;
 2647|      0|        }
 2648|      0|        else
 2649|      0|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2650|      0|    }
 2651|    260|#endif
 2652|       |
 2653|       |    /* Encode fixed header */
 2654|    260|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len, remain_len,
 2655|    260|        MQTT_PACKET_TYPE_UNSUBSCRIBE, 0, MQTT_QOS_1, 0);
 2656|    260|    if (header_len < 0) {
  ------------------
  |  Branch (2656:9): [True: 0, False: 260]
  ------------------
 2657|      0|        return header_len;
 2658|      0|    }
 2659|       |    /* Check for buffer room */
 2660|    260|    if (tx_buf_len < header_len + remain_len) {
  ------------------
  |  Branch (2660:9): [True: 11, False: 249]
  ------------------
 2661|     11|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|     11|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2662|     11|    }
 2663|    249|    tx_payload = &tx_buf[header_len];
 2664|       |
 2665|       |    /* Encode variable header */
 2666|    249|    tx_payload += MqttEncode_Num(&tx_buf[header_len], unsubscribe->packet_id);
 2667|    249|#ifdef WOLFMQTT_V5
 2668|    249|    if (unsubscribe->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|    249|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2668:9): [True: 0, False: 249]
  ------------------
 2669|       |        /* Encode the property length */
 2670|      0|        int tmp_len = MqttEncode_Vbi(tx_payload, props_len);
 2671|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (2671:13): [True: 0, False: 0]
  ------------------
 2672|      0|            return tmp_len;
 2673|      0|        }
 2674|      0|        tx_payload += tmp_len;
 2675|       |
 2676|       |        /* Encode properties */
 2677|      0|        tmp_len = MqttEncode_Props(MQTT_PACKET_TYPE_UNSUBSCRIBE,
 2678|      0|                        unsubscribe->props, tx_payload);
 2679|      0|        if (tmp_len < 0) {
  ------------------
  |  Branch (2679:13): [True: 0, False: 0]
  ------------------
 2680|      0|            return tmp_len;
 2681|      0|        }
 2682|      0|        tx_payload += tmp_len;
 2683|      0|    }
 2684|    249|#endif
 2685|       |
 2686|       |
 2687|       |    /* Encode payload */
 2688|    442|    for (i = 0; i < unsubscribe->topic_count; i++) {
  ------------------
  |  Branch (2688:17): [True: 193, False: 249]
  ------------------
 2689|    193|        topic = &unsubscribe->topics[i];
 2690|    193|        tx_payload += MqttEncode_String(tx_payload, topic->topic_filter);
 2691|    193|    }
 2692|       |
 2693|       |    /* Return total length of packet */
 2694|    249|    return header_len + remain_len;
 2695|    249|}
MqttDecode_UnsubscribeAck:
 2814|    147|{
 2815|    147|    int header_len, remain_len;
 2816|    147|    byte *rx_payload;
 2817|       |
 2818|       |    /* Validate required arguments */
 2819|    147|    if (rx_buf == NULL || rx_buf_len <= 0 || unsubscribe_ack == NULL) {
  ------------------
  |  Branch (2819:9): [True: 0, False: 147]
  |  Branch (2819:27): [True: 0, False: 147]
  |  Branch (2819:46): [True: 0, False: 147]
  ------------------
 2820|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2821|      0|    }
 2822|       |
 2823|       |    /* Decode fixed header */
 2824|    147|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 2825|    147|        MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK, NULL, NULL, NULL);
 2826|    147|    if (header_len < 0) {
  ------------------
  |  Branch (2826:9): [True: 140, False: 7]
  ------------------
 2827|    140|        return header_len;
 2828|    140|    }
 2829|       |
 2830|       |    /* Validate remain_len (need at least packet_id) */
 2831|      7|    if (remain_len < MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|      7|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2831:9): [True: 0, False: 7]
  ------------------
 2832|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2833|      0|    }
 2834|       |
 2835|      7|    rx_payload = &rx_buf[header_len];
 2836|       |
 2837|       |    /* Decode variable header */
 2838|      7|    if (unsubscribe_ack) {
  ------------------
  |  Branch (2838:9): [True: 7, False: 0]
  ------------------
 2839|      7|        int tmp;
 2840|      7|        tmp = MqttDecode_Num(rx_payload, &unsubscribe_ack->packet_id,
 2841|      7|                (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2842|      7|        if (tmp < 0) {
  ------------------
  |  Branch (2842:13): [True: 0, False: 7]
  ------------------
 2843|      0|            return tmp;
 2844|      0|        }
 2845|      7|        rx_payload += tmp;
 2846|      7|#ifdef WOLFMQTT_V5
 2847|      7|        unsubscribe_ack->props = NULL;
 2848|      7|        if (unsubscribe_ack->protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
  ------------------
  |  |  368|      7|#define MQTT_CONNECT_PROTOCOL_LEVEL_5   5 /* v5.0 */
  ------------------
  |  Branch (2848:13): [True: 0, False: 7]
  ------------------
 2849|      0|            if (remain_len > MQTT_DATA_LEN_SIZE) {
  ------------------
  |  |   39|      0|#define MQTT_DATA_LEN_SIZE   2
  ------------------
  |  Branch (2849:17): [True: 0, False: 0]
  ------------------
 2850|      0|                word32 props_len = 0;
 2851|      0|                int props_tmp;
 2852|       |
 2853|       |                /* Decode Length of Properties */
 2854|      0|                if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (2854:21): [True: 0, False: 0]
  ------------------
 2855|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2856|      0|                }
 2857|      0|                props_tmp = MqttDecode_Vbi(rx_payload, &props_len,
 2858|      0|                        (word32)(rx_buf_len - (rx_payload - rx_buf)));
 2859|      0|                if (props_tmp < 0)
  ------------------
  |  Branch (2859:21): [True: 0, False: 0]
  ------------------
 2860|      0|                    return props_tmp;
 2861|       |
 2862|      0|                if (props_len <= (word32)(rx_buf_len - (rx_payload - rx_buf))) {
  ------------------
  |  Branch (2862:21): [True: 0, False: 0]
  ------------------
 2863|      0|                    rx_payload += props_tmp;
 2864|      0|                    if (props_len > 0) {
  ------------------
  |  Branch (2864:25): [True: 0, False: 0]
  ------------------
 2865|       |                        /* Decode the Properties */
 2866|      0|                        props_tmp = MqttDecode_Props(MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK,
 2867|      0|                                &unsubscribe_ack->props, rx_payload,
 2868|      0|                                (word32)(rx_buf_len - (rx_payload - rx_buf)),
 2869|      0|                                props_len);
 2870|      0|                        if (props_tmp < 0)
  ------------------
  |  Branch (2870:29): [True: 0, False: 0]
  ------------------
 2871|      0|                            return props_tmp;
 2872|      0|                        rx_payload += props_tmp;
 2873|      0|                    }
 2874|      0|                }
 2875|      0|                else {
 2876|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2877|      0|                }
 2878|      0|            }
 2879|       |
 2880|       |            /* Reason codes are stored in the payload */
 2881|      0|            unsubscribe_ack->reason_codes = rx_payload;
 2882|      0|        }
 2883|      7|#endif
 2884|      7|    }
 2885|      7|    (void)rx_payload;
 2886|       |
 2887|       |    /* Return total length of packet */
 2888|      7|    return header_len + remain_len;
 2889|      7|}
MqttEncode_Ping:
 2983|    910|{
 2984|    910|    int header_len, remain_len = 0;
 2985|       |
 2986|       |    /* Validate required arguments */
 2987|    910|    if (tx_buf == NULL) {
  ------------------
  |  Branch (2987:9): [True: 0, False: 910]
  ------------------
 2988|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 2989|      0|    }
 2990|       |
 2991|       |    /* Encode fixed header */
 2992|    910|    header_len = MqttEncode_FixedHeader(tx_buf, tx_buf_len, remain_len,
 2993|    910|        MQTT_PACKET_TYPE_PING_REQ, 0, 0, 0);
 2994|    910|    if (header_len < 0) {
  ------------------
  |  Branch (2994:9): [True: 0, False: 910]
  ------------------
 2995|      0|        return header_len;
 2996|      0|    }
 2997|       |
 2998|    910|    if (ping) {
  ------------------
  |  Branch (2998:9): [True: 910, False: 0]
  ------------------
 2999|       |        /* nothing to encode */
 3000|    910|    }
 3001|       |
 3002|       |    /* Return total length of packet */
 3003|    910|    return header_len + remain_len;
 3004|    910|}
MqttDecode_Ping:
 3007|     54|{
 3008|     54|    int header_len, remain_len;
 3009|       |
 3010|       |    /* Validate required arguments */
 3011|     54|    if (rx_buf == NULL || rx_buf_len <= 0) {
  ------------------
  |  Branch (3011:9): [True: 0, False: 54]
  |  Branch (3011:27): [True: 0, False: 54]
  ------------------
 3012|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3013|      0|    }
 3014|       |
 3015|       |    /* Decode fixed header */
 3016|     54|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 3017|     54|        MQTT_PACKET_TYPE_PING_RESP, NULL, NULL, NULL);
 3018|     54|    if (header_len < 0) {
  ------------------
  |  Branch (3018:9): [True: 52, False: 2]
  ------------------
 3019|     52|        return header_len;
 3020|     52|    }
 3021|       |
 3022|       |    /* MQTT 3.1.1 section 3.13 / v5 section 3.13: PINGRESP has no variable header and no
 3023|       |     * payload, so Remaining Length MUST be 0. */
 3024|      2|    if (remain_len != 0) {
  ------------------
  |  Branch (3024:9): [True: 2, False: 0]
  ------------------
 3025|      2|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      2|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3026|      2|    }
 3027|       |
 3028|      0|    if (ping) {
  ------------------
  |  Branch (3028:9): [True: 0, False: 0]
  ------------------
 3029|       |        /* nothing to decode */
 3030|      0|    }
 3031|       |
 3032|       |    /* Return total length of packet */
 3033|      0|    return header_len + remain_len;
 3034|      2|}
MqttDecode_Disconnect:
 3162|    319|{
 3163|    319|    int header_len, remain_len;
 3164|    319|    byte *rx_payload;
 3165|    319|    word32 props_len = 0;
 3166|       |
 3167|       |    /* Validate required arguments */
 3168|    319|    if ((rx_buf == NULL) || (rx_buf_len <= 0) || (disc == NULL)) {
  ------------------
  |  Branch (3168:9): [True: 0, False: 319]
  |  Branch (3168:29): [True: 0, False: 319]
  |  Branch (3168:50): [True: 0, False: 319]
  ------------------
 3169|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3170|      0|    }
 3171|       |
 3172|       |    /* Decode fixed header */
 3173|    319|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 3174|    319|        MQTT_PACKET_TYPE_DISCONNECT, NULL, NULL, NULL);
 3175|    319|    if (header_len < 0) {
  ------------------
  |  Branch (3175:9): [True: 292, False: 27]
  ------------------
 3176|    292|        return header_len;
 3177|    292|    }
 3178|     27|    rx_payload = &rx_buf[header_len];
 3179|       |
 3180|     27|    disc->props = NULL;
 3181|     27|    if (remain_len > 0) {
  ------------------
  |  Branch (3181:9): [True: 11, False: 16]
  ------------------
 3182|       |        /* Decode variable header */
 3183|     11|        disc->reason_code = *rx_payload++;
 3184|       |
 3185|     11|        if (remain_len > 1) {
  ------------------
  |  Branch (3185:13): [True: 4, False: 7]
  ------------------
 3186|      4|            int props_tmp;
 3187|       |            /* Decode Length of Properties */
 3188|      4|            if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (3188:17): [True: 0, False: 4]
  ------------------
 3189|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3190|      0|            }
 3191|      4|            props_tmp = MqttDecode_Vbi(rx_payload, &props_len,
 3192|      4|                    (word32)(rx_buf_len - (rx_payload - rx_buf)));
 3193|      4|            if (props_tmp < 0)
  ------------------
  |  Branch (3193:17): [True: 0, False: 4]
  ------------------
 3194|      0|                return props_tmp;
 3195|       |
 3196|      4|            if (props_len <= (word32)(rx_buf_len - (rx_payload - rx_buf))) {
  ------------------
  |  Branch (3196:17): [True: 1, False: 3]
  ------------------
 3197|      1|                rx_payload += props_tmp;
 3198|      1|                if (props_len > 0) {
  ------------------
  |  Branch (3198:21): [True: 1, False: 0]
  ------------------
 3199|       |                    /* Decode the Properties */
 3200|      1|                    props_tmp = MqttDecode_Props(MQTT_PACKET_TYPE_DISCONNECT,
 3201|      1|                            &disc->props, rx_payload,
 3202|      1|                            (word32)(rx_buf_len - (rx_payload - rx_buf)),
 3203|      1|                            props_len);
 3204|      1|                    if (props_tmp < 0)
  ------------------
  |  Branch (3204:25): [True: 1, False: 0]
  ------------------
 3205|      1|                        return props_tmp;
 3206|      0|                    rx_payload += props_tmp;
 3207|      0|                }
 3208|      1|            }
 3209|      3|            else {
 3210|      3|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      3|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3211|      3|            }
 3212|      4|        }
 3213|     11|    }
 3214|       |
 3215|     23|    (void)rx_payload;
 3216|       |
 3217|       |    /* Return total length of packet */
 3218|     23|    return header_len + remain_len;
 3219|     27|}
MqttDecode_Auth:
 3295|    313|{
 3296|    313|    int header_len, remain_len, tmp;
 3297|    313|    byte *rx_payload;
 3298|    313|    word32 props_len = 0;
 3299|       |
 3300|       |
 3301|       |    /* Validate required arguments */
 3302|    313|    if ((rx_buf == NULL) || (rx_buf_len <= 0) || (auth == NULL)) {
  ------------------
  |  Branch (3302:9): [True: 0, False: 313]
  |  Branch (3302:29): [True: 0, False: 313]
  |  Branch (3302:50): [True: 0, False: 313]
  ------------------
 3303|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_BAD_ARG);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3304|      0|    }
 3305|       |
 3306|       |    /* Decode fixed header */
 3307|    313|    header_len = MqttDecode_FixedHeader(rx_buf, rx_buf_len, &remain_len,
 3308|    313|                  MQTT_PACKET_TYPE_AUTH, NULL, NULL, NULL);
 3309|    313|    if (header_len < 0) {
  ------------------
  |  Branch (3309:9): [True: 297, False: 16]
  ------------------
 3310|    297|        return header_len;
 3311|    297|    }
 3312|     16|    rx_payload = &rx_buf[header_len];
 3313|       |
 3314|     16|    auth->props = NULL;
 3315|     16|    if (remain_len > 0) {
  ------------------
  |  Branch (3315:9): [True: 14, False: 2]
  ------------------
 3316|       |        /* Decode variable header */
 3317|     14|        auth->reason_code = *rx_payload++;
 3318|     14|        if ((auth->reason_code == MQTT_REASON_SUCCESS) ||
  ------------------
  |  Branch (3318:13): [True: 12, False: 2]
  ------------------
 3319|      2|            (auth->reason_code == MQTT_REASON_CONT_AUTH) ||
  ------------------
  |  Branch (3319:13): [True: 1, False: 1]
  ------------------
 3320|      1|            (auth->reason_code == MQTT_REASON_REAUTH))
  ------------------
  |  Branch (3320:13): [True: 0, False: 1]
  ------------------
 3321|     13|        {
 3322|       |            /* Decode Length of Properties */
 3323|     13|            if (rx_buf_len < (rx_payload - rx_buf)) {
  ------------------
  |  Branch (3323:17): [True: 0, False: 13]
  ------------------
 3324|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3325|      0|            }
 3326|     13|            tmp = MqttDecode_Vbi(rx_payload, &props_len,
 3327|     13|                    (word32)(rx_buf_len - (rx_payload - rx_buf)));
 3328|     13|            if (tmp < 0)
  ------------------
  |  Branch (3328:17): [True: 1, False: 12]
  ------------------
 3329|      1|                return tmp;
 3330|       |
 3331|     12|            if (props_len <= (word32)(rx_buf_len - (rx_payload - rx_buf))) {
  ------------------
  |  Branch (3331:17): [True: 9, False: 3]
  ------------------
 3332|      9|                rx_payload += tmp;
 3333|      9|                if ((rx_payload - rx_buf) > rx_buf_len) {
  ------------------
  |  Branch (3333:21): [True: 0, False: 9]
  ------------------
 3334|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3335|      0|                }
 3336|      9|                if (props_len > 0) {
  ------------------
  |  Branch (3336:21): [True: 9, False: 0]
  ------------------
 3337|       |                    /* Decode the Properties */
 3338|      9|                    tmp = MqttDecode_Props(MQTT_PACKET_TYPE_AUTH,
 3339|      9|                            &auth->props, rx_payload,
 3340|      9|                            (word32)(rx_buf_len - (rx_payload - rx_buf)),
 3341|      9|                            props_len);
 3342|      9|                    if (tmp < 0)
  ------------------
  |  Branch (3342:25): [True: 9, False: 0]
  ------------------
 3343|      9|                        return tmp;
 3344|      0|                    rx_payload += tmp;
 3345|      0|                }
 3346|      0|                else if (auth->reason_code != MQTT_REASON_SUCCESS) {
  ------------------
  |  Branch (3346:26): [True: 0, False: 0]
  ------------------
 3347|       |                    /* The Reason Code and Property Length can be omitted if
 3348|       |                       the Reason Code is 0x00 (Success) and there are no
 3349|       |                       Properties. In this case the AUTH has a Remaining
 3350|       |                       Length of 0. */
 3351|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3352|      0|                }
 3353|      0|                if (auth->props != NULL) {
  ------------------
  |  Branch (3353:21): [True: 0, False: 0]
  ------------------
 3354|       |                    /* Must have Authentication Method */
 3355|       |
 3356|       |                    /* Must have Authentication Data */
 3357|       |
 3358|       |                    /* May have zero or more User Property pairs */
 3359|      0|                }
 3360|      0|                else {
 3361|      0|                    return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3362|      0|                }
 3363|      0|            }
 3364|      3|            else {
 3365|      3|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      3|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3366|      3|            }
 3367|     12|        }
 3368|      1|        else {
 3369|      1|            return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|      1|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3370|      1|        }
 3371|     14|    }
 3372|      2|    else {
 3373|       |        /* Per MQTT 5.0 section 3.15.2: Remaining Length of 0 implies
 3374|       |           Reason Code of 0x00 (Success) with no Properties */
 3375|      2|        auth->reason_code = MQTT_REASON_SUCCESS;
 3376|      2|    }
 3377|       |
 3378|      2|    (void)rx_payload;
 3379|       |
 3380|       |    /* Return total length of packet */
 3381|      2|    return header_len + remain_len;
 3382|     16|}
MqttProps_Add:
 3415|     10|{
 3416|     10|    MqttProp *new_prop = NULL, *prev = NULL, *cur;
 3417|     10|#ifndef WOLFMQTT_DYN_PROP
 3418|     10|    int i;
 3419|     10|#endif
 3420|       |
 3421|     10|    if (head == NULL) {
  ------------------
  |  Branch (3421:9): [True: 0, False: 10]
  ------------------
 3422|      0|        return NULL;
 3423|      0|    }
 3424|       |
 3425|       |#if !defined(WOLFMQTT_DYN_PROP) && defined(WOLFMQTT_MULTITHREAD)
 3426|       |    if (wm_SemLock(&clientPropStack_lock) != 0) {
 3427|       |        return NULL;
 3428|       |    }
 3429|       |#endif
 3430|       |
 3431|     10|    cur = *head;
 3432|       |
 3433|       |    /* Find the end of the parameter list */
 3434|     10|    while (cur != NULL) {
  ------------------
  |  Branch (3434:12): [True: 0, False: 10]
  ------------------
 3435|      0|        prev = cur;
 3436|      0|        cur = cur->next;
 3437|      0|    };
 3438|       |
 3439|     10|#ifndef WOLFMQTT_DYN_PROP
 3440|       |    /* Find a free element */
 3441|     10|    for (i = 0; i < MQTT_MAX_PROPS; i++) {
  ------------------
  |  |  132|     10|#define MQTT_MAX_PROPS 30
  ------------------
  |  Branch (3441:17): [True: 10, False: 0]
  ------------------
 3442|     10|        if (clientPropStack[i].type == MQTT_PROP_NONE) {
  ------------------
  |  Branch (3442:13): [True: 10, False: 0]
  ------------------
 3443|       |            /* Found one */
 3444|     10|            new_prop = &clientPropStack[i];
 3445|     10|            XMEMSET(new_prop, 0, sizeof(MqttProp));
  ------------------
  |  |  988|     10|    #define XMEMSET(b,c,l)    memset((b),(c),(l))
  ------------------
 3446|     10|            break;
 3447|     10|        }
 3448|     10|    }
 3449|       |#else
 3450|       |    /* Allocate a new prop */
 3451|       |    new_prop = WOLFMQTT_MALLOC(sizeof(MqttProp));
 3452|       |    if (new_prop != NULL) {
 3453|       |        XMEMSET(new_prop, 0, sizeof(MqttProp));
 3454|       |    }
 3455|       |#endif
 3456|       |
 3457|     10|    if (new_prop != NULL) {
  ------------------
  |  Branch (3457:9): [True: 10, False: 0]
  ------------------
 3458|       |        /* set placeholder until caller sets it to a real type */
 3459|     10|        new_prop->type = MQTT_PROP_TYPE_MAX;
 3460|     10|        if (prev == NULL) {
  ------------------
  |  Branch (3460:13): [True: 10, False: 0]
  ------------------
 3461|       |            /* Start a new list */
 3462|     10|            *head = new_prop;
 3463|     10|        }
 3464|      0|        else {
 3465|       |            /* Add to the existing list */
 3466|      0|            prev->next = new_prop;
 3467|      0|        }
 3468|     10|    }
 3469|      0|    else {
 3470|       |        /* Could not allocate property */
 3471|      0|        (void)MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PROPERTY);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3472|      0|    }
 3473|       |
 3474|       |#if !defined(WOLFMQTT_DYN_PROP) && defined(WOLFMQTT_MULTITHREAD)
 3475|       |    (void)wm_SemUnlock(&clientPropStack_lock);
 3476|       |#endif
 3477|       |
 3478|     10|    return new_prop;
 3479|     10|}
MqttProps_Free:
 3483|     16|{
 3484|     16|    int ret = MQTT_CODE_SUCCESS;
 3485|       |#if !defined(WOLFMQTT_DYN_PROP) && defined(WOLFMQTT_MULTITHREAD)
 3486|       |    if ((ret = wm_SemLock(&clientPropStack_lock)) != 0) {
 3487|       |        return ret;
 3488|       |    }
 3489|       |#endif
 3490|     26|    while (head != NULL) {
  ------------------
  |  Branch (3490:12): [True: 10, False: 16]
  ------------------
 3491|     10|#ifndef WOLFMQTT_DYN_PROP
 3492|     10|        head->type = MQTT_PROP_NONE; /* available */
 3493|     10|        head = head->next;
 3494|       |#else
 3495|       |        MqttProp *tmp;
 3496|       |
 3497|       |        tmp = head->next;
 3498|       |        WOLFMQTT_FREE(head);
 3499|       |        head = tmp;
 3500|       |#endif
 3501|     10|    }
 3502|       |#if !defined(WOLFMQTT_DYN_PROP) && defined(WOLFMQTT_MULTITHREAD)
 3503|       |    (void)wm_SemUnlock(&clientPropStack_lock);
 3504|       |#endif
 3505|     16|    return ret;
 3506|     16|}
MqttPacket_HandleNetError:
 3511|  7.49k|{
 3512|  7.49k|    (void)client;
 3513|  7.49k|#ifdef WOLFMQTT_DISCONNECT_CB
 3514|  7.49k|    if (rc < 0 &&
  ------------------
  |  Branch (3514:9): [True: 3.11k, False: 4.37k]
  ------------------
 3515|  3.11k|        rc != MQTT_CODE_CONTINUE &&
  ------------------
  |  Branch (3515:9): [True: 3.11k, False: 0]
  ------------------
 3516|  3.11k|        rc != MQTT_CODE_STDIN_WAKE)
  ------------------
  |  Branch (3516:9): [True: 3.11k, False: 0]
  ------------------
 3517|  3.11k|    {
 3518|       |        /* don't use return code for now - future use */
 3519|  3.11k|        if (client->disconnect_cb)
  ------------------
  |  Branch (3519:13): [True: 0, False: 3.11k]
  ------------------
 3520|      0|            client->disconnect_cb(client, rc, client->disconnect_ctx);
 3521|  3.11k|    }
 3522|  7.49k|#endif
 3523|  7.49k|    return rc;
 3524|  7.49k|}
MqttPacket_Write:
 3527|  4.41k|{
 3528|  4.41k|    int rc;
 3529|  4.41k|#ifdef WOLFMQTT_V5
 3530|  4.41k|    if ((client->packet_sz_max > 0) && (tx_buf_len >
  ------------------
  |  Branch (3530:9): [True: 0, False: 4.41k]
  |  Branch (3530:40): [True: 0, False: 0]
  ------------------
 3531|      0|        (int)client->packet_sz_max))
 3532|      0|    {
 3533|      0|        rc = MQTT_TRACE_ERROR(MQTT_CODE_ERROR_SERVER_PROP);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3534|      0|    }
 3535|  4.41k|    else
 3536|  4.41k|#endif
 3537|  4.41k|    {
 3538|  4.41k|        rc = MqttSocket_Write(client, tx_buf, tx_buf_len,
 3539|  4.41k|                client->cmd_timeout_ms);
 3540|  4.41k|    }
 3541|       |
 3542|  4.41k|    return MqttPacket_HandleNetError(client, rc);
 3543|  4.41k|}
MqttPacket_Read:
 3548|  5.12k|{
 3549|  5.12k|    int rc, len, remain_read = 0;
 3550|  5.12k|    MqttPacket* header = (MqttPacket*)rx_buf;
 3551|       |
 3552|  5.12k|    switch (client->packet.stat)
  ------------------
  |  Branch (3552:13): [True: 5.12k, False: 0]
  ------------------
 3553|  5.12k|    {
 3554|  4.18k|        case MQTT_PK_BEGIN:
  ------------------
  |  Branch (3554:9): [True: 4.18k, False: 937]
  ------------------
 3555|  4.18k|        {
 3556|  4.18k|            client->packet.header_len = MQTT_PACKET_HEADER_MIN_SIZE;
  ------------------
  |  |  300|  4.18k|#define MQTT_PACKET_HEADER_MIN_SIZE        (2)
  ------------------
 3557|  4.18k|            client->packet.remain_len = 0;
 3558|       |
 3559|       |            /* Read fix header portion */
 3560|  4.18k|            rc = MqttSocket_Read(client, rx_buf, client->packet.header_len,
 3561|  4.18k|                    timeout_ms);
 3562|  4.18k|            if (rc < 0) {
  ------------------
  |  Branch (3562:17): [True: 707, False: 3.47k]
  ------------------
 3563|    707|                return MqttPacket_HandleNetError(client, rc);
 3564|    707|            }
 3565|  3.47k|            else if (rc != client->packet.header_len) {
  ------------------
  |  Branch (3565:22): [True: 122, False: 3.35k]
  ------------------
 3566|    122|                return MqttPacket_HandleNetError(client,
 3567|    122|                         MQTT_TRACE_ERROR(MQTT_CODE_ERROR_NETWORK));
  ------------------
  |  |  392|    122|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3568|    122|            }
 3569|  4.18k|        }
 3570|  3.35k|        FALL_THROUGH;
  ------------------
  |  |  472|  3.35k|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 3571|       |
 3572|  3.98k|        case MQTT_PK_READ_HEAD:
  ------------------
  |  Branch (3572:9): [True: 626, False: 4.49k]
  ------------------
 3573|  3.98k|        {
 3574|  3.98k|            int i;
 3575|  3.98k|            client->packet.stat = MQTT_PK_READ_HEAD;
 3576|       |
 3577|  3.98k|            for (i = (client->packet.header_len - MQTT_PACKET_HEADER_MIN_SIZE);
  ------------------
  |  |  300|  3.98k|#define MQTT_PACKET_HEADER_MIN_SIZE        (2)
  ------------------
 3578|  4.87k|                 i < MQTT_PACKET_MAX_LEN_BYTES;
  ------------------
  |  |  283|  4.87k|#define MQTT_PACKET_MAX_LEN_BYTES   4
  ------------------
  |  Branch (3578:18): [True: 4.77k, False: 98]
  ------------------
 3579|  4.77k|                 i++) {
 3580|       |                /* Check if another byte is needed */
 3581|  4.77k|                if ((header->len[i] & MQTT_PACKET_LEN_ENCODE_MASK) == 0) {
  ------------------
  |  |  284|  4.77k|#define MQTT_PACKET_LEN_ENCODE_MASK 0x80UL
  ------------------
  |  Branch (3581:21): [True: 2.98k, False: 1.79k]
  ------------------
 3582|       |                    /* Variable byte length can be determined */
 3583|  2.98k|                    break;
 3584|  2.98k|                }
 3585|       |
 3586|       |                /* Read next byte and try decode again */
 3587|  1.79k|                len = 1;
 3588|  1.79k|                rc = MqttSocket_Read(client, &rx_buf[client->packet.header_len],
 3589|  1.79k|                        len, timeout_ms);
 3590|  1.79k|                if (rc < 0) {
  ------------------
  |  Branch (3590:21): [True: 816, False: 977]
  ------------------
 3591|    816|                    return MqttPacket_HandleNetError(client, rc);
 3592|    816|                }
 3593|    977|                else if (rc != len) {
  ------------------
  |  Branch (3593:26): [True: 87, False: 890]
  ------------------
 3594|     87|                    return MqttPacket_HandleNetError(client,
 3595|     87|                             MQTT_TRACE_ERROR(MQTT_CODE_ERROR_NETWORK));
  ------------------
  |  |  392|     87|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3596|     87|                }
 3597|    890|                client->packet.header_len += len;
 3598|    890|            }
 3599|       |
 3600|  3.07k|            if (i == MQTT_PACKET_MAX_LEN_BYTES) {
  ------------------
  |  |  283|  3.07k|#define MQTT_PACKET_MAX_LEN_BYTES   4
  ------------------
  |  Branch (3600:17): [True: 98, False: 2.98k]
  ------------------
 3601|     98|                return MqttPacket_HandleNetError(client,
 3602|     98|                        MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA));
  ------------------
  |  |  392|     98|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3603|     98|            }
 3604|       |
 3605|       |            /* Try and decode remaining length */
 3606|  2.98k|            if (rx_buf_len < (client->packet.header_len - (i + 1))) {
  ------------------
  |  Branch (3606:17): [True: 0, False: 2.98k]
  ------------------
 3607|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3608|      0|            }
 3609|  2.98k|            rc = MqttDecode_Vbi(header->len,
 3610|  2.98k|                    (word32*)&client->packet.remain_len,
 3611|  2.98k|                    rx_buf_len - (client->packet.header_len - (i + 1)));
 3612|  2.98k|            if (rc < 0) { /* Indicates error */
  ------------------
  |  Branch (3612:17): [True: 75, False: 2.90k]
  ------------------
 3613|     75|                return MqttPacket_HandleNetError(client, rc);
 3614|     75|            }
 3615|       |            /* Indicates decode success and rc is len of header */
 3616|  2.90k|            else {
 3617|       |                /* Add size of type and flags */
 3618|  2.90k|                rc += sizeof(header->type_flags);
 3619|  2.90k|                client->packet.header_len = rc;
 3620|  2.90k|            }
 3621|  2.98k|        }
 3622|  2.90k|        FALL_THROUGH;
  ------------------
  |  |  472|  2.90k|            #define FALL_THROUGH ; __attribute__ ((fallthrough))
  ------------------
 3623|       |
 3624|  3.21k|        case MQTT_PK_READ:
  ------------------
  |  Branch (3624:9): [True: 311, False: 4.81k]
  ------------------
 3625|  3.21k|        {
 3626|       |            /* read remainder of packet */
 3627|  3.21k|            remain_read = client->packet.remain_len;
 3628|  3.21k|            client->packet.stat = MQTT_PK_READ;
 3629|       |
 3630|       |            /* Make sure it does not overflow rx_buf */
 3631|  3.21k|            if (rx_buf_len < client->packet.header_len) {
  ------------------
  |  Branch (3631:17): [True: 0, False: 3.21k]
  ------------------
 3632|      0|                return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
 3633|      0|            }
 3634|  3.21k|            if (remain_read > rx_buf_len - client->packet.header_len) {
  ------------------
  |  Branch (3634:17): [True: 366, False: 2.85k]
  ------------------
 3635|    366|                remain_read = rx_buf_len - client->packet.header_len;
 3636|    366|            }
 3637|       |
 3638|       |            /* Read remaining */
 3639|  3.21k|            if (client->packet.remain_len > 0) {
  ------------------
  |  Branch (3639:17): [True: 2.40k, False: 810]
  ------------------
 3640|  2.40k|                rc = MqttSocket_Read(client, &rx_buf[client->packet.header_len],
 3641|  2.40k|                    remain_read, timeout_ms);
 3642|  2.40k|                if (rc <= 0) {
  ------------------
  |  Branch (3642:21): [True: 1.16k, False: 1.24k]
  ------------------
 3643|  1.16k|                    return MqttPacket_HandleNetError(client, rc);
 3644|  1.16k|                }
 3645|  1.24k|                remain_read = rc;
 3646|  1.24k|            }
 3647|  2.05k|            break;
 3648|  3.21k|        }
 3649|  5.12k|    } /* switch (client->packet.stat) */
 3650|       |
 3651|       |    /* reset state */
 3652|  2.05k|    client->packet.stat = MQTT_PK_BEGIN;
 3653|       |
 3654|       |    /* Return read length */
 3655|  2.05k|    return client->packet.header_len + remain_read;
 3656|  5.12k|}
mqtt_packet.c:FixedHeaderFlagsExpected:
  188|  1.78k|{
  189|  1.78k|    switch (type) {
  190|      0|        case MQTT_PACKET_TYPE_CONNECT:
  ------------------
  |  Branch (190:9): [True: 0, False: 1.78k]
  ------------------
  191|    414|        case MQTT_PACKET_TYPE_CONNECT_ACK:
  ------------------
  |  Branch (191:9): [True: 414, False: 1.37k]
  ------------------
  192|    612|        case MQTT_PACKET_TYPE_PUBLISH_ACK:
  ------------------
  |  Branch (192:9): [True: 198, False: 1.59k]
  ------------------
  193|    654|        case MQTT_PACKET_TYPE_PUBLISH_REC:
  ------------------
  |  Branch (193:9): [True: 42, False: 1.74k]
  ------------------
  194|    683|        case MQTT_PACKET_TYPE_PUBLISH_COMP:
  ------------------
  |  Branch (194:9): [True: 29, False: 1.76k]
  ------------------
  195|    904|        case MQTT_PACKET_TYPE_SUBSCRIBE_ACK:
  ------------------
  |  Branch (195:9): [True: 221, False: 1.56k]
  ------------------
  196|  1.05k|        case MQTT_PACKET_TYPE_UNSUBSCRIBE_ACK:
  ------------------
  |  Branch (196:9): [True: 147, False: 1.64k]
  ------------------
  197|  1.05k|        case MQTT_PACKET_TYPE_PING_REQ:
  ------------------
  |  Branch (197:9): [True: 0, False: 1.78k]
  ------------------
  198|  1.10k|        case MQTT_PACKET_TYPE_PING_RESP:
  ------------------
  |  Branch (198:9): [True: 54, False: 1.73k]
  ------------------
  199|  1.42k|        case MQTT_PACKET_TYPE_DISCONNECT:
  ------------------
  |  Branch (199:9): [True: 319, False: 1.47k]
  ------------------
  200|  1.73k|        case MQTT_PACKET_TYPE_AUTH:
  ------------------
  |  Branch (200:9): [True: 313, False: 1.47k]
  ------------------
  201|  1.73k|            *expected = 0x0;
  202|  1.73k|            return 1;
  203|     52|        case MQTT_PACKET_TYPE_PUBLISH_REL:
  ------------------
  |  Branch (203:9): [True: 52, False: 1.73k]
  ------------------
  204|     52|        case MQTT_PACKET_TYPE_SUBSCRIBE:
  ------------------
  |  Branch (204:9): [True: 0, False: 1.78k]
  ------------------
  205|     52|        case MQTT_PACKET_TYPE_UNSUBSCRIBE:
  ------------------
  |  Branch (205:9): [True: 0, False: 1.78k]
  ------------------
  206|     52|            *expected = 0x2;
  207|     52|            return 1;
  208|      0|        default:
  ------------------
  |  Branch (208:9): [True: 0, False: 1.78k]
  ------------------
  209|      0|            return 0;
  210|  1.78k|    }
  211|  1.78k|}
mqtt_packet.c:Utf8WellFormed:
  546|     25|{
  547|     25|    word16 i = 0;
  548|     35|    while (i < len) {
  ------------------
  |  Branch (548:12): [True: 35, False: 0]
  ------------------
  549|     35|        byte b0 = s[i];
  550|     35|        byte b1, b2, b3;
  551|       |
  552|     35|        if (b0 == 0x00) {
  ------------------
  |  Branch (552:13): [True: 14, False: 21]
  ------------------
  553|       |            /* [MQTT-1.5.3-2] U+0000 forbidden in MQTT UTF-8 strings. */
  554|     14|            return 0;
  555|     14|        }
  556|     21|        if (b0 < 0x80) {
  ------------------
  |  Branch (556:13): [True: 10, False: 11]
  ------------------
  557|     10|            i++;
  558|     10|            continue;
  559|     10|        }
  560|     11|        if (b0 < 0xC2 || b0 > 0xF4) {
  ------------------
  |  Branch (560:13): [True: 3, False: 8]
  |  Branch (560:26): [True: 6, False: 2]
  ------------------
  561|       |            /* C0/C1 are overlong-only; F5..FF exceed U+10FFFF or are not
  562|       |             * UTF-8 leading bytes. */
  563|      9|            return 0;
  564|      9|        }
  565|      2|        if (b0 < 0xE0) {
  ------------------
  |  Branch (565:13): [True: 1, False: 1]
  ------------------
  566|       |            /* 2-byte */
  567|      1|            if ((word32)i + 1 >= (word32)len) return 0;
  ------------------
  |  Branch (567:17): [True: 0, False: 1]
  ------------------
  568|      1|            b1 = s[i+1];
  569|      1|            if ((b1 & 0xC0) != 0x80) return 0;
  ------------------
  |  Branch (569:17): [True: 1, False: 0]
  ------------------
  570|      0|            i += 2;
  571|      0|        }
  572|      1|        else if (b0 < 0xF0) {
  ------------------
  |  Branch (572:18): [True: 0, False: 1]
  ------------------
  573|       |            /* 3-byte */
  574|      0|            if ((word32)i + 2 >= (word32)len) return 0;
  ------------------
  |  Branch (574:17): [True: 0, False: 0]
  ------------------
  575|      0|            b1 = s[i+1];
  576|      0|            b2 = s[i+2];
  577|      0|            if ((b1 & 0xC0) != 0x80 || (b2 & 0xC0) != 0x80) return 0;
  ------------------
  |  Branch (577:17): [True: 0, False: 0]
  |  Branch (577:40): [True: 0, False: 0]
  ------------------
  578|      0|            if (b0 == 0xE0 && b1 < 0xA0) return 0;          /* overlong */
  ------------------
  |  Branch (578:17): [True: 0, False: 0]
  |  Branch (578:31): [True: 0, False: 0]
  ------------------
  579|      0|            if (b0 == 0xED && b1 >= 0xA0) return 0;         /* surrogate */
  ------------------
  |  Branch (579:17): [True: 0, False: 0]
  |  Branch (579:31): [True: 0, False: 0]
  ------------------
  580|      0|            i += 3;
  581|      0|        }
  582|      1|        else {
  583|       |            /* 4-byte (b0 in F0..F4) */
  584|      1|            if ((word32)i + 3 >= (word32)len) return 0;
  ------------------
  |  Branch (584:17): [True: 0, False: 1]
  ------------------
  585|      1|            b1 = s[i+1];
  586|      1|            b2 = s[i+2];
  587|      1|            b3 = s[i+3];
  588|      1|            if ((b1 & 0xC0) != 0x80 ||
  ------------------
  |  Branch (588:17): [True: 1, False: 0]
  ------------------
  589|      0|                (b2 & 0xC0) != 0x80 ||
  ------------------
  |  Branch (589:17): [True: 0, False: 0]
  ------------------
  590|      1|                (b3 & 0xC0) != 0x80) return 0;
  ------------------
  |  Branch (590:17): [True: 0, False: 0]
  ------------------
  591|      0|            if (b0 == 0xF0 && b1 < 0x90) return 0;          /* overlong */
  ------------------
  |  Branch (591:17): [True: 0, False: 0]
  |  Branch (591:31): [True: 0, False: 0]
  ------------------
  592|      0|            if (b0 == 0xF4 && b1 >= 0x90) return 0;         /* > U+10FFFF */
  ------------------
  |  Branch (592:17): [True: 0, False: 0]
  |  Branch (592:31): [True: 0, False: 0]
  ------------------
  593|      0|            i += 4;
  594|      0|        }
  595|      2|    }
  596|      0|    return 1;
  597|     25|}
mqtt_packet.c:MqttEncode_FixedHeader:
  152|  4.37k|{
  153|  4.37k|    int header_len;
  154|  4.37k|    MqttPacket* header = (MqttPacket*)tx_buf;
  155|       |
  156|       |    /* make sure destination buffer has space for header */
  157|  4.37k|    if (tx_buf_len < MQTT_PACKET_MAX_LEN_BYTES+1) {
  ------------------
  |  |  283|  4.37k|#define MQTT_PACKET_MAX_LEN_BYTES   4
  ------------------
  |  Branch (157:9): [True: 0, False: 4.37k]
  ------------------
  158|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  159|      0|    }
  160|       |
  161|       |    /* Encode fixed header */
  162|  4.37k|    header->type_flags = MQTT_PACKET_TYPE_SET(type) | MQTT_PACKET_FLAGS_SET(0);
  ------------------
  |  |  245|  4.37k|#define MQTT_PACKET_TYPE_SET(x)  (((x) & 0xF) << 4)
  ------------------
                  header->type_flags = MQTT_PACKET_TYPE_SET(type) | MQTT_PACKET_FLAGS_SET(0);
  ------------------
  |  |  268|  4.37k|#define MQTT_PACKET_FLAGS_SET(x) (x)
  ------------------
  163|  4.37k|    if (retain) {
  ------------------
  |  Branch (163:9): [True: 8, False: 4.36k]
  ------------------
  164|      8|        header->type_flags |= MQTT_PACKET_FLAGS_SET(MQTT_PACKET_FLAG_RETAIN);
  ------------------
  |  |  268|      8|#define MQTT_PACKET_FLAGS_SET(x) (x)
  ------------------
  165|      8|    }
  166|  4.37k|    if (qos) {
  ------------------
  |  Branch (166:9): [True: 769, False: 3.60k]
  ------------------
  167|    769|        header->type_flags |= MQTT_PACKET_FLAGS_SET_QOS(qos);
  ------------------
  |  |  273|    769|    (MQTT_PACKET_FLAGS_SET(((qos) << MQTT_PACKET_FLAG_QOS_SHIFT) & \
  |  |  ------------------
  |  |  |  |  268|    769|#define MQTT_PACKET_FLAGS_SET(x) (x)
  |  |  ------------------
  |  |  274|    769|        MQTT_PACKET_FLAG_QOS_MASK))
  ------------------
  168|    769|    }
  169|  4.37k|    if (duplicate) {
  ------------------
  |  Branch (169:9): [True: 3, False: 4.36k]
  ------------------
  170|      3|        header->type_flags |=
  171|      3|            MQTT_PACKET_FLAGS_SET(MQTT_PACKET_FLAG_DUPLICATE);
  ------------------
  |  |  268|      3|#define MQTT_PACKET_FLAGS_SET(x) (x)
  ------------------
  172|      3|    }
  173|       |
  174|       |    /* Encode the length remaining into the header */
  175|  4.37k|    header_len = MqttEncode_Vbi(header->len, remain_len);
  176|  4.37k|    if (header_len > 0) {
  ------------------
  |  Branch (176:9): [True: 4.37k, False: 0]
  ------------------
  177|  4.37k|        header_len++; /* Add one for type and flags */
  178|  4.37k|    }
  179|       |
  180|  4.37k|    (void) tx_buf_len;
  181|       |
  182|  4.37k|    return header_len;
  183|  4.37k|}
mqtt_packet.c:MqttDecode_FixedHeader:
  368|  2.01k|{
  369|  2.01k|    int header_len;
  370|  2.01k|    MqttPacket* header = (MqttPacket*)rx_buf;
  371|       |
  372|       |    /* Decode the length remaining */
  373|  2.01k|    header_len = MqttDecode_Vbi(header->len, (word32*)remain_len, rx_buf_len);
  374|  2.01k|    if (header_len < 0) {
  ------------------
  |  Branch (374:9): [True: 0, False: 2.01k]
  ------------------
  375|      0|        return header_len;
  376|      0|    }
  377|       |
  378|       |    /* Validate packet type */
  379|  2.01k|    if (MQTT_PACKET_TYPE_GET(header->type_flags) != type) {
  ------------------
  |  |  244|  2.01k|#define MQTT_PACKET_TYPE_GET(x)  (((x) >> 4) & 0xF)
  ------------------
  |  Branch (379:9): [True: 0, False: 2.01k]
  ------------------
  380|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_PACKET_TYPE);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  381|      0|    }
  382|       |
  383|       |    /* [MQTT-2.2.2-2] Reject invalid fixed-header reserved flags. */
  384|  2.01k|    if (!MqttPacket_FixedHeaderFlagsValid(header->type_flags)) {
  ------------------
  |  Branch (384:9): [True: 1.72k, False: 294]
  ------------------
  385|  1.72k|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_MALFORMED_DATA);
  ------------------
  |  |  392|  1.72k|#define MQTT_TRACE_ERROR(err) err
  ------------------
  386|  1.72k|    }
  387|       |
  388|       |    /* Extract header flags */
  389|    294|    if (p_qos) {
  ------------------
  |  Branch (389:9): [True: 180, False: 114]
  ------------------
  390|    180|        *p_qos = (MqttQoS)MQTT_PACKET_FLAGS_GET_QOS(header->type_flags);
  ------------------
  |  |  270|    180|    ((MQTT_PACKET_FLAGS_GET((type_flags)) & \
  |  |  ------------------
  |  |  |  |  267|    180|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  |  |  ------------------
  |  |  271|    180|        MQTT_PACKET_FLAG_QOS_MASK) >> MQTT_PACKET_FLAG_QOS_SHIFT)
  ------------------
  391|    180|    }
  392|    294|    if (p_retain) {
  ------------------
  |  Branch (392:9): [True: 180, False: 114]
  ------------------
  393|    180|        *p_retain = (MQTT_PACKET_FLAGS_GET(header->type_flags) &
  ------------------
  |  |  267|    180|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  ------------------
  |  Branch (393:21): [True: 62, False: 118]
  ------------------
  394|    180|            MQTT_PACKET_FLAG_RETAIN) ? 1 : 0;
  395|    180|    }
  396|    294|    if (p_duplicate) {
  ------------------
  |  Branch (396:9): [True: 180, False: 114]
  ------------------
  397|    180|        *p_duplicate = (MQTT_PACKET_FLAGS_GET(header->type_flags) &
  ------------------
  |  |  267|    180|#define MQTT_PACKET_FLAGS_GET(x) ((x) & 0xF)
  ------------------
  |  Branch (397:24): [True: 77, False: 103]
  ------------------
  398|    180|            MQTT_PACKET_FLAG_DUPLICATE) ? 1 : 0;
  399|    180|    }
  400|       |
  401|    294|    header_len += sizeof(header->type_flags); /* Add size of type and flags */
  402|       |
  403|    294|    (void)rx_buf_len;
  404|       |
  405|    294|    return header_len;
  406|  2.01k|}

MqttSocket_Init:
  112|  2.64k|{
  113|  2.64k|    int rc = MQTT_CODE_ERROR_BAD_ARG;
  114|  2.64k|    if (client) {
  ------------------
  |  Branch (114:9): [True: 2.64k, False: 0]
  ------------------
  115|       |    #ifdef ENABLE_MQTT_CURL
  116|       |        curl_global_init(CURL_GLOBAL_DEFAULT);
  117|       |    #endif
  118|       |
  119|  2.64k|        client->net = net;
  120|  2.64k|        MqttClient_Flags(client, (MQTT_CLIENT_FLAG_IS_CONNECTED |
  121|  2.64k|            MQTT_CLIENT_FLAG_IS_TLS), 0);;
  122|  2.64k|    #if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
  123|  2.64k|        client->tls.ctx = NULL;
  124|  2.64k|        client->tls.ssl = NULL;
  125|  2.64k|        client->tls.timeout_ms_read = client->cmd_timeout_ms;
  126|  2.64k|        client->tls.timeout_ms_write = client->cmd_timeout_ms;
  127|  2.64k|    #endif
  128|       |
  129|       |        /* Validate callbacks are not null! */
  130|  2.64k|        if (net && net->connect && net->read && net->write && net->disconnect) {
  ------------------
  |  Branch (130:13): [True: 2.64k, False: 0]
  |  Branch (130:20): [True: 2.64k, False: 0]
  |  Branch (130:36): [True: 2.64k, False: 0]
  |  Branch (130:49): [True: 2.64k, False: 0]
  |  Branch (130:63): [True: 2.64k, False: 0]
  ------------------
  131|  2.64k|            rc = MQTT_CODE_SUCCESS;
  132|  2.64k|        }
  133|  2.64k|    }
  134|  2.64k|    return rc;
  135|  2.64k|}
MqttSocket_Write:
  189|  4.41k|{
  190|  4.41k|    int rc;
  191|       |
  192|       |    /* Validate arguments */
  193|  4.41k|    if (client == NULL || client->net == NULL || client->net->write == NULL ||
  ------------------
  |  Branch (193:9): [True: 0, False: 4.41k]
  |  Branch (193:27): [True: 0, False: 4.41k]
  |  Branch (193:50): [True: 0, False: 4.41k]
  ------------------
  194|  4.41k|        buf == NULL || buf_len <= 0) {
  ------------------
  |  Branch (194:9): [True: 0, False: 4.41k]
  |  Branch (194:24): [True: 0, False: 4.41k]
  ------------------
  195|      0|        return MQTT_CODE_ERROR_BAD_ARG;
  196|      0|    }
  197|       |
  198|       |    /* check for buffer position overflow */
  199|  4.41k|    if (client->write.pos >= buf_len) {
  ------------------
  |  Branch (199:9): [True: 4, False: 4.41k]
  ------------------
  200|      4|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      4|#define MQTT_TRACE_ERROR(err) err
  ------------------
  201|      4|    }
  202|       |
  203|       |#ifdef WOLFMQTT_NONBLOCK
  204|       |    rc = MqttSocket_WriteDo(client, &buf[client->write.pos],
  205|       |        buf_len - client->write.pos, timeout_ms);
  206|       |    if (rc >= 0) {
  207|       |        /* Clamp return value: write callback is user-provided and may
  208|       |         * return more than the requested length */
  209|       |        if (rc > buf_len - client->write.pos) {
  210|       |            rc = buf_len - client->write.pos;
  211|       |        }
  212|       |        client->write.pos += rc;
  213|       |        client->write.total += rc;
  214|       |        if (client->write.pos < buf_len) {
  215|       |            rc = MQTT_CODE_CONTINUE;
  216|       |        }
  217|       |    }
  218|       |    else if (rc == EWOULDBLOCK || rc == EAGAIN) {
  219|       |        rc = MQTT_CODE_CONTINUE;
  220|       |    }
  221|       |
  222|       |#else
  223|  4.64k|    do {
  224|  4.64k|        rc = MqttSocket_WriteDo(client, &buf[client->write.pos],
  225|  4.64k|            buf_len - client->write.pos, timeout_ms);
  226|  4.64k|        if (rc <= 0) {
  ------------------
  |  Branch (226:13): [True: 2.53k, False: 2.10k]
  ------------------
  227|  2.53k|            break;
  228|  2.53k|        }
  229|       |        /* Clamp return value: write callback is user-provided and may
  230|       |         * return more than the requested length */
  231|  2.10k|        if (rc > buf_len - client->write.pos) {
  ------------------
  |  Branch (231:13): [True: 0, False: 2.10k]
  ------------------
  232|      0|            rc = buf_len - client->write.pos;
  233|      0|        }
  234|  2.10k|        client->write.pos += rc;
  235|  2.10k|        client->write.total += rc;
  236|  2.10k|    } while (client->write.pos < buf_len);
  ------------------
  |  Branch (236:14): [True: 225, False: 1.87k]
  ------------------
  237|  4.41k|#endif /* WOLFMQTT_NONBLOCK */
  238|       |
  239|       |    /* handle return code */
  240|  4.41k|    if (rc > 0) {
  ------------------
  |  Branch (240:9): [True: 1.87k, False: 2.53k]
  ------------------
  241|       |        /* return length write and reset position */
  242|  1.87k|        rc = client->write.pos;
  243|  1.87k|        client->write.pos = 0;
  244|  1.87k|    }
  245|       |
  246|  4.41k|    return rc;
  247|  4.41k|}
MqttSocket_Read:
  304|  8.38k|{
  305|  8.38k|    int rc;
  306|       |
  307|       |    /* Validate arguments */
  308|  8.38k|    if (client == NULL || client->net == NULL || client->net->read == NULL ||
  ------------------
  |  Branch (308:9): [True: 0, False: 8.38k]
  |  Branch (308:27): [True: 0, False: 8.38k]
  |  Branch (308:50): [True: 0, False: 8.38k]
  ------------------
  309|  8.38k|        buf == NULL || buf_len <= 0) {
  ------------------
  |  Branch (309:9): [True: 0, False: 8.38k]
  |  Branch (309:24): [True: 0, False: 8.38k]
  ------------------
  310|      0|        return MQTT_CODE_ERROR_BAD_ARG;
  311|      0|    }
  312|       |
  313|       |    /* check for buffer position overflow */
  314|  8.38k|    if (client->read.pos >= buf_len) {
  ------------------
  |  Branch (314:9): [True: 0, False: 8.38k]
  ------------------
  315|      0|        return MQTT_TRACE_ERROR(MQTT_CODE_ERROR_OUT_OF_BUFFER);
  ------------------
  |  |  392|      0|#define MQTT_TRACE_ERROR(err) err
  ------------------
  316|      0|    }
  317|       |
  318|       |#ifdef WOLFMQTT_NONBLOCK
  319|       |    rc = MqttSocket_ReadDo(client, &buf[client->read.pos],
  320|       |        buf_len - client->read.pos, timeout_ms);
  321|       |    if (rc >= 0) {
  322|       |        /* Clamp return value: read callback is user-provided and may
  323|       |         * return more than the requested length */
  324|       |        if (rc > buf_len - client->read.pos) {
  325|       |            rc = buf_len - client->read.pos;
  326|       |        }
  327|       |        client->read.pos += rc;
  328|       |        client->read.total += rc;
  329|       |        if (client->read.pos < buf_len) {
  330|       |            rc = MQTT_CODE_CONTINUE;
  331|       |        }
  332|       |    }
  333|       |    else if (rc == EWOULDBLOCK || rc == EAGAIN) {
  334|       |        rc = MQTT_CODE_CONTINUE;
  335|       |    }
  336|       |
  337|       |#else
  338|  8.63k|    do {
  339|  8.63k|        rc = MqttSocket_ReadDo(client, &buf[client->read.pos],
  340|  8.63k|            buf_len - client->read.pos, timeout_ms);
  341|  8.63k|        if (rc <= 0) {
  ------------------
  |  Branch (341:13): [True: 2.89k, False: 5.74k]
  ------------------
  342|  2.89k|            break;
  343|  2.89k|        }
  344|       |        /* Clamp return value: read callback is user-provided and may
  345|       |         * return more than the requested length */
  346|  5.74k|        if (rc > buf_len - client->read.pos) {
  ------------------
  |  Branch (346:13): [True: 0, False: 5.74k]
  ------------------
  347|      0|            rc = buf_len - client->read.pos;
  348|      0|        }
  349|  5.74k|        client->read.pos += rc;
  350|  5.74k|        client->read.total += rc;
  351|  5.74k|    } while (client->read.pos < buf_len);
  ------------------
  |  Branch (351:14): [True: 255, False: 5.48k]
  ------------------
  352|  8.38k|#endif /* WOLFMQTT_NONBLOCK */
  353|       |
  354|       |    /* handle return code */
  355|  8.38k|    if (rc > 0) {
  ------------------
  |  Branch (355:9): [True: 5.48k, False: 2.89k]
  ------------------
  356|       |        /* return length read and reset position */
  357|  5.48k|        rc = client->read.pos;
  358|  5.48k|        client->read.pos = 0;
  359|  5.48k|    }
  360|       |
  361|  8.38k|    return rc;
  362|  8.38k|}
MqttSocket_Connect:
  396|  2.64k|{
  397|  2.64k|    int rc = MQTT_CODE_SUCCESS;
  398|       |
  399|       |    /* Validate arguments */
  400|  2.64k|    if (client == NULL || client->net == NULL ||
  ------------------
  |  Branch (400:9): [True: 0, False: 2.64k]
  |  Branch (400:27): [True: 0, False: 2.64k]
  ------------------
  401|  2.64k|        client->net->connect == NULL) {
  ------------------
  |  Branch (401:9): [True: 0, False: 2.64k]
  ------------------
  402|      0|        return MQTT_CODE_ERROR_BAD_ARG;
  403|      0|    }
  404|       |
  405|       |#ifndef ENABLE_MQTT_TLS
  406|       |    /* cannot use TLS unless ENABLE_MQTT_TLS is defined */
  407|       |    if (use_tls) {
  408|       |        return MQTT_CODE_ERROR_BAD_ARG;
  409|       |    }
  410|       |#endif
  411|       |
  412|  2.64k|    if ((MqttClient_Flags(client, 0, 0) & MQTT_CLIENT_FLAG_IS_CONNECTED) == 0) {
  ------------------
  |  Branch (412:9): [True: 2.64k, False: 0]
  ------------------
  413|       |        /* Validate port */
  414|  2.64k|        if (port == 0) {
  ------------------
  |  Branch (414:13): [True: 0, False: 2.64k]
  ------------------
  415|      0|            port = (use_tls) ? MQTT_SECURE_PORT : MQTT_DEFAULT_PORT;
  ------------------
  |  |   48|      0|#define MQTT_SECURE_PORT    8883
  ------------------
                          port = (use_tls) ? MQTT_SECURE_PORT : MQTT_DEFAULT_PORT;
  ------------------
  |  |   47|      0|#define MQTT_DEFAULT_PORT   1883
  ------------------
  |  Branch (415:20): [True: 0, False: 0]
  ------------------
  416|      0|        }
  417|       |
  418|       |        /* Connect to host */
  419|  2.64k|        rc = client->net->connect(client->net->context, host, port, timeout_ms);
  420|  2.64k|        if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (420:13): [True: 0, False: 2.64k]
  ------------------
  421|      0|            return rc;
  422|      0|        }
  423|  2.64k|        MqttClient_Flags(client, 0, MQTT_CLIENT_FLAG_IS_CONNECTED);
  424|  2.64k|    }
  425|       |
  426|  2.64k|#if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
  427|  2.64k|    if (use_tls) {
  ------------------
  |  Branch (427:9): [True: 0, False: 2.64k]
  ------------------
  428|       |        /* Clear any previous TLS error */
  429|      0|        client->tls.lastError = 0;
  430|       |
  431|      0|        if (client->tls.ctx == NULL) {
  ------------------
  |  Branch (431:13): [True: 0, False: 0]
  ------------------
  432|       |        #ifdef DEBUG_WOLFSSL
  433|       |            wolfSSL_Debugging_ON();
  434|       |        #endif
  435|       |
  436|       |            /* Setup the WolfSSL library */
  437|      0|            rc = wolfSSL_Init();
  438|       |
  439|       |            /* Issue callback to allow setup of the wolfSSL_CTX and cert
  440|       |               verification settings */
  441|      0|            if ((rc == WOLFSSL_SUCCESS) && (cb != NULL)) {
  ------------------
  |  Branch (441:17): [True: 0, False: 0]
  |  Branch (441:44): [True: 0, False: 0]
  ------------------
  442|      0|                rc = cb(client);
  443|      0|            }
  444|      0|            if (rc != WOLFSSL_SUCCESS) {
  ------------------
  |  Branch (444:17): [True: 0, False: 0]
  ------------------
  445|      0|                rc = MQTT_CODE_ERROR_TLS_CONNECT;
  446|      0|                goto exit;
  447|      0|            }
  448|      0|        }
  449|       |
  450|       |        /* Create and initialize the WOLFSSL_CTX structure */
  451|      0|        if (client->tls.ctx == NULL) {
  ------------------
  |  Branch (451:13): [True: 0, False: 0]
  ------------------
  452|       |            /* Use defaults */
  453|       |            /* Use highest available and allow downgrade. If wolfSSL is built
  454|       |             *  with old TLS support, it is possible for a server to force a
  455|       |             *  downgrade to an insecure version. */
  456|      0|            if (!(MqttClient_Flags(client,0,0) & MQTT_CLIENT_FLAG_IS_DTLS)) {
  ------------------
  |  Branch (456:17): [True: 0, False: 0]
  ------------------
  457|      0|                client->tls.ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  458|      0|            }
  459|       |    #ifdef WOLFSSL_DTLS
  460|       |            else {
  461|       |                client->tls.ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
  462|       |            }
  463|       |    #endif
  464|      0|            if (client->tls.ctx == NULL) {
  ------------------
  |  Branch (464:17): [True: 0, False: 0]
  ------------------
  465|      0|                rc = MQTT_CODE_ERROR_TLS_CONNECT;
  466|      0|                goto exit;
  467|      0|            }
  468|      0|            wolfSSL_CTX_set_verify(client->tls.ctx, WOLFSSL_VERIFY_NONE, 0);
  469|       |        #ifdef WOLFMQTT_DEBUG_SOCKET
  470|       |            PRINTF("Warning: TLS set to VERIFY_NONE. Use MqttClient_SetTlsCb "
  471|       |                "to set peer verification in production");
  472|       |        #endif
  473|      0|        }
  474|       |
  475|      0|    #ifndef NO_DH
  476|      0|        wolfSSL_CTX_SetMinDhKey_Sz(client->tls.ctx, WOLF_TLS_DHKEY_BITS_MIN);
  ------------------
  |  |   86|      0|            #define WOLF_TLS_DHKEY_BITS_MIN 1024
  ------------------
  477|      0|    #endif
  478|       |
  479|       |        /* Setup the IO callbacks */
  480|      0|        wolfSSL_CTX_SetIORecv(client->tls.ctx, MqttSocket_TlsSocketReceive);
  481|      0|        wolfSSL_CTX_SetIOSend(client->tls.ctx, MqttSocket_TlsSocketSend);
  482|       |
  483|      0|        if (client->tls.ssl == NULL) {
  ------------------
  |  Branch (483:13): [True: 0, False: 0]
  ------------------
  484|      0|            client->tls.ssl = wolfSSL_new(client->tls.ctx);
  485|       |
  486|      0|            if (client->tls.ssl == NULL) {
  ------------------
  |  Branch (486:17): [True: 0, False: 0]
  ------------------
  487|      0|                rc = MQTT_CODE_ERROR_TLS_CONNECT;
  488|      0|                goto exit;
  489|      0|            }
  490|      0|        } else {
  491|       |            /* Since the user setup client->tls.ssl the IO callbacks didn't get
  492|       |             * associated with this wolfSSL struct */
  493|      0|            wolfSSL_SSLSetIORecv(client->tls.ssl, MqttSocket_TlsSocketReceive);
  494|      0|            wolfSSL_SSLSetIOSend(client->tls.ssl, MqttSocket_TlsSocketSend);
  495|      0|        }
  496|       |        /* Set the IO callback context */
  497|      0|        wolfSSL_SetIOReadCtx(client->tls.ssl, (void *)client);
  498|      0|        wolfSSL_SetIOWriteCtx(client->tls.ssl, (void *)client);
  499|       |
  500|      0|        if (client->ctx != NULL) {
  ------------------
  |  Branch (500:13): [True: 0, False: 0]
  ------------------
  501|       |            /* Store any app data for use by the tls verify callback*/
  502|      0|            wolfSSL_SetCertCbCtx(client->tls.ssl, client->ctx);
  503|      0|        }
  504|       |
  505|      0|        MqttClient_Flags(client, 0, MQTT_CLIENT_FLAG_IS_TLS);
  506|      0|        rc = wolfSSL_connect(client->tls.ssl);
  507|      0|        if (rc != WOLFSSL_SUCCESS) {
  ------------------
  |  Branch (507:13): [True: 0, False: 0]
  ------------------
  508|      0|            rc = MQTT_CODE_ERROR_TLS_CONNECT;
  509|      0|            MqttClient_Flags(client, MQTT_CLIENT_FLAG_IS_TLS, 0);
  510|      0|            goto exit;
  511|      0|        }
  512|       |
  513|      0|        rc = MQTT_CODE_SUCCESS;
  514|      0|  }
  515|       |
  516|  2.64k|exit:
  517|       |    /* Handle error case */
  518|  2.64k|    if (rc != MQTT_CODE_SUCCESS) {
  ------------------
  |  Branch (518:9): [True: 0, False: 2.64k]
  ------------------
  519|       |    #ifdef WOLFMQTT_DEBUG_SOCKET
  520|       |        const char* errstr = "";
  521|       |    #endif
  522|      0|        int errnum = 0;
  523|      0|        if (client->tls.ssl) {
  ------------------
  |  Branch (523:13): [True: 0, False: 0]
  ------------------
  524|      0|            errnum = wolfSSL_get_error(client->tls.ssl, 0);
  525|      0|            if (   errnum == WOLFSSL_ERROR_WANT_READ
  ------------------
  |  Branch (525:20): [True: 0, False: 0]
  ------------------
  526|      0|                || errnum == WOLFSSL_ERROR_WANT_WRITE
  ------------------
  |  Branch (526:20): [True: 0, False: 0]
  ------------------
  527|       |            #ifdef WOLFSSL_ASYNC_CRYPT
  528|       |                || errnum == WC_PENDING_E
  529|       |            #endif
  530|      0|            ) {
  531|      0|                return MQTT_CODE_CONTINUE;
  532|      0|            }
  533|       |            /* Preserve the error to be used later, e.g. in net callback */
  534|      0|            client->tls.lastError = errnum;
  535|       |        #ifdef WOLFMQTT_DEBUG_SOCKET
  536|       |            errstr = wolfSSL_ERR_reason_error_string(errnum);
  537|       |        #endif
  538|      0|        }
  539|       |
  540|       |    #ifdef WOLFMQTT_DEBUG_SOCKET
  541|       |        PRINTF("MqttSocket_TlsConnect Error %d: Num %d, %s",
  542|       |            rc, errnum, errstr);
  543|       |    #endif /* WOLFMQTT_DEBUG_SOCKET */
  544|       |
  545|       |        /* Make sure we cleanup on error */
  546|      0|        MqttSocket_Disconnect(client);
  547|      0|    }
  548|       |
  549|       |#else
  550|       |    (void)cb;
  551|       |#endif /* ENABLE_MQTT_TLS && !ENABLE_MQTT_CURL */
  552|       |
  553|       |#ifdef WOLFMQTT_DEBUG_SOCKET
  554|       |    PRINTF("MqttSocket_Connect: Rc=%d", rc);
  555|       |#endif
  556|       |
  557|  2.64k|    return rc;
  558|  2.64k|}
MqttSocket_Disconnect:
  561|    226|{
  562|    226|    int rc = MQTT_CODE_SUCCESS;
  563|    226|    if (client) {
  ------------------
  |  Branch (563:9): [True: 226, False: 0]
  ------------------
  564|    226|    #if defined(ENABLE_MQTT_TLS)
  565|    226|        #if !defined(ENABLE_MQTT_CURL)
  566|    226|        if (client->tls.ssl) {
  ------------------
  |  Branch (566:13): [True: 0, False: 226]
  ------------------
  567|      0|            wolfSSL_free(client->tls.ssl);
  568|      0|            client->tls.ssl = NULL;
  569|      0|        }
  570|    226|        if (client->tls.ctx) {
  ------------------
  |  Branch (570:13): [True: 0, False: 226]
  ------------------
  571|      0|            wolfSSL_CTX_free(client->tls.ctx);
  572|      0|            client->tls.ctx = NULL;
  573|      0|        }
  574|    226|        wolfSSL_Cleanup();
  575|    226|        #endif
  576|    226|        MqttClient_Flags(client,
  577|    226|                (MQTT_CLIENT_FLAG_IS_TLS | MQTT_CLIENT_FLAG_IS_DTLS), 0);
  578|    226|    #endif
  579|       |
  580|       |        /* Make sure socket is closed */
  581|    226|        if (client->net && client->net->disconnect) {
  ------------------
  |  Branch (581:13): [True: 226, False: 0]
  |  Branch (581:28): [True: 226, False: 0]
  ------------------
  582|    226|            rc = client->net->disconnect(client->net->context);
  583|    226|        }
  584|    226|        MqttClient_Flags(client, MQTT_CLIENT_FLAG_IS_CONNECTED, 0);
  585|       |
  586|       |    #ifdef ENABLE_MQTT_CURL
  587|       |        curl_global_cleanup();
  588|       |    #endif
  589|    226|    }
  590|       |#ifdef WOLFMQTT_DEBUG_SOCKET
  591|       |    PRINTF("MqttSocket_Disconnect: Rc=%d", rc);
  592|       |#endif
  593|       |
  594|       |    /* Check for error */
  595|    226|    if (rc < 0) {
  ------------------
  |  Branch (595:9): [True: 0, False: 226]
  ------------------
  596|      0|        rc = MQTT_CODE_ERROR_NETWORK;
  597|      0|    }
  598|       |
  599|    226|    return rc;
  600|    226|}
mqtt_socket.c:MqttSocket_WriteDo:
  139|  4.64k|{
  140|  4.64k|    int rc;
  141|       |
  142|  4.64k|#if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
  143|  4.64k|    if (MqttClient_Flags(client,0,0) & MQTT_CLIENT_FLAG_IS_TLS) {
  ------------------
  |  Branch (143:9): [True: 0, False: 4.64k]
  ------------------
  144|      0|        client->tls.timeout_ms_write = timeout_ms;
  145|      0|        client->tls.sockRcWrite = 0; /* init value */
  146|       |
  147|      0|        rc = wolfSSL_write(client->tls.ssl, (char*)buf, buf_len);
  148|      0|        if (rc < 0) {
  ------------------
  |  Branch (148:13): [True: 0, False: 0]
  ------------------
  149|      0|            int error = wolfSSL_get_error(client->tls.ssl, 0);
  150|      0|            client->tls.lastError = error;
  151|       |        #ifdef WOLFMQTT_DEBUG_SOCKET
  152|       |            if (error != WOLFSSL_ERROR_WANT_WRITE
  153|       |            #ifdef WOLFSSL_ASYNC_CRYPT
  154|       |                && error != WC_PENDING_E
  155|       |            #endif
  156|       |            ) {
  157|       |                PRINTF("MqttSocket_WriteDo: SSL Error=%d (rc %d, sockrc %d)",
  158|       |                    error, rc, client->tls.sockRcWrite);
  159|       |            }
  160|       |        #endif
  161|       |
  162|       |            /* return code from net callback */
  163|      0|            rc = client->tls.sockRcWrite;
  164|       |        #ifdef WOLFSSL_ASYNC_CRYPT
  165|       |            if (error == WC_PENDING_E) {
  166|       |                rc = MQTT_CODE_CONTINUE;
  167|       |            }
  168|       |        #endif
  169|      0|        }
  170|      0|    }
  171|  4.64k|    else
  172|  4.64k|#endif /* ENABLE_MQTT_TLS && !ENABLE_MQTT_CURL */
  173|  4.64k|    {
  174|  4.64k|        rc = client->net->write(client->net->context, buf, buf_len,
  175|  4.64k|            timeout_ms);
  176|  4.64k|    }
  177|       |
  178|       |#ifdef WOLFMQTT_DEBUG_SOCKET
  179|       |    if (rc != 0 && rc != MQTT_CODE_CONTINUE) { /* hide in non-blocking case */
  180|       |        PRINTF("MqttSocket_Write: Len=%d, Rc=%d", buf_len, rc);
  181|       |    }
  182|       |#endif
  183|       |
  184|  4.64k|    return rc;
  185|  4.64k|}
mqtt_socket.c:MqttSocket_ReadDo:
  251|  8.63k|{
  252|  8.63k|    int rc;
  253|       |
  254|  8.63k|#if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
  255|  8.63k|    if (MqttClient_Flags(client,0,0) & MQTT_CLIENT_FLAG_IS_TLS) {
  ------------------
  |  Branch (255:9): [True: 0, False: 8.63k]
  ------------------
  256|      0|        client->tls.timeout_ms_read = timeout_ms;
  257|      0|        client->tls.sockRcRead = 0; /* init value */
  258|       |
  259|      0|        rc = wolfSSL_read(client->tls.ssl, (char*)buf, buf_len);
  260|      0|        if (rc < 0) {
  ------------------
  |  Branch (260:13): [True: 0, False: 0]
  ------------------
  261|      0|            int error = wolfSSL_get_error(client->tls.ssl, 0);
  262|      0|            client->tls.lastError = error;
  263|       |        #ifdef WOLFMQTT_DEBUG_SOCKET
  264|       |            if (error != WOLFSSL_ERROR_WANT_READ
  265|       |            #ifdef WOLFSSL_ASYNC_CRYPT
  266|       |                && error != WC_PENDING_E
  267|       |            #endif
  268|       |            ) {
  269|       |                PRINTF("MqttSocket_ReadDo: SSL Error=%d (rc %d, sockrc %d)",
  270|       |                    error, rc, client->tls.sockRcRead);
  271|       |            }
  272|       |        #endif
  273|       |
  274|       |            /* return code from net callback */
  275|      0|            rc = client->tls.sockRcRead;
  276|       |        #ifdef WOLFSSL_ASYNC_CRYPT
  277|       |            if (error == WC_PENDING_E) {
  278|       |                rc = MQTT_CODE_CONTINUE;
  279|       |            }
  280|       |            else
  281|       |        #endif
  282|       |            /* used with compatibility layer to communicate peer close */
  283|      0|            if (error == WOLFSSL_ERROR_ZERO_RETURN) {
  ------------------
  |  Branch (283:17): [True: 0, False: 0]
  ------------------
  284|      0|                rc = MQTT_CODE_ERROR_NETWORK;
  285|      0|            }
  286|      0|        }
  287|      0|    }
  288|  8.63k|    else
  289|  8.63k|#endif /* ENABLE_MQTT_TLS && !ENABLE_MQTT_CURL */
  290|  8.63k|    {
  291|  8.63k|        rc = client->net->read(client->net->context, buf, buf_len, timeout_ms);
  292|  8.63k|    }
  293|       |
  294|       |#ifdef WOLFMQTT_DEBUG_SOCKET
  295|       |    if (rc != 0 && rc != MQTT_CODE_CONTINUE) { /* hide in non-blocking case */
  296|       |        PRINTF("MqttSocket_ReadDo: Len=%d, Rc=%d", buf_len, rc);
  297|       |    }
  298|       |#endif
  299|       |
  300|  8.63k|    return rc;
  301|  8.63k|}

wolfSSL_Cleanup:
 7572|    226|{
 7573|    226|    int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
 7574|    226|    int release = 0;
 7575|    226|#if !defined(NO_SESSION_CACHE)
 7576|    226|    int i;
 7577|    226|    int j;
 7578|    226|#endif
 7579|       |
 7580|    226|    WOLFSSL_ENTER("wolfSSL_Cleanup");
  ------------------
  |  |  367|    226|    #define WOLFSSL_ENTER(m)          WC_DO_NOTHING
  |  |  ------------------
  |  |  |  |  418|    226|    #define WC_DO_NOTHING do {} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (418:40): [Folded, False: 226]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7581|       |
 7582|       |#ifndef WOLFSSL_MUTEX_INITIALIZER
 7583|       |    if (inits_count_mutex_valid == 1) {
 7584|       |#endif
 7585|    226|        if (wc_LockMutex(&inits_count_mutex) != 0) {
  ------------------
  |  Branch (7585:13): [True: 0, False: 226]
  ------------------
 7586|      0|            WOLFSSL_MSG("Bad Lock Mutex count");
  ------------------
  |  |  392|      0|    #define WOLFSSL_MSG(m)            WC_DO_NOTHING
  |  |  ------------------
  |  |  |  |  418|      0|    #define WC_DO_NOTHING do {} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (418:40): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7587|      0|            return BAD_MUTEX_E;
 7588|      0|        }
 7589|       |#ifndef WOLFSSL_MUTEX_INITIALIZER
 7590|       |    }
 7591|       |#endif
 7592|       |
 7593|    226|    if (initRefCount > 0) {
  ------------------
  |  Branch (7593:9): [True: 0, False: 226]
  ------------------
 7594|      0|        initRefCount = initRefCount - 1;
 7595|      0|        if (initRefCount == 0)
  ------------------
  |  Branch (7595:13): [True: 0, False: 0]
  ------------------
 7596|      0|            release = 1;
 7597|      0|    }
 7598|       |
 7599|       |#ifndef WOLFSSL_MUTEX_INITIALIZER
 7600|       |    if (inits_count_mutex_valid == 1) {
 7601|       |#endif
 7602|    226|        wc_UnLockMutex(&inits_count_mutex);
 7603|       |#ifndef WOLFSSL_MUTEX_INITIALIZER
 7604|       |    }
 7605|       |#endif
 7606|       |
 7607|    226|    if (!release)
  ------------------
  |  Branch (7607:9): [True: 226, False: 0]
  ------------------
 7608|    226|        return ret;
 7609|       |
 7610|       |#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
 7611|       |    wolfSSL_crypto_policy_disable();
 7612|       |#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
 7613|       |
 7614|       |#ifdef OPENSSL_EXTRA
 7615|       |    wolfSSL_BN_free_one();
 7616|       |#endif
 7617|       |
 7618|      0|#ifndef NO_SESSION_CACHE
 7619|       |    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
 7620|       |    for (i = 0; i < SESSION_ROWS; ++i) {
 7621|       |        if ((SessionCache[i].lock_valid == 1) &&
 7622|       |            (wc_FreeRwLock(&SessionCache[i].row_lock) != 0)) {
 7623|       |            if (ret == WOLFSSL_SUCCESS)
 7624|       |                ret = BAD_MUTEX_E;
 7625|       |        }
 7626|       |        SessionCache[i].lock_valid = 0;
 7627|       |    }
 7628|       |    #else
 7629|      0|    if ((session_lock_valid == 1) && (wc_FreeRwLock(&session_lock) != 0)) {
  ------------------
  |  Branch (7629:9): [True: 0, False: 0]
  |  Branch (7629:38): [True: 0, False: 0]
  ------------------
 7630|      0|        if (ret == WOLFSSL_SUCCESS)
  ------------------
  |  Branch (7630:13): [True: 0, False: 0]
  ------------------
 7631|      0|            ret = BAD_MUTEX_E;
 7632|      0|    }
 7633|      0|    session_lock_valid = 0;
 7634|      0|    #endif
 7635|      0|    for (i = 0; i < SESSION_ROWS; i++) {
  ------------------
  |  |   85|      0|        #define SESSION_ROWS 11
  ------------------
  |  Branch (7635:17): [True: 0, False: 0]
  ------------------
 7636|      0|        for (j = 0; j < SESSIONS_PER_ROW; j++) {
  ------------------
  |  |   84|      0|        #define SESSIONS_PER_ROW 3
  ------------------
  |  Branch (7636:21): [True: 0, False: 0]
  ------------------
 7637|       |    #ifdef SESSION_CACHE_DYNAMIC_MEM
 7638|       |            if (SessionCache[i].Sessions[j]) {
 7639|       |                EvictSessionFromCache(SessionCache[i].Sessions[j]);
 7640|       |                XFREE(SessionCache[i].Sessions[j], SessionCache[i].heap,
 7641|       |                      DYNAMIC_TYPE_SESSION);
 7642|       |                SessionCache[i].Sessions[j] = NULL;
 7643|       |            }
 7644|       |    #else
 7645|      0|            EvictSessionFromCache(&SessionCache[i].Sessions[j]);
 7646|      0|    #endif
 7647|      0|        }
 7648|      0|    }
 7649|      0|    #ifndef NO_CLIENT_CACHE
 7650|       |    #ifndef WOLFSSL_MUTEX_INITIALIZER
 7651|       |    if ((clisession_mutex_valid == 1) &&
 7652|       |        (wc_FreeMutex(&clisession_mutex) != 0)) {
 7653|       |        if (ret == WOLFSSL_SUCCESS)
 7654|       |            ret = BAD_MUTEX_E;
 7655|       |    }
 7656|       |    clisession_mutex_valid = 0;
 7657|       |    #endif
 7658|      0|    #endif
 7659|      0|#endif /* !NO_SESSION_CACHE */
 7660|       |
 7661|       |#if !defined(WOLFSSL_MUTEX_INITIALIZER) && \
 7662|       |      !WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
 7663|       |    if ((inits_count_mutex_valid == 1) &&
 7664|       |            (wc_FreeMutex(&inits_count_mutex) != 0)) {
 7665|       |        if (ret == WOLFSSL_SUCCESS)
 7666|       |            ret = BAD_MUTEX_E;
 7667|       |    }
 7668|       |    inits_count_mutex_valid = 0;
 7669|       |#endif
 7670|       |
 7671|       |#ifdef OPENSSL_EXTRA
 7672|       |    wolfSSL_RAND_Cleanup();
 7673|       |#endif
 7674|       |
 7675|      0|    if (wolfCrypt_Cleanup() != 0) {
  ------------------
  |  Branch (7675:9): [True: 0, False: 0]
  ------------------
 7676|      0|        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
  ------------------
  |  |  392|      0|    #define WOLFSSL_MSG(m)            WC_DO_NOTHING
  |  |  ------------------
  |  |  |  |  418|      0|    #define WC_DO_NOTHING do {} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (418:40): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7677|      0|        if (ret == WOLFSSL_SUCCESS)
  ------------------
  |  Branch (7677:13): [True: 0, False: 0]
  ------------------
 7678|      0|            ret = WC_CLEANUP_E;
 7679|      0|    }
 7680|       |
 7681|       |#if FIPS_VERSION_GE(5,1)
 7682|       |    if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
 7683|       |        if (ret == WOLFSSL_SUCCESS)
 7684|       |            ret = WC_CLEANUP_E;
 7685|       |    }
 7686|       |#endif
 7687|       |
 7688|      0|#ifdef HAVE_GLOBAL_RNG
 7689|       |#ifndef WOLFSSL_MUTEX_INITIALIZER
 7690|       |    if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
 7691|       |        if (ret == WOLFSSL_SUCCESS)
 7692|       |            ret = BAD_MUTEX_E;
 7693|       |    }
 7694|       |    globalRNGMutex_valid = 0;
 7695|       |#endif /* !WOLFSSL_MUTEX_INITIALIZER */
 7696|       |
 7697|       |    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
 7698|       |    wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
 7699|       |    gDrbgDefCtx = NULL;
 7700|       |    #endif
 7701|      0|#endif
 7702|       |
 7703|       |#ifdef HAVE_EX_DATA_CRYPTO
 7704|       |    crypto_ex_cb_free(crypto_ex_cb_ctx_session);
 7705|       |    crypto_ex_cb_ctx_session = NULL;
 7706|       |#endif
 7707|       |
 7708|       |#ifdef WOLFSSL_MEM_FAIL_COUNT
 7709|       |    wc_MemFailCount_Free();
 7710|       |#endif
 7711|       |
 7712|      0|    return ret;
 7713|    226|}

wc_LockMutex:
 2756|    226|    {
 2757|    226|        if (pthread_mutex_lock(m) == 0)
  ------------------
  |  Branch (2757:13): [True: 226, False: 0]
  ------------------
 2758|    226|            return 0;
 2759|      0|        else
 2760|      0|            return BAD_MUTEX_E;
 2761|    226|    }
wc_UnLockMutex:
 2765|    226|    {
 2766|    226|        if (pthread_mutex_unlock(m) == 0)
  ------------------
  |  Branch (2766:13): [True: 226, False: 0]
  ------------------
 2767|    226|            return 0;
 2768|      0|        else
 2769|      0|            return BAD_MUTEX_E;
 2770|    226|    }

