⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smpp_pdu.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * smpp_pdu.c - parse and generate SMPP PDUs * * Lars Wirzenius * Alexander Malysh <a.malysh@centrium.de>: *     Extended optional parameters implementation. */#include <string.h>#include "smpp_pdu.h"#define MIN_SMPP_PDU_LEN    (4*4)/* old value was (1024). We need more because message_payload can be up to 64K octets*/#define MAX_SMPP_PDU_LEN    (7424) static long decode_integer(Octstr *os, long pos, int octets){    unsigned long u;    int i;    if (octstr_len(os) < pos + octets)         return -1;    u = 0;    for (i = 0; i < octets; ++i)    	u = (u << 8) | octstr_get_char(os, pos + i);    return u;}static void append_encoded_integer(Octstr *os, unsigned long u, long octets){    long i;    for (i = 0; i < octets; ++i)    	octstr_append_char(os, (u >> ((octets - i - 1) * 8)) & 0xFF);}static Octstr *copy_until_nul(Octstr *os, long *pos, long max_octets){    long nul;    Octstr *data;    nul = octstr_search_char(os, '\0', *pos);    if (nul == -1) {	warning(0, "SMPP: PDU NULL terminated string has no NULL.");    	return NULL;    }    if (*pos + max_octets < nul) {	error(0, "SMPP: PDU NULL terminated string longer than allowed.");    	return NULL;    }    data = (nul - *pos > 0) ? octstr_copy(os, *pos, nul - *pos) : NULL;    *pos = nul + 1;    return data;}SMPP_PDU *smpp_pdu_create(unsigned long type, unsigned long seq_no){    SMPP_PDU *pdu;    pdu = gw_malloc(sizeof(*pdu));    pdu->type = type;    switch (type) {    #define OPTIONAL_BEGIN    #define TLV_INTEGER(name, octets) p->name = -1;    #define TLV_NULTERMINATED(name, max_len) p->name = NULL;    #define TLV_OCTETS(name, min_len, max_len) p->name = NULL;    #define OPTIONAL_END    #define INTEGER(name, octets) \   	if (strcmp(#name, "command_id") == 0) p->name = type; \    	else if (strcmp(#name, "sequence_number") == 0) p->name = seq_no; \    	else p->name = 0;    #define NULTERMINATED(name, max_octets) p->name = NULL;    #define OCTETS(name, field_giving_octetst) p->name = NULL;    #define PDU(name, id, fields) \    	case id: { \	    struct name *p = &pdu->u.name; \	    pdu->type_name = #name; \	    fields \	} break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error.");    	gw_free(pdu);	return NULL;    }    return pdu;}void smpp_pdu_destroy(SMPP_PDU *pdu){    if (pdu == NULL)    	return;    switch (pdu->type) {    #define OPTIONAL_BEGIN    #define TLV_INTEGER(name, octets) p->name = -1;    #define TLV_NULTERMINATED(name, max_octets) octstr_destroy(p->name);    #define TLV_OCTETS(name, min_len, max_len) octstr_destroy(p->name);    #define OPTIONAL_END    #define INTEGER(name, octets) p->name = 0; /* Make sure "p" is used */    #define NULTERMINATED(name, max_octets) octstr_destroy(p->name);    #define OCTETS(name, field_giving_octets) octstr_destroy(p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while destroying.");    }    gw_free(pdu);}Octstr *smpp_pdu_pack(SMPP_PDU *pdu){    Octstr *os;    Octstr *temp;    os = octstr_create("");    gw_assert(pdu != NULL);    /*     * Fix lengths of octet string fields.     */    switch (pdu->type) {    #define OPTIONAL_BEGIN    #define TLV_INTEGER(name, octets)    #define TLV_NULTERMINATED(name, max_len)    #define TLV_OCTETS(name, min_len, max_len)    #define OPTIONAL_END    #define INTEGER(name, octets) p = *(&p);    #define NULTERMINATED(name, max_octets) p = *(&p);    #define OCTETS(name, field_giving_octets) \    	p->field_giving_octets = octstr_len(p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"    default:    	error(0, "Unknown SMPP_PDU type, internal error while packing.");    }    switch (pdu->type) {    #define TL(name, octets) \        append_encoded_integer(os, SMPP_##name, 2); \        append_encoded_integer(os, octets, 2);    #define OPTIONAL_BEGIN    #define TLV_INTEGER(name, octets) \        if (p->name != -1) { \            TL(name, octets); \            INTEGER(name, octets) \        }    #define TLV_NULTERMINATED(name, max_len) \        if (p->name != NULL) { \            TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name))); \            NULTERMINATED(name, max_len) \        }    #define TLV_OCTETS(name, min_len, max_len) \        if (p->name != NULL) { \            unsigned long len = octstr_len(p->name); \            if (len > max_len || len < min_len) { \                error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \                    #name, len, min_len, max_len);\            } else { \                TL(name, len); \                octstr_append(os, p->name); \            } \        }    #define OPTIONAL_END    #define INTEGER(name, octets) \    	append_encoded_integer(os, p->name, octets);    #define NULTERMINATED(name, max_octets) \        if (p->name != NULL) { \            if (octstr_len(p->name) >= max_octets) { \                warning(0, "SMPP: PDU element <%s> too long " \                        "(length is %ld, should be %d)", \                        #name, octstr_len(p->name), max_octets-1); \                temp = octstr_copy(p->name, 0, max_octets-1); \            } else \                temp = octstr_duplicate(p->name); \            octstr_append(os, temp); \            octstr_destroy(temp); \        } \        octstr_append_char(os, '\0');    #define OCTETS(name, field_giving_octets) \        if (p->name) octstr_append(os, p->name);    #define PDU(name, id, fields) \    	case id: { struct name *p = &pdu->u.name; fields } break;    #include "smpp_pdu.def"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -