/* 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; }
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; }