// Called by the UPnP Remote I/O Microstack
// Implements the SetPeerOverride call, lets a CP connect this RIO client to
// a new URI. If this RIO client is currently connected, it will disconnect and
// switch to the new URI.
void UpnpRemoteIOClient_RemoteIO_SetPeerOverride(void* upnptoken,char* PeerConnection)
{
	struct parser_result* ParsedAddress = NULL;
	char* RemoteIOSessionPath = NULL;
	char* RemoteIOSessionAddress = NULL;
	int address = 0;

	
	if (upnptoken && (PeerConnection == NULL || (int)strlen(PeerConnection) < 7))
	{
		UpnpResponse_Error(upnptoken,700,"Invalid PeerConnection");
		return;
	}

	sem_wait(&RemoteIOLock);
	if (RIO->PeerConnection == NULL || strcmp(RIO->PeerConnection,PeerConnection) != 0)
	{
		if (RIO->PeerConnection != NULL)
		{
			// Disconnect the socket
			ILibAsyncSocket_Disconnect(RIO->Session);
			free(RIO->PeerConnection);
		}

		// Set the new session URI
		RIO->PeerConnection = (char*)malloc((int)strlen(PeerConnection) + 1);
		strcpy(RIO->PeerConnection,PeerConnection);

		// Event the new connection
		UpnpSetState_RemoteIOClient_RemoteIO_PeerConnection(RIO->RIOmicroStack,RIO->PeerConnection);

		// Connect session
		ParseUri(RIO->PeerConnection,&RemoteIOSessionAddress,&RIO->SessionPort,&RemoteIOSessionPath);
		free(RemoteIOSessionPath);

		ParsedAddress = ILibParseString(RemoteIOSessionAddress,0,(int)strlen(RemoteIOSessionAddress),".",1);

		address  = atoi(ParsedAddress->FirstResult->data);
		address += atoi(ParsedAddress->FirstResult->NextResult->data) << 8;
		address += atoi(ParsedAddress->FirstResult->NextResult->NextResult->data) << 16;
		address += atoi(ParsedAddress->FirstResult->NextResult->NextResult->NextResult->data) << 24;

		ILibAsyncSocket_ConnectTo(RIO->Session,0,address,RIO->SessionPort,NULL,NULL);
		ILibDestructParserResults(ParsedAddress);
		free(RemoteIOSessionAddress);
		sem_post(&RemoteIOLock);

		// Event the user
		if (RemoteIOConnectionChanged != NULL) RemoteIOConnectionChanged(RIO->PeerConnection);
	}
	else 
	{
		sem_post(&RemoteIOLock);
	}
	
	if(upnptoken) {UpnpResponse_RemoteIOClient_RemoteIO_SetPeerOverride(upnptoken);}
}
// Parse a URI string and returns the IP, port and Path portions of the URI
void ParseUri(char* URI, char** IP, int* Port, char** Path)
{
	struct parser_result *result,*result2,*result3;
	char *TempString,*TempString2;
	int TempStringLength,TempStringLength2;
	
	result = ILibParseString(URI, 0, (int)strlen(URI), "://", 3);
	TempString = result->LastResult->data;
	TempStringLength = result->LastResult->datalength;
	
	/* Parse Path */
	result2 = ILibParseString(TempString,0,TempStringLength,"/",1);
	TempStringLength2 = TempStringLength-result2->FirstResult->datalength;
	*Path = (char*)MALLOC(TempStringLength2+1);
	memcpy(*Path,TempString+(result2->FirstResult->datalength),TempStringLength2);
	(*Path)[TempStringLength2] = '\0';
	
	/* Parse Port Number */
	result3 = ILibParseString(result2->FirstResult->data,0,result2->FirstResult->datalength,":",1);
	if(result3->NumResults==1)
	{
		*Port = 80;
	}
	else
	{
		TempString2 = (char*)MALLOC(result3->LastResult->datalength+1);
		memcpy(TempString2,result3->LastResult->data,result3->LastResult->datalength);
		TempString2[result3->LastResult->datalength] = '\0';
		*Port = atoi(TempString2);
		FREE(TempString2);
	}
	/* Parse IP Address */
	TempStringLength2 = result3->FirstResult->datalength;
	*IP = (char*)MALLOC(TempStringLength2+1);
	memcpy(*IP,result3->FirstResult->data,TempStringLength2);
	(*IP)[TempStringLength2] = '\0';
	ILibDestructParserResults(result3);
	ILibDestructParserResults(result2);
	ILibDestructParserResults(result);
}
예제 #3
0
// Called by the UPnP Remote I/O Microstack
// Implements the ForceDisconnect call, lets a CP connect this RIO client
// to a URI if, and only if, this RIO client is not currently connected.
void UpnpRemoteIO_SetPeerInterlock(void* upnptoken,char* PeerConnection)
{
	struct parser_result* ParsedAddress = NULL;
	char* RemoteIOSessionPath = NULL;
	char* RemoteIOSessionAddress = NULL;
	int address = 0;

	if (PeerConnection == NULL || (int)strlen(PeerConnection) < 7)
	{
		UpnpResponse_Error(upnptoken,700,"Invalid PeerConnection");
		return;
	}

	sem_wait(&RemoteIOLock);
	if (RIO->PeerConnection == NULL)
	{
		RIO->PeerConnection = (char*)RIO_MALLOC((int)strlen(PeerConnection) + 1);
		strcpy(RIO->PeerConnection,PeerConnection);

		// Event the new connection
		UpnpSetState_RemoteIO_PeerConnection(RIO->RIOmicroStack,RIO->PeerConnection);

		// Connect session
		ParseUri(RIO->PeerConnection,&RemoteIOSessionAddress,&RIO->SessionPort,&RemoteIOSessionPath);
		RIO_FREE(RemoteIOSessionPath);

		ParsedAddress = ILibParseString(RemoteIOSessionAddress,0,(int)strlen(RemoteIOSessionAddress),".",1);

		address  = atoi(ParsedAddress->FirstResult->data);
		address += atoi(ParsedAddress->FirstResult->NextResult->data) << 8;
		address += atoi(ParsedAddress->FirstResult->NextResult->NextResult->data) << 16;
		address += atoi(ParsedAddress->FirstResult->NextResult->NextResult->NextResult->data) << 24;

		ILibConnectTo(RIO->Session,0,address,RIO->SessionPort);
		ILibDestructParserResults(ParsedAddress);
		RIO_FREE(RemoteIOSessionAddress);
		UpnpResponse_RemoteIO_SetPeerInterlock(upnptoken,RIO->PeerConnection);
		sem_post(&RemoteIOLock);

		// Event the user
		if (RemoteIOConnectionChanged != NULL) RemoteIOConnectionChanged(RIO->PeerConnection);
	}
	else
	{
		UpnpResponse_RemoteIO_SetPeerInterlock(upnptoken,RIO->PeerConnection);
		sem_post(&RemoteIOLock);
	}
}
예제 #4
0
void* ILibCreateSSDPClientModule(void *chain, char* DeviceURN, int DeviceURNLength, void (*CallbackPtr)(void *sender, char* UDN, int Alive, char* LocationURL, int Timeout, UPnPSSDP_MESSAGE m,void *user),void *user)
{
    int i;
    struct SSDPClientModule *RetVal = (struct SSDPClientModule*)malloc(sizeof(struct SSDPClientModule));
    unsigned char TTL = 4;
    struct parser_result *pr;

    RetVal->Destroy = &ILibSSDPClientModule_Destroy;
    RetVal->PreSelect = &ILibSSDPClientModule_PreSelect;
    RetVal->PostSelect = NULL;
    RetVal->Reserved = user;
    RetVal->Terminate = 0;
    RetVal->FunctionCallback = CallbackPtr;
    RetVal->DeviceURN = (char*)malloc(DeviceURNLength+1);
    memcpy(RetVal->DeviceURN,DeviceURN,DeviceURNLength);
    RetVal->DeviceURN[DeviceURNLength] = '\0';
    RetVal->DeviceURNLength = DeviceURNLength;

    // Populate the Prefix portion of the URN, for matching purposes
    RetVal->DeviceURN_Prefix = RetVal->DeviceURN;
    pr = ILibParseString(RetVal->DeviceURN,0,RetVal->DeviceURNLength,":",1);
    RetVal->DeviceURN_PrefixLength = (int)((pr->LastResult->data)-(RetVal->DeviceURN));
    pr->LastResult->data[pr->LastResult->datalength]=0;
    RetVal->BaseDeviceVersionNumber = atoi(pr->LastResult->data);
    ILibDestructParserResults(pr);


    RetVal->IPAddress=NULL;


    RetVal->SSDPListenSocket = ILibAsyncUDPSocket_Create(chain, 4096, 0, 1900, ILibAsyncUDPSocket_Reuse_SHARED, ILibSSDPClient_OnData , NULL, RetVal);
    RetVal->MSEARCH_Response_Socket = ILibAsyncUDPSocket_Create(chain, 4096, 0, 0, ILibAsyncUDPSocket_Reuse_EXCLUSIVE, ILibSSDPClient_OnData , NULL, RetVal);


    ILibAddToChain(chain,RetVal);
    ILibAsyncUDPSocket_SetMulticastTTL(RetVal->MSEARCH_Response_Socket, TTL);


    return(RetVal);
}
예제 #5
0
/* Main entry point to the sample application */
int _tmain(int argc, _TCHAR* argv[])
{
	char *targetFile;

	char *tempBuffer;
	int tempBufferLength;

	char *sourceBuffer;
	char *buffer;
	char *delimiter;
	int delimiterLength;

	int x;

	FILE* TargetFile;
	int TargetFileLength;
	int SourceFileLength;
	struct parser_result *pr;

	HANDLE target,src;
	FILETIME targetFT,srcFT;

	DWORD ptid=0;
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
		
	targetFile = (char*)malloc(2+strlen(argv[1]));
	strcpy(targetFile,argv[1]);
	targetFile[strlen(argv[1])] = '~';
	targetFile[strlen(argv[1])+1] = 0;

	if(argc==2)
	{
		TargetFileLength = ILibReadFileFromDiskEx(&buffer,targetFile);
		if(TargetFileLength!=0)
		{
			ILibWriteStringToDiskEx(argv[1],buffer,TargetFileLength);
			free(buffer);
			ILibDeleteFileFromDisk(targetFile);
		}
		return;
	}

	target = CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	src = CreateFile(argv[2],GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

	GetFileTime(target,NULL,NULL,&targetFT);
	GetFileTime(src,NULL,NULL,&srcFT);

	CloseHandle(target);
	CloseHandle(src);

	if(srcFT.dwHighDateTime < targetFT.dwHighDateTime ||
		(srcFT.dwHighDateTime == targetFT.dwHighDateTime && srcFT.dwLowDateTime < targetFT.dwLowDateTime))
	{
		//return;
	}

	printf("SourceCodeInjector:\r\n");
	printf("	TargetFile: %s\r\n",argv[1]);
	printf("	SourceFile: %s\r\n",argv[2]);
	printf("	VariableName: %s\r\n",argv[3]);
	if(argc==5)
	{
		printf("	Delimiter: %s\r\n",argv[4]);
	}
	// argv[1] = TargetFile
	// argv[2] = SourceFile
	// argv[3] = VariableName

	if(argc==5)
	{
		delimiter = (char*)malloc((int)strlen(argv[4])+1);
		delimiterLength=sprintf(delimiter,"%s",argv[4]);
	}
	else
	{
		delimiter = (char*)malloc((int)strlen(argv[3])+20);
		delimiterLength=sprintf(delimiter,"// -=S3P4R470R=- {%s}",argv[3]);
	}

	TargetFileLength = ILibReadFileFromDiskEx(&buffer,targetFile);
	SourceFileLength = ILibReadFileFromDiskEx(&sourceBuffer,argv[2]);

	if(TargetFileLength == 0)
	{
		TargetFileLength = ILibReadFileFromDiskEx(&buffer,argv[1]);
	}

	if(TargetFileLength == NULL || SourceFileLength == 0)
	{
		exit(0);
	}
	

	tempBufferLength = ILibBase64Encode(sourceBuffer,SourceFileLength,&tempBuffer);
	free(sourceBuffer);
	sourceBuffer = tempBuffer;
	SourceFileLength = tempBufferLength;

	pr = ILibParseString(buffer,0,TargetFileLength,delimiter,delimiterLength);

	TargetFile = fopen(targetFile,"wb");
	fwrite(pr->FirstResult->data,sizeof(char),pr->FirstResult->datalength,TargetFile);
	fwrite(delimiter,sizeof(char),delimiterLength,TargetFile);
	fwrite("\n",sizeof(char),1,TargetFile);

	//fwrite("private static byte[] ",sizeof(char),22,TargetFile);
	//fwrite(argv[3],sizeof(char),strlen(argv[3]),TargetFile);
	//fwrite(" = {",sizeof(char),4,TargetFile);

	fwrite("private static string ",sizeof(char),22,TargetFile);
	fwrite(argv[3],sizeof(char),strlen(argv[3]),TargetFile);
	fwrite(" = \"",sizeof(char),4,TargetFile);

	for(x=0;x<SourceFileLength;++x)
	{
		if(argv[3] != '-')
		{
			if(sourceBuffer[x] == '"')
			{
				fwrite("\\\"",sizeof(char),2,TargetFile);
			}
			else if(sourceBuffer[x] == '\\')
			{
				fwrite("\\\\",sizeof(char),2,TargetFile);
			}
			else if(sourceBuffer[x] == '\r')
			{
				fwrite("\\r",sizeof(char),2,TargetFile);
			}
			else if(sourceBuffer[x] == '\n')
			{
				fwrite("\\n",sizeof(char),2,TargetFile);
			}
			else
			{
				fwrite(&sourceBuffer[x],sizeof(char),1,TargetFile);
			}

			if(x!=0 && x%100==0)
			{
				fwrite("\"\n",sizeof(char),2,TargetFile);
				//if(x!=SourceFileLength-1)
				//{
					fwrite("+\"",sizeof(char),2,TargetFile);
				//}
			}
		}
		else
		{
			fwrite(&sourceBuffer[x],sizeof(char),1,TargetFile);
		}
	}

	if(argv[3]!='-')
	{
		fwrite("\";\n",sizeof(char),3,TargetFile);
	}

	fwrite(delimiter,sizeof(char),delimiterLength,TargetFile);
	fwrite(pr->LastResult->data,sizeof(char),pr->LastResult->datalength,TargetFile);
	fflush(TargetFile);
	fclose(TargetFile);


	ILibDestructParserResults(pr);
	free(sourceBuffer);
	free(buffer);
	free(delimiter);
	free(targetFile);
	return 0;
}
예제 #6
0
void ILibReadSSDP(struct packetheader *packet,int remoteInterface, unsigned short remotePort, struct SSDPClientModule *module)
{
    struct packetheader_field_node *node;
    struct parser_result *pnode,*pnode2;
    struct parser_result_field *prf;

    char* Location = NULL;
    char* UDN = NULL;
    int Timeout = 0;
    int Alive = 0;
    int OK;
    int rt;


    char *IP;
    unsigned short PORT;
    char *PATH;
    int MATCH=0;




    if(packet->Directive==NULL)
    {
        /* M-SEARCH Response */
        if(packet->StatusCode==200)
        {
            node = packet->FirstField;
            while(node!=NULL)
            {

                if(strncasecmp(node->Field,"LOCATION",8)==0)
                {
                    Location = node->FieldData;
                    Location[node->FieldDataLength] = 0;
                    //Location = (char*)malloc(node->FieldDataLength+1);
                    //memcpy(Location,node->FieldData,node->FieldDataLength);
                    //Location[node->FieldDataLength] = '\0';
                }
                if(strncasecmp(node->Field,"CACHE-CONTROL",13)==0)
                {
                    pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, ",", 1);
                    prf = pnode->FirstResult;
                    while(prf!=NULL)
                    {
                        pnode2 = ILibParseString(prf->data, 0, prf->datalength, "=", 1);
                        pnode2->FirstResult->datalength = ILibTrimString(&(pnode2->FirstResult->data),pnode2->FirstResult->datalength);
                        pnode2->FirstResult->data[pnode2->FirstResult->datalength]=0;
                        if(strcasecmp(pnode2->FirstResult->data,"max-age")==0)
                        {
                            pnode2->LastResult->datalength = ILibTrimString(&(pnode2->LastResult->data),pnode2->LastResult->datalength);
                            pnode2->LastResult->data[pnode2->LastResult->datalength]=0;
                            Timeout = atoi(pnode2->LastResult->data);
                            ILibDestructParserResults(pnode2);
                            break;
                        }
                        prf = prf->NextResult;
                        ILibDestructParserResults(pnode2);
                    }
                    ILibDestructParserResults(pnode);
                }
                if(strncasecmp(node->Field,"USN",3)==0)
                {
                    pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "::", 2);
                    pnode->FirstResult->data[pnode->FirstResult->datalength] = '\0';
                    UDN = pnode->FirstResult->data+5;
                    ILibDestructParserResults(pnode);
                }
                node = node->NextField;
            }
            ILibParseUri(Location,&IP,&PORT,&PATH);
            if(remoteInterface==inet_addr(IP))
            {

                if(module->FunctionCallback!=NULL)
                {
                    module->FunctionCallback(module,UDN,-1,Location,Timeout,UPnPSSDP_MSEARCH,module->Reserved);
                }
            }
            free(IP);
            free(PATH);
        }
    }
    else
    {
        /* Notify Packet */
        if(strncasecmp(packet->Directive,"NOTIFY",6)==0)
        {
            OK = 0;
            rt = 0;
            node = packet->FirstField;

            while(node!=NULL)
            {
                node->Field[node->FieldLength] = '\0';
                if(strncasecmp(node->Field,"NT",2)==0 && node->FieldLength==2)
                {
                    node->FieldData[node->FieldDataLength] = '\0';
                    if(strncasecmp(node->FieldData,module->DeviceURN_Prefix,module->DeviceURN_PrefixLength)==0)
                    {


                        if(atoi(node->FieldData+module->DeviceURN_PrefixLength)>=module->BaseDeviceVersionNumber)
                        {
                            OK = -1;
                        }

                    }

                    else if(strncasecmp(node->FieldData,"upnp:rootdevice",15)==0)
                    {
                        rt = -1;
                    }

                }
                if(strncasecmp(node->Field,"NTS",3)==0)
                {
                    if(strncasecmp(node->FieldData,"ssdp:alive",10)==0)
                    {
                        Alive = -1;
                        rt = 0;
                    }
                    else
                    {
                        Alive = 0;
                        OK = 0;
                    }
                }
                if(strncasecmp(node->Field,"USN",3)==0)
                {
                    pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "::", 2);
                    pnode->FirstResult->data[pnode->FirstResult->datalength] = '\0';
                    UDN = pnode->FirstResult->data+5;
                    ILibDestructParserResults(pnode);
                }
                if(strncasecmp(node->Field,"LOCATION",8)==0)
                {
                    Location = node->FieldData;
                    Location[node->FieldDataLength] = 0;
                }

                if(strncasecmp(node->Field,"CACHE-CONTROL",13)==0)
                {
                    pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, ",", 1);
                    prf = pnode->FirstResult;
                    while(prf!=NULL)
                    {
                        pnode2 = ILibParseString(prf->data, 0, prf->datalength, "=", 1);
                        pnode2->FirstResult->datalength = ILibTrimString(&(pnode2->FirstResult->data),pnode2->FirstResult->datalength);
                        pnode2->FirstResult->data[pnode2->FirstResult->datalength]=0;
                        if(strcasecmp(pnode2->FirstResult->data,"max-age")==0)
                        {
                            pnode2->LastResult->datalength = ILibTrimString(&(pnode2->LastResult->data),pnode2->LastResult->datalength);
                            pnode2->LastResult->data[pnode2->LastResult->datalength]=0;
                            Timeout = atoi(pnode2->LastResult->data);
                            ILibDestructParserResults(pnode2);
                            break;
                        }
                        prf = prf->NextResult;
                        ILibDestructParserResults(pnode2);
                    }
                    ILibDestructParserResults(pnode);
                }
                node = node->NextField;
            }
            if((OK!=0 && Alive!=0) || (Alive==0))
            {
                if(Location!=NULL)
                {
                    ILibParseUri(Location,&IP,&PORT,&PATH);
                    if(remoteInterface==inet_addr(IP))
                    {
                        MATCH=1;
                    }
                    else
                    {
                        MATCH=0;
                    }
                    free(IP);
                    free(PATH);

                }
                if(Alive==0 || MATCH!=0)
                {
                    if(module->FunctionCallback!=NULL)
                    {
                        module->FunctionCallback(module,UDN,Alive,Location,Timeout,UPnPSSDP_NOTIFY,module->Reserved);
                    }
                }
            }

        }
    }
}
예제 #7
0
	__declspec(dllexport) void ILibWrapper_DestructParserResults(struct parser_result *result)
	{
		ILibDestructParserResults(result);
	}
