/************************************************************************ * Function : process_reply * * Parameters: * IN char* request_buf: the response came from the device * IN int buf_len: The length of the response buffer * IN struct sockaddr_in* dest_addr: The address of the device * IN void *cookie : cookie passed by the control point application * at the time of sending search message * * Description: * This function processes reply recevied from a search * * Returns: void * ***************************************************************************/ static XINLINE void process_reply( IN char *request_buf, IN int buf_len, IN struct sockaddr_in *dest_addr, IN void *cookie ) { http_parser_t parser; parser_response_init( &parser, HTTPMETHOD_MSEARCH ); // parse if( parser_append( &parser, request_buf, buf_len ) != PARSE_SUCCESS ) { httpmsg_destroy( &parser.msg ); return; } // handle reply ssdp_handle_ctrlpt_msg( &parser.msg, dest_addr, FALSE, cookie ); // done httpmsg_destroy( &parser.msg ); }
void readFromSSDPSocket(SOCKET socket) { char *requestBuf = NULL; char staticBuf[BUFSIZE]; struct sockaddr_storage __ss; ThreadPoolJob job; ssdp_thread_data *data = NULL; socklen_t socklen = sizeof(__ss); ssize_t byteReceived = 0; char ntop_buf[INET6_ADDRSTRLEN]; memset(&job, 0, sizeof(job)); requestBuf = staticBuf; /* in case memory can't be allocated, still drain the socket using a * static buffer. */ data = malloc(sizeof(ssdp_thread_data)); if (data) { /* initialize parser */ #ifdef INCLUDE_CLIENT_APIS if (socket == gSsdpReqSocket4 #ifdef UPNP_ENABLE_IPV6 || socket == gSsdpReqSocket6 #endif /* UPNP_ENABLE_IPV6 */ ) parser_response_init(&data->parser, HTTPMETHOD_MSEARCH); else parser_request_init(&data->parser); #else /* INCLUDE_CLIENT_APIS */ parser_request_init(&data->parser); #endif /* INCLUDE_CLIENT_APIS */ /* set size of parser buffer */ if (membuffer_set_size(&data->parser.msg.msg, BUFSIZE) == 0) /* use this as the buffer for recv */ requestBuf = data->parser.msg.msg.buf; else { free(data); data = NULL; } } byteReceived = recvfrom(socket, requestBuf, BUFSIZE - (size_t)1, 0, (struct sockaddr *)&__ss, &socklen); if ((byteReceived > 0) && IsBoundAddress(((struct sockaddr_in *)&__ss)->sin_addr.s_addr)) { requestBuf[byteReceived] = '\0'; switch (__ss.ss_family) { case AF_INET: inet_ntop(AF_INET, &((struct sockaddr_in *)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf)); break; #ifdef UPNP_ENABLE_IPV6 case AF_INET6: inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf)); break; #endif /* UPNP_ENABLE_IPV6 */ default: memset(ntop_buf, 0, sizeof(ntop_buf)); strncpy(ntop_buf, "<Invalid address family>", sizeof(ntop_buf) - 1); } UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "Start of received response ----------------------------------------------------\n" "%s\n" "End of received response ------------------------------------------------------\n" "From host %s\n", requestBuf, ntop_buf); /* add thread pool job to handle request */ if (data != NULL) { data->parser.msg.msg.length += (size_t) byteReceived; /* null-terminate */ data->parser.msg.msg.buf[byteReceived] = 0; memcpy(&data->dest_addr, &__ss, sizeof(__ss)); TPJobInit(&job, (start_routine) ssdp_event_handler_thread, data); TPJobSetFreeFunction(&job, free_ssdp_event_handler_data); TPJobSetPriority(&job, MED_PRIORITY); if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0) free_ssdp_event_handler_data(data); } } else free_ssdp_event_handler_data(data); }