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

📄 smsc_oisd.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ====================================================================  * 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.   */ /* * smsc.oisd.c - Driver for Sema Group SMS Center G8.1 (OIS 5.8) * using direct TCP/IP access interface * * Dariusz Markowicz <dm@tenbit.pl> 2002-2004 * * This code is based on the CIMD2 module design. * * References: * *   [1] Sema SMSC Version G8.1 Open Interface Specification *       document version 5.8, 18 January 2001, Sema Telecoms. */#include <ctype.h>#include <time.h>#include <errno.h>#include <limits.h>#include <string.h>#include <unistd.h>#include "gwlib/gwlib.h"#include "smscconn.h"#include "smscconn_p.h"#include "bb_smscconn_cb.h"#include "shared.h"#include "sms.h"#include "dlr.h"typedef struct privdata {    Octstr  *host;    long    port;    long    keepalive;    Octstr  *my_number;    long    validityperiod;    int     no_dlr;    int     socket;    unsigned long send_seq;    Octstr  *inbuffer;    List    *received;    time_t  next_ping;    List *outgoing_queue;    SMSCConn *conn;    int io_thread;    int quitting;    List *stopped; /* list-trick for suspend/isolate */} PrivData;/* Microseconds before giving up on a request */#define RESPONSE_TIMEOUT (10 * 1000000)#define RESULT_SUCCESS 0enum {    INVOKE = 0,    RESULT = 1};/* Textual names for the operation codes defined by the OISD spec. *//* If you make changes here, also change the operation table. */enum {    SUBMIT_SM = 0,    STATUS_REPORT = 4,    DELIVER_SM = 9,    RETRIEVE_REQUEST = 11,    /* Not a request; add to any request to make it a response */    RESPONSE = 50};static int isphonedigit(int c){    return isdigit(c) || c == '+' || c == '-';}static const int parm_valid_address(Octstr *value){    return octstr_check_range(value, 0, octstr_len(value), isphonedigit);}/***************************************************************************//* Some functions to look up information about operation codes             *//***************************************************************************/static int operation_find(int operation);static Octstr *operation_name(int operation);static const int operation_can_send(int operation);static const int operation_can_receive(int operation);static const struct{    unsigned char *name;    int code;    int can_send;    int can_receive;}operations[] = {    { "Submit SM", SUBMIT_SM, 1, 0 },    { "Status Report", STATUS_REPORT, 0, 1 },    { "Deliver SM", DELIVER_SM, 0, 1 },    { "Retrieve Request", RETRIEVE_REQUEST, 1, 0 },    { NULL, 0, 0, 0 }};static int operation_find(int operation){    int i;    for (i = 0; operations[i].name != NULL; i++) {        if (operations[i].code == operation)            return i;    }    return -1;}/* Return a human-readable representation of this operation code */static Octstr *operation_name(int operation){    int i;    i = operation_find(operation);    if (i >= 0)        return octstr_create(operations[i].name);    if (operation >= RESPONSE) {        i = operation_find(operation - RESPONSE);        if (i >= 0) {            Octstr *name = octstr_create(operations[i].name);            octstr_append_cstr(name, " response");            return name;        }    }    /* Put the operation number here when we have octstr_format */    return octstr_create("(unknown)");}/* Return true if a OISD client may send this operation */static const int operation_can_send(int operation){    int i = operation_find(operation);    if (i >= 0)        return operations[i].can_send;    /* If we can receive the request, then we can send the response. */    if (operation >= RESPONSE)        return operation_can_receive(operation - RESPONSE);    return 0;}/* Return true if a OISD server may send this operation */static const int operation_can_receive(int operation){    int i = operation_find(operation);    if (i >= 0)        return operations[i].can_receive;    /* If we can send the request, then we can receive the response. */    if (operation >= RESPONSE)        return operation_can_send(operation - RESPONSE);    return 0;}/*************************************************************************** * Packet encoding/decoding functions.  They handle packets at the octet   * * level, and know nothing of the network.                                 * ***************************************************************************/struct packet{    unsigned long opref; /* operation reference */    int operation;    Octstr *data;        /* Encoded packet */};/* A reminder that packets are created without a valid sequence number */#define BOGUS_SEQUENCE 0static Msg *oisd_accept_delivery_report_message(struct packet *request,                                                SMSCConn *conn);static void packet_parse_header(struct packet *packet){    packet->opref = (octstr_get_char(packet->data, 3) << 24)                  | (octstr_get_char(packet->data, 2) << 16)                  | (octstr_get_char(packet->data, 1) << 8)                  | (octstr_get_char(packet->data, 0));    packet->operation = octstr_get_char(packet->data, 5);    if (octstr_get_char(packet->data, 4) == 1)        packet->operation += RESPONSE;}/* * Accept an Octstr containing one packet, build a struct packet around * it, and return that struct.  The Octstr is stored in the struct. * No error checking is done here yet. */static struct packet *packet_parse(Octstr *packet_data){    struct packet *packet;    packet = gw_malloc(sizeof(*packet));    packet->data = packet_data;    /* Fill in packet->operation and packet->opref */    packet_parse_header(packet);    return packet;}/* Deallocate this packet */static void packet_destroy(struct packet *packet){    if (packet != NULL) {        octstr_destroy(packet->data);        gw_free(packet);    }}/* * Find the first packet in "in", delete it from "in", and return it as * a struct.  Return NULL if "in" contains no packet.  Always delete * leading non-packet data from "in". */static struct packet *packet_extract(Octstr *in, SMSCConn *conn){    Octstr *packet;    int size, i;    static char s[4][4] = {        { 0x01, 0x0b, 0x00, 0x00 },        { 0x01, 0x00, 0x00, 0x00 },        { 0x00, 0x04, 0x00, 0x00 },        { 0x00, 0x09, 0x00, 0x00 }    }; /* msgtype, oper, 0, 0 */    char known_bytes[4];    if (octstr_len(in) < 10)        return NULL;    octstr_get_many_chars(known_bytes, in, 4, 4);    /* Find s, and delete everything up to it. */    /* If packet starts with one of s, it should be good packet */    for (i = 0; i < 4; i++) {        if (memcmp(s[i], known_bytes, 4) == 0)            break;    }    if (i >= 4) {        error(0, "OISD[%s]: wrong packet",              octstr_get_cstr(conn->id));        octstr_dump(in, 0);        return NULL;    }    /* Find end of packet */    size = (octstr_get_char(in, 9) << 8) | octstr_get_char(in, 8);    if (size + 10 > octstr_len(in))        return NULL;    packet = octstr_copy(in, 0, size + 10);    octstr_delete(in, 0, size + 10);    return packet_parse(packet);}static void packet_check_can_receive(struct packet *packet, SMSCConn *conn){    gw_assert(packet != NULL);    if (!operation_can_receive(packet->operation)) {        Octstr *name = operation_name(packet->operation);        warning(0, "OISD[%s]: SMSC sent us %s request",                octstr_get_cstr(conn->id),                octstr_get_cstr(name));        octstr_destroy(name);    }}static int oisd_expand_gsm7_to_bits(char *bits, Octstr *raw7){    int i, j, k;    int len;    char ch;    len = octstr_len(raw7) * 7; /* number of bits in the gsm 7-bit msg */    for (j = i = 0; j < len; ++i) {        ch = octstr_get_char(raw7, i);        for (k = 0; k < 8; ++k) {            bits[j++] = (char) (ch & 0x01);            ch >>= 1;        }    }    return j;}static char oisd_expand_gsm7_from_bits(const char *bits, int pos){    int i;    char ch;    pos *= 7; /* septet position in bits */    ch = '\0';    for (i = 6; i >= 0; --i) {        ch <<= 1;        ch |= bits[pos + i];    }    return ch;}static Octstr *oisd_expand_gsm7(Octstr *raw7){    Octstr *raw8;    int i, len;    char *bits;    raw8 = octstr_create("");    bits = gw_malloc(8 * octstr_len(raw7) + 1);    oisd_expand_gsm7_to_bits(bits, raw7);    len = octstr_len(raw7);    for (i = 0; i < len; ++i) {

⌨️ 快捷键说明

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