int main(int argc, char *argv[]) { // Process command line arguments char *config_filename = NULL; if( argc > 1) { config_filename = argv[1]; } char *mm_ip = NULL; if( argc > 2) { mm_ip = argv[2]; } static CMessage inMsg; Initialize(); bool try_again = true; while(try_again) { try { fprintf(stdout, "Connecting to Dragonfly\n"); if( mm_ip == NULL) dragonfly.ConnectToMMM(); else dragonfly.ConnectToMMM(mm_ip); dragonfly.Subscribe(MT_EXIT); dragonfly.Subscribe(MT_PING); dragonfly.Subscribe(MT_RAW_SPIKECOUNT); dragonfly.SendModuleReady(); fprintf(stdout, "Connected to Dragonfly\n"); ResetCount(); ResetActiveSources(); bool keep_running = true; while(keep_running) { double timeout = .5; // seconds bool got_msg = dragonfly.ReadMessage( &inMsg, timeout); if( got_msg) { keep_running = ProcessMessage(&dragonfly, &inMsg); if( !keep_running) { try_again = false; break; } } else { //fprintf(stdout, "Waiting for messages\n"); } } } catch(UPipeClosedException) { fprintf(stderr, "Reconnecting to Dragonfly\n"); Sleep(500); // milliseconds } catch(UPipeException) { fprintf(stderr, "Cannot connect to Dragonfly, waiting to reconnect\n"); Sleep(500); // milliseconds } } }
void mexFunction( int num_output_args, // Number of left hand side (output) arguments mxArray *output_arg[], // Array of left hand side arguments int num_input_args, // Number of right hand side (input) arguments const mxArray *input_arg[]) // Array of right hand side arguments { int opcode; MODULE_ID ModuleID, DestModID; HOST_ID DestHostID; short *HostAddress_raw; char HostAddress[MAX_HOST_ADDR_LENGTH]; int HostAddressLength = 0; MSG_TYPE MessageType; double timeout; int status; unsigned int SnoozeTime; int TimerID; int logger_status; void *pData; int NumDataBytes; const mxArray *Template; mxArray *ReturnData; bool try_again; double begin_time, end_time, elapsed_time; try { if( num_input_args < 1) { Error( "MatlabDragonfly takes at least 1 argument!"); } // // Get the "opcode" argument to determine what needs to be done // opcode = (int) mxGetScalar( input_arg[0]); switch( opcode) { case CONNECT_TO_MMM: if( num_input_args < 4) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { mexPrintf( "Disconnecting...\n"); TheModule.DisconnectFromMMM(); mexPrintf( "Re-connecting...\n"); } ModuleID = (MODULE_ID) mxGetScalar( input_arg[1]); HostAddressLength = mxGetNumberOfElements( input_arg[2]); logger_status = (int) mxGetScalar( input_arg[3]); TheModule.InitVariables( ModuleID, 0); try{ if( HostAddressLength > 0) { // Convert unicode matlab string to regular character string if( HostAddressLength > MAX_HOST_ADDR_LENGTH-1) Error( "Server name exceeds maximum allowed length"); HostAddress_raw = (short*) mxGetData( input_arg[2]); int i; for( i = 0; i < HostAddressLength; i++) HostAddress[i] = (char) HostAddress_raw[i]; HostAddress[i] = 0; // zero-terminate the string status = TheModule.ConnectToMMM( HostAddress, logger_status); } else { status = TheModule.ConnectToMMM( logger_status); } }catch(MyCException &E){ MyCString err("Failed to connect to MM:"); E.AppendTraceToString(err); Error(err.GetContent()); } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case DISCONNECT_FROM_MMM: if( num_input_args < 1) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { status = TheModule.DisconnectFromMMM( ); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SUBSCRIBE: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.Subscribe( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case UNSUBSCRIBE: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.Unsubscribe( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case PAUSE_SUBSCRIPTION: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.PauseSubscription( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case RESUME_SUBSCRIPTION: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); status = TheModule.ResumeSubscription( MessageType); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SEND_MESSAGE: if( num_input_args < 5) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); pData = SerializeData( input_arg[2], &NumDataBytes); M.Set( MessageType, pData, NumDataBytes); DestModID = (MODULE_ID) mxGetScalar( input_arg[3]); DestHostID = (HOST_ID) mxGetScalar( input_arg[4]); status = TheModule.SendMessage( &M, DestModID, DestHostID); mxFree( pData); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); output_arg[1] = mxCreateDoubleScalar( M.send_time); output_arg[2] = mxCreateDoubleScalar( (double) M.msg_count); break; case SEND_SIGNAL: if( num_input_args < 4) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { MessageType = (MSG_TYPE) mxGetScalar( input_arg[1]); DestModID = (MODULE_ID) mxGetScalar( input_arg[2]); DestHostID = (HOST_ID) mxGetScalar( input_arg[3]); M.Set( MessageType); status = TheModule.SendMessage( &M, DestModID, DestHostID); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); output_arg[1] = mxCreateDoubleScalar( M.send_time); output_arg[2] = mxCreateDoubleScalar( (double) M.msg_count); break; case READ_MESSAGE_HDR: if( num_input_args < 3) Error( "incorrect number of arguments"); if( !TheModule.IsConnected( )) { output_arg[0] = EmptyMatrix( ); break; } timeout = mxGetScalar( input_arg[2]); begin_time = GetAbsTime(); do { try_again = false; try { status = TheModule.ReadMessage( &M, timeout); } catch( UPipeSignalException &e) { end_time = GetAbsTime(); elapsed_time = end_time - begin_time; timeout = timeout - elapsed_time; if( timeout < 0) timeout = 0; //mexPrintf("\nSignal caught and ignored!\n"); try_again = true; } } while( try_again); if( status > 0) { Template = input_arg[1]; ReturnData = C2Matlab( Template, &M, sizeof(DF_MSG_HEADER)); output_arg[0] = ReturnData; } else { output_arg[0] = EmptyMatrix( ); } break; case READ_MESSAGE_DATA: if( num_input_args < 2) Error( "incorrect number of arguments"); Template = input_arg[1]; ReturnData = C2Matlab( Template, M.GetDataPointer(), M.num_data_bytes); output_arg[0] = ReturnData; break; case SET_TIMER: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { SnoozeTime = (unsigned int) mxGetScalar( input_arg[1]); TimerID = TheModule.SetTimer( SnoozeTime); } else { TimerID = -1; } output_arg[0] = mxCreateDoubleScalar( (double) TimerID); break; case CANCEL_TIMER: if( num_input_args < 2) Error( "incorrect number of arguments"); if( TheModule.IsConnected( )) { TimerID = (unsigned int) mxGetScalar( input_arg[1]); status = TheModule.CancelTimer( TimerID); } else { status = -1; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case SEND_MODULE_READY: if( TheModule.IsConnected( )) { status = TheModule.SendModuleReady( ); } else { status = 0; } output_arg[0] = mxCreateDoubleScalar( (double) status); break; case GET_TIME: output_arg[0] = mxCreateDoubleScalar( GetAbsTime()); break; case GET_MODULE_ID: output_arg[0] = mxCreateDoubleScalar( TheModule.GetModuleID()); break; default: Error( "Invalid opcode"); } } catch( MyCException &e) { MyCString S; e.AppendTraceToString( S); char *s = S.GetContent( ); Error( s); } } // mexFunction
// This program takes 3 commandline arguments: // - IP of network interface that the NSP is connected to // - Zero-based numeric ID of the NSP (i.e. 0 for the first box, 1 for the second etc) // If you specify a string that is not an integer number then it will the default value 0 will be applied // This ID will be used in outgoing packets to identify which NSP the information is coming from // - IP of the Message Manager // For example, the following command // SPM_Cerebus 192.168.137.4 3 192.168.2.74 // will connect to the NSP on the network interface 192.168.137.4, it will label // spike count messages with the ID 3, and will connect to message manager at 192.168.2.74 // If the arguments are omitted, then default values will be applied int main( int argc, char *argv[]) { try { // Process command line arguments char *nsp_ip = NULL; if( argc > 1) { nsp_ip = argv[1]; } int nsp_index = 0; if( argc > 2) { nsp_index = atoi( argv[2]); } char *mm_ip; char default_mm_ip[] = DEFAULT_MM_IP; if( argc > 3) { mm_ip = argv[3]; } if( argc > 4) { collect_snippets = atoi( argv[4]); } if( argc > 5) { collect_LFP = atoi(argv[5]); } int stimSyncBit = -1; // negative value means disconnected int stimParamBit = -1; if( argc > 6) acceptAllDigEvts = atoi(argv[6]); if (argc > 7) stimSyncBit = atoi(argv[4]); if (stimSyncBit > -1) stimSyncMask = (1 << stimSyncBit); if (stimParamBit > -1) stimParamMask = (1 << stimParamBit); printf("collect LFP: %d\n", collect_LFP); printf("Connecting to Dragonfly: "); // Connect to Dragonfly MODULE_ID mod_id = MID_SPM_MOD1 + nsp_index; dragonfly.InitVariables( mod_id, 0); dragonfly.ConnectToMMM( mm_ip); dragonfly.SendModuleReady(); printf(" done\n"); // get frequency for high performance timer QueryPerformanceFrequency(&frequency); double d_bufferPeriod = bufferDelay * frequency.QuadPart; bufferPeriod.QuadPart = (LONGLONG)d_bufferPeriod; // Run in a loop, reading UDP messages from Cerebus, sending out spike counts to Dragonfly CerebusClient client; int loop_count = 0; Overall_Spike_Count = 0; Snippet_Message_Number = 0; Overall_Rejected_Count = 0; Rejected_Snippet_Message_Number = 0; Dig_Message_Number = 0; bool keep_running = true; double timeout = 1.0; // in units of seconds bool got_packet = false; bool cerebus_connected = false; while( keep_running) { // // Connect to Cerebus port (unless already connected) // if( !cerebus_connected) { cerebus_connected = client.SetupConnection( nsp_ip); if( !cerebus_connected) { printf( "Failed to connect to Cerebus port, will continue trying...\n"); } } // // Read packet from Cerebus (time out after 1 second // to make sure we don't keep waiting if Cerebus goes down) // if( cerebus_connected) { Packet *pack = client.ReadPacket( timeout); if( pack) { ProcessPacket( pack, nsp_index); delete pack; } else { printf( "Timed out while waiting for packets from Cerebus\n"); cerebus_connected = false; } } // check spike Queue and process spikes checkSpikeQueue(nsp_index); // // Pause if cerebus not connected // because otherwise this program will busy-loop // if( !cerebus_connected) Sleep( 1000); } // end while (keep running) } catch(UPipeException &e){ MyCString trace; e.AppendTraceToString( trace); std::cout << "UPipeException occurred: " << trace.GetContent() << std::endl; } catch(MyCException &e){ MyCString trace; e.AppendTraceToString( trace); std::cout << "MyCException occurred: " << trace.GetContent() << std::endl; } catch(std::exception &e){ std::cout << "Exception occurred: " << e.what() << std::endl; } catch(...){ std::cout << "Unknown exception occurred!" << std::endl; } }