push_server.c

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

C
2,135
字号
        if (next->isSIPEntry) {            if (checksipfilter((unsigned char *)next->filter, sender)) {                /*                 * If a media type tag was specified in the connection URI,                 * then the message is only dispatched if it contains                 * an Accept-Contact header with a matching media feature                 * tag.                 */                required_type_len = getMIMEType(next->value, &p);                if (required_type_len) {                    required_type = (unsigned char *)                                    pcsl_mem_malloc(required_type_len + 1);                    if (required_type != NULL) {                        strncpy((char *)required_type, p, required_type_len);                        required_type[required_type_len] = '\0';                    }                    /*                     * Extract the message media type.                     */                    acceptcontact_type =                     getSipAcceptContactType(                                           (unsigned char *) pushp->pCachedData->buffer,                                           pushp->pCachedData->length);                    if (acceptcontact_type != NULL &&                        midp_strcasecmp((char *)required_type,                                        (char*)acceptcontact_type) == 0) {                        REPORT_INFO2(LC_PROTOCOL,                                     "SIP Push Message Media Type Matched: %s == %s",                                     required_type,acceptcontact_type);                        /* Required type matched. */                        found = KNI_TRUE;                        break;                    }                    REPORT_INFO2(LC_PROTOCOL,                                 "SIP Push Message Media Type Filtered: %s != %s",                                 required_type, acceptcontact_type);                } else {                    /* No type required. */                    found = KNI_TRUE;                    break;                }            }            if (!pushp->isShared || NULL == next->next) {                /* for dedicated connection                    and last entry of shared connections chain */                pushcheckinentry(next);                /* and clear chached data for shared connection */                midpFree(pushp->pCachedData);                pushp->pCachedData = NULL;                break;            } else if (pushp == next) {                /*  mark first chain element as checked in and look for                    next element */                next->state = CHECKED_IN;            } else {                /*  keep the state for the rest:                    non-sip and  intermediate chanin member */            }        }        /* scan for entries shared the same connection */        next = next->next;    } while (pushp->isShared);    midpFree(acceptcontact_type);    midpFree(required_type);    midpFree(sender);    if (found && LAUNCH_PENDING != next->state) {        next->state = LAUNCH_PENDING;        return midpStrdup(next->value);    }    return NULL;}#endif#if ENABLE_SERVER_SOCKET/** * Accepts the incoming connection. * * @param pushp push entry with information about the server socket * @param prevState state of the push entry before transition to LAUNCH_PENDING * * @return a midlet suite to launch or NULL */static char* pushAcceptConnection(PushEntry* pushp, int prevState) {    int status;    char ipAddress[MAX_HOST_LENGTH];    void *clientHandle;    void *context;    /*     * accept0() returns a brand new client socket descriptor.     * So resource check should be done against a client socket     * limit.     *     * IMPL_NOTE : an IOException should be thrown when the resource     * is not available, but since this is not a shared code, only     * NULL is returned that would result in returning -1     * to getMIDlet0().     */    if (midpCheckResourceLimit(RSC_TYPE_TCP_CLI, 1) == 0) {        REPORT_INFO(LC_PROTOCOL, "(Push)Resource limit exceeded for"                    " TCP client sockets");        pushp->fdsock = -1;        pushp->state = prevState;        return NULL;    }#ifdef ENABLE_JSR_180    if (prevState == RECEIVED_EVENT && pushp->pCachedData != NULL) {        pushp->fdAccepted = pushp->fdsock;        status = pcsl_socket_read_finish(                                        (void *)pushp->fdsock, (unsigned char *)pushp->pCachedData->buffer,                                        MAX_CACHED_DATA_SIZE, &(pushp->pCachedData->length),                                        &context);        if (status != PCSL_NET_SUCCESS) {            /*             * Receive failed - no data available.             * Cancel the launch pending.             */            REPORT_ERROR1(LC_PUSH,                          "(Push) Cannot receive data, errno = %d\n",                          pcsl_network_error((void*)pushp->fdsock));            pushcheckinentry(pushp);            return NULL;        }        return pushApplySipFilter(pushp);    } else#endif /* ENABLE_JSR_180 */    {        /*         * For a server socket connection, accept the inbound         * socket connection so the end point filter can be checked.         */        status = pcsl_serversocket_accept_start((void*)pushp->fd,                                                &clientHandle, &context);        if (status != PCSL_NET_SUCCESS) {            /*             * Can't accept the connection.             * Cancel the launch pending.             */            REPORT_ERROR1(LC_PUSH,                          "(Push) Cannot accept serversocket, errno = %d\n",                          pcsl_network_error((void*)pushp->fd));            pushcheckinentry(pushp);            return NULL;        }    }    /* Update the resource count for client sockets */    if (midpIncResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) {        REPORT_INFO(LC_PROTOCOL,                    "(Push) Resource limit update error");    }    pushp->fdsock = (int)clientHandle;    pcsl_socket_getremoteaddr((void *)pushp->fdsock, ipAddress);#if ENABLE_JSR_180    if (pushp->isSIPEntry) {        unsigned char ipBytes[MAX_ADDR_LENGTH];        pushp->state = WAITING_DATA;        pushp->pCachedData = (PacketEntry*) midpMalloc(sizeof (PacketEntry));        if (pushp->pCachedData == NULL) {            pushcheckinentry(pushp);            return NULL;        }        pushp->pCachedData->offs = 0;        /* Set the raw IP address */        memcpy(&(pushp->pCachedData->ipAddress), ipBytes, MAX_ADDR_LENGTH);        memset(ipAddress, '\0', MAX_HOST_LENGTH);        strcpy(ipAddress, pcsl_inet_ntoa(&ipBytes));        status = pcsl_socket_read_start(                                       (void *)pushp->fdsock, (unsigned char *)pushp->pCachedData->buffer,                                       MAX_CACHED_DATA_SIZE, &(pushp->pCachedData->length), &context);        if (status == PCSL_NET_SUCCESS) {            status = pcsl_socket_read_finish(                                            (void *)pushp->fdsock, (unsigned char *)pushp->pCachedData->buffer,                                            MAX_CACHED_DATA_SIZE, &(pushp->pCachedData->length),                                            &context);            if (status != PCSL_NET_SUCCESS) {                /*                 * Receive failed - no data available.                 * Cancel the launch pending.                 */                REPORT_ERROR1(LC_PUSH,                              "(Push) Cannot receive data, errno = %d\n",                              pcsl_network_error((void*)pushp->fdsock));                pushcheckinentry(pushp);                return NULL;            }            return pushApplySipFilter(pushp);        }if (status == PCSL_NET_WOULDBLOCK) {            pcsl_add_network_notifier((void *)pushp->fdsock,                                      PCSL_NET_CHECK_READ);            return NULL;        } else {            pushcheckinentry(pushp);            return NULL;        }    } else#endif        /* Datagram and Socket connections use the IP filter. */        /* SIP has its own filtering mechanism applied above. */        if (checkfilter(pushp->filter, ipAddress)) {        return midpStrdup(pushp->value);    }    /*     * Dispose of the filtered push request.     * Close any accepted socket not accessed, yet.     */    pushcheckinentry(pushp);    return NULL;}#endif/** * Lookup the push entry, given a handle. * * @param fd The handle to a push connection * * @return The full text push entry from the push list */char *pushfindfd(int fd) {    PushEntry *pushp;    PushEntry *pushtmp;    int temp_state = AVAILABLE;    AlarmEntry *alarmp;    AlarmEntry *alarmtmp;    char *alarmentry = NULL;    char ipAddress[MAX_HOST_LENGTH];    int status;    unsigned char ipBytes[MAX_ADDR_LENGTH];    void *context = NULL;    /* Find the entry to pass off the open file descriptor. */    for (pushp = pushlist; pushp != NULL ; pushp = pushp->next) {        if ((pushp->fd == (int)fd)) {            for (pushtmp = pushp; pushtmp != NULL; pushtmp = pushtmp->next) {                if ((pushtmp->fd == fd) &&                    (pushtmp->state == LAUNCH_PENDING)) {                    /*                     * Some MIDlet is launching and expecting to                     * read from this fd. Don't steal its traffic.                     */                    return NULL;                }            }            temp_state = pushp->state;            pushp->state = LAUNCH_PENDING;#ifdef ENABLE_JSR_82            if (bt_is_bluetooth_url(pushp->value)) {                bt_pushid_t id = bt_push_find_server((bt_handle_t)fd);                if (id != BT_INVALID_PUSH_HANDLE) {                    if (bt_push_accept(id, pushp->filter,                                       (bt_handle_t *)(void*)&pushp->fdsock)) {                        return midpStrdup(pushp->value);                    }                }                pushcheckinentry(pushp);                return NULL;            }#endif            /*             * Check the push filter, to see if this connection             * is acceptable.             */            if (strncmp(pushp->value, "datagram://:", 12) == 0) {                /*                 * Read the datagram and save it til the application reads it.                 * This is a one datagram message queue.                 */                pushp->pCachedData = (PacketEntry*)                                     midpMalloc(sizeof (PacketEntry));                if (pushp->pCachedData == NULL) {                    pushp->state = temp_state;                    return NULL;                }                pushp->pCachedData->offs = 0;                status = pcsl_datagram_read_finish(                                                  (void *)pushp->fd,                                                  ipBytes,                                                  &(pushp->pCachedData->senderport),                                                  pushp->pCachedData->buffer,                                                  MAX_CACHED_DATA_SIZE,                                                  &(pushp->pCachedData->length),                                                  context);                if (status != PCSL_NET_SUCCESS) {                    /*                     * Receive failed - no data available.                     * cancel the launch pending                     */                    midpFree(pushp->pCachedData);                    pushp->pCachedData = NULL;                    pushp->state = temp_state;                    return NULL;                }                /* Set the raw IP address */                memcpy(&(pushp->pCachedData->ipAddress),                       ipBytes, MAX_ADDR_LENGTH);                memset(ipAddress, '\0', MAX_HOST_LENGTH);                strcpy(ipAddress, pcsl_inet_ntoa(&ipBytes));                /* Datagram and Socket connections use the IP filter. */                if (checkfilter(pushp->filter, ipAddress)) {                    return midpStrdup(pushp->value);                }                /*                 * Dispose of the filtered push request.                 * Release any cached datagrams.                 */                pushcheckinentry(pushp);                return NULL;#if ENABLE_SERVER_SOCKET            } else if (pushIsSocketConnection(pushp->value)) {                return pushAcceptConnection(pushp, temp_state);#endif            }#if ENABLE_JSR_180            /* Check for JSR180 SIP/SIPS connections (UDP). */            else if (pushp->isSIPEntry) {                /* Special case: shared connection. Cached datagram is stored                    at first push entry buffer */                /*                 * Read the SIP datagram and save it til the                 * application reads it.                 * This is a one SIP datagram message queue.                 */                pushp->pCachedData = (PacketEntry*)                                     midpMalloc(sizeof (PacketEntry));                if (pushp->pCachedData == NULL) {                    pushp->state = temp_state;                    return NULL;                }                pushp->pCachedData->offs = 0;                status = pcsl_datagram_read_finish(                                                  (void *)pushp->fd,                                                  ipBytes,                                                  &(pushp->pCachedData->senderport),                                                  pushp->pCachedData->buffer,                                                  MAX_CACHED_DATA_SIZE,                                                  &(pushp->pCachedData->length),                                                  context);                if (status != PCSL_NET_SUCCESS) {                    /*                     * Receive failed - no data available.                     * cancel the launch pending                     */                    midpFree(pushp->pCachedData);                    pushp->pCachedData = NULL;                    pushp->state = temp_state;                    return NULL;                }                /* Set the raw IP address */                memcpy(&(pushp->pCachedData->ipAddress),                       ipBytes, MAX_ADDR_LENGTH);                REPORT_INFO1(LC_PROTOCOL,                             "SIP Push Message: %s",                             pushp->pCachedData->buffer);                /* restore state that will be processed separately at                    pushApplySipFilter */                pushp->state = temp_state;                return pushApplySipFilter(pushp);            }#endif#if (ENABLE_JSR_205 || ENABLE_JSR_120)            else{                /*                 * Return a valid push entry, if the WMA message has been                 * succesfully received (which for sms, mms includes a                 * filter check); otherwise return NULL.                 */                if (pushp->isWMAMessCached){                    return getWmaPushEntry(pushp->value);                } else{                    pushp->state = temp_state;                    return NULL;                }            }#endif            return NULL;        }    }    /*     * If the file descriptor was not found, it could be

⌨️ 快捷键说明

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