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

📄 smsc_cimd2.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ====================================================================  * 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.   */ /* Driver for CIMD 2 SMS centres. * Copyright 2000  WapIT Oy Ltd. * Author: Richard Braakman * * Upgrade to SMSCConn API: 2002 Kalle Marjola / 2003 Angel Fradejas *//* TODO: Check checksums on incoming packets *//* TODO: Leading or trailing spaces are not allowed on parameters * "user identity" and "password".  Check this. *//* TODO: Try to use the "More messages to send" flag *//* This code is based on the CIMD 2 spec, version 2-0 en. * All USSD-specific parts have been left out, since we only want to * communicate with SMSC's. * * I found one contradiction in the spec: * * - The definition of Integer parameters specifies decimal digits only, *   but at least one Integer parameter (Validity Period Relative) can *   be negative.  I assume that this means a leading - is valid. */#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  *username;    Octstr  *password;    Octstr  *host;    long    port;    long    our_port;    long    keepalive;    Octstr  *my_number;    int no_dlr;    int     socket;    int     send_seq;    int     receive_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 (60 * 1000000)/* Textual names for the operation codes defined by the CIMD 2 spec. *//* If you make changes here, also change the operation table. */enum {    /* Requests from client */    LOGIN = 1,    LOGOUT = 2,    SUBMIT_MESSAGE = 3,    ENQUIRE_MESSAGE_STATUS = 4,    DELIVERY_REQUEST = 5,    CANCEL_MESSAGE = 6,    SET_REQ = 8,    GET_REQ = 9,    /* Requests from server */    DELIVER_MESSAGE = 20,    DELIVER_STATUS_REPORT = 23,    /* Requests from either */    ALIVE = 40,    /* Not a request; add to any request to make it a response */    RESPONSE = 50,    /* Responses not related to requests */    GENERAL_ERROR_RESPONSE = 98,    NACK = 99};/* Textual names for the parameters defined by the CIMD 2 spec. *//* If you make changes here, also change the parameter table. */enum {    P_USER_IDENTITY = 10,    P_PASSWORD = 11,    P_DESTINATION_ADDRESS = 21,    P_ORIGINATING_ADDRESS = 23,    P_ORIGINATING_IMSI = 26,    P_ALPHANUMERIC_ORIGINATING_ADDRESS = 27,    P_ORIGINATED_VISITED_MSC = 28,    P_DATA_CODING_SCHEME = 30,    P_USER_DATA_HEADER = 32,    P_USER_DATA = 33,    P_USER_DATA_BINARY = 34,    P_MORE_MESSAGES_TO_SEND = 44,    P_VALIDITY_PERIOD_RELATIVE = 50,    P_VALIDITY_PERIOD_ABSOLUTE = 51,    P_PROTOCOL_IDENTIFIER = 52,    P_FIRST_DELIVERY_TIME_RELATIVE = 53,    P_FIRST_DELIVERY_TIME_ABSOLUTE = 54,    P_REPLY_PATH = 55,    P_STATUS_REPORT_REQUEST = 56,    P_CANCEL_ENABLED = 58,    P_CANCEL_MODE = 59,    P_MC_TIMESTAMP = 60,    P_STATUS_CODE = 61,    P_STATUS_ERROR_CODE = 62,    P_DISCHARGE_TIME = 63,    P_TARIFF_CLASS = 64,    P_SERVICE_DESCRIPTION = 65,    P_MESSAGE_COUNT = 66,    P_PRIORITY = 67,    P_DELIVERY_REQUEST_MODE = 68,    P_SERVICE_CENTER_ADDRESS = 69,    P_GET_PARAMETER = 500,    P_MC_TIME = 501,    P_ERROR_CODE = 900,    P_ERROR_TEXT = 901};/***************************************************************************//* Table of properties of the parameters defined by CIMD 2, and some       *//* functions to look up fields.                                            *//***************************************************************************//* Parameter types, internal.  CIMD 2 spec considers P_TIME to be "Integer" * and P_SMS to be "User Data". */enum { P_INT, P_STRING, P_ADDRESS, P_TIME, P_HEX, P_SMS };/* Information about the parameters defined by the CIMD 2 spec. * Used for warning about invalid incoming messages, and for validating * outgoing messages. */static const struct{    unsigned char *name;    int number;    int maxlen;    int type;  /* P_ values */    int minval, maxval;  /* For P_INT */}parameters[] = {    { "user identity", P_USER_IDENTITY, 32, P_STRING },    { "password", P_PASSWORD, 32, P_STRING },    { "destination address", P_DESTINATION_ADDRESS, 20, P_ADDRESS },    { "originating address", P_ORIGINATING_ADDRESS, 20, P_ADDRESS },    /* IMSI is International Mobile Subscriber Identity number */    { "originating IMSI", P_ORIGINATING_IMSI, 20, P_ADDRESS },    { "alphanumeric originating address", P_ALPHANUMERIC_ORIGINATING_ADDRESS, 11, P_STRING },    { "originated visited MSC", P_ORIGINATED_VISITED_MSC, 20, P_ADDRESS },    { "data coding scheme", P_DATA_CODING_SCHEME, 3, P_INT, 0, 255 },    { "user data header", P_USER_DATA_HEADER, 280, P_HEX },    { "user data", P_USER_DATA, 480, P_SMS },    { "user data binary", P_USER_DATA_BINARY, 280, P_HEX },    { "more messages to send", P_MORE_MESSAGES_TO_SEND, 1, P_INT, 0, 1 },    { "validity period relative", P_VALIDITY_PERIOD_RELATIVE, 3, P_INT, -1, 255 },    { "validity period absolute", P_VALIDITY_PERIOD_ABSOLUTE, 12, P_TIME },    { "protocol identifier", P_PROTOCOL_IDENTIFIER, 3, P_INT, 0, 255 },    { "first delivery time relative", P_FIRST_DELIVERY_TIME_RELATIVE, 3, P_INT, -1, 255 },    { "first delivery time absolute", P_FIRST_DELIVERY_TIME_ABSOLUTE, 12, P_TIME },    { "reply path", P_REPLY_PATH, 1, P_INT, 0, 1 },    { "status report request", P_STATUS_REPORT_REQUEST, 2, P_INT, 0, 63 },    { "cancel enabled", P_CANCEL_ENABLED, 1, P_INT, 0, 1 },    { "cancel mode", P_CANCEL_MODE, 1, P_INT, 0, 2 },    { "service centre timestamp", P_MC_TIMESTAMP, 12, P_TIME },    { "status code", P_STATUS_CODE, 2, P_INT, 0, 9 },    { "status error code", P_STATUS_ERROR_CODE, 3, P_INT, 0, 999 },    { "discharge time", P_DISCHARGE_TIME, 12, P_TIME },    { "tariff class", P_TARIFF_CLASS, 2, P_INT, 0, 99 },    { "service description", P_SERVICE_DESCRIPTION, 2, P_INT, 0, 9 },    { "message count", P_MESSAGE_COUNT, 3, P_INT, 0, 999 },    { "priority", P_PRIORITY, 1, P_INT, 1, 9 },    { "delivery request mode", P_DELIVERY_REQUEST_MODE, 1, P_INT, 0, 2 },    { "service center address", P_SERVICE_CENTER_ADDRESS, 20, P_ADDRESS },    { "get parameter", P_GET_PARAMETER, 3, P_INT, 501, 999 },    { "MC time", P_MC_TIME, 12, P_TIME },    { "error code", P_ERROR_CODE, 3, P_INT, 0, 999 },    { "error text", P_ERROR_TEXT, 64, P_STRING },    { NULL }};/* Return the index in the parameters array for this parameter id. * Return -1 if it is not found. */static const int parm_index(int parmno){    int i;    for (i = 0; parameters[i].name != NULL; i++) {        if (parameters[i].number == parmno)            return i;    }    return -1;}#ifndef NO_GWASSERT/* Return the type of this parameter id.  Return -1 if the id is unknown. */static const int parm_type(int parmno){    int i = parm_index(parmno);    if (i < 0)        return -1;    return parameters[i].type;}#endif/* Return the max length for this parameter id. * Return -1 if the id is unknown. */static const int parm_maxlen(int parmno){    int i = parm_index(parmno);    if (i < 0)        return -1;    return parameters[i].maxlen;}static const char *parm_name(int parmno){    int i = parm_index(parmno);    if (i < 0)        return NULL;    return parameters[i].name;}#ifndef NO_GWASSERT/* Return 1 if the value for this (Integer) parameter is in range. * Return 0 otherwise.  Return -1 if the parameter was not found.  */static const int parm_in_range(int parmno, long value){    int i;    i = parm_index(parmno);    if (i < 0)        return -1;    return (value >= parameters[i].minval && value <= parameters[i].maxval);}#endif/* Helper function to check P_ADDRESS type */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[] = {    { "Login", LOGIN, 1, 0 },    { "Logout", LOGOUT, 1, 0 },    { "Submit message", SUBMIT_MESSAGE, 1, 0 },    { "Enquire message status", ENQUIRE_MESSAGE_STATUS, 1, 0 },    { "Delivery request", DELIVERY_REQUEST, 1, 0 },    { "Cancel message", CANCEL_MESSAGE, 1, 0 },    { "Set parameter", SET_REQ, 1, 0 },    { "Get parameter", GET_REQ, 1, 0 },    { "Deliver message", DELIVER_MESSAGE, 0, 1 },    { "Deliver status report", DELIVER_STATUS_REPORT, 0, 1 },    { "Alive", ALIVE, 1, 1 },    { "NACK", NACK, 1, 1 },    { "General error response", GENERAL_ERROR_RESPONSE, 0, 1 },    { 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);

⌨️ 快捷键说明

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