I have made the following changes intended for : CE:MW:Shared / buteo-mtp
Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below. https://build.pub.meego.com//request/show/7773 Thank You, aard [This message was auto-generated] --- Request # 7773: Messages from BOSS: State: review at 2013-01-30T15:04:18 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: home:aard:branches:CE:MW:Shared / buteo-mtp -> CE:MW:Shared / buteo-mtp changes files: -------------- --- buteo-mtp.changes +++ buteo-mtp.changes @@ -0,0 +1,3 @@ +* Wed Jan 30 2013 Bernd Wachter <[email protected]> - 0.0.42 +- Fix stalling issue + old: ---- buteo-mtp-0.0.41.tar.gz new: ---- buteo-mtp-0.0.42.tar.gz spec files: ----------- --- buteo-mtp.spec +++ buteo-mtp.spec @@ -1,5 +1,5 @@ Name: buteo-mtp -Version: 0.0.41 +Version: 0.0.42 Release: 1 Summary: MTP library Group: System/Libraries other changes: -------------- ++++++ buteo-mtp-0.0.41.tar.gz -> buteo-mtp-0.0.42.tar.gz --- mts/deviceinfo.xml +++ mts/deviceinfo.xml @@ -132,6 +132,7 @@ <AudioFormat>0x3008</AudioFormat><!--WAV--> <AudioFormat>0x3009</AudioFormat><!--MP3--> <AudioFormat>0xB901</AudioFormat><!--WMA--> + <AudioFormat>0xB902</AudioFormat><!--OGG--> <AudioFormat>0xB903</AudioFormat><!--AAC--> <VideoFormat>0x300A</VideoFormat><!--AVI--> --- mts/platform/deviceinfo/deviceinfo.cpp +++ mts/platform/deviceinfo/deviceinfo.cpp @@ -140,6 +140,7 @@ MTP_OBF_FORMAT_WAV, MTP_OBF_FORMAT_MP3, MTP_OBF_FORMAT_WMA, + MTP_OBF_FORMAT_OGG, MTP_OBF_FORMAT_AAC, MTP_OBF_FORMAT_AVI, --- mts/platform/storage/fsstorageplugin/fsstorageplugin.cpp +++ mts/platform/storage/fsstorageplugin/fsstorageplugin.cpp @@ -115,7 +115,7 @@ buildSupportedFormatsList(); // Populate puoids stored persistently and store them in the puoids map. - populatePuoids(); + populatePuoids(); m_tracker = new StorageTracker(); m_thumbnailer = new Thumbnailer(); @@ -149,23 +149,23 @@ m_tracker->getPlaylists(m_newPlaylists.playlistNames, m_newPlaylists.playlistEntries, false); // Add the root folder to storage - m_root = new StorageItem; + m_root = new StorageItem; m_root->m_path = m_storagePath; populateObjectInfo( m_root ); addDirToStorage( m_root, true ); - removeUnusedPuoids(); + removeUnusedPuoids(); // Populate object references stored persistently and add them to the storage. populateObjectReferences(); - + // TODO: The playlist handling is yet unclear. For now, playlists are // implemented as abstract 0 byte objects that contain references to other // objects. // Create playlist folders and sync .pla files with real playlists. assignPlaylistReferences(); - return result; + return result; } /************************************************************ @@ -208,7 +208,7 @@ // We need to synchronize the directories (while the dev was offline something could happened) // First read the Playlists dir and store in a vector - QList<QString> playlistItems; + QList<QString> playlistItems; dir = QDir( m_playlistPath ); QStringList contents = dir.entryList(); for( int i = 0; i < contents.size(); ++i ) @@ -230,7 +230,7 @@ // Second read the internal playlist dir and check if there exists a corresponding file in the // Playlists directory, if not, create it. - // TODO In the future this should synchronize the device playlists + // TODO In the future this should synchronize the device playlists dir = QDir( m_internalPlaylistPath ); contents = dir.entryList(); for( int i = 0; i < contents.size(); ++i ) @@ -294,7 +294,7 @@ m_objectReferencesMap[refHandle] = references; } } - + // Now we do the same for the playlists that are new on the device for(int i = 0; i < m_newPlaylists.playlistNames.size(); i++) { @@ -520,7 +520,7 @@ return; } - // Write puoid + // Write puoid bytesWritten = file.write( reinterpret_cast<const char*>(&puoid), sizeof(MtpInt128) ); id = *(reinterpret_cast<quint32*>(&puoid)); if( -1 == bytesWritten ) @@ -541,6 +541,7 @@ m_formatByExtTable["pla"] = MTP_OBF_FORMAT_Abstract_Audio_Video_Playlist; m_formatByExtTable["wav"] = MTP_OBF_FORMAT_WAV; m_formatByExtTable["mp3"] = MTP_OBF_FORMAT_MP3; + m_formatByExtTable["ogg"] = MTP_OBF_FORMAT_OGG; m_formatByExtTable["txt"] = MTP_OBF_FORMAT_Text; m_formatByExtTable["htm"] = MTP_OBF_FORMAT_HTML; m_formatByExtTable["html"] = MTP_OBF_FORMAT_HTML; @@ -653,9 +654,9 @@ } file.close(); - + // Assign a handle for this item. - thisStorageItem->m_handle = requestNewObjectHandle(); + thisStorageItem->m_handle = requestNewObjectHandle(); // Add the item to the path names map. m_pathNamesMap[ thisStorageItem->m_path ] = thisStorageItem->m_handle; // Add the item to the object handle map. @@ -686,8 +687,8 @@ } // Dates from our device - thisStorageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( thisStorageItem ); - thisStorageItem->m_objectInfo->mtpModificationDate = getModifiedDate( thisStorageItem ); + thisStorageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( thisStorageItem ); + thisStorageItem->m_objectInfo->mtpModificationDate = getModifiedDate( thisStorageItem ); return MTP_RESP_OK; } @@ -712,7 +713,7 @@ // Assign a handle for this item. else { - thisStorageItem->m_handle = requestNewObjectHandle(); + thisStorageItem->m_handle = requestNewObjectHandle(); } // Add the item to the path names map. m_pathNamesMap[ thisStorageItem->m_path ] = thisStorageItem->m_handle; @@ -768,8 +769,8 @@ } // Dates from our device - thisStorageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( thisStorageItem ); - thisStorageItem->m_objectInfo->mtpModificationDate = getModifiedDate( thisStorageItem ); + thisStorageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( thisStorageItem ); + thisStorageItem->m_objectInfo->mtpModificationDate = getModifiedDate( thisStorageItem ); return MTP_RESP_OK; } @@ -816,7 +817,7 @@ childStorageItem->m_parent->m_firstChild = childStorageItem->m_nextSibling; } // not the first child - else + else { StorageItem *itr = childStorageItem->m_parent->m_firstChild; while(itr && itr->m_nextSibling != childStorageItem) @@ -877,7 +878,7 @@ linkChildStorageItem( storageItem, parentStorageItem ); // Create file or directory - switch( info->mtpObjectFormat ) + switch( info->mtpObjectFormat ) { // Directory. case MTP_OBF_FORMAT_Association: @@ -918,7 +919,7 @@ } // Add the object ( file/dir ) to the filesystem storage. - response = addToStorage( storageItem, info ); + response = addToStorage( storageItem, info ); if( storageItem ) { handle = storageItem->m_handle; @@ -934,7 +935,7 @@ MTPResponseCode FSStoragePlugin::deleteItem( const ObjHandle& handle, const MTPObjFormatCode& formatCode ) { // If handle == 0xFFFFFFFF, that means delete all objects that can be deleted ( this could be filered by fmtCode ) - quint32 totalNoOfObjects = m_objectHandlesMap.count() - 1; + quint32 totalNoOfObjects = m_objectHandlesMap.count() - 1; quint32 noOfObjectsByFormat = 0; StorageItem *storageItem = 0; MTPResponseCode response = MTP_RESP_GeneralError; @@ -1002,7 +1003,7 @@ } // If this is a file or an empty dir, just delete this item. - if( !storageItem->m_firstChild ) + if( !storageItem->m_firstChild ) { if( removePhysically && MTP_OBF_FORMAT_Association == storageItem->m_objectInfo->mtpObjectFormat && 0 != storageItem->m_handle ) { @@ -1029,7 +1030,7 @@ removeFromStorage( handle, sendEvent ); } // if this is a non-empty dir. - else + else { StorageItem* itr = storageItem->m_firstChild; while(itr) @@ -1070,7 +1071,7 @@ if(-1 != storageItem->m_wd) { // Remove watch on the path and then remove the wd from the map - removeWatchDescriptor( storageItem ); + removeWatchDescriptor( storageItem ); } m_objectHandlesMap.remove( handle ); m_pathNamesMap.remove( storageItem->m_path ); @@ -1150,7 +1151,7 @@ break; // Count of all objects that are children of an object whose handle = associationHandle; - default: + default: //Check if the association handle is valid. if( !m_objectHandlesMap.contains( associationHandle ) ) { @@ -1275,7 +1276,7 @@ // Write the content to the new item. MTPResponseCode response = MTP_RESP_OK; QString sourcePath = storageItem->m_path; - + // Apply metadata for the destination path m_tracker->copy(sourcePath, destinationPath); // Ask tracker to ignore the next update on the destination path @@ -1307,7 +1308,7 @@ copiedObjectHandle = parentHandle; } // this is a file, copy the data - else + else { response = addItem( const_cast<ObjHandle&>(parentHandle), copiedObjectHandle, &objectInfo ); if( MTP_RESP_OK != response ) @@ -1366,7 +1367,7 @@ { // Move the URI in tracker too m_tracker->move(movedItem->m_path, destinationPath); - + if( MTP_OBF_FORMAT_Abstract_Audio_Video_Playlist == movedItem->m_objectInfo->mtpObjectFormat ) { // If this is a playlist, also need to update the playlist URL @@ -1389,7 +1390,7 @@ MTPResponseCode FSStoragePlugin::moveObject( const ObjHandle &handle, const ObjHandle &parentHandle, const quint32 &destinationStorageId, bool movePhysically ) { // TODO Handle moves across storages; - if( m_storageId != destinationStorageId ) + if( m_storageId != destinationStorageId ) { return MTP_RESP_GeneralError; } @@ -1418,7 +1419,7 @@ QString destinationPath = parentItem->m_path + "/" + storageItem->m_objectInfo->mtpFileName; // If this is a directory already exists, don't overwrite it. - if( MTP_OBF_FORMAT_Association == storageItem->m_objectInfo->mtpObjectFormat ) + if( MTP_OBF_FORMAT_Association == storageItem->m_objectInfo->mtpObjectFormat ) { if( m_pathNamesMap.contains( destinationPath ) ) { @@ -1434,7 +1435,7 @@ // Do the move. if( movePhysically ) { - QDir dir; + QDir dir; if ( !dir.rename( storageItem->m_path, destinationPath ) ) { return MTP_RESP_InvalidParentObject; @@ -1455,7 +1456,7 @@ //storageItem->m_nextSibling = 0; // Reset URI in tracker and ask it to ignore m_tracker->move(storageItem->m_path, destinationPath); - + if(storageItem->m_objectInfo && MTP_OBF_FORMAT_Abstract_Audio_Video_Playlist == storageItem->m_objectInfo->mtpObjectFormat) { @@ -1517,12 +1518,12 @@ ***********************************************************/ void FSStoragePlugin::populateObjectInfo( StorageItem *&storageItem ) { - if( !storageItem ) + if( !storageItem ) { return; } // If we have already stored objectinfo for this item. - if( storageItem->m_objectInfo ) + if( storageItem->m_objectInfo ) { return; } @@ -1537,7 +1538,7 @@ name = name.remove(0,storageItem->m_path.lastIndexOf("/") + 1); storageItem->m_objectInfo->mtpFileName = name; // object format. - storageItem->m_objectInfo->mtpObjectFormat = getObjectFormatByExtension( storageItem ); + storageItem->m_objectInfo->mtpObjectFormat = getObjectFormatByExtension( storageItem ); // protection status. storageItem->m_objectInfo->mtpProtectionStatus = getMTPProtectionStatus( storageItem ); // object size. @@ -1557,7 +1558,7 @@ // image bit depth storageItem->m_objectInfo->mtpImageBitDepth = getImageBitDepth( storageItem ); // parent object. - storageItem->m_objectInfo->mtpParentObject = storageItem->m_parent ? storageItem->m_parent->m_handle : 0x00000000; + storageItem->m_objectInfo->mtpParentObject = storageItem->m_parent ? storageItem->m_parent->m_handle : 0x00000000; // association type storageItem->m_objectInfo->mtpAssociationType = getAssociationType( storageItem ); // association description @@ -1565,11 +1566,11 @@ // sequence number storageItem->m_objectInfo->mtpSequenceNumber = getSequenceNumber( storageItem ); // date created - storageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( storageItem ); + storageItem->m_objectInfo->mtpCaptureDate = getCreatedDate( storageItem ); // date modified - storageItem->m_objectInfo->mtpModificationDate = getModifiedDate( storageItem ); + storageItem->m_objectInfo->mtpModificationDate = getModifiedDate( storageItem ); // keywords. - storageItem->m_objectInfo->mtpKeywords = getKeywords( storageItem ); + storageItem->m_objectInfo->mtpKeywords = getKeywords( storageItem ); } /************************************************************ @@ -1578,7 +1579,7 @@ quint16 FSStoragePlugin::getObjectFormatByExtension( StorageItem *storageItem ) { // TODO Fetch from tracker or determine from the file. - quint16 format = MTP_OBF_FORMAT_Undefined; + quint16 format = MTP_OBF_FORMAT_Undefined; QFileInfo item(storageItem->m_path); if( item.isDir() ) @@ -1593,7 +1594,7 @@ format = m_formatByExtTable[ext]; } } - return format; + return format; } /************************************************************ @@ -1602,7 +1603,7 @@ quint16 FSStoragePlugin::getMTPProtectionStatus( StorageItem* /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1649,12 +1650,12 @@ ***********************************************************/ quint16 FSStoragePlugin::getThumbFormat( StorageItem *storageItem ) { - quint16 format = MTP_OBF_FORMAT_Undefined; + quint16 format = MTP_OBF_FORMAT_Undefined; if( isImage( storageItem ) ) { format = MTP_OBF_FORMAT_JFIF; } - return format; + return format; } /************************************************************ @@ -1662,12 +1663,12 @@ ***********************************************************/ quint32 FSStoragePlugin::getThumbPixelWidth( StorageItem *storageItem ) { - quint16 width = 0; + quint16 width = 0; if( isImage( storageItem ) ) { width = THUMB_WIDTH; } - return width; + return width; } /************************************************************ @@ -1675,12 +1676,12 @@ ***********************************************************/ quint32 FSStoragePlugin::getThumbPixelHeight( StorageItem *storageItem ) { - quint16 height = 0; + quint16 height = 0; if( isImage( storageItem ) ) { height = THUMB_HEIGHT; } - return height; + return height; } /************************************************************ @@ -1689,7 +1690,7 @@ quint32 FSStoragePlugin::getThumbCompressedSize( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1698,7 +1699,7 @@ quint32 FSStoragePlugin::getImagePixelWidth( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1707,7 +1708,7 @@ quint32 FSStoragePlugin::getImagePixelHeight( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1716,7 +1717,7 @@ quint16 FSStoragePlugin::getAssociationType( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1725,7 +1726,7 @@ quint32 FSStoragePlugin::getAssociationDescription( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ @@ -1734,20 +1735,20 @@ quint32 FSStoragePlugin::getImageBitDepth( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker or determine from the file. - return 0; + return 0; } /************************************************************ - * quint32 FSStoragePlugin::getSequenceNumber + * quint32 FSStoragePlugin::getSequenceNumber ***********************************************************/ quint32 FSStoragePlugin::getSequenceNumber( StorageItem * /*storageItem*/ ) { // TODO Fetch from tracker - return 0; + return 0; } /************************************************************ - * QString FSStoragePlugin::getCreatedDate + * QString FSStoragePlugin::getCreatedDate ***********************************************************/ QString FSStoragePlugin::getCreatedDate( StorageItem *storageItem ) { @@ -1778,7 +1779,7 @@ char* FSStoragePlugin::getKeywords( StorageItem * /*storageItem*/ ) { // Not supported. - return 0; + return 0; } /************************************************************ @@ -1821,8 +1822,8 @@ return MTP_RESP_GeneralError; } // TODO: Read this in a loop? - readBufferLen = 0; - do{ + readBufferLen = 0; + do{ readBufferLen = file.read( readBuffer, bytesToRead ); if( -1 == readBufferLen ) { @@ -1878,7 +1879,7 @@ { return MTP_RESP_GeneralError; } - + if( ( true == isLastSegment ) && ( 0 == writeBuffer ) ) { m_writeObjectHandle = 0; @@ -2066,7 +2067,7 @@ ***********************************************************/ MTPResponseCode FSStoragePlugin::getReferences( const ObjHandle &handle , QVector<ObjHandle> &references ) { - if( !m_objectHandlesMap.contains( handle ) ) + if( !m_objectHandlesMap.contains( handle ) ) { removeInvalidObjectReferences( handle ); return MTP_RESP_InvalidObjectHandle; @@ -2220,7 +2221,7 @@ void FSStoragePlugin::storeObjectReferences() { // Write as follows - // 1. No. of objects that have references. + // 1. No. of objects that have references. // 2a. Object PUOID // 2b. No. of references for this object. // 2c. PUOIDs of the referred objects. @@ -2233,7 +2234,7 @@ { return; } - quint32 noOfHandles = m_objectReferencesMap.count(); + quint32 noOfHandles = m_objectReferencesMap.count(); // Recored the position to store the number of object handles at... qint64 posNoOfHandles = file.pos(); bytesWritten = file.write( reinterpret_cast<const char*>(&noOfHandles), sizeof(quint32) ); @@ -2582,10 +2583,10 @@ { // First, we try to check if the object property has a value in the object info data set // or whether if it's statically defined ( hard-coded in other words ). - + if( getFromObjInfo ) { - for(QList<MTPObjPropDescVal>::iterator i = propValList.begin(); + for(QList<MTPObjPropDescVal>::iterator i = propValList.begin(); i != propValList.end(); ++i) { code = getObjectPropertyValueFromStorage( handle, i->propDesc->uPropCode, i->propVal, i->propDesc->uDataType ); @@ -2635,7 +2636,7 @@ m_puoidsMap.remove(storageItem->m_path); // Adjust path in tracker m_tracker->move(storageItem->m_path, path); - + if( MTP_OBF_FORMAT_Abstract_Audio_Video_Playlist == storageItem->m_objectInfo->mtpObjectFormat ) { // If this is a playlist, also need to update the playlist URL @@ -2972,4 +2973,3 @@ } return true; } - --- mts/transport/usb/mtptransporterusb.cpp +++ mts/transport/usb/mtptransporterusb.cpp @@ -352,6 +352,7 @@ { emit cleanup(); + m_containerReadLen = 0; m_bulkRead.m_lock.unlock(); m_bulkWrite.m_lock.unlock(); } --- mts/transport/usb/threadio.cpp +++ mts/transport/usb/threadio.cpp @@ -49,8 +49,10 @@ void IOThread::interrupt() { - if(m_handle) + if(m_handle) { + MTP_LOG_INFO("Sending interrupt signal"); pthread_kill(m_handle, SIGUSR1); + } } bool IOThread::stallWrite() @@ -150,7 +152,7 @@ void ControlReaderThread::handleEvent(struct usb_functionfs_event *event) { - //qDebug() << "Event: " << event_names[event->type]; + MTP_LOG_INFO("Event: " << event_names[event->type]); switch(event->type) { case FUNCTIONFS_ENABLE: case FUNCTIONFS_RESUME: @@ -221,13 +223,19 @@ m_threadRunning = true; char* inbuf = new char[MAX_DATA_IN_SIZE]; - + // + // Use m_lock to control message flow btw bulkreader and main thread + // 1. reader has lock + // 2. read data + // 3. inform main thread + // 4. reader waits in lock until main has processed data and unlocked + // 5. goto 2 + // + m_lock.lock(); // First we have the lock do { readSize = read(m_fd, inbuf, MAX_DATA_IN_SIZE); // Read Header while(readSize != -1) { emit dataRead(inbuf, readSize); - // This will wait until it's released in the main thread - m_lock.tryLock(); if(!m_threadRunning) break; m_lock.lock(); if(!m_threadRunning) break; @@ -385,8 +393,12 @@ int bytesWritten = write(m_fd, dataptr, dataLen); if(bytesWritten == -1) { - if(errno != EINTR) + if(errno == EINTR) + continue; + else { m_running = false; + break; + } } dataptr += bytesWritten; dataLen -= bytesWritten; --- rpm/buteo-mtp.changes +++ rpm/buteo-mtp.changes @@ -1,3 +1,6 @@ +* Wed Jan 30 2013 Bernd Wachter <[email protected]> - 0.0.42 +- Fix stalling issue + * Fri Jan 25 2013 Bernd Wachter <[email protected]> - 0.0.41 - Trap SIGUSR1, preventing premature death of MTP - Change default device identifications to Nemo --- rpm/buteo-mtp.spec +++ rpm/buteo-mtp.spec @@ -1,5 +1,5 @@ Name: buteo-mtp -Version: 0.0.41 +Version: 0.0.42 Release: 1 Summary: MTP library Group: System/Libraries --- service/service.cpp +++ service/service.cpp @@ -35,7 +35,7 @@ using namespace meegomtp1dot0; -void signalHandler(int signum) +void signalHandler(int signum, siginfo_t *info, void *context) { if(signum == SIGUSR1) return; @@ -49,9 +49,15 @@ { QCoreApplication app(argc, argv); - signal(SIGINT, &signalHandler); - signal(SIGALRM, &signalHandler); - signal(SIGUSR1, &signalHandler); + struct sigaction action; + + action.sa_sigaction = signalHandler; + action.sa_flags = SA_SIGINFO | SA_RESTART; + sigemptyset(&action.sa_mask); + + if (sigaction(SIGINT, &action, NULL) < 0) return(-1); + if (sigaction(SIGALRM, &action, NULL) < 0) return(-1); + if (sigaction(SIGUSR1, &action, NULL) < 0) return(-1); QObject::connect(&app,SIGNAL(aboutToQuit()),Mts::getInstance(),SLOT(destroyInstance()));
