예제 #1
0
파일: brunet.c 프로젝트: tphipps/kannel
/* MT related function */
static int brunet_send_sms(SMSCConn *conn, Msg *sms)
{
    ConnData *conndata = conn->data;
    Octstr *url, *tid, *xser;
    List *headers;
    char id[UUID_STR_LEN + 1];
    int dcs;

    /*
     * Construct TransactionId.
     * Beware that brunet needs an "clean" octstr representation,
     * without the dashes in the string. So remove them.
     */
    uuid_unparse(sms->sms.id, id);
    tid = octstr_create(id);
    octstr_replace(tid, octstr_imm("-"), octstr_imm(""));

    /* form the basic URL */
    url = octstr_format("%S?MsIsdn=%E&Originator=%E",
        conndata->send_url, sms->sms.receiver, sms->sms.sender);

    /*
     * We use &binfo=<foobar> from sendsms interface to encode
     * additional paramters. If a mandatory value is not set,
     * a default value is applied
     */
    if (octstr_len(sms->sms.binfo)) {
        octstr_url_decode(sms->sms.binfo);
        octstr_format_append(url, "&%S", sms->sms.binfo);
    }
    /* CustomerId */
    if (octstr_search(url, octstr_create("CustomerId="), 0) == -1) {
        octstr_format_append(url, "&CustomerId=%S", conndata->username);
    }
    /* TransactionId */
    if (octstr_search(url, octstr_create("TransactionId="), 0) == -1) {
        octstr_format_append(url, "&TransactionId=%S", tid);
    }
    /* SMSCount */
    if (octstr_search(url, octstr_create("SMSCount="), 0) == -1) {
        octstr_format_append(url, "&%s", "SMSCount=1");
    }
    /* ActionType */
    if (octstr_search(url, octstr_create("ActionType="), 0) == -1) {
        octstr_format_append(url, "&%s", "ActionType=A");
    }
    /* ServiceDeliveryType */
    if (octstr_search(url, octstr_create("ServiceDeliveryType="), 0) == -1) {
        octstr_format_append(url, "&%s", "ServiceDeliveryType=P");
    }

    /* if coding is not set and UDH exists, assume DC_8BIT
     * else default to DC_7BIT */
    if (sms->sms.coding == DC_UNDEF)
        sms->sms.coding = octstr_len(sms->sms.udhdata) > 0 ? DC_8BIT : DC_7BIT;

    if (sms->sms.coding == DC_8BIT)
        octstr_format_append(url, "&MessageType=B&Text=%H", sms->sms.msgdata);
    else
        octstr_format_append(url, "&MessageType=S&Text=%E", sms->sms.msgdata);

    dcs = fields_to_dcs(sms,
        (sms->sms.alt_dcs != SMS_PARAM_UNDEFINED ? sms->sms.alt_dcs : 0));

    /* XSer processing */
    xser = octstr_create("");
    /* XSer DCS values */
    if (dcs != 0 && dcs != 4)
        octstr_format_append(xser, "0201%02x", dcs & 0xff);
    /* add UDH header */
    if (octstr_len(sms->sms.udhdata)) {
        octstr_format_append(xser, "01%02x%H", octstr_len(sms->sms.udhdata),
                             sms->sms.udhdata);
    }
    if (octstr_len(xser) > 0)
        octstr_format_append(url, "&XSer=%S", xser);
    octstr_destroy(xser);


    headers = http_create_empty_headers();
    debug("smsc.http.brunet", 0, "HTTP[%s]: Sending request <%s>",
          octstr_get_cstr(conn->id), octstr_get_cstr(url));

    /*
     * Brunet requires an SSL-enabled HTTP client call, this is handled
     * transparently by the Kannel HTTP layer module.
     */
    http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers,
                       NULL, 0, sms, NULL);

    octstr_destroy(url);
    octstr_destroy(tid);
    http_destroy_headers(headers);

    return 0;
}
예제 #2
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;    
}