?? smsc_cimd.c
字號:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2005 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_cimd.c - Nokia SMS Center (CIMD 1.3).* Mikael Gueck for WapIT Ltd.*/#include <errno.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <time.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include "smsc.h"#include "smsc_p.h"#include "gwlib/gwlib.h"#include "alt_charsets.h"/******************************************************************************* Static functions*//* do the handshake baby */static int cimd_open_connection(SMSCenter *smsc);/* waits for an ACK message, returns the ACK command number or -1 for error */static int expect_acknowledge(SMSCenter *smsc, int *cmd, int *err);/* sends a general ACK */static int send_acknowledge(SMSCenter *smsc);/* Reconnect to a CIMD server, use an existing structure */static int connect_tcpip(SMSCenter *smsc);static int parse_cimd_to_iso88591(char *from, char *to, int length);static int parse_iso88591_to_cimd( char *from, char *to, int length, int alt_charset);/******************************************************************************* Open the connection and log in** return 0 if ok, -1 on failure*/static int cimd_open_connection(SMSCenter *smsc){ char *tmpbuff = NULL; int ret = 0; int cmd = 0, err = 0; /* allocate some spare space */ tmpbuff = gw_malloc(10 * 1024); memset(tmpbuff, 0, 10*1024); /* connect */ smsc->socket = tcpip_connect_to_server(smsc->cimd_hostname, smsc->cimd_port, NULL); /* XXX add interface_name if required */ if (smsc->socket == -1) goto error; /* receive protocol string "CIMD rel 1.37\n" */ for (;;) { ret = smscenter_read_into_buffer(smsc); if (strstr(smsc->buffer, "CIMD rel 1.37\n") != NULL) break; if (ret < 0) goto logout; } debug("bb.sms.cimd", 0, "got the server identification tag"); smscenter_remove_from_buffer(smsc, smsc->buflen); /* send login string */ sprintf(tmpbuff, "%c%s%c%s%c%s%c%s%c%c", 0x02, "01", 0x09, smsc->cimd_username, 0x09, smsc->cimd_password, 0x09, "11", 0x03, 0x0A); ret = write_to_socket(smsc->socket, tmpbuff); if (ret < 0) goto logout; /* get an acknowledge message */ smsc->cimd_last_spoke = 0; if (expect_acknowledge(smsc, &cmd, &err) < 1) goto logout; debug("bb.sms.cimd", 0, "logged in"); gw_free(tmpbuff); return 0;logout: cimd_close(smsc);error: error(0, "cimd_open: could not open/handshake"); gw_free(tmpbuff); return -1;}/******************************************************************************* Open the smscenter*/SMSCenter *cimd_open(char *hostname, int port, char *username, char *password){ SMSCenter *smsc = NULL; int ret = 0; /* create a SMSCenter structure */ smsc = smscenter_construct(); if (smsc == NULL) goto error; smsc->type = SMSC_TYPE_CIMD; smsc->cimd_hostname = gw_strdup(hostname); smsc->hostname = gw_strdup(hostname); /* Needed by read_into_buffer() */ smsc->cimd_port = port; smsc->cimd_username = gw_strdup(username); smsc->cimd_password = gw_strdup(password); ret = cimd_open_connection(smsc); if (ret < 0) goto error; sprintf(smsc->name, "CIMD:%s:%d:%s", smsc->cimd_hostname, smsc->cimd_port, smsc->cimd_username); return smsc;error: error(0, "cimd_open: could not open!"); smscenter_destruct(smsc); return NULL;}/******************************************************************************* Re-open the connection and log in** return -1 if failed*/int cimd_reopen(SMSCenter *smsc){ cimd_close(smsc); if (cimd_open_connection(smsc) < 0) { error(0, "Failed to re-open the connection!"); return -1; } return 0;}/******************************************************************************* Log out and close the socket**/int cimd_close(SMSCenter *smsc){ char *cbuff = NULL; int sum; int ret; if (smsc->socket == -1) { debug("bb.sms.cimd", 0, "Trying to close cimd while already closed!"); return 0; } cbuff = gw_malloc(2 * 1024); sprintf(cbuff, "%c%s%c%s%c%c", 0x02, "02", 0x09, "11", 0x03, 0x0A); sum = write_to_socket(smsc->socket, cbuff); if (sum < 0) goto error; /* this time we don't block waiting for acknowledge */ recv(smsc->socket, cbuff, 2*1024, 0); gw_free(cbuff); ret = close(smsc->socket); smsc->socket = -1; return ret;error: gw_free(cbuff); return -1;}/******************************************************************************* Check for MO messages, returns as in smsc_submit_smsmessage in smsc.h*/int cimd_pending_smsmessage(SMSCenter *smsc){ char *tmpbuff = NULL, *newline = NULL; int ret = 0; time_t thetime = 0; /* check for input sanity */ if (smsc == NULL) goto error; /* we can only query every 5 seconds */ thetime = time(NULL); if ((smsc->cimd_last_spoke + 5) > thetime) goto no_messages; smsc->cimd_last_spoke = thetime; /* allocate some spare space */ tmpbuff = gw_malloc(10 * 1024); memset(tmpbuff, 0, 10*1024); sprintf(tmpbuff, "%c%s%c%s%c%c", 0x02, /* stx */ "05", 0x09, /* request for message, tab */ "11", /* dummy chksum */ 0x03, 0x0A); /* etx, lf */ /* send the poll message to determine if we have messages in queue */ ret = write_to_socket(smsc->socket, tmpbuff); if (ret < 0) { debug("bb.sms.cimd", 0, "sending poll message failed"); goto error; } /* block while waiting for answer that dataset ends to a 0x0A */ for (;;) { newline = memchr(smsc->buffer, 0x0A, smsc->buflen); if (newline != NULL) break; newline = memchr(smsc->buffer, 0x03, smsc->buflen); if (newline != NULL) break; ret = smscenter_read_into_buffer(smsc); if (ret <= 0) { debug("bb.sms.cimd", 0, "read_into_buffer failed!, ret=%d", ret); goto error; } usleep(500); /* Reconnect if no results in 30 seconds */ if (time(NULL) > (thetime + 30)) { error(0, "timeout occurred, maybe the connection was broken?"); /* Reconnect if neccessary, this catches most of them */ /* XXX this is an ugly kludge, but then again, CIMD 1.3 is an ugly kludge. */ connect_tcpip(smsc); goto no_messages; } } /* if we got an nck, cut the message out and return 0 */ newline = memchr(smsc->buffer, 0x15, smsc->buflen); if (newline != NULL) { newline = memchr(smsc->buffer, 0x0A, smsc->buflen); if (newline == NULL) newline = memchr(smsc->buffer, 0x03, smsc->buflen); smscenter_remove_from_buffer(smsc, newline - smsc->buffer + 1); goto no_messages; } /* miracle of miracles, we got a message */ gw_free(tmpbuff); return 1;no_messages: gw_free(tmpbuff); return 0;error: debug("bb.sms.cimd", 0, "smscenter_pending_smsmessage: returning error"); gw_free(tmpbuff); return -1;}/******************************************************************************* Send a MT message, returns as in smsc_submit_smsmessage in smsc.h*/int cimd_submit_msg(SMSCenter *smsc, Msg *msg){ char *tmpbuff = NULL, *tmptext = NULL; char msgtext[1024]; int ret; int cmd = 0, err = 0; /* Fix these by implementing a could-not-send-because- protocol-does-not-allow in smsc.c or smsgateway.c */ if (octstr_len(msg->sms.msgdata) + octstr_len(msg->sms.udhdata) < 1) { if (msg->sms.msgdata == NULL) msg->sms.msgdata = octstr_create(""); octstr_append_from_hex(msg->sms.msgdata, "20"); } if (octstr_len(msg->sms.sender) < 1) { warning(0, "cimd_submit_smsmessage: ignoring message with 0-length field"); goto okay; /* THIS IS NOT OKAY!!!! XXX */ } if (octstr_len(msg->sms.receiver) < 1) { warning(0, "cimd_submit_smsmessage: ignoring message with 0-length field"); goto okay; /* THIS IS NOT OKAY!!!! XXX */ } tmpbuff = gw_malloc(10 * 1024); tmptext = gw_malloc(10 * 1024); memset(tmpbuff, 0, 10*1024); memset(tmptext, 0, 10*1024); memset(msgtext, 0, sizeof(msgtext)); if (octstr_len(msg->sms.udhdata)) { octstr_get_many_chars(msgtext, msg->sms.udhdata, 0, octstr_len(msg->sms.udhdata)); octstr_get_many_chars(msgtext + octstr_len(msg->sms.udhdata), msg->sms.msgdata, 0,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -