// ---------------------------------------------------------------------------- // HRESULT TextUI::notify( PlayerEventData* pNotify ) { LPCSTR eventName; switch( pNotify->m_event ) { case TRACK_PLAY: eventName = "PLAY"; break; case TRACK_STOP: eventName = "STOP"; break; case TRACK_PAUSE: eventName = "PAUSE"; break; case TRACK_RESUME: eventName = "RESUME"; break; case TRACK_POSITION: eventName = "POSITION"; break; case TRACK_QUEUES: eventName = "TRACK_QUEUES"; break; case PLAYLIST_ADDED: eventName = "PLAYLIST_ADDED"; break; case PLAYLIST_REMOVED: eventName = "PLAYLIST_REMOVED"; break; case PLAYLIST_CHANGED: eventName = "PLAYLIST_CHANGED"; break; default: eventName = "UNKNOWN"; break; } if ( pNotify->m_event != TRACK_QUEUES ) { LPCSTR link = pNotify->m_link == NULL ? "?" : pNotify->m_link; printf( "EVENT: %s %s (%s)\n", eventName, link, (LPCSTR)track_time(pNotify->m_event_ms) ); } else printf( "EVENT: %s played=%lu queued=%lu\n", eventName, pNotify->m_played_size, pNotify->m_queued_size ); return S_OK; }
// ---------------------------------------------------------------------------- // void TextUI::run() { m_running = true; m_text_io.printf( "\n\nSpotify API Test Bench - type ? for command list\n\n" ); m_player->connect(); // Try to connect using stored credentials while ( m_running ) { // See if we need to login if ( !m_player->isLoggedIn() && !spotify_login( ) ) break; CString label; PlayingInfo playing_info; if ( m_player->getPlayingTrack( &playing_info ) ) { label.Format( "Now %s: %s", "Playing", m_player->getTrackFullName( playing_info.track_link ) ); label.AppendFormat( " | length %s remaining %s", track_time(playing_info.track_length), track_time(playing_info.time_remaining) ); if ( m_player->isTrackPaused() ) label.Append( " | PAUSED" ); m_text_io.printf( "\n%s\n", (LPCSTR)label ); } m_text_io.clear(); m_text_io.printf( "> ", (LPCSTR)label ); CString cmd; int retcode = m_text_io.getString( cmd ); m_text_io.printf( "\n" ); if ( !m_player->isLoggedIn() ) continue; if ( retcode != INPUT_SUCCESS ) continue; m_text_io.tokenize( cmd ); if ( !m_text_io.nextToken( cmd ) ) continue; cmd.MakeLower(); HandlerMap::iterator it = function_map.find( cmd ); if ( it == function_map.end() ) { m_text_io.printf( "Unrecognized command '%s' - Type ? for list of commands\n", (LPCTSTR)cmd ); } else if ( !m_running && (*it).second.m_running ) { m_text_io.printf( "UI must be running to use '%s'\n", (LPCTSTR)cmd ); } else { (this->*(*it).second.m_funcptr)(); } } }
static int findframe(db_thread *thr, Wal *pWal, Pgno pgno, u32 *piRead, u64 limitTerm, u64 limitEvnum, u64 *outTerm, u64 *outEvnum) { MDB_val key, data; int rc; size_t ndupl = 0; u8 pagesKeyBuf[sizeof(u64)+sizeof(u32)]; mdbinf *mdb; if (thr->pagesChanged) { #if ATOMIC mdb = g_tsd_wmdb; #else mdb = enif_tsd_get(g_tsd_wmdb); #endif } else mdb = &thr->mdb; track_time(7,thr); DBG("FIND FRAME pgno=%u, index=%llu, limitterm=%llu, limitevnum=%llu", pgno,pWal->index,limitTerm,limitEvnum); // ** - Pages DB: {<<ActorIndex:64, Pgno:32/unsigned>>, // <<Evterm:64,Evnum:64,Counter,CompressedPage/binary>>} memcpy(pagesKeyBuf, &pWal->index,sizeof(u64)); memcpy(pagesKeyBuf + sizeof(u64), &pgno, sizeof(u32)); key.mv_size = sizeof(pagesKeyBuf); key.mv_data = pagesKeyBuf; // u32 pgno2 = *(u32*)(key.mv_data+sizeof(u64)); // DBG("RUN %d",pgno2); rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_SET_KEY); if (rc == MDB_SUCCESS) { mdb_cursor_count(mdb->cursorPages,&ndupl); if (ndupl == 0) { *piRead = 0; return SQLITE_OK; } rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_LAST_DUP); if (rc == MDB_SUCCESS) { while (1) { char frag1 = *(char*)(((char*)data.mv_data)+sizeof(u64)*2); int frag = frag1; u64 term, evnum; memcpy(&term, data.mv_data, sizeof(u64)); memcpy(&evnum, ((u8*)data.mv_data) + sizeof(u64), sizeof(u64)); if (term > limitTerm || evnum > limitEvnum) { rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_PREV_DUP); if (rc == MDB_SUCCESS) continue; else { DBG("Cant move to prev dup, term=%llu, evnum=%llu," " limitterm=%llu, limitevnum=%llu",term,evnum,limitTerm,limitEvnum); *piRead = 0; break; } } if (outTerm != NULL) *outTerm = term; if (outEvnum != NULL) *outEvnum = evnum; DBG("Found page size=%ld, frags=%d",data.mv_size,(int)frag); thr->nResFrames = frag; thr->resFrames[frag--] = data; while (frag >= 0) { rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_PREV_DUP); frag = *(((u8*)data.mv_data)+sizeof(u64)*2); // DBG("SUCCESS? %d frag=%d, size=%ld",pgno,frag,data.mv_size); thr->resFrames[frag--] = data; } *piRead = 1; break; } } else { DBG("Find page no last dup"); *piRead = 0; } } else if (rc == MDB_NOTFOUND) { DBG("Frame not found!"); *piRead = 0; } else { DBG("ERROR findframe: %d",rc); *piRead = 0; } return SQLITE_OK; }
/* Write a frame or frames to the log. */ int sqlite3WalFrames(Wal *pWal, int szPage, PgHdr *pList, Pgno nTruncate, int isCommit, int sync_flags) { PgHdr *p; MDB_val key, data; int rc; mdbinf* mdb; MDB_txn* txn; #if ATOMIC db_thread *thr = g_tsd_thread; db_connection* pCon = g_tsd_conn; #else db_thread* thr = enif_tsd_get(g_tsd_thread); db_connection* pCon = enif_tsd_get(g_tsd_conn); #endif #if ATOMIC if (!g_tsd_wmdb) lock_wtxn(thr->nEnv); mdb = g_tsd_wmdb; #else mdb = enif_tsd_get(g_tsd_wmdb); if (!mdb) lock_wtxn(thr->nEnv); mdb = enif_tsd_get(g_tsd_wmdb); #endif txn = mdb->txn; if (!mdb) return SQLITE_ERROR; key.mv_size = sizeof(u64); key.mv_data = (void*)&pWal->index; // Term/evnum must always be increasing if ((pWal->inProgressTerm > 0 && pWal->inProgressTerm < pWal->lastCompleteTerm) || (pWal->inProgressEvnum > 0 && pWal->inProgressEvnum < pWal->lastCompleteEvnum)) return SQLITE_ERROR; track_time(2,thr); // ** - Pages DB: {<<ActorIndex:64, Pgno:32/unsigned>>, <<Evterm:64,Evnum:64,Fragment,CompressedPage/binary>>} for(p=pList; p; p=p->pDirty) { u8 pagesKeyBuf[sizeof(u64)+sizeof(u32)]; u8 pagesBuf[PAGE_BUFF_SIZE]; int full_size = 0; int page_size = LZ4_compress_default((char*)p->pData,(char*)pagesBuf+sizeof(u64)*2+1,szPage,sizeof(pagesBuf)); char fragment_index = 0; int skipped = 0; track_time(3,thr); DBG("Insert frame, actor=%lld, pgno=%u, " "term=%lld, evnum=%lld, commit=%d, truncate=%d, compressedsize=%d", pWal->index,p->pgno,pWal->inProgressTerm,pWal->inProgressEvnum, isCommit,nTruncate,page_size); if (pCon->doReplicate) { u8 hdr[sizeof(u64)*2+sizeof(u32)*2]; put8byte(hdr, pWal->inProgressTerm); put8byte(hdr+sizeof(u64), pWal->inProgressEvnum); put4byte(hdr+sizeof(u64)*2, p->pgno); if (p->pDirty) put4byte(hdr+sizeof(u64)*2+sizeof(u32), 0); else put4byte(hdr+sizeof(u64)*2+sizeof(u32), nTruncate); #ifndef _TESTAPP_ wal_page_hook(thr,pagesBuf+sizeof(u64)*2+1, page_size, hdr, sizeof(hdr)); #endif } memcpy(pagesKeyBuf, &pWal->index,sizeof(u64)); memcpy(pagesKeyBuf + sizeof(u64), &p->pgno, sizeof(u32)); key.mv_size = sizeof(pagesKeyBuf); key.mv_data = pagesKeyBuf; // Check if there are pages with the same or higher evnum/evterm. If there are, delete them. // This can happen if sqlite flushed some page to disk before commiting, because there were // so many pages that they could not be held in memory. Or it could happen if pages need to be // overwritten because there was a write that did not pass raft consensus. rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_SET_KEY); if (rc == MDB_SUCCESS) { size_t ndupl; mdb_cursor_count(mdb->cursorPages,&ndupl); rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_LAST_DUP); if (rc == MDB_SUCCESS) { MDB_val pgDelKey = {0,NULL}, pgDelVal = {0,NULL}; u64 evnum, evterm; u8 frag = *((u8*)data.mv_data+sizeof(u64)*2); memcpy(&evterm, data.mv_data, sizeof(u64)); memcpy(&evnum, (u8*)data.mv_data + sizeof(u64), sizeof(u64)); while ((evterm > pWal->inProgressTerm || evnum >= pWal->inProgressEvnum)) //(pWal->inProgressTerm + pWal->inProgressEvnum) > 0) { DBG("Deleting pages higher or equal to current. " "Evterm=%llu, evnum=%llu, curterm=%llu, curevn=%llu, dupl=%ld", evterm,evnum,pWal->inProgressTerm,pWal->inProgressEvnum,ndupl); if (pgDelKey.mv_data != NULL) { if ((rc = mdb_del(txn,mdb->pagesdb,&pgDelKey,&pgDelVal)) != MDB_SUCCESS) { DBG("Unable to cleanup page from pagedb %d",rc); break; } pgDelKey.mv_data = NULL; } mdb_cursor_get(mdb->cursorPages,&pgDelKey,&pgDelVal,MDB_GET_CURRENT); // if (mdb_cursor_del(mdb->cursorPages,0) != MDB_SUCCESS) // { // DBG("Cant delete!"); // break; // } if (frag == 0) pWal->allPages--; ndupl--; if (!ndupl) break; rc = mdb_cursor_get(mdb->cursorPages,&key,&data,MDB_PREV_DUP); if (rc != MDB_SUCCESS) break; memcpy(&evterm, data.mv_data, sizeof(u64)); memcpy(&evnum, (u8*)data.mv_data + sizeof(u64), sizeof(u64)); frag = *((u8*)data.mv_data+sizeof(u64)*2); } if (pgDelKey.mv_data != NULL) { if ((rc = mdb_del(txn,mdb->pagesdb,&pgDelKey,&pgDelVal)) != MDB_SUCCESS) { DBG("Unable to cleanup page from pagedb %d",rc); break; } pgDelKey.mv_data = NULL; } } memcpy(pagesKeyBuf, &pWal->index,sizeof(u64)); memcpy(pagesKeyBuf + sizeof(u64), &p->pgno, sizeof(u32)); key.mv_size = sizeof(pagesKeyBuf); key.mv_data = pagesKeyBuf; } track_time(4,thr); memcpy(pagesBuf, &pWal->inProgressTerm, sizeof(u64)); memcpy(pagesBuf + sizeof(u64), &pWal->inProgressEvnum, sizeof(u64)); full_size = page_size + sizeof(u64)*2 + 1; if (full_size < thr->maxvalsize) fragment_index = 0; else { full_size = page_size; skipped = thr->maxvalsize - sizeof(u64)*2 - 1; full_size -= skipped; while(full_size > 0) { full_size -= (thr->maxvalsize - sizeof(u64)*2 - 1); fragment_index++; } full_size = page_size + sizeof(u64)*2 +1; } pagesBuf[sizeof(u64)*2] = fragment_index; data.mv_size = fragment_index == 0 ? full_size : thr->maxvalsize; data.mv_data = pagesBuf; // fragment_index == 0 ? MDB_APPENDDUP : 0 if ((rc = mdb_cursor_put(mdb->cursorPages,&key,&data,0)) != MDB_SUCCESS) { // printf("Cursor put failed to pages %d",rc); DBG("ERROR: cursor put failed=%d, datasize=%d",rc,full_size); return SQLITE_ERROR; } fragment_index--; skipped = data.mv_size; while (fragment_index >= 0) { DBG("Insert fragment %d",(int)fragment_index); if (fragment_index == 0) data.mv_size = full_size - skipped + sizeof(u64)*2 + 1; else data.mv_size = thr->maxvalsize; data.mv_data = pagesBuf + skipped - (sizeof(u64)*2+1); memcpy(pagesBuf + skipped - (sizeof(u64)*2+1), &pWal->inProgressTerm, sizeof(u64)); memcpy(pagesBuf + skipped - (sizeof(u64)+1), &pWal->inProgressEvnum, sizeof(u64)); pagesBuf[skipped-1] = fragment_index; if ((rc = mdb_cursor_put(mdb->cursorPages,&key,&data,0)) != MDB_SUCCESS) { DBG("ERROR: cursor secondary put failed: err=%d, datasize=%d, skipped=%d, frag=%d", rc,full_size, skipped, (int)fragment_index); return SQLITE_ERROR; } skipped += data.mv_size - sizeof(u64)*2 - 1; fragment_index--; } thr->pagesChanged++; } // printf(""); // ** - Log DB: {<<ActorIndex:64, Evterm:64, Evnum:64>>, <<Pgno:32/unsigned>>} if (pWal->inProgressTerm > 0) { for(p=pList; p; p=p->pDirty) { u8 logKeyBuf[sizeof(u64)*3]; DBG("Inserting to log"); memcpy(logKeyBuf, &pWal->index, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64), &pWal->inProgressTerm, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64)*2, &pWal->inProgressEvnum, sizeof(u64)); key.mv_size = sizeof(logKeyBuf); key.mv_data = logKeyBuf; data.mv_size = sizeof(u32); data.mv_data = &p->pgno; if (mdb_cursor_put(mdb->cursorLog,&key,&data,0) != MDB_SUCCESS) { // printf("Cursor put failed to log"); DBG("ERROR: cursor put to log failed: %d",rc); return SQLITE_ERROR; } pWal->allPages++; } } else { DBG("Skipping log"); for(p=pList; p; p=p->pDirty) pWal->allPages++; } /** - Info DB: {<<ActorIndex:64>>, <<V,FirstCompleteTerm:64,FirstCompleteEvnum:64, LastCompleteTerm:64,LastCompleteEvnum:64, InprogressTerm:64,InProgressEvnum:64>>} */ { if (isCommit) { DBG("Commit actor=%llu fct=%llu, fcev=%llu, lct=%llu, lcev=%llu, int=%llu, inev=%llu", pWal->index, pWal->firstCompleteTerm, pWal->firstCompleteEvnum, pWal->lastCompleteTerm, pWal->lastCompleteEvnum, pWal->inProgressTerm,pWal->inProgressEvnum); #ifndef _TESTAPP_ enif_mutex_lock(pWal->mtx); #endif pWal->lastCompleteTerm = pWal->inProgressTerm > 0 ? pWal->inProgressTerm : pWal->lastCompleteTerm; pWal->lastCompleteEvnum = pWal->inProgressEvnum > 0 ? pWal->inProgressEvnum : pWal->lastCompleteEvnum; if (pWal->firstCompleteTerm == 0) { pWal->firstCompleteTerm = pWal->inProgressTerm; pWal->firstCompleteEvnum = pWal->inProgressEvnum; } pWal->inProgressTerm = pWal->inProgressEvnum = 0; pWal->mxPage = pWal->mxPage > nTruncate ? pWal->mxPage : nTruncate; // pWal->changed = 0; thr->forceCommit = 1; pCon->dirty = 0; #ifndef _TESTAPP_ enif_mutex_unlock(pWal->mtx); #endif DBG("cur mxpage=%u",pWal->mxPage); } else { // pWal->changed = 1; pCon->dirty = 1; } thr->pagesChanged++; rc = storeinfo(pWal,0,0,NULL); if (rc != SQLITE_OK) return rc; track_time(5,thr); } return SQLITE_OK; }
void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { #ifdef LINUX pcap_usb_header *usb_header = (pcap_usb_header *) packet; if(usb_header->device_address != device_number) return; // TODO: have a hash table here? static int last_urb_id = 0; // Used for mapping request with it's response unsigned int last_request_type; if(usb_header->setup.bmRequestType == 128 && usb_header->setup.bRequest == 0x06) { // This one seems being requested each time // when we start a data capture. // I don't think that we are insterested in it's contents, // so just display a message. printf("# GET DESCRIPTOR Request DEVICE\n"); // Mark as awaiting response last_urb_id = usb_header->id; last_request_type = usb_header->setup.bmRequestType; return; } if(last_urb_id && last_request_type == 128) { // We do not need it's response as well printf("# GET DESCRIPTOR Response DEVICE\n"); last_urb_id = last_request_type = 0; return; } // Transfer type char transfer_type[5], direction[4]; switch(usb_header->transfer_type) { case URB_ISOCHRONOUS: sprintf(transfer_type, "ISOC"); break; case URB_INTERRUPT: sprintf(transfer_type, "INTR"); break; case URB_CONTROL: sprintf(transfer_type, "CTRL"); break; case URB_BULK: sprintf(transfer_type, "BULK"); break; } if( usb_header->endpoint_number & URB_TRANSFER_IN ) sprintf(direction, "IN"); else sprintf(direction, "OUT"); // Output char prefix[19], hex[MAX_PACKET_SIZE * 2]; if(usb_header->data_len > MAX_PACKET_SIZE) { printf("# Large data block omitted\n"); if(out) fprintf(out, "# Large data block omitted\n"); } else if(usb_header->data_len) { /* Printing transfer type & endpoint*/ sprintf(prefix, "%s_%s(%d.%d):", transfer_type, direction, 0, // avoid redundancy usb_header->endpoint_number & 0x7F); OUT("%-14s", prefix); /* Printing packet's setup */ if(usb_header->transfer_type == URB_CONTROL) { pcap_usb_setup *setup = &(usb_header->setup); OUT("%02x:%02x:%04x:%04x:", setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex); } /* Printing payload */ const unsigned char *raw_data = packet + header->len - usb_header->data_len; void (*print_packet)(FILE *out, pcap_usb_header *usb_header, const unsigned char *raw_data); buf_to_hex(raw_data, usb_header->data_len, hex); OUT("%s", hex); /* Printing timestamp */ long double time_diff = track_time(usb_header->ts_sec, usb_header->ts_usec); OUT(" # %.16Lf\n", time_diff); } #endif }