mqttlib-example.are
/* mqtt v311 connack codes */
CONNACK_ACCEPTED = 0;
CONNACK_REFUSED_PROTOCOL_VERSION = 1;
CONNACK_REFUSED_IDENTIFIER_REJECTED = 2;
CONNACK_REFUSED_SERVER_UNAVAILABLE = 3;
CONNACK_REFUSED_BAD_USERNAME_PASSWORD = 4;
CONNACK_REFUSED_NOT_AUTHORIZED = 5;
 
/* mqtt v5 return codes */
MQTT_RC_SUCCESS = 0;      /* CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH */
MQTT_RC_NORMAL_DISCONNECTION = 0;   /* DISCONNECT */
MQTT_RC_GRANTED_QOS0 = 0;     /* SUBACK */
MQTT_RC_GRANTED_QOS1 = 1;     /* SUBACK */
MQTT_RC_GRANTED_QOS2 = 2;     /* SUBACK */
MQTT_RC_DISCONNECT_WITH_WILL_MSG = 4;  /* DISCONNECT */
MQTT_RC_NO_MATCHING_SUBSCRIBERS = 16;  /* PUBACK, PUBREC */
MQTT_RC_NO_SUBSCRIPTION_EXISTED = 17;  /* UNSUBACK */
MQTT_RC_CONTINUE_AUTHENTICATION = 24;  /* AUTH */
MQTT_RC_REAUTHENTICATE = 25;    /* AUTH */
MQTT_RC_UNSPECIFIED = 128;     /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_MALFORMED_PACKET = 129;    /* CONNACK, DISCONNECT */
MQTT_RC_PROTOCOL_ERROR = 130;    /* DISCONNECT */
MQTT_RC_IMPLEMENTATION_SPECIFIC = 131;  /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION = 132; /* CONNACK */
MQTT_RC_CLIENTID_NOT_VALID = 133;   /* CONNACK */
MQTT_RC_BAD_USERNAME_OR_PASSWORD = 134;  /* CONNACK */
MQTT_RC_NOT_AUTHORIZED = 135;    /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_SERVER_UNAVAILABLE = 136;   /* CONNACK */
MQTT_RC_SERVER_BUSY = 137;     /* CONNACK, DISCONNECT */
MQTT_RC_BANNED = 138;      /* CONNACK */
MQTT_RC_SERVER_SHUTTING_DOWN = 139;   /* DISCONNECT */
MQTT_RC_BAD_AUTHENTICATION_METHOD = 140; /* CONNACK */
MQTT_RC_KEEP_ALIVE_TIMEOUT = 141;   /* DISCONNECT */
MQTT_RC_SESSION_TAKEN_OVER = 142;   /* DISCONNECT */
MQTT_RC_TOPIC_FILTER_INVALID = 143;   /* SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_TOPIC_NAME_INVALID = 144;   /* CONNACK, PUBACK, PUBREC, DISCONNECT */
MQTT_RC_PACKET_ID_IN_USE = 145;    /* PUBACK, SUBACK, UNSUBACK */
MQTT_RC_PACKET_ID_NOT_FOUND = 146;   /* PUBREL, PUBCOMP */
MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED = 147;  /* DISCONNECT */
MQTT_RC_TOPIC_ALIAS_INVALID = 148;   /* DISCONNECT */
MQTT_RC_PACKET_TOO_LARGE = 149;    /* CONNACK, PUBACK, PUBREC, DISCONNECT */
MQTT_RC_MESSAGE_RATE_TOO_HIGH = 150;  /* DISCONNECT */
MQTT_RC_QUOTA_EXCEEDED = 151;    /* PUBACK, PUBREC, SUBACK, DISCONNECT */
MQTT_RC_ADMINISTRATIVE_ACTION = 152;  /* DISCONNECT */
MQTT_RC_PAYLOAD_FORMAT_INVALID = 153;  /* CONNACK, DISCONNECT */
MQTT_RC_RETAIN_NOT_SUPPORTED = 154;   /* CONNACK, DISCONNECT */
MQTT_RC_QOS_NOT_SUPPORTED = 155;   /* CONNACK, DISCONNECT */
MQTT_RC_USE_ANOTHER_SERVER = 156;   /* CONNACK, DISCONNECT */
MQTT_RC_SERVER_MOVED = 157;     /* CONNACK, DISCONNECT */
MQTT_RC_SHARED_SUBS_NOT_SUPPORTED = 158; /* SUBACK, DISCONNECT */
MQTT_RC_CONNECTION_RATE_EXCEEDED = 159;  /* CONNACK, DISCONNECT */
MQTT_RC_MAXIMUM_CONNECT_TIME = 160;   /* DISCONNECT */
MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED = 161; /* SUBACK, DISCONNECT */
MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED = 162; /* SUBACK, DISCONNECT */
 
