/** \fn stop \brief stop */ uint8_t audioDeviceThreaded::stop() { uint32_t maxWait=3*1000; // Should be enough to drain ADM_info("[audioDevice]Stopping device..."); if(stopRequest==AUDIO_DEVICE_STARTED) { CHANGE_STATE(AUDIO_DEVICE_STOP_REQ); while(stopRequest==AUDIO_DEVICE_STOP_REQ && maxWait) { ADM_usleep(1000); maxWait--; } } if(!maxWait) { ADM_error("Audio device did not stop cleanly\n"); } localStop(); if(audioBuffer) { delete [] audioBuffer; audioBuffer=NULL; } if(silence) delete [] silence; silence=NULL; CHANGE_STATE(AUDIO_DEVICE_STOPPED); return 1; }
int ADBTasks() { ADB_RESULT adb_res; UINT32 cmd, arg0, arg1, data_len; void* recv_data; if (adb_conn_state > ADB_CONN_STATE_WAIT_ATTACH) { if (!ADBAttached()) { // detached ADBReset(); return 0; } ADBPacketTasks(); if (adb_buffer_refcount > 0) { if ((adb_res = ADBPacketRecvStatus(&cmd, &arg0, &arg1, &recv_data, &data_len)) != ADB_RESULT_BUSY) { if (adb_res == ADB_RESULT_ERROR) { CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_ERROR); } else { ADBHandlePacket(cmd, arg0, arg1, recv_data, data_len); } ADBBufferUnref(); } } } switch (adb_conn_state) { case ADB_CONN_STATE_WAIT_ATTACH: if (ADBAttached()) { log_printf("Device attached."); ADBPacketReset(); adb_buffer_refcount = 1; ADBPacketRecv(); // start receiving ADBPacketSend(ADB_CNXN, ADB_VERSION, ADB_PACKET_MAX_RECV_DATA_BYTES, ADB_HOSTNAME_STRING, strlen(ADB_HOSTNAME_STRING) + 1); CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_WAIT_CONNECT); } break; case ADB_CONN_STATE_WAIT_CONNECT: break; case ADB_CONN_STATE_CONNECTED: ADBChannelTasks(); break; case ADB_CONN_STATE_ERROR: log_printf("Error occured. Resetting."); ADBReset(); return -1; } return ADBConnected(); }
void ADBPacketSend(UINT32 cmd, UINT32 arg0, UINT32 arg1, const void* data, UINT32 data_len) { assert(!ADB_PACKET_STATE_BUSY(adb_packet_send_state)); adb_packet_send_header.command = cmd; adb_packet_send_header.arg0 = arg0; adb_packet_send_header.arg1 = arg1; adb_packet_send_header.data_length = data_len; adb_packet_send_header.data_check = ADBChecksum(data, data_len); adb_packet_send_header.magic = ~cmd; adb_packet_send_data = (const BYTE*) data; CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_START); }
void audioDeviceThreaded::Loop(void) { printf("[AudioDeviceThreaded] Entering loop\n"); while(stopRequest==AUDIO_DEVICE_STARTED) { sendData(); } CHANGE_STATE(AUDIO_DEVICE_STOP_GR); printf("[AudioDeviceThreaded] Exiting loop\n"); }
static void ADBReset() { // close all open channels ADB_CHANNEL_HANDLE h; for (h = 0; h < ADB_MAX_CHANNELS; ++h) { if (adb_channels[h].state != ADB_CHAN_STATE_FREE) { adb_channels[h].recv_func(h, NULL, 0); } } memset(adb_channels, 0, sizeof adb_channels); adb_buffer_refcount = 0; CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_WAIT_ATTACH); }
/** \fn audioDeviceThreaded \brief destructor */ uint8_t audioDeviceThreaded::init(uint32_t channel, uint32_t fq ,CHANNEL_TYPE *channelMapping) { // Allocate buffer memcpy(incomingMapping,channelMapping,sizeof(CHANNEL_TYPE)*MAX_CHANNELS); _channels=channel; _frequency=fq; sizeOf10ms=(_channels*_frequency*2)/100; sizeOf10ms&=~15; // make sure it is a multiple of 16 silence=new uint8_t[sizeOf10ms]; memset(silence,0,sizeOf10ms); audioBuffer=new uint8_t[ADM_THREAD_BUFFER_SIZE]; rdIndex=wrIndex=0; CHANGE_STATE(AUDIO_DEVICE_STOPPED); // if(!localInit()) return 0; // Spawn CHANGE_STATE(AUDIO_DEVICE_STARTED); ADM_assert(!pthread_create(&myThread,NULL,bouncer,this)); return 1; }
static void ADBPacketSendTasks() { BYTE ret_val; switch (adb_packet_send_state) { case ADB_PACKET_STATE_START: if (USBHostAndroidWrite((BYTE*) &adb_packet_send_header, sizeof(ADB_PACKET_HEADER), ANDROID_INTERFACE_ADB) != USB_SUCCESS) { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_WAIT_HEADER); break; case ADB_PACKET_STATE_WAIT_HEADER: if (USBHostAndroidTxIsComplete(&ret_val, ANDROID_INTERFACE_ADB)) { if (ret_val != USB_SUCCESS) { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_ERROR); break; } if (adb_packet_send_header.data_length == 0) { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_IDLE); break; } if (USBHostAndroidWrite(adb_packet_send_data, adb_packet_send_header.data_length, ANDROID_INTERFACE_ADB) != USB_SUCCESS) { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_WAIT_DATA); } break; case ADB_PACKET_STATE_WAIT_DATA: if (USBHostAndroidTxIsComplete(&ret_val, ANDROID_INTERFACE_ADB)) { if (ret_val != USB_SUCCESS) { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_IDLE); } break; case ADB_PACKET_STATE_IDLE: case ADB_PACKET_STATE_ERROR: break; } }
static void ADBChannelTasks() { static ADB_CHANNEL_HANDLE current_channel = 0; ADB_RESULT adb_res; ADB_CHANNEL_HANDLE h; if ((adb_res = ADBPacketSendStatus()) == ADB_RESULT_BUSY) return; if (adb_res == ADB_RESULT_ERROR) { CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_ERROR); return; } for (h = 0; h < ADB_MAX_CHANNELS; ++h) { if (++current_channel == ADB_MAX_CHANNELS) current_channel = 0; if (adb_channels[current_channel].state == ADB_CHAN_STATE_FREE) { continue; } if (adb_channels[current_channel].state == ADB_CHAN_STATE_START) { ADBPacketSend(ADB_OPEN, adb_channels[current_channel].local_id, 0, adb_channels[current_channel].name, strlen(adb_channels[current_channel].name) + 1); CHANGE_CHANNEL_STATE(current_channel, ADB_CHAN_STATE_WAIT_OPEN); return; } if (adb_channels[current_channel].pending_ack) { ADBPacketSend(ADB_OKAY, adb_channels[current_channel].local_id, adb_channels[current_channel].remote_id, NULL, 0); adb_channels[current_channel].pending_ack = FALSE; return; } if (adb_channels[current_channel].state == ADB_CHAN_STATE_CLOSE_REQUESTED) { ADBPacketSend(ADB_CLSE, adb_channels[current_channel].local_id, adb_channels[current_channel].remote_id, NULL, 0); CHANGE_CHANNEL_STATE(current_channel, ADB_CHAN_STATE_WAIT_CLOSE); return; } if (adb_channels[current_channel].state == ADB_CHAN_STATE_IDLE && adb_channels[current_channel].data != NULL) { ADBPacketSend(ADB_WRTE, adb_channels[current_channel].local_id, adb_channels[current_channel].remote_id, adb_channels[current_channel].data, adb_channels[current_channel].data_len); CHANGE_CHANNEL_STATE(current_channel, ADB_CHAN_STATE_WAIT_READY); return; } } }
/**** Global functions definitions. ****/ TA_RetCode TA_FileIndexParsePath( TA_FileIndexPriv *fileIndexPriv, TA_String *path ) { typedef enum { INIT_PROCESSING, FIX_PROCESSING, FIELD_PROCESSING, WILD_PROCESSING, SEP_PROCESSING } State; TA_PROLOG State currentState; const char *currentTokenStart; unsigned int length; char *str; char *pos; char sepTmp[2]; TA_RetCode retCode; unsigned int tokenSize; TA_TokenId tokenId; const char *sourcePattern; TA_TRACE_BEGIN( TA_FileIndexParsePath ); TA_ASSERT( path != NULL ); sepTmp[1] = '\0'; sourcePattern = TA_StringToChar( path ); /* The following macro should help for the readability of the parsing logic. * These macro are used only inside this function. */ #define RETURN(y) {TA_Free(str); TA_TRACE_RETURN( y );} #define REJECT_STATE(x,y) { if(currentState==x)RETURN(y); } #define CHANGE_STATE(x) {currentState=x; currentTokenStart=pos+1;} #define ADD_TOKEN(id,value) \ { \ retCode = addToken(fileIndexPriv,id,value); \ if( retCode != TA_SUCCESS) RETURN(retCode); \ } #define FLUSH_FIX() \ { \ retCode = flushFixPart(fileIndexPriv,currentTokenStart,pos); \ if( retCode != TA_SUCCESS ) RETURN(retCode); \ } /* This function build a list representing the tokens * of the sourcePattern. * * Example: "C:\a\*AZD?\[S]\data.txt" becomes * * TokenId Value * TA_TOK_FIX "C:" * TA_TOK_SEP "\" * TA_TOK_FIX "a" * TA_TOK_SEP "\" * TA_TOK_WILD "*" * TA_TOK_FIX "AZD" * TA_TOK_WILD_CHAR "?" * TA_TOK_SEP "\" * TA_TOK_S "?*" * TA_TOK_SEP "\" * TA_TOK_FIX "data.txt" * TA_TOK_END (null) * * In the values, the '?' and '*' character represent MS-DOS kind * of wildcards: * '?' is any character (but only one). * '*' zero or more of any character */ if( sourcePattern == NULL ) return TA_INVALID_PATH; length = strlen( sourcePattern ) + 1; if( (length <= 1) || (length > 2048) ) return TA_INVALID_PATH; str = (char *)TA_Malloc( length ); strcpy( str, sourcePattern ); pos = str; currentState = INIT_PROCESSING; currentTokenStart = pos; while( *pos != '\0' ) { if( (*pos == '\\') || (*pos == '/') ) { /* Handle directories separator character. */ REJECT_STATE( FIELD_PROCESSING, TA_INVALID_FIELD ); REJECT_STATE( SEP_PROCESSING, TA_INVALID_PATH ); FLUSH_FIX(); #if 0 !!! Needed? /* Check that the string prior to the separator * does not terminate with a dot '.' */ if( currentState != INIT_PROCESSING ) { if( *(pos-1) == '.' ) RETURN( TA_INVALID_PATH ); } #endif /* Transform into the directory delimiter * used on the host file system. */ sepTmp[0] = (char)TA_SeparatorASCII(); ADD_TOKEN( TA_TOK_SEP, sepTmp ); CHANGE_STATE( SEP_PROCESSING ); } else switch( *pos )
void ADBInit() { memset(adb_channels, 0, sizeof adb_channels); CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_WAIT_ATTACH); }
static void ADBHandlePacket(UINT32 cmd, UINT32 arg0, UINT32 arg1, const void* recv_data, UINT32 data_len) { int h = arg1 & 0xFF; switch(cmd) { case ADB_CNXN: log_printf("ADB established connection with [%s]", (const char*) recv_data); // TODO: arg1 contains max_data - handle CHANGE_STATE(adb_conn_state, ADB_CONN_STATE_CONNECTED); break; case ADB_OPEN: // should not happen. ignored. break; case ADB_OKAY: if (h >= 0 && h < ADB_MAX_CHANNELS && adb_channels[h].local_id == arg1) { if (adb_channels[h].state == ADB_CHAN_STATE_WAIT_OPEN) { log_printf("Channel %d is open. Remote ID: 0x%lx. Name: %s", h, arg0, adb_channels[h].name); adb_channels[h].remote_id = arg0; CHANGE_CHANNEL_STATE(h, ADB_CHAN_STATE_IDLE); } else if (adb_channels[h].state == ADB_CHAN_STATE_WAIT_READY && adb_channels[h].remote_id == arg0) { adb_channels[h].data = NULL; CHANGE_CHANNEL_STATE(h, ADB_CHAN_STATE_IDLE); } } else { log_printf("Remote side sent an OK on an unexpected ID: 0x%lx", arg1); } break; case ADB_CLSE: if (h >= 0 && h < ADB_MAX_CHANNELS && adb_channels[h].local_id == arg1) { if (adb_channels[h].state == ADB_CHAN_STATE_WAIT_OPEN) { log_printf("Channel %d open failed. Name: %s", h, adb_channels[h].name); adb_channels[h].recv_func(h, NULL, 0); CHANGE_CHANNEL_STATE(h, ADB_CHAN_STATE_FREE); } else if (adb_channels[h].state == ADB_CHAN_STATE_WAIT_CLOSE || adb_channels[h].state == ADB_CHAN_STATE_CLOSE_REQUESTED) { log_printf("Channel %d closed. Name: %s", h, adb_channels[h].name); adb_channels[h].recv_func(h, NULL, 0); CHANGE_CHANNEL_STATE(h, ADB_CHAN_STATE_FREE); } else if ((adb_channels[h].state == ADB_CHAN_STATE_WAIT_READY || adb_channels[h].state == ADB_CHAN_STATE_IDLE) // in the ADB documentation it says that only failed attempts to open // will result in CLSE with local-id (arg0) of 0, and that in any other // case we should ignore the message if it is not equal to our remote // ID. In practice, however, we do get CLSE(0, ...) as result of a // legitimate closure on the server-side, so this check is disabled. /*&& adb_channels[arg1].remote_id == arg0*/) { log_printf("Channel %d closed by remote side. Name: %s", h, adb_channels[h].name); adb_channels[h].recv_func(h, NULL, 0); CHANGE_CHANNEL_STATE(h, ADB_CHAN_STATE_FREE); } } else { log_printf("Remote side sent a CLSE on an unexpected ID: 0x%lx", arg1); } break; case ADB_WRTE: if (h >= 0 && h < ADB_MAX_CHANNELS && adb_channels[h].local_id == arg1 && adb_channels[h].remote_id == arg0) { if (adb_channels[h].state < ADB_CHAN_STATE_CLOSE_REQUESTED && data_len > 0) { adb_channels[h].recv_func(h, recv_data, data_len); } adb_channels[h].pending_ack = TRUE; } else { log_printf("Remote side sent a WRTE on an unexpected ID: 0x%lx", arg1); } break; default: log_printf("Unknown command 0x%lx. Ignoring.", cmd); } }
void ADBPacketReset() { CHANGE_STATE(adb_packet_send_state, ADB_PACKET_STATE_IDLE); CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_IDLE); }
void ADBPacketRecv() { assert(!ADB_PACKET_STATE_BUSY(adb_packet_recv_state)); CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_START); }
static void ADBPacketRecvTasks() { BYTE ret_val; DWORD bytes_received; switch (adb_packet_recv_state) { case ADB_PACKET_STATE_START: if (USBHostAndroidRead((BYTE*) &adb_packet_recv_header, sizeof(ADB_PACKET_HEADER), ANDROID_INTERFACE_ADB) != USB_SUCCESS) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_WAIT_HEADER); break; case ADB_PACKET_STATE_WAIT_HEADER: if (USBHostAndroidRxIsComplete(&ret_val, &bytes_received, ANDROID_INTERFACE_ADB)) { if (ret_val != USB_SUCCESS) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } // TODO: probably not needed // if (bytes_received == 0) { // adb_packet_recv_header.command = 0; // CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_IDLE); // break; // } if (bytes_received != sizeof(ADB_PACKET_HEADER) || adb_packet_recv_header.command != (~adb_packet_recv_header.magic) || adb_packet_recv_header.data_length > ADB_PACKET_MAX_RECV_DATA_BYTES) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } if (adb_packet_recv_header.data_length == 0) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_IDLE); break; } if (USBHostAndroidRead(adb_packet_recv_data, adb_packet_recv_header.data_length, ANDROID_INTERFACE_ADB) != USB_SUCCESS) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_WAIT_DATA); } break; case ADB_PACKET_STATE_WAIT_DATA: if (USBHostAndroidRxIsComplete(&ret_val, &bytes_received, ANDROID_INTERFACE_ADB)) { if (ret_val != USB_SUCCESS || bytes_received != adb_packet_recv_header.data_length) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } if (ADBChecksum(adb_packet_recv_data, adb_packet_recv_header.data_length) != adb_packet_recv_header.data_check) { CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_ERROR); break; } CHANGE_STATE(adb_packet_recv_state, ADB_PACKET_STATE_IDLE); } break; case ADB_PACKET_STATE_IDLE: case ADB_PACKET_STATE_ERROR: break; } }