push_server.c

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

C
2,135
字号
 * * @param pe push entry for which a network notifier should be added */static void pushAddNetworkNotifier(PushEntry* pe) {    /*     * WMA connections have their own notification system.     * So add a notifier only if its not WMA connection.     */    if (!pe->isWMAEntry) {        /* Push only needs to know if a socket has data. */        if (pushIsDatagramConnection(pe->value)) {            pcsl_add_network_notifier((void *)pe->fd, PCSL_NET_CHECK_READ);        } else if (pushIsSocketConnection(pe->value)) {            pcsl_add_network_notifier((void *)pe->fd, PCSL_NET_CHECK_ACCEPT);        }    }}/** * Opens the pushregistry files and populate the push memory structures. * * @param <none> * @return <tt>0</tt> for success, non-zero if there is a resource problem */int pushopen() {#if ENABLE_JSR_82    bt_push_startup();#endif    return pushOpenInternal(1);}/** * Opens the Push Registry file, if it exists and populate * an in memory cache of the file contents. * * @param startListening if KNI_TRUE the push system will listen for incoming data *    on the push connections. * * @return 0 for success else non-zero if a resource problem */static int pushOpenInternal(int startListening) {    int pushfd;    int status, push_status, alarm_status;    push_status = alarm_status = 0;    /* Check whether the alarm file has been already read. */    if (PCSL_TRUE == pcsl_string_is_null(&alarmpathname)) {        /*         * Initialize the fully qualified pathname         * of the push persistent file.         */        if (PCSL_STRING_OK != pcsl_string_cat(                                             storage_get_root(INTERNAL_STORAGE_ID),                                             &ALARM_LIST_FILENAME, &alarmpathname)) {            alarm_status = -1;        } else {            alarm_status = alarmopen();        }        if (alarm_status != 0) {            REPORT_ERROR(LC_PROTOCOL, "Error: alarm open failed");            pcsl_string_free(&alarmpathname);        }    }    /* Check whether the push file has been already read. */    if (PCSL_TRUE == pcsl_string_is_null(&pushpathname)) {        /*         * Initialize the fully qualified pathname         * of the push persistent file.         */        if (PCSL_STRING_OK != pcsl_string_cat(                                             storage_get_root(INTERNAL_STORAGE_ID),                                             &PUSH_LIST_FILENAME, &pushpathname)) {            push_status = -1;        } else {            /* Now read the registered connections. */            pushfd = storage_open(&errStr, &pushpathname, OPEN_READ);            if (errStr == NULL) {                /* Read through the file one line at a time */                status = parsePushList(pushfd);                /* Close the storage handle */                storageClose (&errStr, pushfd);                storageFreeError(errStr);                /*                 * IMPL_NOTE: don't check for -1 because in this case some                 * entries can be read anyway                 */                if (status != -2) { /* out of memory */                    if (startListening) {                        pushStartListening();                    }                } else {                    push_status = -1;                }            } else {                REPORT_WARN1(LC_PROTOCOL,                             "Warning: could not open push registration file: %s",                             errStr);                /*                  * This is normal until the first push registration                 * is created.                 */                storageFreeError(errStr);            }        }        if (push_status != 0) {            REPORT_ERROR(LC_PROTOCOL, "Error: push open failed");            pcsl_string_free(&pushpathname);        }    }    return(!push_status && !alarm_status) ? 0 : -1;}/** * Destroys the push and alarm memory resources. Maintain the push * registrations in the push registry file. */void pushclose() {    pushListFree();    alarmListFree();#if ENABLE_JSR_82    bt_push_shutdown();#endif    pcsl_string_free(&pushpathname);    pcsl_string_free(&alarmpathname);}/** * Saves the in memory cache of push registrations to a persistent * file for use in subsequent runs. */static void pushsave() {    int  pushfd;    PushEntry *p;    pushfd = storage_open(&errStr, &pushpathname, OPEN_READ_WRITE_TRUNCATE);    if (errStr == NULL){        /* Write a new list of push registrations to the persistent file */        for (p = pushlist; p != NULL ; p = p->next) {            storageWrite(&errStr, pushfd, p->value, strlen(p->value));            storageWrite(&errStr, pushfd, "\n", 1);        }        /* Close the storage handle */        storageClose (&errStr, pushfd);    } else {        REPORT_WARN1(LC_PROTOCOL,                     "Warning: could not write push registration file: %s",                     errStr);        storageFreeError(errStr);    }}/** * Adds one entry to the push registry. * If the entry already exists return IO_ERROR_LEN (midpString.h). * * @param suiteId ID of the suite * @param connection generic connection name (no spaces) * @param midlet class name of the MIDlet (no spaces) * @param filter filter string (no spaces) * * @return 0 for success, OUT_OF_MEM_LEN for out of memory, * IO_ERROR_LEN if already registered */int midpAddPushEntry(SuiteIdType suiteId,                     const pcsl_string * connection,                     const pcsl_string * midlet,                     const pcsl_string * filter) {    int opened = 0;    int status = 0;    pcsl_string temp = PCSL_STRING_NULL;    const jbyte* pszTemp = NULL;    jsize total_len;    if (NULL == pushlist) {        /* VM not running */        /* Tell push open not to start listening to connections. */        if (pushOpenInternal(0) != 0) {            return OUT_OF_MEM_LEN;        }        opened = 1;    }    total_len = pcsl_string_length(connection)                + pcsl_string_length(midlet)                + pcsl_string_length(filter)                + GET_SUITE_ID_LEN(suiteId)                + PCSL_STRING_LITERAL_LENGTH(COMMA_STRING) * 3;    pcsl_string_predict_size(&temp, total_len);    status = OUT_OF_MEM_LEN;    do {        if (PCSL_STRING_OK != pcsl_string_append(&temp, connection)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp, &COMMA_STRING)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp, midlet)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp, &COMMA_STRING)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp, filter)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp, &COMMA_STRING)) {            break;        }        if (PCSL_STRING_OK != pcsl_string_append(&temp,                                                 midp_suiteid2pcsl_string(suiteId))) {            break;        }        pszTemp = pcsl_string_get_utf8_data(&temp);        if (NULL == pszTemp) {            break;        }        status = pushadd((char *)pszTemp);        pcsl_string_release_utf8_data(pszTemp, &temp);        if (-1 == status) {            status = IO_ERROR_LEN;        } else if (-2 == status) {            status = OUT_OF_MEM_LEN;        }    } while (0);    pcsl_string_free(&temp);    if (opened) {        pushclose();    }    return status;}/** * Adds one entry to the push registry. * If the entry already exists return an error. * On successful registration, write a new copy of the file to disk. * * @param str A push entry string. * @return <tt>0</tt> if successful, *         <tt>-1</tt> if the entry already exists, *         <tt>-2</tt> if out of memory *         <tt>-3</tt> if illegal arguments or unknown connection type */int pushadd(char *str) {    PushEntry *pe;    int comma;    char *cp;    int ret;    /* Count the characters up to the first comma. */    for (comma = 0, cp = str; *cp; comma++, cp++) {        if (*cp == ',') {            break;        }    }    /* Check if the entry already exists? */    for (pe = pushlist; pe != NULL ; pe = pe->next) {        if (strncmp (str, pe->value, comma) == 0) {            return -1 ;        }    }    /* Add the new entry. */    pe = (PushEntry *)midpMalloc(sizeof(PushEntry));    if (NULL == pe) {        return -2;    }    pe->value = midpStrdup(str);    pe->storagename = midpStrdup(pushstorage(str, 3));    pe->filter = pushfilter(str);    if ((pe->value == NULL) || (pe->storagename == NULL) ||            (pe->filter == NULL)) {        midpFree(pe->value);        midpFree(pe->storagename);        midpFree(pe->filter);        midpFree(pe);        return -2;    }    pe->state = AVAILABLE;    pe->fd = -1;    pe->fdsock = -1;    pe->fdAccepted = -1;    pe->pCachedData = NULL;    pe->isWMAEntry = KNI_FALSE;    pe->isWMAMessCached = KNI_FALSE;    pe->appID = NULL;#if ENABLE_JSR_180    pe->isSIPEntry = KNI_FALSE;#endif    /*#if ENABLE_JSR_82    bt_push_register_url(str, NULL, 0);#endif    */    ret = pushProcessPort(pe);    if (pe->fd == -1) {#if ENABLE_JSR_82        bt_push_unregister_url(str);#endif        if (ret == -3) {            /*              * Reject the registration and return error code (-3) for above             * code to raise IllegalArgumentException exception.             */            midpFree(pe->value);            midpFree(pe->storagename);            midpFree(pe->filter);            midpFree(pe);            return -3;        }        /*          * Don't reject the registration.         * Port may be in use by a native application but we can't check this,         * there is a chance network is just not up yet.         */    } else {        pe->state = CHECKED_IN;        pushAddNetworkNotifier(pe);    }    pe->next = pushlist;    pushlist = pe;    pushlength++;    pushsave();    return 0;}/** * Removes one entry from the push registry. * If the entry is not registered return an error. * On successful deletion, write a new copy of the file to disk. * * @param str The push entry string to be deleted * @param store The MIDletSuite storagename * @return <tt>0</tt> if successful, <tt>-2</tt> if the entry belongs *         to another suite. */int pushdel(char *str, char *store) {    PushEntry *p;    PushEntry **pPrevNext = &pushlist;    PushEntry *tmp;    /* Find the entry to remove. */    for (p = pushlist; p != NULL ; p = tmp) {        tmp = p->next;        if (strncmp (str, p->value, strlen(str)) == 0) {            /* Check if the connection belongs to another suite. */            if (strcmp(store, p->storagename) != 0) {                return -2 ;            }#if ENABLE_JSR_82            bt_push_unregister_url(str);#endif            pushDeleteEntry(p, pPrevNext);            pushsave();            return 0;        }        pPrevNext = &p->next;    }    return -1;}/** * Deletes the given entry from the push registry. * This function does the actual work. * * @param p A pointer to the push entry to be removed * @param pPrevNext Address of the <tt>Next</tt> field of the *        previous push entry */static void pushDeleteEntry(PushEntry *p, PushEntry **pPrevNext) {    void *context = NULL;    if (p->fd != -1) {        /*         * Cleanup any connections before closing         * the server socket.         */        if (p->state != CHECKED_OUT) {            /* pushcleanupentry sets the state to CHECKED_IN */            pushcleanupentry(p);            /* closing will disconnect any socket notifiers */            if (pushIsSocketConnection(p->value)) {#if ENABLE_SERVER_SOCKET                pcsl_socket_close_start((void*)(p->fd), &context);                /* Update the resource count */                if (midpDecResourceCount(RSC_TYPE_TCP_SER, 1) == 0) {                    REPORT_INFO(LC_PROTOCOL, "(Push)TCP Server : Resource limit"                                " update error");                }#endif            } else if (pushIsDatagramConnection(p->value)) {                pcsl_datagram_close_start((void *)p->fd, &context);                /* Update the resource count */

⌨️ 快捷键说明

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