/* mqtt v5 subscribe options */
MQTT_SUB_OPT_NO_LOCAL = 0x04;
MQTT_SUB_OPT_RETAIN_AS_PUBLISHED = 0x08;
MQTT_SUB_OPT_SEND_RETAIN_ALWAYS = 0x00;
MQTT_SUB_OPT_SEND_RETAIN_NEW = 0x10;
MQTT_SUB_OPT_SEND_RETAIN_NEVER = 0x20;
 
/* mqtt v5 properties */
MQTT_PROP_PAYLOAD_FORMAT_INDICATOR = 1;  /* Byte :    PUBLISH, Will Properties */
MQTT_PROP_MESSAGE_EXPIRY_INTERVAL = 2;  /* 4 byte int :   PUBLISH, Will Properties */
MQTT_PROP_CONTENT_TYPE = 3;     /* UTF-8 string :  PUBLISH, Will Properties */
MQTT_PROP_RESPONSE_TOPIC = 8;    /* UTF-8 string :  PUBLISH, Will Properties */
MQTT_PROP_CORRELATION_DATA = 9;    /* Binary Data :  PUBLISH, Will Properties */
MQTT_PROP_SUBSCRIPTION_IDENTIFIER = 11;  /* Variable byte int : PUBLISH, SUBSCRIBE */
MQTT_PROP_SESSION_EXPIRY_INTERVAL = 17;  /* 4 byte int :   CONNECT, CONNACK, DISCONNECT */
MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER = 18; /* UTF-8 string :  CONNACK */
MQTT_PROP_SERVER_KEEP_ALIVE = 19;   /* 2 byte int :   CONNACK */
MQTT_PROP_AUTHENTICATION_METHOD = 21;  /* UTF-8 string :  CONNECT, CONNACK, AUTH */
MQTT_PROP_AUTHENTICATION_DATA = 22;   /* Binary Data :  CONNECT, CONNACK, AUTH */
MQTT_PROP_REQUEST_PROBLEM_INFORMATION = 23; /* Byte :    CONNECT */
MQTT_PROP_WILL_DELAY_INTERVAL = 24;   /* 4 byte int :   Will properties */
MQTT_PROP_REQUEST_RESPONSE_INFORMATION = 25;/* Byte :    CONNECT */
MQTT_PROP_RESPONSE_INFORMATION = 26;  /* UTF-8 string :  CONNACK */
MQTT_PROP_SERVER_REFERENCE = 28;   /* UTF-8 string :  CONNACK, DISCONNECT */
MQTT_PROP_REASON_STRING = 31;    /* UTF-8 string :  All except Will properties */
MQTT_PROP_RECEIVE_MAXIMUM = 33;    /* 2 byte int :   CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS_MAXIMUM = 34;   /* 2 byte int :   CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS = 35;     /* 2 byte int :   PUBLISH */
MQTT_PROP_MAXIMUM_QOS = 36;     /* Byte :    CONNACK */
MQTT_PROP_RETAIN_AVAILABLE = 37;   /* Byte :    CONNACK */
MQTT_PROP_USER_PROPERTY = 38;    /* UTF-8 string pair : All */
MQTT_PROP_MAXIMUM_PACKET_SIZE = 39;   /* 4 byte int :   CONNECT, CONNACK */
MQTT_PROP_WILDCARD_SUB_AVAILABLE = 40;  /* Byte :    CONNACK */
MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE = 41; /* Byte :    CONNACK */
MQTT_PROP_SHARED_SUB_AVAILABLE = 42;  /* Byte :    CONNACK */
 
