Annotation of libaitmqtt/src/conn.c, revision 1.1

1.1     ! misho       1: /*************************************************************************
        !             2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
        !             3: *  by Michael Pounov <misho@openbsd-bg.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: aitsched.c,v 1.5 2012/01/24 21:59:47 misho Exp $
        !             7: *
        !             8: **************************************************************************
        !             9: The ELWIX and AITNET software is distributed under the following
        !            10: terms:
        !            11: 
        !            12: All of the documentation and software included in the ELWIX and AITNET
        !            13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
        !            14: 
        !            15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
        !            16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
        !            17: 
        !            18: Redistribution and use in source and binary forms, with or without
        !            19: modification, are permitted provided that the following conditions
        !            20: are met:
        !            21: 1. Redistributions of source code must retain the above copyright
        !            22:    notice, this list of conditions and the following disclaimer.
        !            23: 2. Redistributions in binary form must reproduce the above copyright
        !            24:    notice, this list of conditions and the following disclaimer in the
        !            25:    documentation and/or other materials provided with the distribution.
        !            26: 3. All advertising materials mentioning features or use of this software
        !            27:    must display the following acknowledgement:
        !            28: This product includes software developed by Michael Pounov <misho@elwix.org>
        !            29: ELWIX - Embedded LightWeight unIX and its contributors.
        !            30: 4. Neither the name of AITNET nor the names of its contributors
        !            31:    may be used to endorse or promote products derived from this software
        !            32:    without specific prior written permission.
        !            33: 
        !            34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
        !            35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            44: SUCH DAMAGE.
        !            45: */
        !            46: #include "global.h"
        !            47: 
        !            48: 
        !            49: /* ------------------------------------------------------------------- */
        !            50: 
        !            51: /*
        !            52:  * mqtt_msgCONNECT() Create CONNECT message
        !            53:  *
        !            54:  * @buf = Message buffer
        !            55:  * @csConnID = ConnectID
        !            56:  * @kasec = Keep alive timeout
        !            57:  * @csUser = Username if !=NULL
        !            58:  * @csPass = Password for Username, only if csUser is set
        !            59:  * @csWillTopic = Will Topic if !=NULL Will Flags set into message
        !            60:  * @csWillMessage = Will Message, may be NULL
        !            61:  * @ClrSess = Clear Session subscriptions after disconnect
        !            62:  * @WillQOS = Will QOS if csWillTopic is set
        !            63:  * @WillRetain = Will Retain Will Message if csWillTopic is set
        !            64:  * return: -1 error or >-1 message size for send
        !            65:  */
        !            66: int
        !            67: mqtt_msgCONNECT(mqtt_msg_t * __restrict buf, const char *csConnID, 
        !            68:                u_short kasec, const char *csUser, const char *csPass, 
        !            69:                const char *csWillTopic, const char *csWillMessage, 
        !            70:                u_char ClrSess, u_char WillQOS, u_char WillRetain)
        !            71: {
        !            72:        int siz = 0;
        !            73:        struct mqtthdr *hdr;
        !            74:        mqtthdr_var_t *var, *cid, *topic, *wmsg, *user, *pass;
        !            75:        mqtthdr_protover_t *proto;
        !            76:        mqtthdr_connflgs_t *flags;
        !            77:        mqtt_len_t *ka;
        !            78: 
        !            79:        if (!buf || !csConnID)
        !            80:                return -1;
        !            81:        if (strlen(csConnID) > 23) {
        !            82:                mqtt_SetErr(EINVAL, "Error:: invalid argument ConnID is too long (max 23 bytes)");
        !            83:                return -1;
        !            84:        }
        !            85:        if (csUser && strlen(csUser) > 12) {
        !            86:                mqtt_SetErr(EINVAL, "Error:: invalid argument Username is too long (max 12 bytes)");
        !            87:                return -1;
        !            88:        }
        !            89:        if (csPass && strlen(csPass) > 12) {
        !            90:                mqtt_SetErr(EINVAL, "Error:: invalid argument Password is too long (max 12 bytes)");
        !            91:                return -1;
        !            92:        }
        !            93:        if (WillQOS > MQTT_QOS_EXACTLY) {
        !            94:                mqtt_SetErr(EINVAL, "Error:: invalid argument WillQOS - unknown QOS value");
        !            95:                return -1;
        !            96:        }
        !            97: 
        !            98:        if (mqtt_msgRealloc(buf, BUFSIZ) == -1)
        !            99:                return -1;
        !           100:        else {
        !           101:                hdr = (struct mqtthdr *) (buf->msg_base + siz);
        !           102:                siz += sizeof(struct mqtthdr);
        !           103:                var = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           104:                siz += 8;
        !           105:                proto = buf->msg_base + siz;
        !           106:                siz++;
        !           107:                flags = (mqtthdr_connflgs_t*) (buf->msg_base + siz);
        !           108:                siz++;
        !           109:                ka = (mqtt_len_t*) (buf->msg_base + siz);
        !           110:                siz += sizeof(mqtt_len_t);
        !           111:        }
        !           112: 
        !           113:        /* fixed header */
        !           114:        MQTTHDR_MSGINIT(hdr);
        !           115:        hdr->mqtt_msg.type = MQTT_TYPE_CONNECT;
        !           116:        *hdr->mqtt_len = 0;
        !           117: 
        !           118:        /* variable header */
        !           119:        var->var_sb.sb.l = 6;
        !           120:        memcpy(var->var_data, MQTT_CONN_STR, 6);
        !           121: 
        !           122:        *proto = MQTT_PROTO_VER;
        !           123: 
        !           124:        /* CONNECT header */
        !           125:        flags->clean_sess = ClrSess ? 1 : 0;
        !           126:        if (csUser && *csUser) {
        !           127:                flags->username = 1;
        !           128:                flags->password = csPass ? 1 : 0;
        !           129:        } else {
        !           130:                flags->username = 0;
        !           131:                flags->password = 0;
        !           132:        }
        !           133:        if (csWillTopic && *csWillTopic) {
        !           134:                flags->will_flg = 1;
        !           135:                flags->will_qos = WillQOS;
        !           136:                flags->will_retain = WillRetain ? 1 : 0;
        !           137:        } else {
        !           138:                flags->will_flg = 0;
        !           139:                flags->will_qos = 0;
        !           140:                flags->will_retain = 0;
        !           141:        }
        !           142: 
        !           143:        ka->val = kasec ? htons(kasec) : htons(MQTT_KEEPALIVE);
        !           144: 
        !           145:        /* ConnID */
        !           146:        cid = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           147:        cid->var_sb.val = htons(strlen(csConnID));
        !           148:        siz += MQTTHDR_VAR_SIZEOF(cid);
        !           149:        memcpy(cid->var_data, csConnID, ntohs(cid->var_sb.val));
        !           150: 
        !           151:        /* If Will Flags setup */
        !           152:        if (csWillTopic && *csWillTopic) {
        !           153:                topic = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           154:                topic->var_sb.val = htons(strlen(csWillTopic));
        !           155:                memcpy(topic->var_data, csWillTopic, ntohs(topic->var_sb.val));
        !           156:                siz += MQTTHDR_VAR_SIZEOF(topic);
        !           157: 
        !           158:                wmsg = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           159:                if (csWillMessage && *csWillMessage) {
        !           160:                        wmsg->var_sb.val = htons(strlen(csWillMessage));
        !           161:                        memcpy(wmsg->var_data, csWillMessage, ntohs(wmsg->var_sb.val));
        !           162:                } else
        !           163:                        wmsg->var_sb.val = 0;
        !           164:                siz += MQTTHDR_VAR_SIZEOF(wmsg);
        !           165:        }
        !           166: 
        !           167:        /* If defined Username & Password */
        !           168:        if (csUser && *csUser) {
        !           169:                user = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           170:                user->var_sb.val = htons(strlen(csUser));
        !           171:                memcpy(user->var_data, csUser, ntohs(user->var_sb.val));
        !           172:                siz += MQTTHDR_VAR_SIZEOF(user);
        !           173: 
        !           174:                if (csPass && *csPass) {
        !           175:                        pass = (mqtthdr_var_t*) (buf->msg_base + siz);
        !           176:                        pass->var_sb.val = htons(strlen(csPass));
        !           177:                        memcpy(pass->var_data, csPass, ntohs(pass->var_sb.val));
        !           178:                        siz += MQTTHDR_VAR_SIZEOF(pass);
        !           179:                }
        !           180:        }
        !           181: 
        !           182:        *hdr->mqtt_len = mqtt_encodeLen(siz - sizeof(struct mqtthdr));
        !           183:        mqtt_msgRealloc(buf, siz);
        !           184:        return siz;
        !           185: }
        !           186: 
        !           187: /*
        !           188:  * mqtt_msgCONNACK() Create CONNACK message
        !           189:  *
        !           190:  * @buf = Message buffer
        !           191:  * @retcode = Return code
        !           192:  * return: -1 error or >-1 message size for send
        !           193:  */
        !           194: int
        !           195: mqtt_msgCONNACK(mqtt_msg_t * __restrict buf, u_char retcode)
        !           196: {
        !           197:        int siz = 0;
        !           198:        struct mqtthdr *hdr;
        !           199:        mqtthdr_connack_t *ack;
        !           200: 
        !           201:        if (!buf)
        !           202:                return -1;
        !           203:        if (retcode > MQTT_RETCODE_DENIED) {
        !           204:                mqtt_SetErr(EINVAL, "Error:: invalid retcode");
        !           205:                return -1;
        !           206:        }
        !           207: 
        !           208:        if (mqtt_msgRealloc(buf, sizeof(struct mqtthdr) + sizeof(mqtthdr_connack_t)) == -1)
        !           209:                return -1;
        !           210:        else {
        !           211:                hdr = (struct mqtthdr *) (buf->msg_base + siz);
        !           212:                siz += sizeof(struct mqtthdr);
        !           213:                ack = (mqtthdr_connack_t*) (buf->msg_base + siz);
        !           214:                siz += sizeof(mqtthdr_connack_t);
        !           215:        }
        !           216: 
        !           217:        /* fixed header */
        !           218:        MQTTHDR_MSGINIT(hdr);
        !           219:        hdr->mqtt_msg.type = MQTT_TYPE_CONNACK;
        !           220:        *hdr->mqtt_len = sizeof(mqtthdr_connack_t);
        !           221: 
        !           222:        /* CONNACK header */
        !           223:        ack->reserved = 0;
        !           224:        ack->retcode = retcode;
        !           225: 
        !           226:        return siz;
        !           227: }
        !           228: 
        !           229: static int
        !           230: _mqtt_msgSIMPLE_(mqtt_msg_t * __restrict buf, u_char cmd)
        !           231: {
        !           232:        int siz = 0;
        !           233:        struct mqtthdr *hdr;
        !           234: 
        !           235:        if (!buf)
        !           236:                return -1;
        !           237: 
        !           238:        if (mqtt_msgRealloc(buf, sizeof(struct mqtthdr)) == -1)
        !           239:                return -1;
        !           240:        else {
        !           241:                hdr = (struct mqtthdr *) (buf->msg_base + siz);
        !           242:                siz += sizeof(struct mqtthdr);
        !           243:        }
        !           244: 
        !           245:        /* fixed header */
        !           246:        MQTTHDR_MSGINIT(hdr);
        !           247:        hdr->mqtt_msg.type = cmd;
        !           248:        *hdr->mqtt_len = 0;
        !           249: 
        !           250:        return siz;
        !           251: }
        !           252: 
        !           253: /*
        !           254:  * mqtt_msgPINGREQ() Create PINGREQ message
        !           255:  *
        !           256:  * @buf = Message buffer
        !           257:  * return: -1 error or >-1 message size for send
        !           258:  */
        !           259: int
        !           260: mqtt_msgPINGREQ(mqtt_msg_t * __restrict buf)
        !           261: {
        !           262:        return _mqtt_msgSIMPLE_(buf, MQTT_TYPE_PINGREQ);
        !           263: }
        !           264: 
        !           265: /*
        !           266:  * mqtt_msgPINGRESP() Create PINGRESP message
        !           267:  *
        !           268:  * @buf = Message buffer
        !           269:  * return: -1 error or >-1 message size for send
        !           270:  */
        !           271: int
        !           272: mqtt_msgPINGRESP(mqtt_msg_t * __restrict buf)
        !           273: {
        !           274:        return _mqtt_msgSIMPLE_(buf, MQTT_TYPE_PINGRESP);
        !           275: }
        !           276: 
        !           277: /*
        !           278:  * mqtt_msgDISCONNECT() Create DISCONNECT message
        !           279:  *
        !           280:  * @buf = Message buffer
        !           281:  * return: -1 error or >-1 message size for send
        !           282:  */
        !           283: int
        !           284: mqtt_msgDISCONNECT(mqtt_msg_t * __restrict buf)
        !           285: {
        !           286:        return _mqtt_msgSIMPLE_(buf, MQTT_TYPE_DISCONNECT);
        !           287: }
        !           288: 
        !           289: /* ============= decode ============ */
        !           290: 
        !           291: /*
        !           292:  * mqtt_readCONNECT() Read elements from CONNECT message
        !           293:  *
        !           294:  * @buf = Message buffer
        !           295:  * @kasec = Keep Alive in seconds for current connection
        !           296:  * @psConnID = ConnectID
        !           297:  * @connLen = ConnectID length
        !           298:  * @psUser = Username if !=NULL
        !           299:  * @userLen = Username length
        !           300:  * @psPass = Password for Username, only if csUser is set
        !           301:  * @passLen = Password length
        !           302:  * @psWillTopic = Will Topic if !=NULL Will Flags set into message and must be free()
        !           303:  * @psWillMessage = Will Message, may be NULL if !NULL must be free() after use!
        !           304:  * return: .reserved == 1 is error or == 0 connection flags & msg ok
        !           305:  */
        !           306: mqtthdr_connack_t
        !           307: mqtt_readCONNECT(mqtt_msg_t * __restrict buf, u_short *kasec, char * __restrict psConnID, int connLen, 
        !           308:                char * __restrict psUser, int userLen, char * __restrict psPass, int passLen,  
        !           309:                char ** __restrict psWillTopic, char ** __restrict psWillMessage)
        !           310: {
        !           311:        mqtthdr_connflgs_t flg = { MQTT_CONNFLGS_INIT };
        !           312:        mqtthdr_connack_t cack = { 1, MQTT_RETCODE_DENIED };
        !           313:        struct mqtthdr *hdr;
        !           314:        mqtthdr_var_t *var;
        !           315:        mqtt_len_t *ka;
        !           316:        mqtthdr_protover_t *proto;
        !           317:        int len, ret;
        !           318:        caddr_t pos;
        !           319: 
        !           320:        if (!buf || !buf->msg_base || !buf->msg_len || !psConnID || !connLen)
        !           321:                return cack;
        !           322: 
        !           323:        hdr = _mqtt_readHEADER(buf, MQTT_TYPE_CONNECT, &ret, &len);
        !           324:        if (!hdr)
        !           325:                return cack;
        !           326:        if (len < 12) {
        !           327:                mqtt_SetErr(EINVAL, "Error:: short message length %d", len);
        !           328:                return cack;
        !           329:        } else {
        !           330:                pos = buf->msg_base + ret + 1;
        !           331:                var = (mqtthdr_var_t*) pos;
        !           332:        }
        !           333:        /* check init string & protocol */
        !           334:        if (var->var_sb.sb.l != 6 || strncmp((char*) var->var_data, MQTT_CONN_STR, 6)) {
        !           335:                mqtt_SetErr(EINVAL, "Error:: invalid init string %.6s(%d)", 
        !           336:                                var->var_data, var->var_sb.sb.l);
        !           337:                cack.retcode = MQTT_RETCODE_REFUSE_UNAVAIL;
        !           338:                return cack;
        !           339:        } else {
        !           340:                pos += var->var_sb.sb.l + sizeof(mqtt_len_t);
        !           341:                proto = (mqtthdr_protover_t*) pos;
        !           342:        }
        !           343:        if (*proto != MQTT_PROTO_VER) {
        !           344:                mqtt_SetErr(EINVAL, "Error:: invalid protocol version %d", *pos);
        !           345:                cack.retcode = MQTT_RETCODE_REFUSE_VER;
        !           346:                return cack;
        !           347:        } else
        !           348:                pos++;
        !           349:        flg = *(mqtthdr_connflgs_t*) pos;
        !           350:        pos++;
        !           351:        ka = (mqtt_len_t*) pos;
        !           352:        *kasec = ntohs(ka->val);
        !           353:        pos += sizeof(mqtt_len_t);
        !           354: 
        !           355:        len -= pos - (caddr_t) var;
        !           356: 
        !           357:        /* get ConnID */
        !           358:        var = (mqtthdr_var_t*) pos;
        !           359:        len -= MQTTHDR_VAR_SIZEOF(var);
        !           360:        if (len < 0 || var->var_sb.sb.l > 23) {
        !           361:                mqtt_SetErr(EINVAL, "Error:: unexpected EOM at Connection ID %d", len);
        !           362:                cack.retcode = MQTT_RETCODE_REFUSE_ID;
        !           363:                return cack;
        !           364:        } else {
        !           365:                memset(psConnID, 0, connLen--);
        !           366:                memcpy(psConnID, var->var_data, ntohs(var->var_sb.val) > connLen ? connLen : ntohs(var->var_sb.val));
        !           367:                pos += MQTTHDR_VAR_SIZEOF(var);
        !           368:        }
        !           369: 
        !           370:        /* get Willz */
        !           371:        if (flg.will_flg) {
        !           372:                var = (mqtthdr_var_t*) pos;
        !           373:                len -= MQTTHDR_VAR_SIZEOF(var);
        !           374:                if (len < 0) {
        !           375:                        mqtt_SetErr(EINVAL, "Error:: unexpected EOM at Will Topic %d", len);
        !           376:                        cack.retcode = MQTT_RETCODE_REFUSE_ID;
        !           377:                        return cack;
        !           378:                } else {
        !           379:                        if (psWillTopic) {
        !           380:                                *psWillTopic = malloc(ntohs(var->var_sb.val) + 1);
        !           381:                                if (!*psWillTopic) {
        !           382:                                        LOGERR;
        !           383:                                        cack.retcode = MQTT_RETCODE_REFUSE_UNAVAIL;
        !           384:                                        return cack;
        !           385:                                } else
        !           386:                                        memset(*psWillTopic, 0, ntohs(var->var_sb.val) + 1);
        !           387:                                memcpy(*psWillTopic, var->var_data, ntohs(var->var_sb.val));
        !           388:                        }
        !           389:                        pos += MQTTHDR_VAR_SIZEOF(var);
        !           390:                }
        !           391: 
        !           392:                var = (mqtthdr_var_t*) pos;
        !           393:                len -= MQTTHDR_VAR_SIZEOF(var);
        !           394:                if (len < 0) {
        !           395:                        mqtt_SetErr(EINVAL, "Error:: unexpected EOM at Will Message %d", len);
        !           396:                        cack.retcode = MQTT_RETCODE_REFUSE_ID;
        !           397:                        return cack;
        !           398:                } else {
        !           399:                        if (psWillMessage) {
        !           400:                                *psWillMessage = malloc(ntohs(var->var_sb.val) + 1);
        !           401:                                if (!*psWillMessage) {
        !           402:                                        LOGERR;
        !           403:                                        cack.retcode = MQTT_RETCODE_REFUSE_UNAVAIL;
        !           404:                                        return cack;
        !           405:                                } else
        !           406:                                        memset(*psWillMessage, 0, ntohs(var->var_sb.val) + 1);
        !           407:                                memcpy(*psWillMessage, var->var_data, ntohs(var->var_sb.val));
        !           408:                        }
        !           409:                        pos += MQTTHDR_VAR_SIZEOF(var);
        !           410:                }
        !           411:        }
        !           412: 
        !           413:        /* get User/Pass */
        !           414:        if (flg.username) {
        !           415:                var = (mqtthdr_var_t*) pos;
        !           416:                len -= MQTTHDR_VAR_SIZEOF(var);
        !           417:                if (len < 0 || var->var_sb.sb.l > 12) {
        !           418:                        mqtt_SetErr(EINVAL, "Error:: unexpected EOM at Username %d", len);
        !           419:                        cack.retcode = MQTT_RETCODE_REFUSE_USERPASS;
        !           420:                        return cack;
        !           421:                } else {
        !           422:                        if (psUser && userLen) {
        !           423:                                memset(psUser, 0, userLen--);
        !           424:                                memcpy(psUser, var->var_data, 
        !           425:                                                ntohs(var->var_sb.val) > userLen ? userLen : ntohs(var->var_sb.val));
        !           426:                        }
        !           427:                        pos += MQTTHDR_VAR_SIZEOF(var);
        !           428:                }
        !           429:        }
        !           430:        if (flg.password) {
        !           431:                var = (mqtthdr_var_t*) pos;
        !           432:                len -= MQTTHDR_VAR_SIZEOF(var);
        !           433:                if (len < 0 || var->var_sb.sb.l > 12) {
        !           434:                        mqtt_SetErr(EINVAL, "Error:: unexpected EOM at Password %d", len);
        !           435:                        cack.retcode = MQTT_RETCODE_REFUSE_USERPASS;
        !           436:                        return cack;
        !           437:                } else {
        !           438:                        if (psPass && passLen) {
        !           439:                                memset(psPass, 0, passLen--);
        !           440:                                memcpy(psPass, var->var_data, 
        !           441:                                                ntohs(var->var_sb.val) > passLen ? passLen : ntohs(var->var_sb.val));
        !           442:                        }
        !           443:                        pos += MQTTHDR_VAR_SIZEOF(var);
        !           444:                }
        !           445:        }
        !           446: 
        !           447:        flg.reserved = 0;
        !           448:        cack.reserved = flg.flags;
        !           449:        cack.retcode = MQTT_RETCODE_ACCEPTED;
        !           450:        return cack;
        !           451: }
        !           452: 
        !           453: /*
        !           454:  * mqtt_readCONNACK() Read CONNACK message
        !           455:  *
        !           456:  * @buf = Message buffer
        !           457:  * return: -1 error or >-1 CONNECT message return code
        !           458:  */
        !           459: u_char
        !           460: mqtt_readCONNACK(mqtt_msg_t * __restrict buf)
        !           461: {
        !           462:        int len, ret;
        !           463:        struct mqtthdr *hdr;
        !           464:        mqtthdr_connack_t *ack;
        !           465:        caddr_t pos;
        !           466: 
        !           467:        if (!buf || !buf->msg_base || !buf->msg_len)
        !           468:                return (u_char) -1;
        !           469: 
        !           470:        hdr = _mqtt_readHEADER(buf, MQTT_TYPE_CONNACK, &ret, &len);
        !           471:        if (!hdr)
        !           472:                return (u_char) -1;
        !           473:        if (len < sizeof(mqtthdr_connack_t)) {
        !           474:                mqtt_SetErr(EINVAL, "Error:: short message length %d", len);
        !           475:                return (u_char) -1;
        !           476:        } else {
        !           477:                pos = buf->msg_base + ret + 1;
        !           478:                ack = (mqtthdr_connack_t*) pos;
        !           479:        }
        !           480: 
        !           481:        if (ack->retcode > MQTT_RETCODE_DENIED) {
        !           482:                mqtt_SetErr(EINVAL, "Error:: invalid retcode %u", ack->retcode);
        !           483:                return (u_char) -1;
        !           484:        }
        !           485: 
        !           486:        return ack->retcode;
        !           487: }
        !           488: 
        !           489: /*
        !           490:  * mqtt_readDISCONNECT() Read DISCONNECT message
        !           491:  *
        !           492:  * @buf = Message buffer
        !           493:  * return: -1 error, 0 ok, >0 undefined result
        !           494:  */
        !           495: int
        !           496: mqtt_readDISCONNECT(mqtt_msg_t * __restrict buf)
        !           497: {
        !           498:        int len, ret;
        !           499:        struct mqtthdr *hdr;
        !           500: 
        !           501:        hdr = _mqtt_readHEADER(buf, MQTT_TYPE_DISCONNECT, &ret, &len);
        !           502:        if (!hdr || ret != 1)
        !           503:                return -1;
        !           504: 
        !           505:        return len;
        !           506: }
        !           507: 
        !           508: /*
        !           509:  * mqtt_readPINGREQ() Read PINGREQ message
        !           510:  *
        !           511:  * @buf = Message buffer
        !           512:  * return: -1 error, 0 ok, >0 undefined result
        !           513:  */
        !           514: int
        !           515: mqtt_readPINGREQ(mqtt_msg_t * __restrict buf)
        !           516: {
        !           517:        int len, ret;
        !           518:        struct mqtthdr *hdr;
        !           519: 
        !           520:        hdr = _mqtt_readHEADER(buf, MQTT_TYPE_PINGREQ, &ret, &len);
        !           521:        if (!hdr || ret != 1)
        !           522:                return -1;
        !           523: 
        !           524:        return len;
        !           525: }
        !           526: 
        !           527: /*
        !           528:  * mqtt_readPINGRESP() Read PINGRESP message
        !           529:  *
        !           530:  * @buf = Message buffer
        !           531:  * return: -1 error, 0 ok, >0 undefined result
        !           532:  */
        !           533: int
        !           534: mqtt_readPINGRESP(mqtt_msg_t * __restrict buf)
        !           535: {
        !           536:        int len, ret;
        !           537:        struct mqtthdr *hdr;
        !           538: 
        !           539:        hdr = _mqtt_readHEADER(buf, MQTT_TYPE_PINGRESP, &ret, &len);
        !           540:        if (!hdr || ret != 1)
        !           541:                return -1;
        !           542: 
        !           543:        return len;
        !           544: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>