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