📄 smsc_http.c
字号:
octstr_format_append(url, "&dlr-mask=%d", sms->sms.dlr_mask); headers = gwlist_create(); debug("smsc.http.kannel", 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 kannel_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body){ /* Test on three cases: * 1. an smsbox reply of an remote kannel instance * 2. an smsc_http response (if used for MT to MO looping) * 3. an smsbox reply of partly successful sendings */ if ((status == HTTP_OK || status == HTTP_ACCEPTED) && (octstr_case_compare(body, octstr_imm("Sent.")) == 0 || octstr_case_compare(body, octstr_imm("Ok.")) == 0 || octstr_ncompare(body, octstr_imm("Result: OK"),10) == 0)) { bb_smscconn_sent(conn, msg, NULL); } else { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(body)); }}static void kannel_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars){ ConnData *conndata = conn->data; Octstr *user, *pass, *from, *to, *text, *udh, *account, *binfo, *tmp_string; Octstr *retmsg; int mclass, mwi, coding, validity, deferred; List *reply_headers; int ret; mclass = mwi = coding = validity = deferred = 0; user = http_cgi_variable(cgivars, "username"); pass = http_cgi_variable(cgivars, "password"); from = http_cgi_variable(cgivars, "from"); to = http_cgi_variable(cgivars, "to"); text = http_cgi_variable(cgivars, "text"); udh = http_cgi_variable(cgivars, "udh"); account = http_cgi_variable(cgivars, "account"); binfo = http_cgi_variable(cgivars, "binfo"); tmp_string = http_cgi_variable(cgivars, "flash"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mclass"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mwi"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mwi); } tmp_string = http_cgi_variable(cgivars, "coding"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &coding); } tmp_string = http_cgi_variable(cgivars, "validity"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &validity); } tmp_string = http_cgi_variable(cgivars, "deferred"); if(tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &deferred); } debug("smsc.http.kannel", 0, "HTTP[%s]: Received an HTTP 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", octstr_get_cstr(conn->id)); retmsg = octstr_create("Authorization failed for sendsms"); } else if (from == NULL || to == NULL || text == NULL) { error(0, "HTTP[%s]: Insufficient args", octstr_get_cstr(conn->id)); retmsg = octstr_create("Insufficient args, rejected"); } else if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) { error(0, "HTTP[%s]: UDH field misformed, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field misformed, rejected"); } else if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) { error(0, "HTTP[%s]: UDH field is too long, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field is too long, rejected"); } else { Msg *msg; msg = msg_create(sms); debug("smsc.http.kannel", 0, "HTTP[%s]: Constructing new 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.udhdata = octstr_duplicate(udh); 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; msg->sms.account = octstr_duplicate(account); msg->sms.binfo = octstr_duplicate(binfo); ret = bb_smscconn_receive(conn, msg); if (ret == -1) retmsg = octstr_create("Not accepted"); else retmsg = octstr_create("Sent."); } reply_headers = gwlist_create(); http_header_add(reply_headers, "Content-Type", "text/plain"); debug("smsc.http.kannel", 0, "HTTP[%s]: Sending reply", octstr_get_cstr(conn->id)); http_send_reply(client, HTTP_ACCEPTED, reply_headers, retmsg); octstr_destroy(retmsg); http_destroy_headers(reply_headers);}/*---------------------------------------------------------------- * Clickatell - http://api.clickatell.com/ * * Rene Kluwen <rene.kluwen@chimit.nl> *//* MT related function */static void clickatell_send_sms(SMSCConn *conn, Msg *sms){ ConnData *conndata = conn->data; Octstr *url; List *headers; /* form the basic URL */ url = octstr_format("%S/sendmsg?to=%E&from=%E&api_id=%E&user=%E&password=%E", conndata->send_url, sms->sms.receiver, sms->sms.sender, conndata->system_id, conndata->username, conndata->password); /* * 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); } /* add UDH header */ if (octstr_len(sms->sms.udhdata)) { octstr_format_append(url, "&data=%H", sms->sms.msgdata); octstr_format_append(url, "&udh=%H", sms->sms.udhdata); } else { octstr_format_append(url, "&text=%E", sms->sms.msgdata); } if (DLR_IS_ENABLED_DEVICE(sms->sms.dlr_mask)) octstr_format_append(url, "&callback=3&deliv_ack=1"); headers = http_create_empty_headers(); debug("smsc.http.clickatell", 0, "HTTP[%s]: Sending request <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(url)); /* * Clickatell requires optionally 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); http_destroy_headers(headers);}/* * Parse a line in the format: ID: XXXXXXXXXXXXXXXXXX * and return a Dict with the 'ID' as key and the value as value, * otherwise return NULL if a parsing error occures. */static Dict *clickatell_parse_body(Octstr *body){ Dict *param = NULL; List *words = NULL; long len; Octstr *word, *value; words = octstr_split_words(body); if ((len = gwlist_len(words)) > 1) { word = gwlist_extract_first(words); if (octstr_compare(word, octstr_imm("ID:")) == 0) { value = gwlist_extract_first(words); param = dict_create(4, NULL); dict_put(param, octstr_imm("ID"), value); } else if (octstr_compare(word, octstr_imm("ERR:")) == 0) { value = gwlist_extract_first(words); param = dict_create(4, NULL); dict_put(param, octstr_imm("ERR"), value); } octstr_destroy(word); } gwlist_destroy(words, (void(*)(void *)) octstr_destroy); return param;}static void clickatell_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body){ if (status == HTTP_OK || status == HTTP_ACCEPTED) { Dict *param; Octstr *msgid; if ((param = clickatell_parse_body(body)) != NULL && (msgid = dict_get(param, octstr_imm("ID"))) != NULL && msgid != NULL) { /* SMSC ACK.. now we have the message id. */ if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) dlr_add(conn->id, msgid, msg); bb_smscconn_sent(conn, msg, NULL); } else { error(0, "HTTP[%s]: Message was malformed or error was returned. SMSC response `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(body)); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(body)); } dict_destroy(param); } else { error(0, "HTTP[%s]: Message was rejected. SMSC reponse `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(body)); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_REJECTED, octstr_duplicate(body)); }}/* MO related function */static void clickatell_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars){ List *reply_headers; int ret; Octstr *apimsgid, *status, *timestamp, *retmsg, *dest, *charge; Octstr *api_id, *from, *to, *text, *charset, *udh; int httpstatus = HTTP_UNAUTHORIZED, dlrstat; Msg *dlrmsg, *momsg; struct tm tm; /* dlr parameters */ apimsgid = http_cgi_variable(cgivars, "apiMsgId"); status = http_cgi_variable(cgivars, "status"); /* timestamp is for both DLR & MO */ timestamp = http_cgi_variable(cgivars, "timestamp"); dest = http_cgi_variable(cgivars, "to"); charge = http_cgi_variable(cgivars, "charge"); /* MO parameters */ api_id = http_cgi_variable(cgivars, "api_id"); from = http_cgi_variable(cgivars, "from"); to = http_cgi_variable(cgivars, "to"); text = http_cgi_variable(cgivars, "text"); charset = http_cgi_variable(cgivars, "charset"); udh = http_cgi_variable(cgivars, "udh"); debug("smsc.http.clickatell", 0, "HTTP[%s]: Received a request", octstr_get_cstr(conn->id)); if (api_id != NULL && from != NULL && to != NULL && timestamp != NULL && text != NULL && charset != NULL && udh != NULL) { /* we received an MO message */ debug("smsc.http.clickatell", 0, "HTTP[%s]: Received MO message from %s: <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(from), octstr_get_cstr(text)); momsg = msg_create(sms); momsg->sms.sms_type = mo; momsg->sms.sender = octstr_duplicate(from); momsg->sms.receiver = octstr_duplicate(to); momsg->sms.msgdata = octstr_duplicate(text); momsg->sms.charset = octstr_duplicate(charset); momsg->sms.binfo = octstr_duplicate(api_id); momsg->sms.smsc_id = octstr_duplicate(conn->id); if (octstr_len(udh) > 0) { momsg->sms.udhdata = octstr_duplicate(udh); } strptime(octstr_get_cstr(timestamp), "%Y-%m-%d %H:%M:%S", &tm); momsg->sms.time = gw_mktime(&tm); /* note: implicit msg_destroy */ ret = bb_smscconn_receive(conn, momsg); httpstatus = HTTP_OK; retmsg = octstr_create("Thanks"); } else if (apimsgid == NULL || status == NULL || timestamp == NULL || dest == NULL) { error(0, "HTTP[%s]: Insufficient args.", octstr_get_cstr(conn->id)); httpstatus = HTTP_BAD_REQUEST; retmsg = octstr_create("Insufficient arguments, rejected."); } else { switch (atoi(octstr_get_cstr(status))) { case 1: /* message unknown */ case 5: /* error with message */ case 6: /* user cancelled message */ case 7: /* error delivering message */ case 9: /* routing error */ case 10: /* message expired */ dlrstat = 2; /* delivery failure */ break; case 2: /* message queued */ case 3: /* delivered */ case 11: /* message queued for later delivery */ dlrstat = 4; /* message buffered */ break; case 4: /* received by recipient */ case 8: /* OK */ dlrstat = 1; /* message received */ break; default: /* unknown status code */ dlrstat = 16; /* smsc reject */ break; } dlrmsg = dlr_find(conn->id, apimsgid, /* smsc message id */ dest , /* destination */ dlrstat); if (dlrmsg != NULL) { /* dlrmsg->sms.msgdata = octstr_duplicate(apimsgid); */ dlrmsg->sms.sms_type = report_mo; dlrmsg->sms.time = atoi(octstr_get_cstr(timestamp)); if (charge) { /* unsure if smsbox relays the binfo field to dlrs. But it is here in case they will start to do it. */ dlrmsg->sms.binfo = octstr_duplicate(charge); } ret = bb_smscconn_receive(conn, dlrmsg); httpstatus = (ret == 0 ? HTTP_OK : HTTP_FORBIDDEN); retmsg = octstr_create("Sent"); } else { error(0,"HTTP[%s]: got DLR but could not find message or was not interested " "in it id<%s> dst<%s>, type<%d>", octstr_get_cstr(conn->id), octstr_get_cstr(apimsgid), octstr_get_cstr(dest), dlrstat); httpstatus = HTTP_OK; retmsg = octstr_create("Thanks"); } } reply_headers = gwlist_create(); http_header_add(reply_headers, "Content-Type", "text/plain"); debug("smsc.http.clickatell", 0, "HTTP[%s]: Sending reply `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(retmsg)); http_send_reply(client, httpstatus, reply_headers, retmsg); octstr_destroy(retmsg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -