push_server.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,135 行 · 第 1/5 页

C
2,135
字号
/* * * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * Push Registry Persistent File Management module. * * Contains functions and data structures that are used to implement the * auto-invocation subsystem. This includes push (i.e., listening * for incoming connections), and alarms (responding to time events). * The module opens the push registry file and caches the contents in * memory at startup. Subsequent additions and deletions * update the cache and rewrite the persistent data file. */#ifndef _WIN32_WCE    #include <errno.h>#endif#include <string.h>#include <java_types.h>#include <kni.h>#include <sni.h>#include <pcsl_memory.h>#include <pcsl_string.h>#include <midpMalloc.h>#include <midpStorage.h>#include <midp_properties_port.h>#include <midpResourceLimit.h>#include <midpError.h>#include <midpServices.h>#include <midp_logging.h>#include <midp_libc_ext.h>#include <kni_globals.h>#include <midp_thread.h>#include <pcsl_network.h>#include <pcsl_socket.h>#include <pcsl_serversocket.h>#include <pcsl_network_notifier.h>#include <push_server_export.h>#include <push_server_resource_mgmt.h>#include <timer_export.h>#if (ENABLE_JSR_205 || ENABLE_JSR_120)    #include <wmaPushRegistry.h>    #include <stdio.h>#endif#if ENABLE_JSR_180    #include <SipPushRegistry.h>#endif#if ENABLE_JSR_82    #include <stdio.h>    #include "btPush.h"#endif#if ENABLE_I3_TEST    #include <midpUtilKni.h>#endif#ifndef MAX_CACHED_DATA_SIZE    #define MAX_CACHED_DATA_SIZE 1500#endif /* MAX_CACHED_DATA_SIZE *//** For build a parameter string. */PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START(COMMA_STRING){',', '\0'}PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END(COMMA_STRING);/** Filename to save the push connections. ("pushlist.txt") */PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START(PUSH_LIST_FILENAME){'p', 'u', 's', 'h', 'l', 'i', 's', 't', '.', 't', 'x', 't', '\0'}PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END(PUSH_LIST_FILENAME);/** Filename to save the alarms. ("alarmlist.txt") */PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START(ALARM_LIST_FILENAME){'a', 'l', 'a', 'r', 'm', 'l', 'i', 's', 't', '.', 't', 'x', 't', '\0'}PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END(ALARM_LIST_FILENAME);/** Pathname for persistent push connection list. */static pcsl_string pushpathname = PCSL_STRING_NULL_INITIALIZER;/** Pathname for persistent alarm notification list. */static pcsl_string alarmpathname = PCSL_STRING_NULL_INITIALIZER;/** Pointer to error message. */static char *errStr = NULL;/* Maximum buffer size for line parsing. */#define MAX_LINE 512/** * The internal representation of a datagram or TCP packet. * Datagrams read by the push mechanism are buffered in the push * registry for use by the midlet after it is invoked by push. */typedef struct _packetentry {    /** The IP Address of the sender. */    int ipAddress;    /** The port ID on which the packet was received. */    int senderport;    /** The length of data in the buffer. */    int length;    /** The offset in the buffer where the read pointer is located. */    int offs;    /** The buffer that holds the data of the datagram. */    char buffer[MAX_CACHED_DATA_SIZE];} PacketEntry;/** * The internal representation of an entry in the Push Registry list. When * the push registry is initialized, the persistent push registry is read * and stored in a null-terminated linked-list of elements like this. Updates * to the push registry are first made to the linked list in memory, and * subsequently written to persistent storage. */typedef struct _pushentry {    /** Pointer to the next entry in the list. Last entry has NULL here. */    struct _pushentry *next;    /** The full text entry from the persistent store. */    char *value;    /** The name of the midletsuitestorage persistent store. */    char *storagename;    /** The filter with which to filter ip addresses. */    char *filter;    /** The socket to listen to. */    int fd;    /** The socket to use for the connection. */    int fdsock;    /** The socket that is used when buffering the incoming TCP packet. */    int fdAccepted;    /** Port id to listen to. */    int port;    /** MMS application ID. */    char *appID;    /** Current state of the connection. */    int state;    /** Pointers for packets that have already arrived. */    PacketEntry *pCachedData;    /** Flag denoting whether a WMA message has arrived and been cached. */    jboolean isWMAMessCached;    /** True if this entry should be handled by WMA rather then by MIDP Push. */    jboolean isWMAEntry;#if ENABLE_JSR_180    /** True if this entry is a SIP-entry. */    jboolean isSIPEntry;    /** Marks shared connection for quick search */    jboolean isShared;#endif} PushEntry;/** * The internal representation of an alarm entry in the Push Registry * list. When * the push registry is initialized, the persistent push registry is read * and stored in a null-terminated linked-list of elements like this. Updates * to the push registry are first made to the linked list in memory, and * subsequently written to persistent storage. */typedef struct _alarmentry {    /** Pointer to the next entry in the list. Last entry has NULL here. */    struct _alarmentry *next;    /**     * Pointer to a string containing the name of the MIDlet to be     * wakened.     */    char *midlet;    /**     * Pointer to a string containing the persistent store name of the     * MIDletSuite.     */    char *storagename;    /** Absolute time after which this alarm is to be fired. */    jlong wakeup;    /** Handle to the Timer instance currently counting this alarm. */    int timerHandle;    /** The state of the current alarm. */    int state;} AlarmEntry;static PushEntry *pushlist = NULL;static AlarmEntry *alarmlist = NULL;typedef enum {    NET_STATUS_DOWN       = -3,    NET_STATUS_GOING_DOWN = -2, /* network finalization is in progress */    NET_STATUS_ERROR      = -1,    NET_STATUS_UNKNOWN    = 0,    NET_STATUS_GOING_UP   = 1, /* network initialization is in progress */    NET_STATUS_UP         = 2} network_status_t;/** * Current network status. */static network_status_t networkStatus = NET_STATUS_UNKNOWN;/** * Checks current status of the network. * * @return <tt>1</tt> if network is enabled, <tt>0</tt> otherwise */static int isNetworkUp();static int pushlength = 0;static int pushProcessPort(PushEntry* pe);static void pushStartListening();static int alarmopen();static void alarmsave();static void pushListFree();static void alarmListFree();static int parsePushList(int);static int parseAlarmList(int);static int checkfilter(char *filter, char *ip);static void pushcheckinentry(PushEntry *p);static void pushcleanupentry(PushEntry *p);static void pushDeleteSuiteNoVM(SuiteIdType id);static void pushDeleteSuiteLive(SuiteIdType id);static int pushOpenInternal(int startListening);static void pushDeleteEntry(PushEntry *p, PushEntry **pPrevNext);static void alarmstart(AlarmEntry *entry, jlong alarm);static long readLine(char** ppszError, int handle, char* buffer, long length);static void pcsl_network_initialized(int isInit, int status);/** * Parses and extracts a field from the registry entry string. * * @param value address of registry entry string * @param field which field to extract * * @return address of the desired field (comma or null terminated) * */static char *pushstorage(char *value, int field) {    char *storagefield;    char *storagename = NULL;    int comma = 0;    for (storagefield = value; *storagefield; storagefield++) {        if (*storagefield == ',') {            comma ++;        }        /* Push entry contains "connection, midletname, filter, storage" */        /* Alarm entry contains "midletname, alarm, storage" */        if (comma == field) {            storagename = storagefield + 1;            break;        }    }    return storagename;}#if (ENABLE_JSR_205 || ENABLE_JSR_120)/** * Converts a given string to a suite ID. * * @param strId a string to convert * * @return suite ID (UNUSED_SUITE_ID if conversion failed) * */static SuiteIdType suiteIdFromChars(const char* strId) {    unsigned long lid;    SuiteIdType suiteId = UNUSED_SUITE_ID;    if (strId) {        /* IMPL NOTE: here it's assumed that strId represents a HEX integer */        if (sscanf(strId, "%lx", &lid) == 1) {            suiteId = (SuiteIdType)lid;        }    }    return suiteId;}#endif/** * Parses and extracts the filter field from the registry entry string. * * @param value address of registry entry string * @return a copy of the filter field from the registry entry * */static char *pushfilter(char *value) {    char *ptr, *filter_dup;    char *filter = pushstorage(value, 2);    /* Push entry contains "connection, midletname, filter, storage" */    for (ptr = filter; *ptr; ptr++) {        if (*ptr == ',')            break;    }    *ptr = '\0';    filter_dup = midpStrdup(filter);    *ptr = ',';    return filter_dup;}/** * Parses and extract the MIDlet class name field from connection entry * string. * * @param value address of connection entry string * @param pLength address of where the length of the name should be output * * @return address of the desired field * */static char *pushclassname(char *value, int *pLength) {    char *classfield;    char *classname = NULL;    int length = 0;    /* Push entry contains "connection,midletname,filter,storage" */    for (classfield = value; *classfield != 0; classfield++) {        if (*classfield == ',') {            classname = classfield + 1;            for (classfield++; *classfield != 0 && *classfield != ',';                classfield++, length++);            break;        }    }    *pLength = length;    return classname;}/** * Checks if the given string represents a datagram connection * or a socket connection. * * @param pBuffer buffer with a string describing the connection * @param checkIfDatagram defines what this function should check: if 1, *                        it should be checked that the given string represents *                        a datagram connection, 0 - a socket connection * * @return 1 if the given buffer represents the given connection type */static int pushIsConnectionOfGivenType(const char* pBuffer,                                       int checkIfDatagram) {    if (pBuffer == NULL) {        return 0;    }    if (strncmp(pBuffer, "datagram://:", 12) == 0) {        return checkIfDatagram;    }#if ENABLE_SERVER_SOCKET    else if (strncmp(pBuffer, "socket://:", 10) == 0) {        return !checkIfDatagram;    }#endif#if ENABLE_JSR_180    /* Check for JSR180 SIP/SIPS connections. */    if ((strncmp(pBuffer, "sips:", 5) == 0) ||        (strncmp(pBuffer, "sip:", 4) == 0)) {        /*         * IMPL_NOTE: the following check is very simplified, but its enough         *            for the practical cases.         */        const char* pTransport = strstr(pBuffer, "transport=tcp");        return checkIfDatagram != (pTransport != NULL);    }#endif    return 0;}/** * Checks if the given string represents a socket connection. * * @param pBuffer buffer with a string describing the connection * * @return 1 if the given buffer represents a socket connection, 0 otherwise */static int pushIsSocketConnection(const char* pBuffer) {    int f = pushIsConnectionOfGivenType(pBuffer, 0);    return f;}/** * Checks if the given string represents a datagram connection. * * @param pBuffer buffer with a string describing the connection * * @return 1 if the given buffer represents a datagram connection, 0 otherwise */static int pushIsDatagramConnection(const char* pBuffer) {    int f = pushIsConnectionOfGivenType(pBuffer, 1);    return f;}/** * Adds a network notifier for the given push entry.

⌨️ 快捷键说明

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