📄 smsc_http.c
字号:
octstr_format_append(url, "&type=200&dcs=%d&esm=%d&message=%H", dcs, esm_class, new_msg); } else { /* additions for text (7bit) msgs */ octstr_format_append(url, "&type=%E&message=%E", (sms->sms.mclass ? octstr_imm("1") : octstr_imm("0")), sms->sms.msgdata); } /* * We use &account=<foobar> from sendsms interface to encode any additionaly * proxied parameters, ie. billing information. */ if (octstr_len(sms->sms.account)) { octstr_url_decode(sms->sms.account); octstr_format_append(url, "&%s", octstr_get_cstr(sms->sms.account)); } headers = list_create(); debug("smsc.http.xidris", 0, "HTTP[%s]: Sending request <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(url)); http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, NULL, 0, sms, NULL); octstr_destroy(url); octstr_destroy(new_msg); http_destroy_headers(headers);}/* * Parse for an parameter of an given XML tag and return it as Octstr */static Octstr *parse_xml_tag(Octstr *body, Octstr *tag){ Octstr *stag, *etag, *ret; int spos, epos; stag = octstr_format("<%s>", octstr_get_cstr(tag)); if ((spos = octstr_search(body, stag, 0)) == -1) { octstr_destroy(stag); return NULL; } etag = octstr_format("</%s>", octstr_get_cstr(tag)); if ((epos = octstr_search(body, etag, spos+octstr_len(stag))) == -1) { octstr_destroy(stag); octstr_destroy(etag); return NULL; } ret = octstr_copy(body, spos+octstr_len(stag), epos+1 - (spos+octstr_len(etag))); octstr_strip_blanks(ret); octstr_strip_crlfs(ret); octstr_destroy(stag); octstr_destroy(etag); return ret;}static void xidris_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body){ Octstr *code, *desc; if (status == HTTP_OK || status == HTTP_ACCEPTED) { /* now parse the XML document for error code */ code = parse_xml_tag(body, octstr_imm("status")); desc = parse_xml_tag(body, octstr_imm("description")); if (octstr_case_compare(code, octstr_imm("0")) == 0) { bb_smscconn_sent(conn, msg, NULL); } else { error(0, "HTTP[%s]: Message not accepted. Status code <%s> " "description `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(code), octstr_get_cstr(desc)); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(desc)); } } else { error(0, "HTTP[%s]: Message was rejected. SMSC reponse was:", octstr_get_cstr(conn->id)); octstr_dump(body, 0); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED")); }}/* MO related function */static void xidris_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars){ ConnData *conndata = conn->data; Octstr *user, *pass, *from, *to, *text, *account, *binfo; Octstr *retmsg; int mclass, mwi, coding, validity, deferred; List *reply_headers; int ret, status; mclass = mwi = coding = validity = deferred = 0; retmsg = NULL; user = http_cgi_variable(cgivars, "app_id"); pass = http_cgi_variable(cgivars, "key"); from = http_cgi_variable(cgivars, "source_addr"); to = http_cgi_variable(cgivars, "dest_addr"); text = http_cgi_variable(cgivars, "message"); account = http_cgi_variable(cgivars, "operator"); binfo = http_cgi_variable(cgivars, "tariff"); debug("smsc.http.xidris", 0, "HTTP[%s]: Received a request", octstr_get_cstr(conn->id)); if (user == NULL || pass == NULL || octstr_compare(user, conndata->username) != 0 || octstr_compare(pass, conndata->password) != 0) { error(0, "HTTP[%s]: Authorization failure. username was <%s>.", octstr_get_cstr(conn->id), octstr_get_cstr(user)); retmsg = octstr_create("Authorization failed for MO submission."); status = HTTP_UNAUTHORIZED; } else if (from == NULL || to == NULL || text == NULL) { error(0, "HTTP[%s]: Insufficient args.", octstr_get_cstr(conn->id)); retmsg = octstr_create("Insufficient arguments, rejected."); status = HTTP_BAD_REQUEST; } else { Msg *msg; msg = msg_create(sms); debug("smsc.http.xidris", 0, "HTTP[%s]: Received new MO SMS.", octstr_get_cstr(conn->id)); msg->sms.sender = octstr_duplicate(from); msg->sms.receiver = octstr_duplicate(to); msg->sms.msgdata = octstr_duplicate(text); msg->sms.account = octstr_duplicate(account); msg->sms.binfo = octstr_duplicate(binfo); msg->sms.smsc_id = octstr_duplicate(conn->id); msg->sms.time = time(NULL); msg->sms.mclass = mclass; msg->sms.mwi = mwi; msg->sms.coding = coding; msg->sms.validity = validity; msg->sms.deferred = deferred; ret = bb_smscconn_receive(conn, msg); status = (ret == 0 ? HTTP_OK : HTTP_FORBIDDEN); } reply_headers = list_create(); debug("smsc.http.xidris", 0, "HTTP[%s]: Sending reply with HTTP status <%d>.", octstr_get_cstr(conn->id), status); http_send_reply(client, status, reply_headers, retmsg); octstr_destroy(retmsg); http_destroy_headers(reply_headers);}/*---------------------------------------------------------------- * Wapme SMS Proxy * * Stipe Tolj <tolj@wapme-systems.de> */static void wapme_smsproxy_send_sms(SMSCConn *conn, Msg *sms){ ConnData *conndata = conn->data; Octstr *url; List *headers; url = octstr_format("%S?command=forward&smsText=%E&phoneNumber=%E" "&serviceNumber=%E&smsc=%E", conndata->send_url, sms->sms.msgdata, sms->sms.sender, sms->sms.receiver, sms->sms.smsc_id); headers = list_create(); debug("smsc.http.wapme", 0, "HTTP[%s]: Start request", octstr_get_cstr(conn->id)); http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, NULL, 0, sms, NULL); octstr_destroy(url); http_destroy_headers(headers);}static void wapme_smsproxy_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body){ if (status == HTTP_OK || status == HTTP_ACCEPTED) { bb_smscconn_sent(conn, msg, NULL); } else { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(body)); }}/* * static void wapme_smsproxy_receive_sms(SMSCConn *conn, HTTPClient *client, * List *headers, Octstr *body, List *cgivars) * * The HTTP server for MO messages will act with the same interface as smsbox's * sendsms interface, so that the logical difference is hidden and SMS Proxy * can act transparently. So there is no need for an explicite implementation * here. *//*----------------------------------------------------------------- * functions to implement various smscconn operations */static int httpsmsc_send(SMSCConn *conn, Msg *msg){ ConnData *conndata = conn->data; Msg *sms = msg_duplicate(msg); double delay = 0; if (conn->throughput) { delay = 1.0 / conn->throughput; } conndata->open_sends++; conndata->send_sms(conn, sms); /* obey throughput speed limit, if any */ if (conn->throughput) gwthread_sleep(delay); return 0;}static long httpsmsc_queued(SMSCConn *conn){ ConnData *conndata = conn->data; return (conndata ? (conn->status != SMSCCONN_DEAD ? conndata->open_sends : 0) : 0);}static int httpsmsc_shutdown(SMSCConn *conn, int finish_sending){ ConnData *conndata = conn->data; debug("httpsmsc_shutdown", 0, "HTTP[%s]: Shutting down", octstr_get_cstr(conn->id)); conn->why_killed = SMSCCONN_KILLED_SHUTDOWN; conndata->shutdown = 1; http_close_port(conndata->port); return 0;}int smsc_http_create(SMSCConn *conn, CfgGroup *cfg){ ConnData *conndata = NULL; Octstr *type; long portno; /* has to be long because of cfg_get_integer */ int ssl = 0; /* indicate if SSL-enabled server should be used */ if (cfg_get_integer(&portno, cfg, octstr_imm("port")) == -1) { error(0, "HTTP[%s]: 'port' invalid in smsc 'http' record.", octstr_get_cstr(conn->id)); return -1; } if ((type = cfg_get(cfg, octstr_imm("system-type")))==NULL) { error(0, "HTTP[%s]: 'type' missing in smsc 'http' record.", octstr_get_cstr(conn->id)); octstr_destroy(type); return -1; } conndata = gw_malloc(sizeof(ConnData)); conndata->http_ref = NULL; conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip")); conndata->send_url = cfg_get(cfg, octstr_imm("send-url")); conndata->username = cfg_get(cfg, octstr_imm("smsc-username")); conndata->password = cfg_get(cfg, octstr_imm("smsc-password")); cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender")); cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding")); cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep")); conndata->proxy = cfg_get(cfg, octstr_imm("system-id")); if (conndata->send_url == NULL) panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.", octstr_get_cstr(conn->id)); if (octstr_case_compare(type, octstr_imm("kannel")) == 0) { if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->receive_sms = kannel_receive_sms; conndata->send_sms = kannel_send_sms; conndata->parse_reply = kannel_parse_reply; } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) { if (conndata->username == NULL) { error(0, "HTTP[%s]: 'username' (=CustomerId) required for bruNET http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->receive_sms = brunet_receive_sms; conndata->send_sms = brunet_send_sms; conndata->parse_reply = brunet_parse_reply; } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) { if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Xidris http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->receive_sms = xidris_receive_sms; conndata->send_sms = xidris_send_sms; conndata->parse_reply = xidris_parse_reply; } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) { if (conndata->send_url == NULL) { error(0, "HTTP[%s]: 'send-url' required for Wapme http smsc", octstr_get_cstr(conn->id)); goto error; } else if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Wapme http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->receive_sms = kannel_receive_sms; /* emulate sendsms interface */ conndata->send_sms = wapme_smsproxy_send_sms; conndata->parse_reply = wapme_smsproxy_parse_reply; } /* * ADD NEW HTTP SMSC TYPES HERE */ else { error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } conndata->open_sends = 0; conndata->http_ref = http_caller_create(); conn->data = conndata; conn->name = octstr_format("HTTP:%S", type); conn->status = SMSCCONN_ACTIVE; conn->connect_time = time(NULL); conn->shutdown = httpsmsc_shutdown; conn->queued = httpsmsc_queued; conn->send_msg = httpsmsc_send; if (http_open_port_if(portno, ssl, conn->our_host)==-1) goto error; conndata->port = portno; conndata->shutdown = 0; if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1) goto error; if ((conndata->send_cb_thread = gwthread_create(httpsmsc_send_cb, conn)) == -1) goto error; info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id)); octstr_destroy(type); return 0;error: error(0, "HTTP[%s]: Failed to create http smsc connection", octstr_get_cstr(conn->id)); conn->data = NULL; conndata_destroy(conndata); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; octstr_destroy(type); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -