UPNP_MSEARCH_HANDLE_ITEM* UPNP_MSEARCH_HANDLE_ITEM_Create(UPNP_SERVER_HANDLE handle) { UPNP_MSEARCH_HANDLE_ITEM* item = NULL; UPNP_SSDP_HANDLE_ITEM* srvHandle = NULL; int ret = 0; if( handle == NULL ){ return NULL; } srvHandle = (UPNP_SSDP_HANDLE_ITEM*)handle; item = (UPNP_MSEARCH_HANDLE_ITEM*)malloc(sizeof(UPNP_MSEARCH_HANDLE_ITEM)); if( item != NULL ){ item->msearchCallBack = srvHandle->msearchCallBack; item->msearchCallBackParam = srvHandle->msearchCallBackParam; item->lockHandle = MP_LOCK_CreateHandle(); item->msearchThread = NULL; item->msearchStopFlag = 0; item->resultList = SORT_LIST_CreateHandle(0, SORT_LIST_COMPDEF_strcmp, NULL, UPNP_SSDP_SOCKET_ITEM_Delete); } return item; }
//ハンドルの作成 //戻り値:ハンドル、エラー時NULL UPNP_SERVER_HANDLE UPNP_SERVER_CreateHandle( UPNP_SSDP_CALLBACK ssdpCallBack, //[IN]SSDPのNotify通知用コールバック void* ssdpCallBackParam, //[IN]SSDPのNotify通知用コールバック呼出時に入れるパラメーター UPNP_MSEARCH_REQUEST_CALLBACK msearchCallBack, //[IN]SSDPのM-SEARCHリクエスト通知用コールバック void* msearchCallBackParam //[IN]SSDPのM-SEARCHリクエスト通知用コールバック呼出時に入れるパラメーター ) { UPNP_SSDP_HANDLE_ITEM* item = NULL; #ifdef _WIN32 WSADATA wsaData; #endif item = (UPNP_SSDP_HANDLE_ITEM*)malloc(sizeof(UPNP_SSDP_HANDLE_ITEM)); if( item != NULL ){ item->ssdpCallBack = ssdpCallBack; item->ssdpCallBackParam = ssdpCallBackParam; item->msearchCallBack = msearchCallBack; item->msearchCallBackParam = msearchCallBackParam; item->lockHandle = MP_LOCK_CreateHandle(); item->ssdpSrvThread = NULL; item->ssdpSrvStopFlag = 0; item->notifySendThread = NULL; item->notifySendStopFlag = 0; item->ssdpSockList = SORT_LIST_CreateHandle(1, SORT_LIST_COMPDEF_strcmp, NULL, UPNP_SSDP_SOCKET_ITEM_Delete); item->recvThreadList = SORT_LIST_CreateHandle(1, SORT_LIST_COMPDEF_strcmp, NULL, UPNP_SSDP_RECV_PARAM_Delete); item->notifyDeviceList = SORT_LIST_CreateHandle(0, SORT_LIST_COMPDEF_strcmp, NULL, UPNP_SSDP_NOTIFY_DEVICE_INFO_Delete); #ifdef _WIN32 CoInitialize(NULL); ZeroMemory(&wsaData, sizeof(wsaData)); WSAStartup(MAKEWORD(2, 2), &wsaData); #endif } return (void*)item; }
HTTP_REQUEST_HEADER* HTTP_REQUEST_HEADER_New() { HTTP_REQUEST_HEADER* item = NULL; item = (HTTP_REQUEST_HEADER*)malloc(sizeof(HTTP_REQUEST_HEADER)); if( item != NULL ){ item->method = NULL; item->uri = NULL; item->version = NULL; item->headerList = SORT_LIST_CreateHandle(0, SORT_LIST_COMPDEF_stricmp, NULL, HTTP_HEADER_FIELD_INFO_Delete); } return item; }
UPNP_SSDP_NOTIFY_DEVICE_INFO* UPNP_SSDP_NOTIFY_DEVICE_INFO_New() { UPNP_SSDP_NOTIFY_DEVICE_INFO* item = NULL; item = (UPNP_SSDP_NOTIFY_DEVICE_INFO*)malloc(sizeof(UPNP_SSDP_NOTIFY_DEVICE_INFO)); if( item != NULL ){ item->uuid = NULL; item->locationPort = 0; item->locationUri = NULL; item->urnList = SORT_LIST_CreateHandle(0, SORT_LIST_COMPDEF_strcmp, NULL, SORT_LIST_DELDEF_free); } return item; }
void UPNP_SERVER_SSDPMSearchMsg(UPNP_SSDP_RECV_PARAM* param, HTTP_REQUEST_HEADER* httpReqHeader, char* src) { UPNP_SSDP_RECV_PARAM* info = NULL; UPNP_SSDP_HANDLE_ITEM* handle = NULL; UPNP_MSEARCH_REQUEST_INFO* requestParam = NULL; SORT_LIST_HANDLE resDeviceList = NULL; HTTP_HEADER_FIELD_INFO* headerItem = NULL; UPNP_MSEARCH_RES_DEV_INFO* devInfo = NULL; int length = 0; int i=0; char nowTime[30] = ""; char resMsg[1024] = ""; char buff[256] = ""; SOCKET sendSock; char ua[128] = ""; info = (UPNP_SSDP_RECV_PARAM*)param; if( info == NULL ){ return ; } handle = (UPNP_SSDP_HANDLE_ITEM*)info->ssdpHandle; if( handle == NULL ){ return ; } if( handle->msearchCallBack == NULL ){ return ; } requestParam = UPNP_MSEARCH_REQUEST_INFO_New(); resDeviceList = SORT_LIST_CreateHandle(1, SORT_LIST_COMPDEF_stricmp, NULL, UPNP_MSEARCH_RES_DEV_INFO_Delete); //リクエスト全体 length = (int)strlen(param->recvData); requestParam->res = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->res, length+1, param->recvData); #else strcpy(requestParam->res, param->recvData); #endif //ヘッダをコピー headerItem = (HTTP_HEADER_FIELD_INFO*)SORT_LIST_FindItem(httpReqHeader->headerList, (void*)"HOST" ); if( headerItem != NULL ){ length = (int)strlen(headerItem->value); requestParam->host = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->host, length+1, headerItem->value); #else strcpy(requestParam->host, headerItem->value); #endif } headerItem = (HTTP_HEADER_FIELD_INFO*)SORT_LIST_FindItem(httpReqHeader->headerList, (void*)"MAN" ); if( headerItem != NULL ){ length = (int)strlen(headerItem->value); requestParam->man = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->man, length+1, headerItem->value); #else strcpy(requestParam->man, headerItem->value); #endif } headerItem = (HTTP_HEADER_FIELD_INFO*)SORT_LIST_FindItem(httpReqHeader->headerList, (void*)"MX" ); if( headerItem != NULL ){ length = (int)strlen(headerItem->value); requestParam->mx = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->mx, length+1, headerItem->value); #else strcpy(requestParam->mx, headerItem->value); #endif } headerItem = (HTTP_HEADER_FIELD_INFO*)SORT_LIST_FindItem(httpReqHeader->headerList, (void*)"ST" ); if( headerItem != NULL ){ length = (int)strlen(headerItem->value); requestParam->st = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->st, length+1, headerItem->value); #else strcpy(requestParam->st, headerItem->value); #endif } headerItem = (HTTP_HEADER_FIELD_INFO*)SORT_LIST_FindItem(httpReqHeader->headerList, (void*)"USER-AGENT" ); if( headerItem != NULL ){ length = (int)strlen(headerItem->value); requestParam->userAgent = (char*)malloc(length+1); #ifdef _WIN32 strcpy_s(requestParam->userAgent, length+1, headerItem->value); #else strcpy(requestParam->userAgent, headerItem->value); #endif } //通知 handle->msearchCallBack(requestParam, handle->msearchCallBackParam, resDeviceList); //MP_Sleep(500); MP_TIME_GetNowTime_RFC1123(nowTime, sizeof(nowTime)); //デバイスごとに送信 for(i=0; i<SORT_LIST_GetCount(resDeviceList); i++ ){ devInfo = (UPNP_MSEARCH_RES_DEV_INFO*)SORT_LIST_GetItemByIndex(resDeviceList, i); if( param->nicInfo->ipv4 == NULL || devInfo->uri == NULL ){ continue; } #ifdef _WIN32 strcpy_s(resMsg, sizeof(resMsg), "HTTP/1.1 200 OK\r\n"); sprintf_s(buff, sizeof(buff), "CACHE-CONTROL: max-age=%d\r\n", devInfo->max_age); strcat_s(resMsg, sizeof(resMsg), buff); // sprintf_s(buff, sizeof(buff), "DATE: %s\r\n", nowTime); // strcat_s(resMsg, sizeof(resMsg), buff); sprintf_s(buff, sizeof(buff), "LOCATION: http://%s:%d%s\r\n", param->nicInfo->ipv4, devInfo->port, devInfo->uri); strcat_s(resMsg, sizeof(resMsg), buff); sprintf_s(buff, sizeof(buff), "ST: %s\r\n", requestParam->st); strcat_s(resMsg, sizeof(resMsg), buff); if(devInfo->usn != NULL ){ sprintf_s(buff, sizeof(buff), "USN: %s\r\n", devInfo->usn); strcat_s(resMsg, sizeof(resMsg), buff); } UPNP_UTIL_GetUserAgent(ua, sizeof(ua)); sprintf_s(buff, sizeof(buff), "SERVER: %s\r\n", ua); strcat_s(resMsg, sizeof(resMsg), buff); strcat_s(resMsg, sizeof(resMsg), "EXT:\r\n"); strcat_s(resMsg, sizeof(resMsg), "\r\n"); #else strcpy(resMsg, "HTTP/1.1 200 OK\r\n"); sprintf(buff, "CACHE-CONTROL: max-age=%d\r\n", devInfo->max_age); strcat(resMsg, buff); // sprintf(buff, "DATE: %s\r\n", nowTime); // strcat(resMsg, buff); sprintf(buff, "LOCATION: http://%s:%d%s\r\n", param->nicInfo->ipv4, devInfo->port, devInfo->uri); strcat(resMsg, buff); sprintf(buff, "ST: %s\r\n", requestParam->st); strcat(resMsg, buff); if(devInfo->usn != NULL ){ sprintf(buff, "USN: %s\r\n", devInfo->usn); strcat(resMsg, buff); } UPNP_UTIL_GetUserAgent(ua, sizeof(ua)); sprintf_s(buff, sizeof(buff), "SERVER: %s\r\n", ua); strcat_s(resMsg, sizeof(resMsg), buff); strcat(resMsg, "EXT:\r\n"); strcat(resMsg, "\r\n"); #endif //レスポンス送信 MP_Sleep(10); sendSock = socket(AF_INET, SOCK_DGRAM, 0); //OutputDebugStringA(resMsg); sendto(sendSock, resMsg, (int)strlen(resMsg), 0, (struct sockaddr *)¶m->client, sizeof(param->client)); shutdown(sendSock, SD_BOTH); closesocket(sendSock); } SORT_LIST_CloseHandle(&resDeviceList); UPNP_MSEARCH_REQUEST_INFO_Delete(requestParam); }