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

📄 wap-appl.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * 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 "mime_decompiler.h"#include "wap/wap.h"#include "wap-appl.h"#include "wap_push_ppg.h"#include "wap/wsp_strings.h"#include "wap/wsp_caps.h"#include "wap/wsp.h"#ifdef ENABLE_COOKIES#include "wap/cookies.h"#endif#include "radius/radius_acct.h"#include "wap-error.h"#include "wap-maps.h"#define ENABLE_NOT_ACCEPTED /* * 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;    Octstr *version;};/* * A mapping from HTTP request identifiers to information about the request. */struct request_data {    long client_SDU_size;    WAPEvent *event;    long session_id;    Octstr *method;    Octstr *url;    long x_wap_tod;    List *request_headers;};/* * WSP smart error messaging */extern int wsp_smart_errors;extern Octstr *device_home;/* * Defines if PPG is running in wapbox instance */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);/* DAVI: To-Do static Octstr *convert_multipart_mixed(struct content *content); */static Octstr *deconvert_multipart_formdata(struct content *content);/* DAVI: To-Do static Octstr *deconvert_mms_message(struct content *content); */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 },/* DAVI: To-Do    { "multipart/mixed",      "application/vnd.wap.multipart.mixed",      convert_multipart_mixed }, */};#define NUM_CONVERTERS ((long)(sizeof(converters) / sizeof(converters[0])))static struct {    char *type;    char *result_type;    Octstr *(*deconvert)(struct content *);} deconverters[] = {    { "application/vnd.wap.multipart.form-data",      "multipart/form-data; boundary=kannel_boundary",      deconvert_multipart_formdata },/* DAVI: To-Do    { "application/vnd.wap.mms-message",      "multipart/related; type=application/smil; boundary=kannel_boundary; start=<t0>",      deconvert_mms_message },*/};#define NUM_DECONVERTERS ((long)(sizeof(deconverters) / sizeof(deconverters[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);        wap_map_destroy();     wap_map_user_destroy();     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, "WAP-APPL: Can't handle %s event",               wap_event_name(ind->type));        break;    } /* switch */    } /* while */}/* * Tries to convert or compile a specific content-type to * it's complementing one. It does not convert if the client has explicitely * told us via Accept: header that a specific type is supported. * Returns 1 if an convertion has been successfull, * -1 if an convertion failed and 0 if no convertion routine * was maching this content-type */static int convert_content(struct content *content, List *request_headers,                            int allow_empty) {    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 &&            !http_type_accepted(request_headers, octstr_get_cstr(content->type))) {            debug("wap.convert",0,"WSP: Converting from <%s> to <%s>",                   octstr_get_cstr(content->type), converters[i].result_type);            /* 

⌨️ 快捷键说明

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