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