Exemple #1
0
/*
 * NB: This data includes bearer information. We use IPv4 values. Address Type
 * is defined in wsp, table 16, p. 65
 */
static Octstr *pack_server_address(void)
{
    Octstr *address,
           *ip_address;
    unsigned char address_len;
    long port;
    int bearer_type;

    bearer_type = GSM_CSD_IPV4;
    port = CONNECTED_PORT;

    mutex_lock(bearerbox->mutex);  
    ip_address = octstr_duplicate(bearerbox->address);
    address_len = octstr_len(bearerbox->address);
    mutex_unlock(bearerbox->mutex);  

    address = octstr_create("");
    octstr_append_char(address, address_len);
    octstr_set_bits(address, 0, 1, 1); /* bearer type included */
    octstr_set_bits(address, 1, 1, 1); /* port number included */
    octstr_append_char(address, bearer_type);
    octstr_append_decimal(address, port);
    octstr_append(address, ip_address);
    octstr_destroy(ip_address);
    
    return address;
}
Exemple #2
0
static void *pgsql_open_conn(const DBConf *db_conf)
{
    PGconn *conn = NULL;
    PgSQLConf *conf = db_conf->pgsql; /* make compiler happy */
    Octstr *tmp, *cs;

    /* sanity check */
    if (conf == NULL)
        return NULL;

    cs = octstr_create("");
    add1(" host=%S", conf->host);
    /* TODO: add hostaddr support via 'host' directive too.
     * This needs an octstr_is_addr(Octstr *os) checking if a given string
     * contains a valid IPv4 address. Obviously parsing on our own via gwlib
     * functions or using regex. If found, insert hostaddr instead of host
     * for the connection string. */
    /* add1(" hostaddr=%S", conf->host); */
    if (conf->port > 0) {   /* add only if user set a value */
        octstr_append_cstr(cs, " port=");    
        octstr_append_decimal(cs, conf->port);
    }
    add1(" user=%S", conf->username);
    add1(" password=%S", conf->password);
    add1(" dbname=%S", conf->database);

#if 0
    /* TODO: This is very bad to show password in the log file */
    info(0, "PGSQL: Using connection string: %s.", octstr_get_cstr(cs));
#endif

    conn = PQconnectdb(octstr_get_cstr(cs));

    octstr_destroy(cs);
    if (conn == NULL)
        goto failed;

    gw_assert(conn != NULL);

    if (PQstatus(conn) == CONNECTION_BAD) {
        error(0, "PGSQL: connection to database '%s' failed!", octstr_get_cstr(conf->database)); 
        panic(0, "PGSQL: %s", PQerrorMessage(conn));
        goto failed;
    }

    info(0, "PGSQL: Connected to server at '%s'.", octstr_get_cstr(conf->host));

    return conn;

failed:
    PQfinish(conn);
    return NULL;
}
Exemple #3
0
static struct cgwop *cgwop_create(int op, int trn)
{
    struct cgwop *ret;
    Octstr *trnstr;

    ret = gw_malloc(sizeof(struct cgwop));

    ret->op = op;
    ret->num_fields = 0;
    ret->trn = trn;

    ret->name = gw_malloc(CGWOP_MAXARGS * sizeof(Octstr *));
    ret->value = gw_malloc(CGWOP_MAXARGS * sizeof(Octstr *));

    if (trn != -1)
    {
        trnstr = octstr_create("");
        octstr_append_decimal(trnstr, trn);
        cgwop_add(ret, octstr_imm("client-id"), trnstr);
        octstr_destroy(trnstr);
    }

