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 + -
显示快捷键?