📄 mms-appl.c
字号:
/* * gw/mms-appl.c - wapbox application layer implements MMS behaviour */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <sys/ioctl.h>#include <sys/types.h>#include <net/if.h>#include <net/if_arp.h>#include <arpa/inet.h>#include <string.h>#include "gwlib/gwlib.h"#include "xml_shared.h"#include "wml_compiler.h"#include "wap/wap.h"#include "mms-appl.h"#include "wap/wsp_strings.h"#include "wap-error.h"#include "urltrans.h"#include "mms/mms_pdu.h"#include "gw/smsc/smsc_at2.h"/* to start/stop dialup bearer service without having to go through its web interface */extern SMSCConn *modemConn;typedef enum {#define STATE_NAME(name) name,#define ROW(state, event, condition, action, next_state)#include "mms/mms_receiver_states.def"#define STATE_NAME(name) name,#define ROW(state, event, condition, action, next_state)#include "mms/mms_sender_states.def" MMSState_count} MMSState;#define HTTP_MAX_RETRIES 30#define HTTP_RETRY_DELAY 10 /* in sec. *//* * 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;/* * Incoming MMS messages */static List *incoming_mms = NULL;/* machines for sending and recieving */static List *clientMachines = NULL;static List *clientSendMachines = NULL;static List *http_requests = NULL; /* the outbound HTTP request queue *//* * HTTP caller identifier for application layer. */HTTPCaller *mms_caller = NULL;static Counter *num_outstanding_requests;static Octstr *interface;/* how to contact the MMS server */static Octstr *mmsscUrl = NULL;static Octstr *wapIpAddress = NULL;static long wapPort = 8201;static Octstr *mmsDirectory;static Octstr *mmsSignalFile = NULL;static Octstr *mmsSignalURL = NULL;static Counter *mms_client_counter;static Counter *mms_transaction_counter;static long mms_control_port;static Octstr *mms_control_interface;static Octstr *mms_control_url;static long default_bearerinit_delay;static unsigned long max_http_retries = HTTP_MAX_RETRIES;static unsigned long http_queue_delay = HTTP_RETRY_DELAY;/* * Private functions. */static void main_thread(void *);static void bearer_polling_thread(void *);static void mms_control_thread(void *arg);static void mms_retrieve_unanswered();static void url_result_thread(void *arg);static void http_queue_thread(void *arg);/*********************************************************************** * The public interface to the application layer. */void mms_appl_init(Cfg *cfg) { CfgGroup *grp; gw_assert(run_status == limbo); queue = list_create(); list_add_producer(queue); incoming_mms = list_create(); list_add_producer(incoming_mms); clientMachines = list_create(); list_add_producer(clientMachines); clientSendMachines = list_create(); list_add_producer(clientSendMachines); http_requests = list_create(); list_add_producer(http_requests); mms_client_counter = counter_create(); mms_transaction_counter = counter_create(); num_outstanding_requests = counter_create(); run_status = running; mms_caller = http_caller_create(); grp = cfg_get_single_group(cfg, octstr_imm("mms-client")); if (grp == NULL) panic(0, "No 'mms-client' group in configuration"); /* notifying client of new MMS messages */ mmsSignalURL = cfg_get(grp, octstr_imm("mms-signal-url")); mmsDirectory = cfg_get(grp, octstr_imm("mms-directory")); mmsSignalFile = cfg_get(grp, octstr_imm("mms-signal-file")); /* bearer interface (probably ppp0) for wap */ interface = cfg_get(grp, octstr_imm("wap-bearer-interface")); /* information about the MMS service centre */ mmsscUrl = cfg_get(grp, octstr_imm("mms-sc-url")); /* Information about the WAP relay host */ cfg_get_integer(&wapPort, grp, octstr_imm("wap-port")); wapIpAddress = cfg_get(grp, octstr_imm("wap-ipaddress")); /* controlling the MMS stack */ cfg_get_integer(&mms_control_port, grp, octstr_imm("mms-control-port")); if ((mms_control_url = cfg_get(grp, octstr_imm("mms-control-url"))) == NULL) mms_control_url = octstr_imm("/cgi-bin/mms"); /* controlling the MMS stack */ cfg_get_integer(&default_bearerinit_delay, grp, octstr_imm("bearer-init-timeout")); if (default_bearerinit_delay == -1) default_bearerinit_delay = 60; /* read any cached PDUs from disk and stick back in queue */ mms_retrieve_unanswered(); if (mms_control_port > 0) { if (http_open_port_if(mms_control_port, 0, mms_control_interface) == -1) { panic(0, "Failed to open HTTP socket"); } else { info(0, "Set up MMS control service at port %ld", mms_control_port); gwthread_create(mms_control_thread, NULL); gwthread_join_every(mms_control_thread); } } gwthread_create(main_thread, cfg); gwthread_create(bearer_polling_thread, NULL); /* only need HTTP support if configured */ if (mmsSignalURL != NULL || wapIpAddress == NULL) { gwthread_create(http_queue_thread, NULL); gwthread_create(url_result_thread, NULL); }}void mms_appl_shutdown(void) { gw_assert(run_status == running); run_status = terminating; counter_destroy(mms_client_counter); counter_destroy(mms_transaction_counter); counter_destroy(num_outstanding_requests); list_remove_producer(queue); list_remove_producer(clientMachines); list_remove_producer(clientSendMachines); list_remove_producer(incoming_mms); list_remove_producer(http_requests); gwthread_join_every(main_thread); gwthread_join_every(bearer_polling_thread); http_caller_signal_shutdown(mms_caller); /*gwthread_join_every(return_replies_thread);*/ http_caller_destroy(mms_caller); list_destroy(queue, wap_event_destroy_item); gw_assert(list_len(incoming_mms) == 0); list_destroy(incoming_mms, NULL); list_destroy(http_requests, NULL); octstr_destroy(interface); octstr_destroy(mmsscUrl); octstr_destroy(mmsDirectory); octstr_destroy(mmsSignalFile); octstr_destroy(mmsSignalURL); octstr_destroy(mms_control_interface); octstr_destroy(mms_control_url);}void mms_appl_dispatch(WAPEvent *event) { gw_assert(run_status == running); list_produce(queue, event);}MMSClientSendMachine *mms_create_client_send_machine(WAPEvent *event) { MMSClientSendMachine *machine; machine = gw_malloc(sizeof(*machine)); machine->mms_send_req = event; machine->sendconf = NULL; machine->state = state_idle; machine->timer = gwtimer_create(queue); machine->machine_id = counter_increase(mms_client_counter); return machine;}MMSClientMachine *mms_create_client_machine(MMS_PDU *pdu) { MMSClientMachine *machine; machine = gw_malloc(sizeof(*machine)); machine->notification = pdu; machine->retrieveconf = NULL; machine->addrtuple = NULL; machine->state = state_idle; machine->timer = gwtimer_create(queue); machine->machine_id = counter_increase(mms_client_counter); /* TODO write PDU to disk */ machine->savedNotification = NULL; return machine;}void mms_destroy_client_send_machine(MMSClientSendMachine *machine) { if (machine->mms_send_req != NULL) wap_event_destroy(machine->mms_send_req); if (machine->sendconf != NULL) mms_pdu_destroy(machine->sendconf); if (machine->timer != NULL) gwtimer_destroy(machine->timer); gw_free(machine);}void mms_destroy_client_machine(MMSClientMachine *machine) { if (machine->notification != NULL) mms_pdu_destroy(machine->notification); if (machine->retrieveconf != NULL) mms_pdu_destroy(machine->retrieveconf); if (machine->addrtuple != NULL) wap_addr_tuple_destroy(machine->addrtuple); if (machine->timer != NULL) gwtimer_destroy(machine->timer); gw_free(machine);}static char *state_name(int state) { switch (state) {#define STATE_NAME(name) case name: return #name;#define ROW(state, event, cond, stmt, next_state)#include "mms/mms_receiver_states.def"#define STATE_NAME(name) case name: return #name;#define ROW(state, event, cond, stmt, next_state)#include "mms/mms_sender_states.def" default: return "unknown mms state"; }}static void mms_retrieve_unanswered() { /* TODO read from disk and put in queue */}struct receiver { unsigned long handle; int method; /* the HTTP method to use */ Octstr *url; /* the after pattern URL */ List *http_headers; Octstr *body; /* body content of the request */ unsigned long retries; /* number of performed retries */};void *remember_receiver(unsigned long handle, int method, Octstr *url, List *headers, Octstr *body, unsigned int retries) { struct receiver *receiver; counter_increase(num_outstanding_requests); receiver = gw_malloc(sizeof(*receiver)); receiver->handle = handle; receiver->method = method; receiver->url = octstr_duplicate(url); receiver->http_headers = http_header_duplicate(headers); receiver->body = octstr_duplicate(body); receiver->retries = retries; /* TODO save receiver to file */ return receiver;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -