void _StartPlayListProcessingFromThread(PlayListManager_S state) { char* IP; char* Path; unsigned short Port; char *host; int hostLen; struct sockaddr_in dest; ILibWebClient_RequestToken token; char* uri = state->Parent->URI; struct packetheader* header = ILibCreateEmptyPacket(); ILibParseUri(uri, &IP, &Port, &Path); ILibSetVersion(header, "1.1", 3); ILibSetDirective(header, "GET", 3, Path, (int)strlen(Path)); host = (char*)malloc((int)strlen(IP) + 10); hostLen = sprintf(host, "%s:%u", IP, Port); ILibAddHeaderLine(header, "Host", 4, host, hostLen); ILibAddHeaderLine(header, "transferMode.dlna.org", 21, "Interactive", 11); memset(&dest, 0, sizeof(struct sockaddr_in)); dest.sin_addr.s_addr = inet_addr(IP); dest.sin_port = htons(Port); token = ILibWebClient_PipelineRequest(state->Parent->RequestManager, &dest, header, &_RequestResponseCallback, state, NULL); if(IP != NULL) { free(IP); } if(Path != NULL) { free(Path); } free(host); }
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); } } } } } }
DH_TransferStatus DHC_IssuePostRequestFromFile(ILibWebClient_RequestManager request_manager, ILibThreadPool pool, const char* target_uri, const char *file_path, int resume_pos, enum DH_TransferModes requestedTransferMode, const char *mime_type, const char *content_features, void* user_obj, DHC_OnResponseDone callback_response) { DH_TransferStatus RetVal; struct packetheader *h; struct sockaddr_in addr; char host[22]; struct DHC_Data *data = NULL; FILE *f; long fileLength; char *Ip; char *Path; unsigned short Port; ILibReaderWriterLock rwLock = (ILibReaderWriterLock)ILibWebClient_GetUser(request_manager); if(rwLock==NULL) { rwLock = ILibReaderWriterLock_CreateEx(ILibWebClient_GetChain(request_manager)); ILibWebClient_SetUser(request_manager,rwLock); } f = fopen(file_path,"rb"); if(f==NULL) { // // Couldn't open file // return(NULL); } data = (struct DHC_Data*)malloc(sizeof(struct DHC_Data)); memset(data,0,sizeof(struct DHC_Data)); data->TransferMode = requestedTransferMode; data->f = f; data->user = user_obj; data->Callback = callback_response; data->pool = pool; data->buffer = (char*)malloc(DHC_READ_BLOCK_SIZE); data->bufferLength = DHC_READ_BLOCK_SIZE; RetVal = data->TransferStatus = DH_CreateNewTransferStatus(); data->rwLock = rwLock; ILibParseUri((char*)target_uri,&Ip,&Port,&Path); memset(&addr,0,sizeof(struct sockaddr_in)); addr.sin_addr.s_addr = inet_addr(Ip); addr.sin_port = htons(Port); sprintf(host,"%s:%u",Ip,Port); h = ILibCreateEmptyPacket(); ILibSetVersion(h,"1.1",3); ILibSetDirective(h,"POST",4,Path,(int)strlen(Path)); ILibAddHeaderLine(h,"Host",4,host,(int)strlen(host)); ILibAddHeaderLine(h,"Expect",6,"100-Continue",12); if(resume_pos>0) { fseek(f,0,SEEK_END); fileLength = ftell(f); fseek(f,(long)resume_pos,SEEK_SET); DH_AddHeader_ContentRange(h,resume_pos,fileLength-1,fileLength); } if(requestedTransferMode!=DH_TransferMode_Unspecified) { DH_AddHeader_transferMode(h, DH_TransferMode_Bulk); } if(content_features!=NULL) { ILibAddHeaderLine(h,"contentFeatures.dlna.org",24,(char*) content_features,(int)strlen(content_features)); } if(mime_type!=NULL) { ILibAddHeaderLine(h,"Content-Type",12,(char*)mime_type,(int)strlen(mime_type)); } ILibReaderWriterLock_WriteLock(rwLock); switch(data->TransferMode) { case DH_TransferMode_Bulk: ILibWebClient_SetQosForNextRequest(request_manager,ILibAsyncSocket_QOS_BACKGROUND); break; case DH_TransferMode_Streaming: ILibWebClient_SetQosForNextRequest(request_manager,ILibAsyncSocket_QOS_AUDIO_VIDEO); break; } data->token = data->TransferStatus->RequestToken = ILibWebClient_PipelineStreamedRequest(request_manager,&addr,h,&DHC_OnResponse,&DHC_OnSendOK,NULL,data); ILibReaderWriterLock_WriteUnLock(rwLock); free(Ip); free(Path); return(RetVal); }
DH_TransferStatus DHC_IssueRequestAndSave(ILibWebClient_RequestManager request_manager, ILibThreadPool pool, const char *file_path, long append_flag, const char *target_uri, enum DH_TransferModes requestedTransferMode, void* user_obj, DHC_OnResponseDone callback_response) { DH_TransferStatus RetVal = NULL; char *IP, *Path; unsigned short Port; struct sockaddr_in dest; char *host; int hostLen; struct packetheader *req; FILE *f; struct DHC_Data *data; ILibReaderWriterLock rwLock = (ILibReaderWriterLock)ILibWebClient_GetUser(request_manager); if(rwLock==NULL) { rwLock = ILibReaderWriterLock_CreateEx(ILibWebClient_GetChain(request_manager)); ILibWebClient_SetUser(request_manager,rwLock); } memset(&dest,0,sizeof(struct sockaddr_in)); if(append_flag==0) { f = fopen(file_path,"wb"); } else { f = fopen(file_path,"r+b"); } if(f!=NULL) { data = (struct DHC_Data*)malloc(sizeof(struct DHC_Data)); memset(data,0,sizeof(struct DHC_Data)); data->TransferMode = requestedTransferMode; data->f = f; data->manager = request_manager; data->Callback = callback_response; data->pool = pool; data->user = user_obj; data->TransferStatus = DH_CreateNewTransferStatus(); RetVal = data->TransferStatus; data->rwLock = rwLock; req = ILibCreateEmptyPacket(); ILibSetVersion(req,"1.1",3); ILibParseUri((char*)target_uri,&IP,&Port,&Path); dest.sin_addr.s_addr = inet_addr(IP); dest.sin_port = htons(Port); host = (char*)malloc((int)strlen(IP)+10); hostLen = sprintf(host,"%s:%u",IP,Port); ILibAddHeaderLine(req,"Host",4,host,hostLen); ILibSetDirective(req,"GET",3,Path,(int)strlen(Path)); // // Look at the append_flag // if(append_flag==-1) { // // Move to the end of the file // fseek(f,0,SEEK_END); append_flag = ftell(f); } if(append_flag>0) { if(fseek(f,append_flag,SEEK_SET)!=0) { fseek(f,0,SEEK_END); append_flag = ftell(f); } data->StartPosition = append_flag; } if(requestedTransferMode!=DH_TransferMode_Unspecified) { DH_AddHeader_transferMode(req,requestedTransferMode); } data->ActualPacket = req; req = ILibCreateEmptyPacket(); ILibSetVersion(req,"1.1",3); ILibAddHeaderLine(req,"Host",4,host,hostLen); ILibSetDirective(req,"HEAD",4,Path,(int)strlen(Path)); // // Choose a transfer mode that is supported // determine if Range is supported // ILibAddHeaderLine(req,"getcontentFeatures.dlna.org",27,"1",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(request_manager,&dest,req,&DH_RequestResponse,data,NULL); ILibReaderWriterLock_WriteUnLock(rwLock); free(host); free(IP); free(Path); } return(RetVal); }
char* _GetTrackMetadata(PlayListManager_S state, int trackNumber, int* offset, int* length) { int trackBase; int rangeStart; int rangeLength; int rangeEnd; struct __TMData* data = (struct __TMData*)malloc(sizeof(struct __TMData)); memset(data, 0, sizeof(struct __TMData)); data->State = state; if(IndexBlocks_GetTrackRangeInfo(state->Blocks, trackNumber, &rangeStart, &rangeLength, &trackBase) == 1) { char* IP; char* Path; unsigned short Port; char *host; int hostLen; struct sockaddr_in dest; ILibWebClient_RequestToken token; char* uri = state->Parent->URI; struct packetheader* header = ILibCreateEmptyPacket(); char rangeVal[64]; char* metadata = NULL; data->LocalTrackNumber = trackNumber - trackBase; rangeEnd = rangeStart + rangeLength - 1; sprintf(rangeVal, "bytes=%d-%d", rangeStart, rangeEnd); ILibParseUri(uri, &IP, &Port, &Path); ILibSetVersion(header, "1.1", 3); ILibSetDirective(header, "GET", 3, Path, (int)strlen(Path)); host = (char*)malloc((int)strlen(IP) + 10); hostLen = sprintf(host, "%s:%u", IP, Port); ILibAddHeaderLine(header, "Host", 4, host, hostLen); ILibAddHeaderLine(header, "Range", 5, rangeVal, (int)strlen(rangeVal)); ILibAddHeaderLine(header, "transferMode.dlna.org", 21, "Interactive", 11); memset(&dest, 0, sizeof(struct sockaddr_in)); dest.sin_addr.s_addr = inet_addr(IP); dest.sin_port = htons(Port); data->Metadata = (char*)malloc((size_t)rangeLength); metadata = data->Metadata; sem_init(&data->Sync, 0, 0); token = ILibWebClient_PipelineRequest(state->Parent->RequestManager, &dest, header, &_GetMetadataResponseCallback, data, NULL); sem_wait(&data->Sync); sem_destroy(&data->Sync); metadata = data->Metadata; free(host); free(data); FREE(IP); FREE(Path); if(metadata != NULL) { int i; int found = 0; int count = -1; int localTrack = trackNumber - trackBase; for(i = 0; i < (rangeLength - 5); i++) { if(memcmp(metadata + i, "<item", (size_t)5) == 0) { count++; found = i; if(count == localTrack) { break; } } } if(count < localTrack) { free(metadata); metadata = NULL; } else { int i; int newFound = 0; for(i = 0; i < (rangeLength - found - 6); i++) { if(memcmp(metadata + found + i, "</item>", 7) == 0) { newFound = i; break; } } if(newFound > 0) { *offset = found; *length = newFound - found + 7; //found + newFound + 7; } else { free(metadata); return NULL; } } } return metadata; } free(data); return NULL; }