    return ret;
}
Exemple #4
0
static Octstr *get_pattern(SMSCConn *conn, Msg *msg, const char *message)
{
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result;
    const char *pattern;
    Octstr *temp, *text, *udh;
    size_t n;
    long i;
 
    text = msg->sms.msgdata ? octstr_duplicate(msg->sms.msgdata) : octstr_create("");
    udh = msg->sms.udhdata ? octstr_duplicate(msg->sms.udhdata) : octstr_create("");
    if ((msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2))
        octstr_binary_to_hex(text, 1);
    else
        octstr_convert_printable(text);
    octstr_binary_to_hex(udh, 1);

    if (octstr_len(text)) {
        word_list = octstr_split_words(text);
        num_words = gwlist_len(word_list);
    } else {
    	word_list = gwlist_create();
        num_words = 0;
    }

    result = octstr_create("");
    pattern = octstr_get_cstr(custom_log_format);

    nextarg = 1;

    while(*pattern != '\0') {
        n = strcspn(pattern, "%");
        octstr_append_data(result, pattern, n);
        pattern += n;
        gw_assert(*pattern == '%' || *pattern == '\0');
        if (*pattern == '\0')
            break;

        pattern++;
        
        switch (*pattern) {
	case 'k':
	    if (num_words <= 0)
                break;
	    octstr_append(result, gwlist_get(word_list, 0));
	    break;

	case 's':
	    if (nextarg >= num_words)
                break;
	    octstr_append(result, gwlist_get(word_list, nextarg));
	    ++nextarg;
	    break;

	case 'S':
	    if (nextarg >= num_words)
                break;
	    temp = gwlist_get(word_list, nextarg);
	    for (i = 0; i < octstr_len(temp); ++i) {
		if (octstr_get_char(temp, i) == '*')
		    octstr_append_char(result, '~');
		else
		    octstr_append_char(result, octstr_get_char(temp, i));
	    }
	    ++nextarg;
	    break;

	case 'r':
	    for (j = nextarg; j < num_words; ++j) {
		if (j != nextarg)
		    octstr_append_char(result, '+');
		octstr_append(result, gwlist_get(word_list, j));
	    }
	    break;
    
	case 'l':
            if (message)
	        octstr_append_cstr(result, message);
	    break;

	case 'P':
            if (msg->sms.receiver)
	        octstr_append(result, msg->sms.receiver);
	    break;

	case 'p':
            if (msg->sms.sender)
	        octstr_append(result, msg->sms.sender);
	    break;

	case 'a':
	    for (j = 0; j < num_words; ++j) {
                if (j > 0)
                    octstr_append_char(result, ' ');
                octstr_append(result, gwlist_get(word_list, j));
            }
            break;

	case 'b':
            if (text)
	        octstr_append(result, text);
	    break;

	case 'L':
	    octstr_append_decimal(result, octstr_len(msg->sms.msgdata));
	    break;

	case 't':
	    tm = gw_gmtime(msg->sms.time);
	    octstr_format_append(result, "%04d-%02d-%02d %02d:%02d:%02d",
				 tm.tm_year + 1900,
				 tm.tm_mon + 1,
				 tm.tm_mday,
				 tm.tm_hour,
				 tm.tm_min,
				 tm.tm_sec);
	    break;

	case 'T':
	    if (msg->sms.time != MSG_PARAM_UNDEFINED)
	        octstr_format_append(result, "%ld", msg->sms.time);
	    break;

	case 'i':
	    if (conn && smscconn_id(conn))
	        octstr_append(result, smscconn_id(conn));
	    else if (conn && smscconn_name(conn))
	        octstr_append(result, smscconn_name(conn));
	    else if (msg->sms.smsc_id)
	        octstr_append(result, msg->sms.smsc_id);
	    break;

	case 'I':
	    if (!uuid_is_null(msg->sms.id)) {
                char id[UUID_STR_LEN + 1];
                uuid_unparse(msg->sms.id, id);
	        octstr_append_cstr(result, id);
            }
	    break;

	case 'n':
	    if (msg->sms.service != NULL)
	        octstr_append(result, msg->sms.service);
	    break;

	case 'd':
	    octstr_append_decimal(result, msg->sms.dlr_mask);
	    break;

	case 'c':
	    octstr_append_decimal(result, msg->sms.coding);
	    break;

	case 'm':
	    octstr_append_decimal(result, msg->sms.mclass);
	    break;

	case 'C':
	    octstr_append_decimal(result, msg->sms.compress);
	    break;

	case 'M':
	    octstr_append_decimal(result, msg->sms.mwi);
	    break;

	case 'u':
	    if (octstr_len(udh)) {
                octstr_append(result, udh);
	    }
	    break;

	case 'U':
	    octstr_append_decimal(result, octstr_len(msg->sms.udhdata));
	    break;

	case 'B':  /* billing identifier/information */
	    if (octstr_len(msg->sms.binfo)) {
                octstr_append(result, msg->sms.binfo);
            }
            break;

	case 'A':  /* account */
	    if (octstr_len(msg->sms.account)) {
                octstr_append(result, msg->sms.account);
            }
            break;

        /* XXX add more here if needed */

	case '%':
	    octstr_format_append(result, "%%");
	    break;

	default:
	    warning(0, "Unknown escape code (%%%c) within custom-log-format, skipping!", *pattern);
            octstr_format_append(result, "%%%c", *pattern);
	    break;
        } /* switch(...) */
    
        pattern++;
    } /* for ... */

    gwlist_destroy(word_list, octstr_destroy_item);

    return result;
}
Exemple #5
0
/******************************************************************************
 * This function handles incoming operations. Used by both receiver and sender
 * threads (i.e. sender thread uses this function for delivery and ack
 * operations).
 * Returns 1 if successfull, otherwise 0
 */