예제 #8
0
BOOL ParsePlayContainerUri(PlayListManager_PC state, char* uri)
{
	struct parser_result_field* field;
	struct parser_result* parseResults;
	int length;
	char* pos = NULL;
	char* tmp = NULL;

	uri = PC_UriUnescape(uri);
	pos = uri + 21;

	if(ILibString_StartsWith(uri, (int)strlen(uri), "dlna-playcontainer://", 21) == 0)
	{
		free(uri);
		return FALSE;
	}
	if(ILibString_StartsWithEx(pos, (int)strlen(pos), "uuid:", 5, 0) != 0)
	{
		pos += 5;
	}
	{
		char out[4096];
		sprintf(out, "%s\n", pos);
		OutputDebugString(out);
	}
	tmp = MyStrChr(pos, 0x003f);
	{
		char out[4096];
		sprintf(out, "%s\n", tmp);
		OutputDebugString(out);
	}
	if(tmp == NULL)
	{
		free(uri);
		return FALSE;
	}
	length = (int)(tmp - pos);
	String_Destroy(state->UDN);
	state->UDN = String_CreateSize(length);
	strncpy(state->UDN, pos, (size_t)length);
	state->UDN[length] = 0;
	if(state->UDN[length - 1] == '/')
	{
		state->UDN[length - 1] = 0;
	}
	pos += length + 1;

	parseResults = ILibParseString(pos, 0, (int)strlen(pos), "&", 1);

	state->FirstItemIndex = -1;

	field = parseResults->FirstResult;
	while(field != NULL)
	{
		int length;
		char* val = field->data;
		if(ILibString_StartsWith(field->data, field->datalength, "sid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->ServiceID);
			state->ServiceID = String_CreateSize(length);
			strncpy(state->ServiceID, val, (size_t)length);
			state->ServiceID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "cid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->ContainerID);
			state->ContainerID = String_CreateSize(length);
			strncpy(state->ContainerID, val, (size_t)length);
			state->ContainerID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "fid=", 4) != 0)
		{
			length = field->datalength - 4;
			val += 4;
			String_Destroy(state->FirstItemID);
			state->FirstItemID = String_CreateSize(length);
			strncpy(state->FirstItemID, val, (size_t)length);
			state->FirstItemID[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "fii=", 4) != 0)
		{
			char* tmp = NULL;
			length = field->datalength - 4;
			val += 4;
			tmp = String_CreateSize(length);
			strncpy(tmp, val, length);
			tmp[length] = 0;
			state->FirstItemIndex = atoi(tmp);
			String_Destroy(tmp);
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "sc=", 3) != 0)
		{
			length = field->datalength - 3;
			val += 3;
			String_Destroy(state->SortArgs);
			state->SortArgs = String_CreateSize(length);
			strncpy(state->SortArgs, val, (size_t)length);
			state->SortArgs[length] = 0;
		}
		else if(ILibString_StartsWith(field->data, field->datalength, "md=", 3) != 0)
		{
			char* tmp = NULL;
			length = field->datalength - 3;
			val += 3;
			tmp = String_CreateSize(length);
			strncpy(tmp, val, length);
			tmp[length] = 0;
			state->MaxDepth = atoi(tmp);
			String_Destroy(tmp);
		}
		else
		{
			String_Destroy(state->UDN);
			String_Destroy(state->ServiceID);
			String_Destroy(state->ContainerID);
			String_Destroy(state->FirstItemID);
			String_Destroy(state->SortArgs);
			ILibDestructParserResults(parseResults);

			return FALSE;
		}
		field = field->NextResult;
	}

	ILibDestructParserResults(parseResults);

	if(state->ServiceID != NULL && state->ContainerID != NULL && state->FirstItemID != NULL && state->FirstItemIndex != -1)
	{
		free(uri);
		return TRUE;
	}
	else
	{
		String_Destroy(state->UDN);
		String_Destroy(state->ServiceID);
		String_Destroy(state->ContainerID);
		String_Destroy(state->FirstItemID);
		String_Destroy(state->SortArgs);

		free(uri);
		return FALSE;
	}
}
예제 #9
0
void ILibReadSSDP(SOCKET ReadSocket, struct SSDPClientModule *module)
{
	int bytesRead = 0;
	char* buffer = (char*)malloc(4096);
	struct sockaddr_in addr;
	int addrlen = sizeof(struct sockaddr_in);
	struct packetheader *packet;
	struct packetheader_field_node *node;
	struct parser_result* pnode;
	
	char* Location = NULL;
	char* UDN = NULL;
	int Timeout = 0;
	int Alive = 0;
	int OK;
	int rt;
	
	bytesRead = recvfrom(ReadSocket, buffer, 4096, 0, (struct sockaddr *) &addr, &addrlen);
	if(bytesRead<=0) 
	{
		FREE(buffer);
		return;
	}
	packet = ILibParsePacketHeader(buffer,0,bytesRead);
	
	if(packet->Directive==NULL)
	{
		/* M-SEARCH Response */
		if(packet->StatusCode==200)
		{
			node = packet->FirstField;
			while(node!=NULL)
			{
				if(strncasecmp(node->Field,"LOCATION",8)==0)
				{
					Location = (char*)MALLOC(node->FieldDataLength+1);
					memcpy(Location,node->FieldData,node->FieldDataLength);
					Location[node->FieldDataLength] = '\0';
				}
				if(strncasecmp(node->Field,"CACHE-CONTROL",13)==0)
				{
					pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "=", 1);
					pnode->LastResult->data[pnode->LastResult->datalength] = '\0';
					Timeout = atoi(pnode->LastResult->data);
					ILibDestructParserResults(pnode);
				}
				if(strncasecmp(node->Field,"USN",3)==0)
				{
					pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "::", 2);
					pnode->FirstResult->data[pnode->FirstResult->datalength] = '\0';
					UDN = pnode->FirstResult->data+5;
					ILibDestructParserResults(pnode);
				}
				node = node->NextField;
			}
			if(module->FunctionCallback!=NULL)
			{
				module->FunctionCallback(module,UDN,-1,Location,Timeout,module->Reserved);
			}
			
		}
	}
	else
	{
		/* Notify Packet */
		if(strncasecmp(packet->Directive,"NOTIFY",6)==0)
		{
			OK = 0;
			rt = 0;
			node = packet->FirstField;
			while(node!=NULL)
			{
				node->Field[node->FieldLength] = '\0';
				if(strncasecmp(node->Field,"NT",2)==0 && node->FieldLength==2)
				{
					node->FieldData[node->FieldDataLength] = '\0';
					if(strncasecmp(node->FieldData,module->DeviceURN,module->DeviceURNLength)==0)
					{
						OK = -1;
					}
					else if(strncasecmp(node->FieldData,"upnp:rootdevice",15)==0)
					{
						rt = -1;
					}
					else
					{
						break;
					}
				}
				if(strncasecmp(node->Field,"NTS",3)==0)
				{
					if(strncasecmp(node->FieldData,"ssdp:alive",10)==0)
					{
						Alive = -1;
						rt = 0;
					}
					else
					{
						Alive = 0;
						OK = 0;
					}
				}
				if(strncasecmp(node->Field,"USN",3)==0)
				{
					pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "::", 2);
					pnode->FirstResult->data[pnode->FirstResult->datalength] = '\0';
					UDN = pnode->FirstResult->data+5;
					ILibDestructParserResults(pnode);
				}
				if(strncasecmp(node->Field,"LOCATION",8)==0)
				{
					Location = (char*)MALLOC(node->FieldDataLength+1);
					memcpy(Location,node->FieldData,node->FieldDataLength);
					Location[node->FieldDataLength] = '\0';
				}
				if(strncasecmp(node->Field,"CACHE-CONTROL",13)==0)
				{
					pnode = ILibParseString(node->FieldData, 0, node->FieldDataLength, "=", 1);
					pnode->LastResult->data[pnode->LastResult->datalength] = '\0';
					Timeout = atoi(pnode->LastResult->data);
					ILibDestructParserResults(pnode);
				}
				node = node->NextField;
			}
			if((OK!=0 && Alive!=0) || (rt!=0 && Alive==0))
			{
				if(module->FunctionCallback!=NULL)
				{
					module->FunctionCallback(module,UDN,Alive,Location,Timeout,module->Reserved);
				}
			}
		}
	}
	if(Location!=NULL) {FREE(Location);}
	ILibDestructPacket(packet);
	FREE(buffer);
}
void ILibWebServer_OnResponse(void *WebReaderToken,
								int InterruptFlag,
								struct packetheader *header,
								char *bodyBuffer,
								int *beginPointer,
								int endPointer,
								int done,
								void *user1,
								void *user2,
								int *PAUSE)
{
	struct ILibWebServer_Session *ws = (struct ILibWebServer_Session*)user2;
	struct ILibWebServer_StateModule *wsm = (struct ILibWebServer_StateModule*)ws->Parent;
	
	char *tmp;
	int tmpLength;
	struct parser_result *pr;
	int PreSlash=0;

	if(ws->Reserved4!=0 || ws->Reserved5==0)
	{
		// Not Idle anymore
		ws->Reserved4 = 0;
		ws->Reserved5 = 1;
		ws->Reserved8 = 0;
		ILibLifeTime_Remove(((struct ILibWebServer_StateModule*)ws->Parent)->LifeTime,ws);
	}


	//Check Virtual Directory
	if(wsm->VirtualDirectoryTable!=NULL)
	{
		if(ws->Reserved7==NULL)
		{
			pr = ILibParseString(header->DirectiveObj,0,header->DirectiveObjLength,"/",1);
			if(pr->FirstResult->datalength==0)
			{
				// Does not start with '/'
				tmp = pr->FirstResult->NextResult->data;
				tmpLength = pr->FirstResult->NextResult->datalength;
			}
			else
			{
				// Starts with '/'
				tmp = pr->FirstResult->data;
				tmpLength = pr->FirstResult->datalength;
				PreSlash=1;
			}
			ILibDestructParserResults(pr);
			if(ILibHasEntry(wsm->VirtualDirectoryTable,tmp,tmpLength)!=0)
			{
				// Virtual Directory Defined
				header->DirectiveObj = tmp+tmpLength;
				header->DirectiveObjLength -= (tmpLength+PreSlash);
				ws->Reserved7 = ILibGetEntry(wsm->VirtualDirectoryTable,tmp,tmpLength);

				((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user);
			}
			else if(ws->OnReceive!=NULL)
			{
				ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done);
			}
		}
		else
		{
			((ILibWebServer_VirtualDirectory)((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->callback)(ws,header,bodyBuffer,beginPointer,endPointer,done,((struct ILibWebServer_VirDir_Data*)ws->Reserved7)->user);
		}
	}
	else if(ws->OnReceive!=NULL)
	{
		ws->OnReceive(ws,InterruptFlag,header,bodyBuffer,beginPointer,endPointer,done);
	}


	if(done!=0 && InterruptFlag==0 && header!=NULL && ws->Reserved8==0)
	{
		*PAUSE=1;
	}
}
struct packetheader* ILibParsePacketHeader(char* buffer, int offset, int length)
{
	struct packetheader *RetVal = (struct packetheader*)MALLOC(sizeof(struct packetheader));
	struct parser_result *_packet;
	struct parser_result *p;
	struct parser_result *StartLine;
	struct parser_result_field *HeaderLine;
	struct parser_result_field *f;
	char* tempbuffer;
	struct packetheader_field_node *node;
	int i=0;
	int FLNWS = -1;
	int FTNWS = -1;
	RetVal->UserAllocStrings = 0;
	RetVal->Directive = NULL;
	RetVal->DirectiveLength = 0;
	RetVal->Body = NULL;
	RetVal->BodyLength = 0;
	RetVal->FirstField = NULL;
	RetVal->LastField = NULL;
	RetVal->Source = NULL;
	p = (struct parser_result*)ILibParseString(buffer,offset,length,"\r\n",2);
	_packet = p;
	f = p->FirstResult;
	StartLine = (struct parser_result*)ILibParseString(f->data,0,f->datalength," ",1);
	HeaderLine = f->NextResult;
	if(memcmp(StartLine->FirstResult->data,
	"HTTP/",
	5)==0)
	{
		/* Response Packet */
		p = (struct parser_result*)ILibParseString(StartLine->FirstResult->data,
		0,
		StartLine->FirstResult->datalength,
		"/",1);
		RetVal->Version = p->LastResult->data;
		RetVal->VersionLength = p->LastResult->datalength;
		ILibDestructParserResults(p);
		tempbuffer = (char*)MALLOC(1+sizeof(char)*(StartLine->FirstResult->NextResult->datalength));
		memcpy(tempbuffer,StartLine->FirstResult->NextResult->data,
		StartLine->FirstResult->NextResult->datalength);
		tempbuffer[StartLine->FirstResult->NextResult->datalength] = '\0';
		RetVal->StatusCode = (int)atoi(tempbuffer);
		FREE(tempbuffer);
		RetVal->StatusData = StartLine->FirstResult->NextResult->NextResult->data;
		RetVal->StatusDataLength = StartLine->FirstResult->NextResult->NextResult->datalength;
	}
	else
	{
		/* Request Packet */
		RetVal->Directive = StartLine->FirstResult->data;
		RetVal->DirectiveLength = StartLine->FirstResult->datalength;
		RetVal->DirectiveObj = StartLine->FirstResult->NextResult->data;
		RetVal->DirectiveObjLength = StartLine->FirstResult->NextResult->datalength;
		RetVal->StatusCode = -1;
		p = (struct parser_result*)ILibParseString(StartLine->LastResult->data,
		0,
		StartLine->LastResult->datalength,
		"/",1);
		RetVal->Version = p->LastResult->data;
		RetVal->VersionLength = p->LastResult->datalength;
		ILibDestructParserResults(p);
		
		RetVal->Directive[RetVal->DirectiveLength] = '\0';
		RetVal->DirectiveObj[RetVal->DirectiveObjLength] = '\0';
	}
	while(HeaderLine!=NULL)
	{
		if(HeaderLine->datalength==0)
		{
			break;
		}
		node = (struct packetheader_field_node*)MALLOC(sizeof(struct packetheader_field_node));
		memset(node,0,sizeof(struct packetheader_field_node));
		for(i=0;i<HeaderLine->datalength;++i)
		{
			if(*((HeaderLine->data)+i)==':')
			{
				node->Field = HeaderLine->data;
				node->FieldLength = i;
				node->FieldData = HeaderLine->data + i + 1;
				node->FieldDataLength = (HeaderLine->datalength)-i-1;
				break;
			}
		}
		if(node->Field==NULL)
		{
			FREE(RetVal);
			RetVal = NULL;
			break;
		}
		FLNWS = 0;
		FTNWS = node->FieldDataLength-1;
		for(i=0;i<node->FieldDataLength;++i)
		{
			if(*((node->FieldData)+i)!=' ')
			{
				FLNWS = i;
				break;
			}
		}
		for(i=(node->FieldDataLength)-1;i>=0;--i)
		{
			if(*((node->FieldData)+i)!=' ')
			{
				FTNWS = i;
				break;
			}
		}
		node->FieldData = (node->FieldData) + FLNWS;
		node->FieldDataLength = (FTNWS - FLNWS)+1;
		
		node->Field[node->FieldLength] = '\0';
		node->FieldData[node->FieldDataLength] = '\0';
		
		node->UserAllocStrings = 0;
		node->NextField = NULL;
		
		if(RetVal->FirstField==NULL)
		{
			RetVal->FirstField = node;
			RetVal->LastField = node;
		}
		else
		{
			RetVal->LastField->NextField = node;	
		}
		RetVal->LastField = node;
		HeaderLine = HeaderLine->NextResult;
	}
	ILibDestructParserResults(_packet);
	ILibDestructParserResults(StartLine);
	return(RetVal);
}
struct ILibXMLNode *ILibParseXML(char *buffer, int offset, int length)
{
	struct parser_result *xml;
	struct parser_result_field *field;
	struct parser_result *temp;
	struct parser_result *temp2;
	struct parser_result *temp3;
	char* TagName;
	int TagNameLength;
	int StartTag;
	int EmptyTag;
	int i;
	
	struct ILibXMLNode *RetVal = NULL;
	struct ILibXMLNode *current = NULL;
	struct ILibXMLNode *x = NULL;
	
	char *NSTag;
	int NSTagLength;
	
	xml = ILibParseString(buffer,offset,length,"<",1);
	field = xml->FirstResult;
	while(field!=NULL)
	{
		if(memcmp(field->data,"?",1)!=0)
		{
			EmptyTag = 0;
			if(memcmp(field->data,"/",1)==0)
			{
				StartTag = 0;
				field->data = field->data+1;
				field->datalength -= 1;
				temp2 = ILibParseString(field->data,0,field->datalength,">",1);
			}
			else
			{
				StartTag = -1;
				temp2 = ILibParseString(field->data,0,field->datalength,">",1);
				if(temp2->FirstResult->data[temp2->FirstResult->datalength-1]=='/')
				{
					EmptyTag = -1;
				}
			}
			temp = ILibParseString(temp2->FirstResult->data,0,temp2->FirstResult->datalength," ",1);
			temp3 = ILibParseString(temp->FirstResult->data,0,temp->FirstResult->datalength,":",1);
			if(temp3->NumResults==1)
			{
				NSTag = NULL;
				NSTagLength = 0;
				TagName = temp3->FirstResult->data;
				TagNameLength = temp3->FirstResult->datalength;
			}
			else
			{
				NSTag = temp3->FirstResult->data;
				NSTagLength = temp3->FirstResult->datalength;
				TagName = temp3->FirstResult->NextResult->data;
				TagNameLength = temp3->FirstResult->NextResult->datalength;
			}
			ILibDestructParserResults(temp3);
			
			for(i=0;i<TagNameLength;++i)
			{
				if( (TagName[i]==' ')||(TagName[i]=='/')||(TagName[i]=='>')||(TagName[i]=='\r')||(TagName[i]=='\n') )
				{
					if(i!=0)
					{
						if(TagName[i]=='/')
						{
							EmptyTag = -1;
						}
						TagNameLength = i;
						break;
					}
				}
			}
			
			if(TagNameLength!=0)
			{
				x = (struct ILibXMLNode*)MALLOC(sizeof(struct ILibXMLNode));
				x->Next = NULL;
				x->Name = TagName;
				x->NameLength = TagNameLength;
				x->StartTag = StartTag;
				x->NSTag = NSTag;
				x->NSLength = NSTagLength;
				
				x->Parent = NULL;
				x->Peer = NULL;
				x->ClosingTag = NULL;
				x->EmptyTag = 0;
				
				
				if(StartTag==0)
				{
					x->Reserved = field->data;
					do
					{
						(char*)x->Reserved -= 1;
					}while(*((char*)x->Reserved)=='<');
				}
				else
				{
					x->Reserved = temp2->LastResult->data;
				}
				
				if(RetVal==NULL)
				{
					RetVal = x;
				}
				else
				{
					current->Next = x;
				}
				current = x;
				if(EmptyTag!=0)
				{
					x = (struct ILibXMLNode*)MALLOC(sizeof(struct ILibXMLNode));
					x->Next = NULL;
					x->Name = TagName;
					x->NameLength = TagNameLength;
					x->StartTag = 0;
					x->NSTag = NSTag;
					x->NSLength = NSTagLength;
					
					x->Parent = NULL;
					x->Peer = NULL;
					x->ClosingTag = NULL;
					
					x->Reserved = current->Reserved;
					current->EmptyTag = -1;
					current->Next = x;
					current = x;
				}
			}
			
			ILibDestructParserResults(temp2);
			ILibDestructParserResults(temp);
		}
		field = field->NextResult;
	}
	
	ILibDestructParserResults(xml);
	return(RetVal);
}
struct ILibXMLAttribute *ILibGetXMLAttributes(struct ILibXMLNode *node)
{
	struct ILibXMLAttribute *RetVal = NULL;
	struct ILibXMLAttribute *current = NULL;
	char *c;
	int EndReserved = (node->EmptyTag==0)?1:2;
	
	struct parser_result *xml;
	struct parser_result_field *field;
	struct parser_result *temp2;
	struct parser_result *temp3;
	
	c = (char*)node->Reserved - 1;
	while(*c!='<')
	{
		c = c -1;
	}
	c = c +1;
	
	xml = ILibParseStringAdv(c,0,(int)((char*)node->Reserved - c -EndReserved)," ",1);
	field = xml->FirstResult;
	if(field!=NULL) {field = field->NextResult;}
	while(field!=NULL)
	{
		if(RetVal==NULL)
		{
			RetVal = (struct ILibXMLAttribute*)MALLOC(sizeof(struct ILibXMLAttribute));
			RetVal->Next = NULL;
		}
		else
		{
			current = (struct ILibXMLAttribute*)MALLOC(sizeof(struct ILibXMLAttribute));
			current->Next = RetVal;
			RetVal = current;
		}
		temp2 = ILibParseStringAdv(field->data,0,field->datalength,":",1);
		if(temp2->NumResults==1)
		{
			RetVal->Prefix = NULL;
			RetVal->PrefixLength = 0;
			temp3 = ILibParseStringAdv(field->data,0,field->datalength,"=",1);
		}
		else
		{
			RetVal->Prefix = temp2->FirstResult->data;
			RetVal->PrefixLength = temp2->FirstResult->datalength;
			temp3 = ILibParseStringAdv(field->data,RetVal->PrefixLength+1,field->datalength-RetVal->PrefixLength-1,"=",1);
		}
		ILibDestructParserResults(temp2);
		RetVal->Name = temp3->FirstResult->data;
		RetVal->NameLength = temp3->FirstResult->datalength;
		RetVal->Value = temp3->LastResult->data;
		RetVal->ValueLength = temp3->LastResult->datalength;
		ILibDestructParserResults(temp3);
		field = field->NextResult;
	}
	
	ILibDestructParserResults(xml);
	return(RetVal);
	
}
예제 #14
0
struct DLNAProtocolInfo *DLNAProtocolInfo_Parse(char *protocolInfo, int protocolInfoLength)
{
	struct parser_result *pr,*pr2,*pr3,*pr4;
	struct parser_result_field *prf,*prf2;
	char *temp;

	long flags;
	int tempInt;

	struct DLNAProtocolInfo *RetVal = (struct DLNAProtocolInfo*)malloc(sizeof(struct DLNAProtocolInfo));
	memset(RetVal,0,sizeof(struct DLNAProtocolInfo));
	RetVal->NameValueTable = ILibInitHashTree_CaseInSensitive();

	RetVal->DLNA_Major_Version = 1;
	RetVal->Protocol = DLNAProtocolInfo_ProtocolType_UNKNOWN;

	pr = ILibParseString(protocolInfo,0,protocolInfoLength,":",1);
	if(pr->NumResults==4 || pr->NumResults==1)
	{
		if(pr->NumResults==4)
		{
			if(pr->FirstResult->datalength==8 && memcmp(pr->FirstResult->data,"http-get",8)==0)
			{
				RetVal->Protocol = DLNAProtocolInfo_ProtocolType_HTTP;
			}
			else if(pr->FirstResult->datalength==19 && memcmp(pr->FirstResult->data,"playsingle-http-get",19)==0)
			{
				RetVal->Protocol = DLNAProtocolInfo_ProtocolType_HTTP;
				RetVal->IsPlaySingleUri = 1;
			}
			else if(pr->FirstResult->datalength==12 && memcmp(pr->FirstResult->data,"rtsp-rtp-udp",12)==0)
			{
				RetVal->Protocol = DLNAProtocolInfo_ProtocolType_RTP;
			}
			else if(pr->FirstResult->datalength==23 && memcmp(pr->FirstResult->data,"playsingle-rtsp-rtp-udp",23)==0)
			{
				RetVal->Protocol = DLNAProtocolInfo_ProtocolType_RTP;
				RetVal->IsPlaySingleUri = 1;
			}
			else if(pr->FirstResult->datalength==1 && memcmp(pr->FirstResult->data,"*",1)==0)
			{
				RetVal->Protocol = DLNAProtocolInfo_ProtocolType_ANY;
			}

			RetVal->MimeType = (char*)malloc(pr->FirstResult->NextResult->NextResult->datalength+1);
			memcpy(RetVal->MimeType,pr->FirstResult->NextResult->NextResult->data,pr->FirstResult->NextResult->NextResult->datalength);
			RetVal->MimeType[pr->FirstResult->NextResult->NextResult->datalength]=0;
		}
		pr2 = ILibParseString(pr->LastResult->data,0,pr->LastResult->datalength,";",1);
		prf = pr2->FirstResult;
		while(prf!=NULL)
		{
			pr3 = ILibParseString(prf->data,0,prf->datalength,"=",1);
			ILibAddEntry(RetVal->NameValueTable,pr3->FirstResult->data,pr3->FirstResult->datalength,ILibString_Copy(pr3->LastResult->data,pr3->LastResult->datalength));
			if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_PN",11)==0)
			{
				//
				// Profile
				//
				temp = (char*)malloc(pr3->LastResult->datalength+1);
				memcpy(temp,pr3->LastResult->data,pr3->LastResult->datalength);
				temp[pr3->LastResult->datalength]=0;
				RetVal->Profile = temp;
			}
			if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_OP",11)==0)
			{
				//
				// OP Code
				//
				flags = DLNA_StringToLong(2,pr3->LastResult->data,pr3->LastResult->datalength);
				if(RetVal->Protocol == DLNAProtocolInfo_ProtocolType_HTTP)
				{
					RetVal->SupportsTimeBasedSeek = DLNA_Bits(&flags)->Bit1; 
					RetVal->SupportsByteBasedSeek = DLNA_Bits(&flags)->Bit0;
				}
				else if(RetVal->Protocol == DLNAProtocolInfo_ProtocolType_RTP)
				{
					RetVal->SupportsTimeBasedSeek = DLNA_Bits(&flags)->Bit0;
				}
			}
			if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_PS",11)==0)
			{
				//
				// Supported Play Speeds
				//
				pr4 = ILibParseString(pr3->LastResult->data,0,pr3->LastResult->datalength,",",1);
				RetVal->SupportedPlaySpeedsLength = pr4->NumResults;
				RetVal->SupportedPlaySpeeds = (char**)malloc(RetVal->SupportedPlaySpeedsLength*sizeof(char*));
				tempInt = 0;
				prf2 = pr4->FirstResult;
				while(prf2!=NULL)
				{
					RetVal->SupportedPlaySpeeds[tempInt] = (char*)malloc(2+prf2->datalength);
					memcpy(RetVal->SupportedPlaySpeeds[tempInt],prf2->data,prf2->datalength);
					RetVal->SupportedPlaySpeeds[tempInt][prf2->datalength]=0;
					++tempInt;
					prf2 = prf2->NextResult;
				}
				ILibDestructParserResults(pr4);
			}
			if(pr3->FirstResult->datalength==11 && memcmp(pr3->FirstResult->data,"DLNA.ORG_CI",11)==0)
			{
				//
				// Conversion Indication
				//
				RetVal->IsConvertedContent = (int)DLNA_StringToLong(2,pr3->LastResult->data,pr3->LastResult->datalength);
			}
			if(pr3->FirstResult->datalength==14 && memcmp(pr3->FirstResult->data,"DLNA.ORG_FLAGS",14)==0)
			{
				//
				// Primary Flags (8 digits)
				//
				flags = DLNA_StringToLong(16,pr3->LastResult->data,pr3->LastResult->datalength<8?pr3->LastResult->datalength:8);
				if(DLNA_Bits(&flags)->Bit20)
				{
					RetVal->DLNA_Major_Version = 1;
					RetVal->DLNA_Minor_Version = 5;
				}
				if(RetVal->DLNA_Major_Version==1 && RetVal->DLNA_Minor_Version>=5)
				{
					RetVal->SenderPaced = DLNA_Bits(&flags)->Bit31;
					RetVal->LimitedOperations_TimeBasedSeek = DLNA_Bits(&flags)->Bit30;
					RetVal->LimitedOperations_ByteBasedSeek = DLNA_Bits(&flags)->Bit29;
					RetVal->DLNAPlayContainer = DLNA_Bits(&flags)->Bit28;
					RetVal->S0_Increasing = DLNA_Bits(&flags)->Bit27;
					RetVal->SN_Increasing = DLNA_Bits(&flags)->Bit26;
					RetVal->RTSP_Pause = DLNA_Bits(&flags)->Bit25;
					RetVal->TM_S = DLNA_Bits(&flags)->Bit24;
					RetVal->TM_I = DLNA_Bits(&flags)->Bit23;
					RetVal->TM_B = DLNA_Bits(&flags)->Bit22;
				}
				RetVal->HTTP_Stalling = DLNA_Bits(&flags)->Bit21;
			}
			if(pr3->FirstResult->datalength==14 && memcmp(pr3->FirstResult->data,"DLNA.ORG_MAXSP",14)==0)
			{
				pr4 = ILibParseString(pr3->LastResult->data,0,pr3->LastResult->datalength,".",1);
				RetVal->MaxSpeed_Major = (int)DLNA_StringToLong(10,pr4->FirstResult->data,pr4->FirstResult->datalength);
				if(pr4->NumResults==2)
				{
					RetVal->MaxSpeed_Minor = (int)DLNA_StringToLong(10,pr4->LastResult->data,pr4->LastResult->datalength);
				}
				ILibDestructParserResults(pr4);
			}

			ILibDestructParserResults(pr3);
			prf = prf->NextResult;
		}
		ILibDestructParserResults(pr2);
	}
	ILibDestructParserResults(pr);
	return(RetVal);
}
예제 #15
0
void DH_RequestResponse(ILibWebClient_StateObject WebStateObject,int InterruptFlag,struct packetheader *header,char *bodyBuffer,int *beginPointer,int endPointer,int done,void *user1,void *user2,int *PAUSE)
{
	struct DHC_Data *data = (struct DHC_Data*)user1;
	enum DHC_Errors status;
	void *Abort = NULL;
	char *rangeResult;
	struct parser_result *pr;
	long total;
	char *contentFeatures;
	struct DLNAProtocolInfo *pi;

	ILibReaderWriterLock rwLock = NULL;
	struct packetheader *GetRequest = NULL;
	struct sockaddr_in dest;

	int needToIssueRange = 0;
	int needToIssueRealRequest = 0;
	int MustNotResume = 0;
	struct packetheader *req;
	char *temp;

	if(data==NULL)
	{
		//
		// We appeared to be in the wrong state, most likely received
		// some bad responses, so if we ignore it, we should recover.
		//
		return;
	}

	if((header==NULL && done!=0) || (header!=NULL && header->StatusCode!=200 && header->StatusCode!=206 && done!=0))
	{
		fclose(data->f);
		if(header==NULL)
		{
			status = DHC_ERRORS_CONNECTION_FAILED_OR_ABORTED;
		}
		else
		{
			status = DHC_ERRORS_HTTP;
		}

		if(data->Callback!=NULL)
		{
			if(header!=NULL)
			{
				header->StatusData[header->StatusDataLength]=0;
			}
			data->Callback(data->TransferStatus, status, header==NULL?0:header->StatusCode, header==NULL?NULL:header->StatusData,data->user);
		}
		DH_DestroyTransferStatus(data->TransferStatus);
		if(data->ActualPacket!=NULL)
		{
			ILibDestructPacket(data->ActualPacket);
		}
		free(data);
		ILibWebClient_ResetUserObjects(WebStateObject,NULL, NULL);
	}
	else if(header!=NULL && (header->StatusCode==200 || header->StatusCode==206))
	{
		if(data->ActualPacket!=NULL)
		{
			if(data->DoneProcessingContentFeatures==0)
			{
				data->DoneProcessingContentFeatures = 1;

				//
				// Determine if Range is supported, then do another Head Range Request
				//
				if(data->TransferStatus->Reserved4!=0 && data->TransferStatus->RequestToken!=NULL)
				{
					//
					// Abort... Nothing really to do, because at this point we already finished.
					// Only thing to do, is to not actually issue the request.
					//
					data->TransferStatus->RequestToken = NULL;
				}
				else
				{

					//
					// Transfer Mode wasn't specified
					//
					contentFeatures = ILibGetHeaderLine(header,"contentFeatures.dlna.org",24);
					if(contentFeatures!=NULL)
					{
						temp = ILibString_Cat("http-get:*:*:",13,contentFeatures,(int)strlen(contentFeatures));
						pi = DLNAProtocolInfo_Parse(temp,(int)strlen(temp));
						if(pi!=NULL)
						{
							if(pi->TM_B!=0)
							{
								DH_AddHeader_transferMode(data->ActualPacket,DH_TransferMode_Bulk);
								data->TransferMode = DH_TransferMode_Bulk;
							}
							else if(pi->TM_I!=0)
							{
								DH_AddHeader_transferMode(data->ActualPacket,DH_TransferMode_Interactive);
								data->TransferMode = DH_TransferMode_Interactive;
							}
							else if(pi->TM_S!=0)
							{
								DH_AddHeader_transferMode(data->ActualPacket,DH_TransferMode_Streaming);
								data->TransferMode = DH_TransferMode_Streaming;
							}
							needToIssueRange = pi->SupportsByteBasedSeek;
							DLNAProtocolInfo_Destruct(pi);
						}
						free(temp);
					}
					else
					{
						//
						// since the server didn't respond with a DLNA Content Features, then
						// most likely this is a plain Media Server, in which case, if it doesn't support range
						// it won't return an error, and it'll just ignore the header, so we can issue a range
						// request anyways.
						//
						needToIssueRange = 1;
					}
					if(needToIssueRange!=0)
					{
						//
						// Issue a Range Request
						//
						req = ILibCreateEmptyPacket();
						ILibSetVersion(req,"1.1",3);
						ILibAddHeaderLine(req,"Host",4,ILibGetHeaderLine(data->ActualPacket,"Host",4),(int)strlen(ILibGetHeaderLine(data->ActualPacket,"Host",4)));					
						ILibSetDirective(req,"HEAD",4,data->ActualPacket->DirectiveObj,data->ActualPacket->DirectiveObjLength);
						DH_AddHeader_Range(req,0,-1);

						memset(&dest,0,sizeof(struct sockaddr_in));
						dest.sin_family = AF_INET;
						dest.sin_addr.s_addr = header->Source->sin_addr.s_addr;
						dest.sin_port = header->Source->sin_port;

						ILibReaderWriterLock_WriteLock(data->rwLock);
						switch(data->TransferMode)
						{
							case DH_TransferMode_Bulk:
								ILibWebClient_SetQosForNextRequest(data->manager,ILibAsyncSocket_QOS_BACKGROUND);
								break;
							case DH_TransferMode_Streaming:
								ILibWebClient_SetQosForNextRequest(data->manager,ILibAsyncSocket_QOS_AUDIO_VIDEO);
								break;
						}
						data->TransferStatus->RequestToken = data->token = ILibWebClient_PipelineRequest(data->manager,&dest,req,&DH_RequestResponse,data,NULL);
						ILibReaderWriterLock_WriteUnLock(data->rwLock);
					}
					else
					{
						//
						// Range is not supported, so just continue with making the request.
						// However, before we do, since range isn't supported, we need to make
						// sure that we aren't trying to resume.
						MustNotResume = 1;
						needToIssueRealRequest = 1;
					}
				}
			}
			else
			{
				//
				// Process the Range Response
				//
				rangeResult = ILibGetHeaderLine(header,"content-range",13);
				if(rangeResult!=NULL)
				{
					pr = ILibParseString(rangeResult,0,(int)strlen(rangeResult),"/",1);
					total = atol(pr->LastResult->data);
					ILibDestructParserResults(pr);
					total -= data->StartPosition;
					sem_wait(&(data->TransferStatus->syncLock));
					data->TransferStatus->TotalBytesToBeReceived = total;
					sem_post(&(data->TransferStatus->syncLock));
				}
				else
				{
					//
					// We couldn't get a range result, so we need to make sure
					// we don't try to do a resume.
					//
					MustNotResume = 1;
				}

				//
				// Continue with actually making the content request
				//
				needToIssueRealRequest = 1;
			}

			if(needToIssueRealRequest!=0 && !(data->TransferStatus->Reserved4!=0 && data->TransferStatus->RequestToken!=NULL))
			{
				GetRequest = data->ActualPacket;
				data->ActualPacket = NULL;

				rwLock = (ILibReaderWriterLock)ILibWebClient_GetUser(data->manager);
				memset(&dest,0,sizeof(struct sockaddr_in));
	
				dest.sin_family = AF_INET;
				dest.sin_addr.s_addr = header->Source->sin_addr.s_addr;
				dest.sin_port = header->Source->sin_port;

				if(MustNotResume!=0)
				{
					//
					// Range isn't supported, so we must not resume
					//
					if(data->StartPosition!=0)
					{
						data->StartPosition = 0;
						fseek(data->f,0,SEEK_SET);
					}
				}
				else if(data->StartPosition!=0)
				{
					DH_AddHeader_Range(GetRequest,data->StartPosition,-1);
				}

				ILibReaderWriterLock_WriteLock(rwLock);
				switch(data->TransferMode)
				{
					case DH_TransferMode_Bulk:
						ILibWebClient_SetQosForNextRequest(data->manager,ILibAsyncSocket_QOS_BACKGROUND);
						break;
					case DH_TransferMode_Streaming:
						ILibWebClient_SetQosForNextRequest(data->manager,ILibAsyncSocket_QOS_AUDIO_VIDEO);
						break;
				}
				data->TransferStatus->RequestToken = data->token = ILibWebClient_PipelineRequest(data->manager,&dest,GetRequest,&DH_RequestResponse,data,NULL);
				ILibReaderWriterLock_WriteUnLock(rwLock);
			}

			*beginPointer = endPointer; // Don't really need to do this, because it should always be zero
			return;
		}


		data->buffer = bodyBuffer;
		data->bufferLength = endPointer;
		*beginPointer = endPointer;
		data->GotContinue = done;
		if(endPointer!=0 || done)
		{
			*PAUSE = 1;
		}
		if(data->token!=NULL)
		{
			data->webState = ILibWebClient_GetStateObjectFromRequestToken(data->token);
		}
		if(data->TransferStatus->Reserved4!=0 && data->TransferStatus->RequestToken!=NULL)
		{
			//
			// Abort
			//
			Abort = data->TransferStatus->RequestToken;
			data->TransferStatus->RequestToken = NULL;
			ILibWebClient_CancelRequest(Abort);
		}
		else if(data->TransferStatus->RequestToken!=NULL)
		{
			if(endPointer>0 || done)
			{
				ILibThreadPool_QueueUserWorkItem(data->pool,data,&DH_Pool_RequestResponse);
			}
		}
	}
}
예제 #16
0
int ILibWrapper_SdpToBlock(char* sdp, int sdpLen, int *isActive, char **username, char **password, char **block)
{
	struct parser_result *pr;
	struct parser_result_field *f;

	int ptr;
	int blockLen;
	void* candidates = NULL;
	char* lines;
	char* dtlshash = NULL;
	int dtlsHashLen = 0;
	int candidatecount = 0;
	int BlockFlags = 0;
	*isActive = 0;
	*username = NULL;
	*password = NULL;


	ILibCreateStack(&candidates);

	lines = ILibString_Replace(sdp, sdpLen, "\n", 1, "\r", 1);
	pr = ILibParseString(lines, 0, sdpLen, "\r", 1);
	f = pr->FirstResult;
	while(f!=NULL)
	{
		if(f->datalength == 0) { f = f->NextResult; continue; }

		f->data[f->datalength] = 0;
		if(strcmp(f->data, "a=setup:passive")==0)
        {			
			BlockFlags |= ILibWebRTC_SDP_Flags_DTLS_SERVER;
        }
		else if(strcmp(f->data, "a=setup:active")==0 || strcmp(f->data, "a=setup:actpass")==0)
		{
			*isActive = 1;
		}

		if(f->datalength > 12 && strncmp(f->data, "a=ice-ufrag:", 12)==0) {*username = f->data + 12;} 
		if(f->datalength > 10 && strncmp(f->data, "a=ice-pwd:", 10)==0) {*password = f->data + 10;} 

		if(f->datalength > 22 && strncmp(f->data, "a=fingerprint:sha-256 ", 22)==0)
		{
			char* tmp = ILibString_Replace(f->data + 22, f->datalength - 22, ":", 1, "", 0);
			dtlsHashLen = util_hexToBuf(tmp, strlen(tmp), tmp);
			dtlshash = tmp;
		}

		if(f->datalength > 12 && strncmp(f->data, "a=candidate:", 12)==0)
        {
			struct parser_result* pr2 = ILibParseString(f->data, 0, f->datalength, " ", 1);

			if(pr2->FirstResult->NextResult->datalength == 1 && pr2->FirstResult->NextResult->data[0] == '1' && pr2->FirstResult->NextResult->NextResult->datalength == 3 && strncasecmp(pr2->FirstResult->NextResult->NextResult->data, "UDP", 3)==0)
			//if(pr2->FirstResult->NextResult->NextResult->datalength == 3 && strncasecmp(pr2->FirstResult->NextResult->NextResult->data, "UDP", 3)==0)
			{
				char* candidateData;
				struct parser_result *pr3;
				char *tmp = pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->NextResult->data;
				unsigned short port;

				tmp[pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->NextResult->datalength] = 0;
				port = atoi(tmp);
				
				pr3 = ILibParseString(pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->data, 0, pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->datalength, ".", 1);					
				if (pr3->NumResults == 4)
				{
					candidateData = pr3->FirstResult->data;
					pr3->FirstResult->data[pr3->FirstResult->datalength] = 0;
					candidateData[0] = (char)atoi(pr3->FirstResult->data);
					pr3->FirstResult->NextResult->data[pr3->FirstResult->NextResult->datalength] = 0;
					candidateData[1] = (char)atoi(pr3->FirstResult->NextResult->data);
					pr3->FirstResult->NextResult->NextResult->data[pr3->FirstResult->NextResult->NextResult->datalength] = 0;
					candidateData[2] = (char)atoi(pr3->FirstResult->NextResult->NextResult->data);
					pr3->FirstResult->NextResult->NextResult->NextResult->data[pr3->FirstResult->NextResult->NextResult->NextResult->datalength] = 0;
					candidateData[3] = (char)atoi(pr3->FirstResult->NextResult->NextResult->NextResult->data);

					((unsigned short*)candidateData)[2] = htons(port);
					candidateData[6] = 0;

					ILibPushStack(&candidates, candidateData);
					++candidatecount;
				}
				ILibDestructParserResults(pr3);
			}

			ILibDestructParserResults(pr2);
        }
		f = f->NextResult;
    }

	if (*username == NULL || *password == NULL || dtlshash == NULL || candidatecount == 0)
    {
		*block = NULL;
		return(0);
    }

	
	blockLen = 6 + strlen(*username)+1 + strlen(*password)+1  + dtlsHashLen + 1 + (candidatecount*6)+1;
	if((*block = (char*)malloc(blockLen))==NULL){ILIBCRITICALEXIT(254);}
	ptr = 0;

	((unsigned short*)*block+ptr)[0] = htons(1);
	ptr += 2;

	((unsigned int*)(*block+ptr))[0] = htonl(BlockFlags);
	ptr += 4;

	(*block)[ptr] = (char)strlen(*username);
	ptr += 1;
	memcpy(*block+ptr, *username, strlen(*username));
	ptr += strlen(*username);

	(*block)[ptr] = (char)strlen(*password);
	ptr += 1;
	memcpy(*block+ptr, *password, strlen(*password));
	ptr += strlen(*password);

	(*block)[ptr] = (char)dtlsHashLen;
	ptr += 1;
	memcpy(*block+ptr, dtlshash, dtlsHashLen);
	ptr += dtlsHashLen;

	(*block)[ptr] = (char)candidatecount;
	ptr += 1;
	while(ILibPeekStack(&candidates)!=NULL)
	{
		memcpy(*block+ptr, ILibPopStack(&candidates), 6);
		ptr += 6;
	}

	ILibDestructParserResults(pr);
	free(lines);
	if(dtlshash!=NULL) {free(dtlshash);}
	return(ptr);
}