/* error values */
MOSQ_ERR_AUTH_CONTINUE = -4;
MOSQ_ERR_NO_SUBSCRIBERS = -3;
MOSQ_ERR_SUB_EXISTS = -2;
MOSQ_ERR_CONN_PENDING = -1;
MOSQ_ERR_SUCCESS = 0;
MOSQ_ERR_NOMEM = 1;
MOSQ_ERR_PROTOCOL = 2;
MOSQ_ERR_INVAL = 3;
MOSQ_ERR_NO_CONN = 4;
MOSQ_ERR_CONN_REFUSED = 5;
MOSQ_ERR_NOT_FOUND = 6;
MOSQ_ERR_CONN_LOST = 7;
MOSQ_ERR_TLS = 8;
MOSQ_ERR_PAYLOAD_SIZE = 9;
MOSQ_ERR_NOT_SUPPORTED = 10;
MOSQ_ERR_AUTH = 11;
MOSQ_ERR_ACL_DENIED = 12;
MOSQ_ERR_UNKNOWN = 13;
MOSQ_ERR_ERRNO = 14;
MOSQ_ERR_EAI = 15;
MOSQ_ERR_PROXY = 16;
MOSQ_ERR_PLUGIN_DEFER = 17;
MOSQ_ERR_MALFORMED_UTF8 = 18;
MOSQ_ERR_KEEPALIVE = 19;
MOSQ_ERR_LOOKUP = 20;
MOSQ_ERR_MALFORMED_PACKET = 21;
MOSQ_ERR_DUPLICATE_PROPERTY = 22;
MOSQ_ERR_TLS_HANDSHAKE = 23;
MOSQ_ERR_QOS_NOT_SUPPORTED = 24;
MOSQ_ERR_OVERSIZE_PACKET = 25;
MOSQ_ERR_OCSP = 26;
 
CA_CERT = "-----BEGIN CERTIFICATE-----
MIIDVTCCAj2gAwIBAgIUVqu7ShFG85T8XijutOA/VNi27U0wDQYJKoZIhvcNAQEL
BQAwOjELMAkGA1UEBhMCQ0gxDTALBgNVBAgMBHRlc3QxDTALBgNVBAoMBHRlc3Qx
DTALBgNVBAsMBHJvb3QwHhcNMjAxMDA4MTEyNTA5WhcNMzcwMzEzMTEyNTA5WjA6
MQswCQYDVQQGEwJDSDENMAsGA1UECAwEdGVzdDENMAsGA1UECgwEdGVzdDENMAsG
A1UECwwEcm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzj+arP
Vw4MQVDGe10LQT2sougxTZuwYnRrEMvsXw9Kzx5DnCweZh0dgpd1Ou6ZY3Fghojr
zsL92D9yNn/qDJaA9tKPGR2Kb9Wr1Ie0CF3y8LiZu/pJA3wKns+GJLDMV/slV7Dq
bDVN1Pj6Y8cr7RsWGK6YOdoYZEBOMb58ffDXmMFbwKrklF4vU0ewMo2JbQ2VBiYm
k6VeTnf093389/nc0OK2Fz/GWvNzwtk+gJSdU7PiYrw+Hkw/N1WyJfzlATm/yimT
ir2+0pB45qvDnreSZIf0uOkbkoG3CUMC0pnUeKzb38cIYYIMOUA1sqR2qOUNMR4y
7i6hLD2KsmMLGXcCAwEAAaNTMFEwHQYDVR0OBBYEFEn4Z2Hn8MgeZghFSnvg/VOt
Xy6qMB8GA1UdIwQYMBaAFEn4Z2Hn8MgeZghFSnvg/VOtXy6qMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIeDHntL7p/+wWHNHQTeVBvsHyP3hOfI
ZR8RprJYL4/fmdfWDpB5/dqJV9CgNdkIpkqb6BuW5AX9HeSoeC/QLuJRit2jmwAJ
qHghS06auVunSHxQM8OnwR53we0733mjzBV0DYWiw55g5nnB/FD+Wg6bTpxmjBhz
wVYQ4p6sMyi4Ac1pAhatvqz72TmlbRNrWWoR+J30+5bLd0JNJWQ0vTMeoGJZ4fpI
QF5e7FqJMZawCVsQXPYbemDgNtOLdX95r9nZrbrtHQlCbx/uSj9X0OmIEZz5kSQb
MryTUFzdY4GDOoyTqd1f80LCvJM97fAj/gY7sHPPK1stCGHBZ2gvkHA=
-----END CERTIFICATE-----
";
 