static int cgw_handle_op(SMSCConn *conn, Connection *server, struct cgwop *cgwop)
{
    PrivData *privdata = conn->data;
    Msg *msg = NULL;
    Octstr *from, *app, *sid, *to, *msgtype, *msgdata; /* for messages */
    Octstr *msid, *status, *txt;    		       /* delivery reports */
    Octstr *clid;    		       		       /* for acks */
    struct cgwop *reply = NULL;
    long trn, stat;                          /* transaction number for ack */
    Msg *dlrmsg = NULL, *origmsg = NULL;
    Octstr *ts;

    if (cgwop == NULL) return 0;

    from = cgwop_get(cgwop, octstr_imm("from"));
    app = cgwop_get(cgwop, octstr_imm("app"));
    sid = cgwop_get(cgwop, octstr_imm("session-id"));
    to = cgwop_get(cgwop, octstr_imm("to"));
    msgtype = cgwop_get(cgwop, octstr_imm("type"));
    msgdata = cgwop_get(cgwop, octstr_imm("msg"));
    txt = cgwop_get(cgwop, octstr_imm("txt"));

    msid = cgwop_get(cgwop, octstr_imm("msid"));
    status = cgwop_get(cgwop, octstr_imm("status"));
    clid = cgwop_get(cgwop, octstr_imm("client-id"));

    if (clid != NULL)
    {
        octstr_parse_long(&trn, clid, 0, 10);
        if ((trn < 0) || (trn >= CGW_TRN_MAX)) { /* invalid transaction number */
	    info(0, "cgw: Invalid transaction number: %d", (int) trn);
            trn = -1;            
	    return 0;
        }
    }

    switch (cgwop->op)
    {
    case CGW_OP_MSG:
        msg = msg_create(sms);
        time(&msg->sms.time);
        msg->sms.msgdata = cgw_decode_msg(octstr_duplicate(msgdata));
        msg->sms.sender = octstr_duplicate(from);
        msg->sms.receiver = octstr_duplicate(to);
        msg->sms.smsc_id = octstr_duplicate(conn->id);
        bb_smscconn_receive(conn, msg);

        reply = cgwop_create(CGW_OP_OK, -1);
        cgwop_add(reply, octstr_imm("session-id"), sid);
        cgwop_send(server, reply);     /* send reply */

        cgwop_destroy(reply);

        break;

    case CGW_OP_DELIVERY:
        if (privdata->dlr[trn]) {

            octstr_parse_long(&stat, status, 0, 10);
            origmsg = privdata->sendmsg[trn];

            if (origmsg == NULL) break;

            ts = octstr_create("");
            octstr_append(ts, conn->id);
            octstr_append_char(ts, '-');
            octstr_append_decimal(ts, trn);

            switch (stat) {
            case 0:     /* delivered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_SUCCESS);
                break;
            case 1:     /* buffered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_BUFFERED);
                break;
            case 2:     /* not delivered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_FAIL);
                break;
            }

            octstr_destroy(ts);
            if (dlrmsg != NULL) {
                dlrmsg->sms.msgdata = octstr_duplicate(txt);
                bb_smscconn_receive(conn, dlrmsg);
            }
        }

        break;

    case CGW_OP_OK:
        if (trn == -1) break;     /* invalid transaction number */
        /* info(0, "cgw: Got ACK: %s", octstr_get_cstr(clid)); */

        privdata->sendtime[trn] = 0;
        privdata->unacked--;

        /* add delivery notification request if wanted */

        msg = privdata->sendmsg[trn];

        if (msg && msg->sms.dlr_url && DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {
            Octstr *ts;

            ts = octstr_create("");
            octstr_append(ts, conn->id);
            octstr_append_char(ts, '-');
            octstr_append_decimal(ts, trn);

            dlr_add(conn->id, ts, msg);

            octstr_destroy(ts);
            privdata->dlr[trn] = 1;
        } else {
            privdata->dlr[trn] = 0;
        }

	/* mark as successfully sent */
        bb_smscconn_sent(conn, msg, NULL);

        break;

    case CGW_OP_STATUS:
        info(0, "CGW: Warning: Got session status");
        /* op:status messages are sent by ProviderServer to tell if there are problems with
           the session status. These are not wanted, and should never occur, as the delivery is
           cancelled, and no end-user billing is done. */

        break;


    case CGW_OP_HELLO:
        info(0, "CGW: Server said: %s", octstr_get_cstr(cgwop_get(cgwop, octstr_imm("hello"))));
        break;

    case CGW_OP_ERR:
        if (trn == -1) break;     /* invalid transaction number */

        info(0, "CGW: Received error: %s", octstr_get_cstr(txt));

        privdata->sendtime[trn] = 0;
        privdata->unacked--;

        bb_smscconn_send_failed(conn, privdata->sendmsg[trn],
                            SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));

        break;

    default:
        info(0, "cgw: Unknown operation: %d", cgwop->op);
        return 0;
    }

    return 1;
}
Exemple #6
0
Octstr *urltrans_fill_escape_codes(Octstr *pattern, Msg *request)
{
    Octstr *enc;
    Octstr *meta_group, *meta_param;
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result;
    long pattern_len;
    long pos;
    int c;
    long i, k;
    Octstr *temp;

    result = octstr_create("");

    if (request->sms.msgdata) {
        word_list = octstr_split_words(request->sms.msgdata);
        num_words = gwlist_len(word_list);
    } else {
        word_list = gwlist_create();
        num_words = 0;
    }
    
    pattern_len = octstr_len(pattern);
    nextarg = 1;
    pos = 0;
    for (;;) {
        while (pos < pattern_len) {
            c = octstr_get_char(pattern, pos);
            if (c == '%' && pos + 1 < pattern_len)
                break;
            octstr_append_char(result, c);
            ++pos;
        }

        if (pos == pattern_len)
            break;

    switch (octstr_get_char(pattern, pos + 1)) {
    case 'a':
        for (j = 0; j < num_words; ++j) {
        enc = octstr_duplicate(gwlist_get(word_list, j));
        octstr_url_encode(enc);
        if (j > 0)
            octstr_append_char(result, '+');
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'A':
        if (request->sms.msgdata) {
        enc = octstr_duplicate(request->sms.msgdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'b':
        enc = octstr_duplicate(request->sms.msgdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'B':  /* billing identifier/information */
        if (octstr_len(request->sms.binfo)) {
            enc = octstr_duplicate(request->sms.binfo);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'c':
        octstr_append_decimal(result, request->sms.coding);
        break;

    case 'C':
        if (octstr_len(request->sms.charset)) {
            octstr_append(result, request->sms.charset);
        } else {
            switch (request->sms.coding) {
            case DC_UNDEF:
            case DC_7BIT:
                octstr_append(result, octstr_imm("UTF-8"));
                break;
            case DC_8BIT:
                octstr_append(result, octstr_imm("8-BIT"));
                break;
            case DC_UCS2:
                octstr_append(result, octstr_imm("UTF-16BE"));
                break;
            }
        }
        break;

    case 'd':
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.dlr_mask);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'D': /* meta_data */
        if (octstr_len(request->sms.meta_data)) {
            enc = octstr_duplicate(request->sms.meta_data);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'f':  /* smsc number*/
        if (octstr_len(request->sms.smsc_number)) {
            enc = octstr_duplicate(request->sms.smsc_number);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'F':
        if (request->sms.foreign_id == NULL)
            break;
        enc = octstr_duplicate(request->sms.foreign_id);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'i':
        if (request->sms.smsc_id == NULL)
        break;
        enc = octstr_duplicate(request->sms.smsc_id);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'I':
        if (!uuid_is_null(request->sms.id)) {
                char id[UUID_STR_LEN + 1];
                uuid_unparse(request->sms.id, id);
            octstr_append_cstr(result, id);
            }
        break;

    case 'k':
        if (num_words <= 0)
        break;
        enc = octstr_duplicate(gwlist_get(word_list, 0));
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'm':  /* mclass - message class */
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.mclass);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'M':  /* mwi - message waiting indicator */
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.mwi);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'n':
        if (request->sms.service == NULL)
        break;
        enc = octstr_duplicate(request->sms.service);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'o':  /* account information (may be operator id for aggregators */
        if (octstr_len(request->sms.account)) {
            enc = octstr_duplicate(request->sms.account);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'O':  /* DCS */
    {
        int dcs;
        dcs = fields_to_dcs(request, request->sms.alt_dcs);
        octstr_format_append(result, "%02d", dcs);
        break;
    }

    /* NOTE: the sender and receiver is already switched in
     *    message, so that's why we must use 'sender' when
     *    we want original receiver and vice versa
     */
    case 'P':
        enc = octstr_duplicate(request->sms.sender);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'p':
        enc = octstr_duplicate(request->sms.receiver);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'q':
        if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
        enc = octstr_copy(request->sms.receiver, 2, 
                          octstr_len(request->sms.receiver));
        octstr_url_encode(enc);
        octstr_format_append(result, "%%2B%S", enc);
        octstr_destroy(enc);
        } else {
        enc = octstr_duplicate(request->sms.receiver);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'Q':
        if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
        enc = octstr_copy(request->sms.sender, 2, 
                          octstr_len(request->sms.sender));
        octstr_url_encode(enc);
        octstr_format_append(result, "%%2B%S", enc);
        octstr_destroy(enc);
        } else {
        enc = octstr_duplicate(request->sms.sender);
                octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'r':
        for (j = nextarg; j < num_words; ++j) {
        enc = octstr_duplicate(gwlist_get(word_list, j));
        octstr_url_encode(enc);
        if (j != nextarg)
            octstr_append_char(result, '+');
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'R': /* dlr_url */
        if (octstr_len(request->sms.dlr_url)) {
            enc = octstr_duplicate(request->sms.dlr_url);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 's':
        if (nextarg >= num_words)
        	break;
        enc = octstr_duplicate(gwlist_get(word_list, nextarg));
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        ++nextarg;
        break;

    case 'S':
        if (nextarg >= num_words)
        	break;
        temp = gwlist_get(word_list, nextarg);
        for (i = 0; i < octstr_len(temp); ++i) {
        	if (octstr_get_char(temp, i) == '*')
        		octstr_append_char(result, '~');
        	else
        		octstr_append_char(result, octstr_get_char(temp, i));
        }
        ++nextarg;
        break;

    case 't':
        tm = gw_gmtime(request->sms.time);
        octstr_format_append(result, "%04d-%02d-%02d+%02d:%02d:%02d",
                 tm.tm_year + 1900,
                 tm.tm_mon + 1,
                 tm.tm_mday,
                 tm.tm_hour,
                 tm.tm_min,
                 tm.tm_sec);
        break;

    case 'T':
        if (request->sms.time == MSG_PARAM_UNDEFINED)
        break;
        octstr_format_append(result, "%ld", request->sms.time);
        break;

    case 'u':
        if(octstr_len(request->sms.udhdata)) {
        enc = octstr_duplicate(request->sms.udhdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'v':
        if (request->sms.validity != MSG_PARAM_UNDEFINED) {
            octstr_format_append(result, "%ld", (request->sms.validity - time(NULL)) / 60);
        }
        break;

    case 'V':
        if (request->sms.deferred != MSG_PARAM_UNDEFINED) {
            octstr_format_append(result, "%ld", (request->sms.deferred - time(NULL)) / 60);
        }
        break;
    
    /*
     * This allows to pass meta-data individual parameters into urls.
     * The syntax is as follows: %#group#parameter#
     * For example: %#smpp#my_param# would be replaced with the value
     * 'my_param' from the group 'smpp' coming inside the meta_data field.
     */
    case '#':
        /* ASCII 0x23 == '#' */
        k = octstr_search_char(pattern, 0x23, pos + 2);
        if (k >= 0) {
            pos += 2;
            meta_group = octstr_copy(pattern, pos, (k-pos));
            pos = k + 1;
            k = octstr_search_char(pattern, 0x23, pos);
            if (k >= 0) {
                meta_param = octstr_copy(pattern, pos, (k-pos));
                pos = k - 1;
                if (request->sms.meta_data != NULL) {
                    enc = meta_data_get_value(request->sms.meta_data,
                            octstr_get_cstr(meta_group), meta_param);
                    octstr_url_encode(enc);
                    octstr_append(result, enc);
                    octstr_destroy(enc);
                }
                octstr_destroy(meta_param);
            } else {
                pos++;
            }
            octstr_destroy(meta_group);
        }
        break;

    /* XXX sms.parameters not present in here:
     *   * pid - will we receive this ? 
     *   * alt-dcs - shouldn't be required unless we want to inform 
     *               which alt-dcs external server should use back
     *   * compress - if we use compression, probably kannel would 
     *                decompress and reset this to 0. not required
     *   * rpi - we don't receive these from smsc
     *   * username, password, dlr-url, account - nonsense to send
     */
    case '%':
        octstr_format_append(result, "%%");
        break;

    default:
        octstr_format_append(result, "%%%c",
                             octstr_get_char(pattern, pos + 1));
        break;
    }

    pos += 2;
    }
    
    gwlist_destroy(word_list, octstr_destroy_item);    

    return result;    
}
Exemple #7
0
/*
 * Trans being NULL means that we are servicing ppg (doing dlr, but this does not
 * concern us here).
 */
Octstr *urltrans_get_pattern(URLTranslation *t, Msg *request)
{
    Octstr *enc;
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result, *pattern;
    long pattern_len;
    long pos;
    int c;
    long i;
    Octstr *temp;
    Octstr *url, *reply; /* For and If delivery report */

    url = reply = NULL;
    
    if (request->sms.sms_type != report_mo && t->type == TRANSTYPE_SENDSMS)
        return octstr_create("");

    if (request->sms.msgdata) {
        word_list = octstr_split_words(request->sms.msgdata);
        num_words = list_len(word_list);
    } else {
    	word_list = list_create();
        num_words = 0;
    }

    result = octstr_create("");

    /* check if this is a delivery report message or not */
    if (request->sms.sms_type != report_mo) {
        pattern = t->pattern;
    } else {

        /* this is a DLR message */
        reply = octstr_duplicate(request->sms.msgdata);
        url = octstr_duplicate(request->sms.dlr_url);

        pattern = url;
        if (octstr_len(pattern) == 0) {
            if (t && octstr_len(t->dlr_url)) {
                pattern = t->dlr_url;
            } else {
                list_destroy(word_list, octstr_destroy_item);
                return octstr_create("");
            }
        }
    }

    pattern_len = octstr_len(pattern);
    nextarg = 1;
    pos = 0;
    for (;;) {
        while (pos < pattern_len) {
            c = octstr_get_char(pattern, pos);
            if (c == '%' && pos + 1 < pattern_len)
                break;
            octstr_append_char(result, c);
            ++pos;
        }

        if (pos == pattern_len)
            break;

    switch (octstr_get_char(pattern, pos + 1)) {
	case 'k':
	    if (num_words <= 0)
		break;
	    enc = octstr_duplicate(list_get(word_list, 0));
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 's':
	    if (nextarg >= num_words)
		break;
	    enc = octstr_duplicate(list_get(word_list, nextarg));
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    ++nextarg;
	    break;

	case 'S':
	    if (nextarg >= num_words)
		break;
	    temp = list_get(word_list, nextarg);
	    for (i = 0; i < octstr_len(temp); ++i) {
		if (octstr_get_char(temp, i) == '*')
		    octstr_append_char(result, '~');
		else
		    octstr_append_char(result, octstr_get_char(temp, i));
	    }
	    ++nextarg;
	    break;

	case 'r':
	    for (j = nextarg; j < num_words; ++j) {
		enc = octstr_duplicate(list_get(word_list, j));
		octstr_url_encode(enc);
		if (j != nextarg)
		    octstr_append_char(result, '+');
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;
    
	/* NOTE: the sender and receiver is already switched in
	 *    message, so that's why we must use 'sender' when
	 *    we want original receiver and vice versa
	 */
	case 'P':
	    enc = octstr_duplicate(request->sms.sender);
    	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'p':
	    enc = octstr_duplicate(request->sms.receiver);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'Q':
	    if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
		enc = octstr_copy(request->sms.sender, 2, 
		    	    	  octstr_len(request->sms.sender));
		octstr_url_encode(enc);
		octstr_format_append(result, "%%2B%S", enc);
		octstr_destroy(enc);
	    } else {
		enc = octstr_duplicate(request->sms.sender);
    	    	octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'q':
	    if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
		enc = octstr_copy(request->sms.receiver, 2, 
		    	    	  octstr_len(request->sms.receiver));
		octstr_url_encode(enc);
		octstr_format_append(result, "%%2B%S", enc);
		octstr_destroy(enc);
	    } else {
		enc = octstr_duplicate(request->sms.receiver);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'a':
	    for (j = 0; j < num_words; ++j) {
		enc = octstr_duplicate(list_get(word_list, j));
		octstr_url_encode(enc);
		if (j > 0)
		    octstr_append_char(result, '+');
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'b':
	    enc = octstr_duplicate(request->sms.msgdata);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 't':
	    tm = gw_gmtime(request->sms.time);
	    octstr_format_append(result, "%04d-%02d-%02d+%02d:%02d:%02d",
				 tm.tm_year + 1900,
				 tm.tm_mon + 1,
				 tm.tm_mday,
				 tm.tm_hour,
				 tm.tm_min,
				 tm.tm_sec);
	    break;

	case 'T':
	    if (request->sms.time == MSG_PARAM_UNDEFINED)
		break;
	    octstr_format_append(result, "%ld", request->sms.time);
	    break;

	case 'i':
	    if (request->sms.smsc_id == NULL)
		break;
	    enc = octstr_duplicate(request->sms.smsc_id);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'I':
	    if (!uuid_is_null(request->sms.id)) {
                char id[UUID_STR_LEN + 1];
                uuid_unparse(request->sms.id, id);
	        octstr_append_cstr(result, id);
            }
	    break;

	case 'n':
	    if (request->sms.service == NULL)
		break;
	    enc = octstr_duplicate(request->sms.service);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'd':
	    enc = octstr_create("");
	    octstr_append_decimal(enc, request->sms.dlr_mask);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'A':
	    if (reply) {
		enc = octstr_duplicate(reply);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'c':
	    octstr_append_decimal(result, request->sms.coding);
	    break;

	case 'C':
	    if(octstr_len(request->sms.charset)) {
		octstr_append(result, request->sms.charset);
	    } else {
		switch (request->sms.coding) {
		    case DC_UNDEF:
		    case DC_7BIT:
			octstr_append(result, octstr_imm("ISO-8859-1"));
			break;
		    case DC_8BIT:
			octstr_append(result, octstr_imm("8-BIT"));
			break;
		    case DC_UCS2:
			octstr_append(result, octstr_imm("UTF16-BE"));
			break;
		}
	    }
	    break;

	case 'u':
	    if(octstr_len(request->sms.udhdata)) {
		enc = octstr_duplicate(request->sms.udhdata);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'B':  /* billing identifier/information */
	    if (octstr_len(request->sms.binfo)) {
            enc = octstr_duplicate(request->sms.binfo);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;
	
    case 'o':  /* account information (may be operator id for aggregators */
	    if (octstr_len(request->sms.account)) {
            enc = octstr_duplicate(request->sms.account);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

	/* XXX sms.parameters not present in here:
	 *   * pid - will we receive this ? 
	 *   * mwi,mclass - will we receive these bits from smsc ?
	 *   * alt-dcs - shouldn't be required unless we want to inform 
	 *               which alt-dcs external server should use back
	 *   * compress - if we use compression, probably kannel would 
	 *                decompress and reset this to 0. not required
	 *   * validity, deferred, rpi - we don't receive these from smsc
	 *   * username, password, dlr-url, account - nonsense to send
	 */

	case '%':
	    octstr_format_append(result, "%%");
	    break;

	default:
	    octstr_format_append(result, "%%%c",
	    	    	    	 octstr_get_char(pattern, pos + 1));
	    break;
	}

	pos += 2;
    }
    /*
     * this SHOULD be done in smsbox, not here, but well,
     * much easier to do here
     */
    if (t && (t->type == TRANSTYPE_POST_URL || t->type == TRANSTYPE_POST_XML)
		    && t->strip_keyword)
	strip_keyword(request);

    octstr_destroy(url);
    octstr_destroy(reply);

    list_destroy(word_list, octstr_destroy_item);
    return result;
}