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

📄 smsc_emi_x25.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ====================================================================  * 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_emi.c - implement interface to the CMG SMS Center (UCP/EMI).* Mikael Gueck for WapIT Ltd.*//* This file implements two smsc interfaces: EMI_X25 */#include <errno.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/param.h>#include <sys/ioctl.h>#include "gwlib/gwlib.h"#include "smsc.h"#include "smsc_p.h"#include "alt_charsets.h"#include "sms.h"#ifndef CRTSCTS#define CRTSCTS 0#endif/******************************************************************************* Static functions*/static int get_data(SMSCenter *smsc, char *buff, int length);static int put_data(SMSCenter *smsc, char *buff, int length, int is_backup);static int memorybuffer_append_data(SMSCenter *smsc, char *buff, int length);static int memorybuffer_insert_data(SMSCenter *smsc, char *buff, int length);static int memorybuffer_has_rawmessage(SMSCenter *smsc, int type, char auth);static int memorybuffer_cut_rawmessage(SMSCenter *smsc, char *buff, int length);static int parse_rawmessage_to_msg(SMSCenter *smsc, Msg **msg,                                   char *rawmessage, int length);static int parse_msg_to_rawmessage(SMSCenter *smsc, Msg *msg,                                   char *rawmessage, int length);static int acknowledge_from_rawmessage(SMSCenter *smsc,                                   char *rawmessage, int length);static int parse_emi_to_iso88591(char *from, char *to,                                 int length, int alt_charset);static int parse_iso88591_to_emi(char *from, char *to,                                 int length, int alt_charset);static int parse_binary_to_emi(char *from, char *to, int length);static int at_dial(char *device, char *phonenum,                   char *at_prefix, time_t how_long);static int guarantee_link(SMSCenter *smsc);static void generate_checksum(const unsigned char *buffer,                              unsigned char *checksum_out);static int wait_for_ack(SMSCenter *smsc, int op_type);static char char_iso_to_sms(unsigned char from, int alt_charset);static char char_sms_to_iso(unsigned char from, int alt_charset);/******************************************************************************* Open the connection and log in - handshake baby*/static int emi_open_connection(SMSCenter *smsc){    char tmpbuff[1024];    sprintf(tmpbuff, "/dev/%s", smsc->emi_serialdevice);    smsc->emi_fd = at_dial(tmpbuff, smsc->emi_phonenum, "ATD", 30);    if (smsc->emi_fd <= 0)        return -1;    return 0;}/* open EMI smscenter */SMSCenter *emi_open(char *phonenum, char *serialdevice, char *username, char *password){    SMSCenter *smsc;    smsc = smscenter_construct();    if (smsc == NULL)        goto error;    smsc->type = SMSC_TYPE_EMI_X25;    smsc->emi_phonenum = gw_strdup(phonenum);    smsc->emi_serialdevice = gw_strdup(serialdevice);    smsc->emi_username = gw_strdup(username);    smsc->emi_password = gw_strdup(password);    smsc->emi_current_msg_number = 0;    if (emi_open_connection(smsc) < 0)        goto error;    sprintf(smsc->name, "EMI:%s:%s", smsc->emi_phonenum,            smsc->emi_username);    return smsc;error:    error(0, "emi_open failed");    smscenter_destruct(smsc);    return NULL;}int emi_reopen(SMSCenter *smsc){    emi_close(smsc);    if (emi_open_connection(smsc) < 0) {        error(0, "emi_reopen failed");        return -1;    }    return 0;}int emi_close(SMSCenter *smsc){    return emi_close_ip(smsc);}static int emi_fill_ucp60_login(char *buf, char *OAdC, char *passwd) {    int max_ia5passwd_len;    char *ia5passwd;    max_ia5passwd_len = strlen(passwd) * 2 + 1;    ia5passwd = gw_malloc(max_ia5passwd_len);    if (parse_binary_to_emi(passwd, ia5passwd, strlen(passwd)) < 0) {        error(0, "parse_binary_to_emi failed");        gw_free(ia5passwd);        return -1;    }    sprintf(buf, "%s/%c/%c/%c/%s//%s/////",	    OAdC,      /* OAdC: Address code originator */	    '6',       /* OTON: 6 = Abbreviated number (short number alias) */	    '5',       /* ONPI: 5 = Private (TCP/IP address/abbreviated number address) */	    '1',       /* STYP: 1 = open session */	    ia5passwd, /* PWD:  Current password encoded into IA5 characters */	    "0100"     /* VERS: Version number  0100 */	    );    gw_free(ia5passwd);    return 0;}static int emi_open_session(SMSCenter *smsc){    char message_whole  [1024];    char message_body   [1024];    char message_header [50];    char message_footer [10];    char my_buffer      [1024];    int length;    memset(message_whole,  0, sizeof(message_whole));    memset(message_body,   0, sizeof(message_body));    memset(message_header, 0, sizeof(message_header));    memset(message_footer, 0, sizeof(message_footer));    if (emi_fill_ucp60_login(message_body, smsc->emi_username, smsc->emi_password) < 0) {        error(0, "emi_fill_ucp60_login failed");        return -1;    }    length = strlen(message_body);    length += 13;  /* header (fixed) */    length += 2;   /* footer (fixed) */    length += 2;   /* slashes between header, body, footer */    sprintf(message_header, "%02i/%05i/O/60",            (smsc->emi_current_msg_number++ % 100), length);        /* FOOTER */    sprintf(my_buffer, "%s/%s/", message_header, message_body);    generate_checksum(my_buffer, message_footer);    sprintf(message_whole, "\x02%s/%s/%s\x03", message_header,            message_body, message_footer);    debug("bb.sms.emi", 0, "final UCP60 msg: <%s>", message_whole);    put_data(smsc, message_whole, strlen(message_whole), 0);    if (!wait_for_ack(smsc, 60)) {	info(0, "emi_open_session: wait for ack failed!");	return -1;    }    return 0;}/******************************************************* * the actual protocol open... quite simple here */static int emi_open_connection_ip(SMSCenter *smsc){    smsc->emi_fd =        tcpip_connect_to_server_with_port(smsc->emi_hostname,                                          smsc->emi_port, smsc->emi_our_port,					  NULL);	    /* XXX add interface_name if required */    if (smsc->emi_fd < 0)        return -1;    if (smsc->emi_username && smsc->emi_password) {	return emi_open_session(smsc);    }        return 0;}int emi_reopen_ip(SMSCenter *smsc){    emi_close_ip(smsc);    return emi_open_connection_ip(smsc);}int emi_close_ip(SMSCenter *smsc){    if (smsc->emi_fd == -1) {        info(0, "Trying to close already closed EMI, ignoring");        return 0;    }    close(smsc->emi_fd);    smsc->emi_fd = -1;    return 0;}/******************************************************************************* Check if the buffers contain any messages*/int emi_pending_smsmessage(SMSCenter *smsc){    char *tmpbuff;    int n = 0;    /*	time_t timenow; */    /* Block until we have a connection */    guarantee_link(smsc);    /* If we have MO-message, then act (return 1) */    if (memorybuffer_has_rawmessage(smsc, 52, 'O') > 0 ||        memorybuffer_has_rawmessage(smsc, 1, 'O') > 0 )        return 1;    tmpbuff = gw_malloc(10 * 1024);    memset(tmpbuff, 0, 10*1024);    /* check for data */    n = get_data(smsc, tmpbuff, 10 * 1024);    if (n > 0)        memorybuffer_insert_data(smsc, tmpbuff, n);    /* delete all ACKs/NACKs/whatever */    while (memorybuffer_has_rawmessage(smsc, 51, 'R') > 0 ||           memorybuffer_has_rawmessage(smsc, 1, 'R') > 0)        memorybuffer_cut_rawmessage(smsc, tmpbuff, 10*1024);    gw_free(tmpbuff);    /* If we have MO-message, then act (return 1) */    if (memorybuffer_has_rawmessage(smsc, 52, 'O') > 0 ||        memorybuffer_has_rawmessage(smsc, 1, 'O') > 0)        return 1;    /*    	time(&timenow);    	if( (smsc->emi_last_spoke + 60*20) < timenow) {    		time(&smsc->emi_last_spoke);    	}    */    return 0;}/****************************************************************************** * Submit (send) a Mobile Terminated message to the EMI server */int emi_submit_msg(SMSCenter *smsc, Msg *omsg){    char *tmpbuff = NULL;    if (smsc == NULL) goto error;    if (omsg == NULL) goto error;    tmpbuff = gw_malloc(10 * 1024);    memset(tmpbuff, 0, 10*1024);    if (parse_msg_to_rawmessage(smsc, omsg, tmpbuff, 10*1024) < 1)        goto error;    if (put_data(smsc, tmpbuff, strlen(tmpbuff), 0) < 0) {        info(0, "put_data failed!");        goto error;    }    wait_for_ack(smsc, 51);    /*	smsc->emi_current_msg_number += 1; */    debug("bb.sms.emi", 0, "Submit Ok...");    gw_free(tmpbuff);    return 0;error:    debug("bb.sms.emi", 0, "Submit Error...");    gw_free(tmpbuff);    return -1;}/******************************************************************************* Receive a Mobile Terminated message to the EMI server*/int emi_receive_msg(SMSCenter *smsc, Msg **tmsg){    char *tmpbuff;    Msg *msg = NULL;    *tmsg = NULL;    tmpbuff = gw_malloc(10 * 1024);    memset(tmpbuff, 0, 10*1024);    /* get and delete message from buffer */    memorybuffer_cut_rawmessage(smsc, tmpbuff, 10*1024);    parse_rawmessage_to_msg(smsc, &msg, tmpbuff, strlen(tmpbuff));    /* yeah yeah, I got the message... */    acknowledge_from_rawmessage(smsc, tmpbuff, strlen(tmpbuff));    /* return with the joyful news */    gw_free(tmpbuff);    if (msg == NULL) goto error;    *tmsg = msg;    return 1;error:    gw_free(tmpbuff);    msg_destroy(msg);    return -1;}/******************************************************************************* Internal functions*//******************************************************************************* Guarantee that we have a link*/static int guarantee_link(SMSCenter *smsc){    int need_to_connect = 0;    /* If something is obviously wrong. */    if (strstr(smsc->buffer, "OK")) need_to_connect = 1;

⌨️ 快捷键说明

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