CLIENT_CRT = "-----BEGIN CERTIFICATE-----
MIIC7zCCAdcCFBya81lY82IG53sMJIFdJ/KIsgRrMA0GCSqGSIb3DQEBCwUAMDox
CzAJBgNVBAYTAkNIMQ0wCwYDVQQIDAR0ZXN0MQ0wCwYDVQQKDAR0ZXN0MQ0wCwYD
VQQLDARyb290MB4XDTIwMTAwODE0MjMzMVoXDTI4MTIyNTE0MjMzMVowLjELMAkG
A1UEBhMCQ0gxDTALBgNVBAgMBHRlc3QxEDAOBgNVBAoMB2NsaWVudDEwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcbBajpeuQSbMQ3F/46off/pu0rzPy
tgJs4qlTEki4pL9cIN2FzsZ9Xr0CydoyKsOdj+S/VxN+oRD4ZeqUrFNHORrx+s/U
VCkPutrT9WGEsVDxkAR55I+cqxxrlxlJQvGBDiDu/4do8L2OUu6YR2Zx2j4nmrp2
j4rhUG7WHT3Q38PC5MESNYBnU3zEwYX/jsw+4dk+uI83TXRwfrL9lHkSWo4sbG51
RxvmNgIeG+Xz8R9X4/e94wWWasURfki8r1oZzYj9aS6WzgTQjiDcEAzQ3PQfDWWm
8GOIBL6cmgSDnKfB9RBjo8Uh0XJSx6bWBY25n/5G+g3z/EPXZhSgpgNlAgMBAAEw
DQYJKoZIhvcNAQELBQADggEBACwQ8Gg+fTIF2IHW0RFLvWhWimgCUGVZxZlsNsf7
1FMxNFFfNgr3h5ofmpNhU8GXG0WDTUzouXqQ5pzl0ww9SrZJpu50w0wRK0uGrQbJ
xcaXtzMZq9LHbXFdu9BJH2osAutcdfwbQyoUZXBoaXCYRdj+u55SnHcN2EG+hE5F
p4Xi6Bmz6OUw7McvVGoAVtGbWE5SnnzDwHJ7ue92fv0mMifdqWBvpyF7OEZMayYt
4+BWu+sIIlhMt9W/9LYRrtKuo38+643ERy0kyUPj+NDCbFc00qaIai/pPo/JKVjJ
Tl77VErtf2iiYdbjjyqe/37iYdcD20gJUqLAoX4qQuwI/8k=
-----END CERTIFICATE-----
";
 
CLIENT_KEY = "-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAnGwWo6XrkEmzENxf+OqH3/6btK8z8rYCbOKpUxJIuKS/XCDd
hc7GfV69AsnaMirDnY/kv1cTfqEQ+GXqlKxTRzka8frP1FQpD7ra0/VhhLFQ8ZAE
eeSPnKsca5cZSULxgQ4g7v+HaPC9jlLumEdmcdo+J5q6do+K4VBu1h090N/DwuTB
EjWAZ1N8xMGF/47MPuHZPriPN010cH6y/ZR5ElqOLGxudUcb5jYCHhvl8/EfV+P3
veMFlmrFEX5IvK9aGc2I/Wkuls4E0I4g3BAM0Nz0Hw1lpvBjiAS+nJoEg5ynwfUQ
Y6PFIdFyUsem1gWNuZ/+RvoN8/xD12YUoKYDZQIDAQABAoIBAQCXAurgVoCSrfQH
5RlqT9GZeE6OI079lKXGxRQ/NLmsOLDdmoUCd1u9EUdcd88E+7AaXx6xcrlJWOnv
RUUw/yTu77yJvGAEVrPFkdlNI+pflmfUrfsESpoy4Cbx38/zoINS2ncFBQCPWUtH
Kd1aeiP26oFy7rfxWibz2xkF8PkKuln6MDezXgKDk8my72h16YY938yGAT7E7CwE
xYr2pFb/lk0ZFJfIl+dpcPOmwFElr+Yo0l0wMXXxlWmQmwGmWBPX+NnYlzPzhI29
lG1WbYkoxc2mNa4Z1VoPazVgROYSuaMChLb36ULXZA0DtgeVKMaj3LY6nFcdSWDe
oAd1VYEBAoGBAMlLEPlLibiCyIdN/xsYOhEr9jkgNHKWwodcoWEvwNEEmeHJZFro
t/h9V+w2XoQ11zL1nYMOkPWsQwvxGZJ3T5k6JJ0DGrJW3h2XSUeaekPUcq/xk1BR
KfiuH86c7IDb4EeTfB7BITp2qVNxlN5N0cyhHyFOQN3Ab6WWJ8aS9W6FAoGBAMbv
IZzS5D3GZdOBc/cUzTuMu9KXeP96XADLcsLcXxisskY/kHHBPcUrWS5m3rbjyGsX
GowDQFTVJF5IQwn0xIjA25SRJJK4GxQirK90u6aRdIq1yU5EMVVUohmWUq9UtcHc
86IkPqsh2+4RYC8a8lAJGzk128J8yFrctYU2k4dhAoGBAL6sE50Bd6hGgirgr/h7
X22qpeaA4g11TzknflpwAIY9hIJC4YPXk4SXPrSq36b+1SUZUaW2I4wDK9NhA2ch
C05KrCnqqdwquuVuy+Q+qPgdgrG09GUNLOO6FLkDHmgFXxKN2vHK4W3evxAis/BL
6KKcML+8v2cOhPNmI7FOvZt9AoGBAJS1qBvSbrpbOD1e1TCMBUuRzcoEX3gjoOkb
LQPLtu78Ehx/YdwXh7R/zh/o2G5BYs3jLH4j5BBGcPRl8m9b4RsViE/MHFntdJid
vxc+HRTMQSF7+SsfwP030iFshQz6NxDfueSoUYyeOAkERjGQZDk+RXKD926w1xlN
Sgh2HtyhAoGBAJwNl8ktsNzYTOc8GN0THRjPrS+S2wrgQmDp9XLBSct1cCtOy6Es
wGb779FEsVdqbF4L8hZmVbqwWD3GKIgc2Xnox5qKQD5mxZNVamNILqx8cOiebEYI
54r9BE2sSOOhQ0Xxw9yp6JIt4bHsFY3StobcWIaQdbNuMW2ZaeI4PSM0
-----END RSA PRIVATE KEY-----
";
 
BROKER_IP = "127.0.0.1";
BROKER_PORT_INSECURE = 1883;
BROKER_PORT_SECURE = 8883;
 
KEEPALIVE = 30;
QOS = 0;
RETAIN = 0;
TOPICS_PARROT = mkarray(
"parrot/#"
);
 
USER = "parrot";
PASSWORD = "parrot";
 
DEFAULT_RESPONSE_TOPIC = "parrot-default";
 
TESTRUNS = 0;
 
PROP_IDS = mkarray(
MQTT_PROP_SESSION_EXPIRY_INTERVAL, 
MQTT_PROP_MAXIMUM_PACKET_SIZE,
MQTT_PROP_SUBSCRIPTION_IDENTIFIER,
MQTT_PROP_RESPONSE_TOPIC,
MQTT_PROP_SESSION_EXPIRY_INTERVAL,
MQTT_PROP_TOPIC_ALIAS_MAXIMUM,
MQTT_PROP_USER_PROPERTY
);
 
CON_PROPS = mkarray(mkarray(MQTT_PROP_SESSION_EXPIRY_INTERVAL, 30), mkarray(MQTT_PROP_MAXIMUM_PACKET_SIZE, 4096));
SUB_OPS = MQTT_SUB_OPT_SEND_RETAIN_ALWAYS;
SUB_PROPS = mkarray(mkarray(MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1));
PUB_PROPS = mkarray(mkarray(MQTT_PROP_RESPONSE_TOPIC, "rtopic"), mkarray(MQTT_PROP_USER_PROPERTY, "myprop", "123"));
DISCON_PROPS = mkarray(mkarray(MQTT_PROP_SESSION_EXPIRY_INTERVAL, 30));
 
void print_array(array a, int d) {
  tabs = "";
  for (i = 0; i < d; i++) {
    tabs = strcat(tabs, "  ");
  }
  printf("%s(array l=%d):\n", "", length(a));
  for (i = 0; i < length(a); i++) {
    val = a[i];
    printf("%s%d: ", tabs, i);
    if (is_array(val)) {
      print_array(val, d+1);
    }
    else if (is_struct(val)) {
      print_struct(val, d+1);
    }
    else {
      printf("%s\n", val);
    }
  }
}
 
void print_struct(struct s, int d) {
  stlist = struct_fields(s);
  tabs = "";
  for (i = 0; i < d; i++) {
    tabs = strcat(tabs, "  ");
  }
  printf("%s(struct l=%d):\n", "", length(stlist));
  for (i = 0; i < length(stlist); i++) {
    val = struct_get(s, stlist[i]);
    printf("%s%s: ", tabs, stlist[i]);
    if (is_array(val)) {
      print_array(val, d+1);
    }
    else if (is_struct(val)) {
      print_struct(val, d+1);
    }
    else {
      printf("%s\n", val);
    }
  }
}
 
array get_property(array properties, int property_id) {
    len = length(properties);
    for (i = 0; i < len; i++) {
        if (properties[i][0] == property_id) {
            return tail(properties[i]);
        }
    }
    return mkarray();
}
 
void subscribe_all(int md, array topics) {
    n_topics = length(topics);
    for (i = 0; i < n_topics; i++) {
        rc = nb_mqttlib_subscribe(md, topics[i], 0, 0);
        if (rc != 0) {
            printf("md=%d subscribe failed! rc = %d\n", md,  rc);
            exit(-1);
        }
 
        rc = nb_mqttlib_get_callback_subscribe(md, 1000, PROP_IDS);
        if (struct_get(rc, "qos_count") != 1) {
            printf("md=%d subscribe failed after ack.\n", md);
            print_struct(rc, 0);
            exit(-1);
        }
    }
}
 
void on_message(int md, string topic, string message, array properties) {
    response_topic = get_property(props, MQTT_PROP_RESPONSE_TOPIC);
    answer = strcat(topic, " sais: ", message);
    if (length(response_topic) > 0) {
        nb_mqttlib_publish(md, response_topic[0], answer, 0, 0);
    } else {
        nb_mqttlib_publish(md, DEFAULT_RESPONSE_TOPIC, answer, 0, 0);
    }
}
 
 
void usage() 
{
    printf("usage: mqttlib-test.are host\n");
    exit(1);
}
 
if (argc < 2) {
    usage();
}
 
BROKER_IP = argv[1];
 
 
printf("----TESTING INSECURE CONNECTION----\n");
 
id = "test";
 
printf("test nb_mqttlib_new\n");
md = nb_mqttlib_new(id, true);
if (md < 0) {
    printf("nb_mqttlib_new failed! md = %d\n", md);
    exit(-1);
}
 
