⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wap-appl.c.backup

📁 mms client
💻 BACKUP
📖 第 1 页 / 共 3 页
字号:
/* * gw/wap-appl.c - wapbox application layer and push ota indication, response * and confirmation primitive implementation. * * This module implements indication and confirmation primitives of WAP-189- * PushOTA-20000217-a (hereafter called ota).  * In addition, WAP-200-WDP-20001212-a (wdp) is referred. * Wapbox application layer is not a Wapforum protocol.  * * The application layer is reads events from its event queue, fetches the  * corresponding URLs and feeds back events to the WSP layer (pull).  * * In addition, the layer forwards WSP events related to push to the module  * wap_push_ppg and wsp, implementing indications, responses  and confirma- * tions of ota. * * Note that push header encoding and decoding are divided two parts: * first decoding and encoding numeric values and then packing these values * into WSP format and unpacking them from WSP format. This module contains * encoding part. * * Lars Wirzenius */#include <string.h>#include "gwlib/gwlib.h"#include "wmlscript/ws.h"#include "xml_shared.h"#include "wml_compiler.h"#include "wap/wap.h"#include "wap-appl.h"#include "wap/wsp_strings.h"#include "wap/wsp_caps.h"#include "wap/wsp.h"#ifdef ENABLE_COOKIES#include "wap/cookies.h"#endif#include "wap-error.h"/* * Give the status the module: * *	limbo *		not running at all *	running *		operating normally *	terminating *		waiting for operations to terminate, returning to limbo */static enum { limbo, running, terminating } run_status = limbo;/* * The queue of incoming events. */static List *queue = NULL;/* * HTTP caller identifier for application layer. */static HTTPCaller *caller = NULL;/* * Number of currently running HTTP fetching threads. */static Counter *fetches = NULL;/* * Charsets supported by WML compiler, queried from wml_compiler. */static List *charsets = NULL;struct content {    Octstr *body;    Octstr *type;    Octstr *charset;    Octstr *url;};/* * A mapping from HTTP request identifiers to information about the request. */struct request_data {    long client_SDU_size;    WAPEvent *event;    long session_id;    Octstr *url;    long x_wap_tod;    List *request_headers;};/* * WSP smart error messaging */extern int wsp_smart_errors;extern Octstr *device_home;/* * */static int have_ppg = 0;/* * Private functions. */static void main_thread(void *);static void start_fetch(WAPEvent *);static void return_replies_thread(void *);static void  dev_null(const char *data, size_t len, void *context);static Octstr *convert_wml_to_wmlc(struct content *content);static Octstr *convert_wmlscript_to_wmlscriptc(struct content *content);static void wsp_http_map_url(Octstr **osp);static List *negotiate_capabilities(List *req_caps);static struct {    char *type;    char *result_type;    Octstr *(*convert)(struct content *);} converters[] = {    { "text/vnd.wap.wml",      "application/vnd.wap.wmlc",      convert_wml_to_wmlc },    { "text/vnd.wap.wmlscript",      "application/vnd.wap.wmlscriptc",      convert_wmlscript_to_wmlscriptc },};#define NUM_CONVERTERS ((long)(sizeof(converters) / sizeof(converters[0])))/* * Following functions implement indications and conformations part of Push * OTA protocol. */static void indicate_push_connection(WAPEvent *e);static void indicate_push_disconnect(WAPEvent *e);static void indicate_push_suspend(WAPEvent *e);static void indicate_push_resume(WAPEvent *e);static void confirm_push(WAPEvent *e);static void indicate_push_abort(WAPEvent *e);static void split_header_list(List **headers, List **new_headers, char *name);static void check_application_headers(List **headers, List **app_headers);static void decode_bearer_indication(List **headers, List **bearer_headers);static void response_push_connection(WAPEvent *e);/*********************************************************************** * The public interface to the application layer. */void wap_appl_init(Cfg *cfg) {    gw_assert(run_status == limbo);    queue = list_create();    fetches = counter_create();    list_add_producer(queue);    run_status = running;    charsets = wml_charsets();    caller = http_caller_create();    gwthread_create(main_thread, NULL);    gwthread_create(return_replies_thread, NULL);    if (cfg != NULL)        have_ppg = 1;    else        have_ppg = 0;}void wap_appl_shutdown(void) {    gw_assert(run_status == running);    run_status = terminating;        list_remove_producer(queue);    gwthread_join_every(main_thread);        http_caller_signal_shutdown(caller);    gwthread_join_every(return_replies_thread);        http_caller_destroy(caller);    list_destroy(queue, wap_event_destroy_item);    list_destroy(charsets, octstr_destroy_item);    counter_destroy(fetches);}void wap_appl_dispatch(WAPEvent *event) {    gw_assert(run_status == running);    list_produce(queue, event);}long wap_appl_get_load(void) {    gw_assert(run_status == running);    return counter_value(fetches) + list_len(queue);}/*********************************************************************** * Private functions. *//* * When we have a push event, create ota indication or confirmation and send  * it to ppg module.  * Because Accept-Application and Bearer-Indication are optional, we cannot  * rely on them. We must ask ppg main module do we have an open push session  * for this initiator. Push is identified by push id. * If there is no ppg configured, do not refer to ppg's sessions' list. */static void main_thread(void *arg) {    WAPEvent *ind, *res;    long sid;    WAPAddrTuple *tuple;        while (run_status == running && (ind = list_consume(queue)) != NULL) {	switch (ind->type) {	case S_MethodInvoke_Ind:	    res = wap_event_create(S_MethodInvoke_Res);	    res->u.S_MethodInvoke_Res.server_transaction_id =	    ind->u.S_MethodInvoke_Ind.server_transaction_id;	    res->u.S_MethodInvoke_Res.session_id =	    ind->u.S_MethodInvoke_Ind.session_id;	    wsp_session_dispatch_event(res);	    start_fetch(ind);	    break;		case S_Unit_MethodInvoke_Ind:	    start_fetch(ind);	    break;	case S_Connect_Ind:            tuple  = ind->u.S_Connect_Ind.addr_tuple;            if (have_ppg && wap_push_ppg_have_push_session_for(tuple)) {	        indicate_push_connection(ind);            } else {	        res = wap_event_create(S_Connect_Res);	    /* FIXME: Not yet used by WSP layer */	       res->u.S_Connect_Res.server_headers = NULL;	       res->u.S_Connect_Res.negotiated_capabilities =	           negotiate_capabilities(	               ind->u.S_Connect_Ind.requested_capabilities);	       res->u.S_Connect_Res.session_id =                    ind->u.S_Connect_Ind.session_id;	       wsp_session_dispatch_event(res);            }            wap_event_destroy(ind);            break;		case S_Disconnect_Ind:	    sid = ind->u.S_Disconnect_Ind.session_handle;            if (have_ppg && wap_push_ppg_have_push_session_for_sid(sid))                 indicate_push_disconnect(ind);	    wap_event_destroy(ind);	    break;	case S_Suspend_Ind:	    sid = ind->u.S_Suspend_Ind.session_id;            if (wap_push_ppg_have_push_session_for_sid(sid))                 indicate_push_suspend(ind);	    wap_event_destroy(ind);	    break;	case S_Resume_Ind:	    sid = ind->u.S_Resume_Ind.session_id;            if (have_ppg && wap_push_ppg_have_push_session_for_sid(sid))                 indicate_push_resume(ind);            else {	        res = wap_event_create(S_Resume_Res);	        res->u.S_Resume_Res.server_headers = NULL;	        res->u.S_Resume_Res.session_id =                     ind->u.S_Resume_Ind.session_id;	        wsp_session_dispatch_event(res);	                    }            wap_event_destroy(ind);	    break;		case S_MethodResult_Cnf:	    wap_event_destroy(ind);	    break;        case S_ConfirmedPush_Cnf:            confirm_push(ind);            wap_event_destroy(ind);	    break;		case S_MethodAbort_Ind:	    /* XXX Interrupt the fetch thread somehow */	    wap_event_destroy(ind);	    break;        case S_PushAbort_Ind:            indicate_push_abort(ind);            wap_event_destroy(ind);	    break;        case Pom_Connect_Res:	    response_push_connection(ind);	    wap_event_destroy(ind);	    break;		default:	    panic(0, "APPL: Can't handle %s event", 	    	  wap_event_name(ind->type));	    break;	}    }}static int convert_content(struct content *content) {    Octstr *new_body;    int failed = 0;    int i;        for (i = 0; i < NUM_CONVERTERS; i++) {	if (octstr_str_compare(content->type, converters[i].type) == 0) {	    new_body = converters[i].convert(content);	    if (new_body != NULL) {		octstr_destroy(content->body);		content->body = new_body;		octstr_destroy(content->type);		content->type = octstr_create(		converters[i].result_type);		return 1;	    }	    failed = 1;	}    }        if (failed)	return -1;    return 0;}/* Add a header identifying our gateway version */static void add_kannel_version(List *headers) {    http_header_add(headers, "X-WAP-Gateway", GW_NAME "/" VERSION);}/* Add Accept-Charset: headers for stuff the WML compiler can * convert to UTF-8. *//* XXX This is not really correct, since we will not be able * to handle those charsets for all content types, just WML. */static void add_charset_headers(List *headers) {    long i, len;        gw_assert(charsets != NULL);    len = list_len(charsets);    for (i = 0; i < len; i++) {	unsigned char *charset = octstr_get_cstr(list_get(charsets, i));	if (!http_charset_accepted(headers, charset))	    http_header_add(headers, "Accept-Charset", charset);    }}/* Add Accept: headers for stuff we can convert for the phone */static void add_accept_headers(List *headers) {    int i;        for (i = 0; i < NUM_CONVERTERS; i++) {	if (http_type_accepted(headers, converters[i].result_type)	    && !http_type_accepted(headers, converters[i].type)) {	    http_header_add(headers, "Accept", converters[i].type);	}    }}static void add_network_info(List *headers, WAPAddrTuple *addr_tuple) {    if (octstr_len(addr_tuple->remote->address) > 0) {	http_header_add(headers, "X_Network_Info", 			octstr_get_cstr(addr_tuple->remote->address));    }}static void add_session_id(List *headers, long session_id) {    if (session_id != -1) {	char buf[40];	sprintf(buf, "%ld", session_id);	http_header_add(headers, "X-WAP-Session-ID", buf);    }}static void add_client_sdu_size(List *headers, long sdu_size) {    if (sdu_size > 0) {	Octstr *buf;		buf = octstr_format("%ld", sdu_size);	http_header_add(headers, "X-WAP-Client-SDU-Size", 	    	    	octstr_get_cstr(buf));	octstr_destroy(buf);    }}static void add_via(List *headers) {    Octstr *os;        os = octstr_format("WAP/1.1 %S (" GW_NAME "/%s)", get_official_name(),		       VERSION);    http_header_add(headers, "Via", octstr_get_cstr(os));    octstr_destroy(os);}/* * Add an X-WAP.TOD header to the response headers.  It is defined in * the "WAP Caching Model" specification. * We generate it in textual form and let WSP header packing convert it * to binary form. */static void add_x_wap_tod(List *headers) {    Octstr *gateway_time;        gateway_time = date_format_http(time(NULL));    if (gateway_time == NULL) {	warning(0, "Could not add X-WAP.TOD response header.");	return;    }        http_header_add(headers, "X-WAP.TOD", octstr_get_cstr(gateway_time));		    octstr_destroy(gateway_time);}static void add_referer_url(List *headers, Octstr *url) {    if (octstr_len(url) > 0) {	   http_header_add(headers, "Referer", octstr_get_cstr(url));    }}static void set_referer_url(Octstr *url, WSPMachine *sm){	gw_assert(url != NULL);	gw_assert(sm != NULL);    octstr_destroy(sm->referer_url);    sm->referer_url = octstr_duplicate(url);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -