// 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); }
// 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); } }
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); }
/* 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; }
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); } } } } } }
// // String Parsing // __declspec(dllexport) void* ILibWrapper_ParseString(char* buffer, int offset, int length, const char* Delimiter, int DelimiterLength) { return(ILibParseString(buffer, offset, length, Delimiter, DelimiterLength)); }
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; } }
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 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); }
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); } } } }
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); }