printf("test nb_mqttlib_set_protocol_version\n");
rc = nb_mqttlib_set_protocol_version(md, "V5");
if (rc != 0) {
    printf("md=%d set_protocol failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_user_pw\n");
rc = nb_mqttlib_set_user_pw(md, USER, PASSWORD);
if (rc != 0) {
    printf("md=%d set_user_pw failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_will\n");
rc = nb_mqttlib_set_will(md, DEFAULT_RESPONSE_TOPIC, "parrot sais: goodbye!", 0, 0);
if (rc != 0) {
    printf("md=%d set_will failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_connect\n");
rc = nb_mqttlib_connect(md, BROKER_IP, BROKER_PORT_INSECURE, KEEPALIVE, CON_PROPS);
if (rc != 0) {
    printf("md=%d connect failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_get_callback_connect\n");
rc = nb_mqttlib_get_callback_connect(md, 10000, PROP_IDS);
if (struct_get(rc, "rc") != MOSQ_ERR_SUCCESS) {
    printf("md=%d get_callback_connect failed! \n", md);
    print_struct(rc, 0);
    exit(-1);
}
 
subscribe_all(md, TOPICS_PARROT);
i = 0;
while (i < 10) 
{
    printf("test nb_mqttlib_get_callback_message\n");
    rc = nb_mqttlib_get_callback_message(md, 1000, PROP_IDS);
    if (length(struct_fields(rc)) > 0) {
        printf("md=%d nb_mqttlib_get_callback_message:\n", md);
        print_struct(rc, 0);
        msg = struct_get(rc, "msg");
        props = struct_get(rc, "props");
        on_message(md, struct_get(msg, "topic"), struct_get(msg, "msg"), props);
        i++;
    }
 
 
 
    printf("test nb_mqttlib_get_callback_connect\n");
    rc = nb_mqttlib_get_callback_connect(md, 0, PROP_IDS);
    printf("RC: %d", rc);
    if (struct_get(rc, "rc") == MOSQ_ERR_SUCCESS) {
        printf("md=%d get_callback_connect: resubscribe \n", md);
        subscribe_all(md, TOPICS_PARROT);
    }
 
 
 
    printf("test nb_mqttlib_get_callback_disconnect\n");
    rc = nb_mqttlib_get_callback_disconnect(md, 0, PROP_IDS);
    if (length(struct_fields(rc)) > 0) {
        printf("md=%d get_callback_disconnect: \n", md);
        print_struct(rc, 0);
    }
}
 
printf("test nb_mqttlib_disconnect\n");
rc = nb_mqttlib_disconnect(md);
if (rc != 0) {
    printf("md=%d nb_mqttlib_disconnect failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_protocol_version\n");
rc = nb_mqttlib_get_callback_disconnect(md, 0, PROP_IDS);
if (length(struct_fields(rc)) > 0) {
	printf("md=%d get_callback_disconnect: \n", md);
	print_struct(rc, 0);
}
 
nb_mqttlib_free(md);
 
printf("----TESTING SECURE CONNECTION----\n");
 
id = "test";
printf("test nb_mqttlib_new w. tls\n");
md = nb_mqttlib_new(id, true);
if (md < 0) {
    printf("nb_mqttlib_new failed! md = %d\n", md);
    exit(-1);
}
 
printf("test nb_mqttlib_set_protocol_version w. tls\n");
rc = nb_mqttlib_set_protocol_version(md, "V5");
if (rc != 0) {
    printf("md=%d set_protocol failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_tls w. tls\n");
rc = nb_mqttlib_set_tls(md, CA_CERT, CLIENT_CRT, CLIENT_KEY);
if (rc != 0) {
    printf("md=%d nb_mqttlib_set_tls failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_tls_insecure w. tls\n");
rc = nb_mqttlib_set_tls_insecure(md, true);
if (rc != 0) {
    printf("md=%d nb_mqttlib_set_tls_insecure failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_user_pw w. tls\n");
rc = nb_mqttlib_set_user_pw(md, USER, PASSWORD);
if (rc != 0) {
    printf("md=%d set_user_pw failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_set_will w. tls\n");
rc = nb_mqttlib_set_will(md, DEFAULT_RESPONSE_TOPIC, "parrot sais: goodbye!", 0, 0);
if (rc != 0) {
    printf("md=%d set_will failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_connect w. tls\n");
rc = nb_mqttlib_connect(md, BROKER_IP, BROKER_PORT_SECURE, KEEPALIVE, CON_PROPS);
if (rc != 0) {
    printf("md=%d connect failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_get_callback_connect w. tls\n");
rc = nb_mqttlib_get_callback_connect(md, 10000, PROP_IDS);
if (struct_get(rc, "rc") != MOSQ_ERR_SUCCESS) {
    printf("md=%d get_callback_connect failed! \n", md);
    print_struct(rc, 0);
    exit(-1);
}
 
subscribe_all(md, TOPICS_PARROT);
 
i = 0;
while (i < 10) 
{
    printf("test nb_mqttlib_get_callback_message w. tls\n");
    rc = nb_mqttlib_get_callback_message(md, 1000, PROP_IDS);
    if (length(struct_fields(rc)) > 0) {
        printf("md=%d nb_mqttlib_get_callback_message:\n", md);
        print_struct(rc, 0);
        msg = struct_get(rc, "msg");
        props = struct_get(rc, "props");
        on_message(md, struct_get(msg, "topic"), struct_get(msg, "msg"), props);
        i++;
    }
 
 
 
    printf("test nb_mqttlib_get_callback_connect w. tls\n");
    rc = nb_mqttlib_get_callback_connect(md, 0, PROP_IDS);
    if (struct_get(rc, "rc") == MOSQ_ERR_SUCCESS) {
        printf("md=%d get_callback_connect: resubscribe \n", md);
        subscribe_all(md, TOPICS_PARROT);
    }
 
 
 
    printf("test nb_mqttlib_get_callback_disconnect w. tls\n");
    rc = nb_mqttlib_get_callback_disconnect(md, 0, PROP_IDS);
    if (length(struct_fields(rc)) > 0) {
        printf("md=%d get_callback_disconnect: \n", md);
        print_struct(rc, 0);
    }
}
 
printf("test nb_mqttlib_disconnect w. tls\n");
rc = nb_mqttlib_disconnect(md);
if (rc != 0) {
    printf("md=%d nb_mqttlib_disconnect failed! rc = %d\n", md,  rc);
    exit(-1);
}
 
printf("test nb_mqttlib_get_callback_disconnect w. tls\n");
rc = nb_mqttlib_get_callback_disconnect(md, 0, PROP_IDS);
if (length(struct_fields(rc)) > 0) {
	printf("md=%d get_callback_disconnect: \n", md);
	print_struct(rc, 0);
}
 
nb_mqttlib_free(md);