MakingThings
  • Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

debugosc.c

Go to the documentation of this file.
00001 /*********************************************************************************
00002 
00003  Copyright 2006-2008 MakingThings
00004 
00005  Licensed under the Apache License, 
00006  Version 2.0 (the "License"); you may not use this file except in compliance 
00007  with the License. You may obtain a copy of the License at
00008 
00009  http://www.apache.org/licenses/LICENSE-2.0 
00010  
00011  Unless required by applicable law or agreed to in writing, software distributed
00012  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00013  CONDITIONS OF ANY KIND, either express or implied. See the License for
00014  the specific language governing permissions and limitations under the License.
00015 
00016 *********************************************************************************/
00017 
00018 /** \file debugosc.c  
00019   Controller Debug.
00020 */
00021 
00022 #include "config.h"
00023 #ifdef OSC
00024 
00025 #include "debug.h"
00026 #include <stdio.h>
00027 #include "osc.h"
00028 #include <stdarg.h>
00029 
00030 #define DEBUG_MAX_MESSAGE 100
00031 
00032 typedef struct Debug_
00033 {
00034   int users;
00035   int level;
00036   int usb;
00037   int udp;
00038   char message[ DEBUG_MAX_MESSAGE ];
00039 } DebugStruct;
00040 
00041 DebugStruct* DebugData;
00042 
00043 /** \defgroup Debug OSC Debug
00044   The Debug subsystem offers a simple way to send debug messages back from the MAKE Controller via OSC.
00045   Even without single-stepping through the code running on the MAKE Controller, it is still easy to get helpful
00046   debug information about the program through the Debug subsystem.
00047   
00048   Specify the level of each debug message and then, in a debug session, set the level you would like to see.  More 
00049   frequent and lower level messages can be filtered out in a debug session by setting the debug
00050   level a bit higher to let through only the messages you're interested in. 
00051 
00052   Possible levels are:
00053   - 0 - Always send
00054   - 1 - Error messages
00055   - 2 - Warning messages
00056   - 3 - Normal/test messages
00057 
00058   \ingroup Core
00059   @{
00060 */
00061 
00062 /**
00063   Sets whether the Debug subsystem is active.
00064   The Debug system is automatically set to active by making a call to any Debug system function,
00065   so you don't typically have to worry about doing that.  But, you can set it to inactive
00066   to recover a bit of space on the heap.
00067   @param state An integer specifying the active state - 1 (active) or 0 (inactive).
00068   @return Zero on success.
00069 
00070   \par Example
00071   \code
00072   // Checking the debug level sets the system to active.
00073   int level = Debug_GetLevel();
00074   // then we can turn it off
00075   Debug_SetActive( 0 );
00076   \endcode
00077 */
00078 int Debug_SetActive( int state )
00079 {
00080   if( state && DebugData == NULL )
00081   {
00082     DebugData = MallocWait( sizeof( struct Debug_ ), 100 );
00083     DebugData->usb = 1;
00084     DebugData->udp = 1;
00085     DebugData->level = DEBUG_MESSAGE;
00086   }
00087   if( !state && DebugData != NULL )
00088   {
00089     Free( DebugData );
00090     DebugData = NULL;
00091   }
00092   return CONTROLLER_OK;
00093 }
00094 
00095 /**
00096   Returns the active state of the Debug subsystem.
00097   @return State - 1 (active) or 0 (inactive).
00098 
00099   \par Example
00100   \code
00101   // Check to see if we're active...
00102   int active = Debug_GetActive();
00103   if( active )
00104     // then do something...
00105   \endcode
00106 */
00107 int Debug_GetActive( )
00108 {
00109   return DebugData != NULL;
00110 }
00111 
00112 /** 
00113   Sets the debug level.
00114   Set to a lower number to get more messages.  Default level is 3.
00115   @param level An integer specifying the level (from 0-3).
00116   @return 0 on success
00117 
00118   \par Example
00119   \code
00120   // Set the level to just report error messages.
00121   Debug_SetLevel( 1 );
00122   \endcode
00123 */
00124 int Debug_SetLevel( int level )
00125 {
00126   if ( !Debug_GetActive() )
00127     Debug_SetActive( 1 );
00128   DebugData->level = level;
00129   return CONTROLLER_OK;
00130 }
00131 
00132 /** 
00133   Read the current debugger level.
00134   @return Level An integer from 0-3 specifying the level.
00135 
00136   \par Example
00137   \code
00138   // Check the current debug level
00139   int level = Debug_GetLevel( );
00140   switch( level )
00141   {
00142     case DEBUG_ALWAYS:
00143       // ...
00144       break;
00145     case DEBUG_ERROR:
00146       // ...
00147       break;
00148     case DEBUG_WARNING:
00149       // ...
00150       break;
00151     case DEBUG_MESSAGE:
00152       // ...
00153       break;
00154   }
00155   \endcode
00156 */
00157 int Debug_GetLevel( )
00158 {
00159   if ( !Debug_GetActive() )
00160     Debug_SetActive( 1 );
00161   return DebugData->level;
00162 }
00163 
00164 /**
00165   Sets whether the Debug subsystem outputs its OSC messages via USB.
00166   This is enabled by default.  
00167   @param state An integer specifying whether or not to send over USB - 1 (on) or 0 (off).
00168   @return Zero on success.
00169 
00170   \par Example
00171   \code
00172   // Turn debugging over USB off.
00173   Debug_SetUsb( 0 );
00174   \endcode
00175 */
00176 int Debug_SetUsb( int state )
00177 {
00178   if ( !Debug_GetActive() )
00179     Debug_SetActive( 1 );
00180   DebugData->usb = state;
00181   return CONTROLLER_OK;
00182 }
00183 
00184 /**
00185   Returns whether the Debug system is set to send its messages over USB.
00186   This is enabled by default.
00187   @return state An integer specifying whether messages will be sent over USB - 1 (enabled) or 0 (disabled).
00188 
00189   \par Example
00190   \code
00191   // Check whether we're sending Debug messages over USB
00192   int usb_debug = Debug_GetUsb( );
00193   \endcode
00194 */
00195 int Debug_GetUsb( )
00196 {
00197   if ( !Debug_GetActive() )
00198     Debug_SetActive( 1 );
00199   return DebugData->usb;
00200 }
00201 
00202 /**
00203   Sets whether the Debug system is set to send its messages over UDP.
00204   This is enabled by default.
00205   @param state An integer specifying the state - 1 (on) or 0 (off).
00206   @return Zero on success.
00207 
00208   \par Example
00209   \code
00210   // Turn debugging over UDP off.
00211   Debug_SetUdp( 0 );
00212   \endcode
00213 */
00214 int Debug_SetUdp( int state )
00215 {
00216   if ( !Debug_GetActive() )
00217     Debug_SetActive( 1 );
00218   DebugData->udp = state;
00219   return CONTROLLER_OK;
00220 }
00221 
00222 /**
00223   Sets whether the Debug subsystem outputs its OSC messages via USB.
00224   This is enabled by default.
00225   @return state An integer specifying whether messages will be sent over USB - 1 (enabled) or 0 (disabled).
00226 
00227   \par Example
00228   \code
00229   // Check whether we're sending Debug messages over UDP
00230   int udp_debug = Debug_GetUdp( );
00231   \endcode
00232 */
00233 int Debug_GetUdp( )
00234 {
00235   if ( !Debug_GetActive() )
00236     Debug_SetActive( 1 );
00237 
00238   return DebugData->udp;
00239 }
00240 
00241 /**
00242   Create a debug message.
00243   @param level An integer specifying the debug level.  
00244   @param format printf()-style formatting. %d, %s, %x, etc.
00245   @param ... The contents of the debug message - this can look just like a call to printf().
00246 
00247   \par Example
00248   \code
00249   // send a simple debug message...
00250   Debug( DEBUG_MESSAGE, "%s", "Hello." );
00251 
00252   // or a slightly more interesting message
00253   SomeTask( void* p )
00254   {
00255     int counter = 0;
00256     while( 1 )
00257     {
00258       Debug( DEBUG_MESSAGE, "%s %d", "Current count is: ", counter++ );
00259       Sleep( 1000 );
00260     }
00261   }
00262   \endcode
00263 
00264   @return 
00265 */
00266 
00267 int Debug( int level, char* format, ... )
00268 {
00269   va_list args;
00270 
00271   if ( !Debug_GetActive() )
00272     Debug_SetActive( 1 );
00273 
00274   if ( Osc_GetActive() && Osc_GetRunning( ) && level <= DebugData->level )
00275   {
00276     va_start( args, format );
00277     vsnprintf( DebugData->message, DEBUG_MAX_MESSAGE, format, args ); 
00278     // va_end( args );
00279     #ifdef MAKE_CTRL_USB
00280     if ( DebugData->usb && Usb_GetActive() )
00281     {
00282       Osc_CreateMessage( OSC_CHANNEL_USB, "/debug/message", ",s", DebugData->message );
00283       Osc_SendPacket( OSC_CHANNEL_USB );
00284     }
00285     #endif
00286     #ifdef MAKE_CTRL_NETWORK
00287     if ( DebugData->udp && Network_GetActive() )
00288     {
00289       Osc_CreateMessage( OSC_CHANNEL_UDP, "/debug/message", ",s", DebugData->message );
00290       Osc_SendPacket( OSC_CHANNEL_UDP );
00291     }
00292     #endif
00293   }
00294   return CONTROLLER_OK;
00295 }
00296 
00297 
00298 /** @}
00299 */
00300 
00301 /** \defgroup DebugOSC Debug - OSC
00302   Debug allows sending/receiving debug messages via OSC.
00303   By default debug messages are sent over both USB and UDP, but this can be modified.
00304   \ingroup OSC
00305    
00306     \section devices Devices
00307     There's only one Debug system, so a device index is not used in OSC messages to it.
00308    
00309     \section properties Properties
00310     Debug has six properties - \b active, \b level, \b usb, and \b udp.
00311 
00312     \par Active
00313     The \b 'active' property corresponds to the active state of the Debug system.
00314     If Debug is set to be inactive, it will not respond to any other OSC messages. 
00315     If you're not seeing appropriate
00316     responses to your messages to Debug, check the whether it's
00317     active by sending a message like
00318     \verbatim /debug/active \endverbatim
00319     \par
00320     You can set the active flag by sending
00321     \verbatim /debug/active 1 \endverbatim
00322     
00323     \par Level
00324     The \b level property corresponds to the level of detail of the debug messages you want to receive.
00325     Typically in a debug system, low-level messages are given a low number and higher-level messages
00326     get higher numbers.  So, if you don't need to see all the low level stuff, you can simply set the debug
00327     level to a higher number so you're not flooded with tons of nitty gritty messages.
00328 
00329     Values for the levels:
00330     - 0 - Always send
00331     - 1 - Error messages
00332     - 2 - Warning messages
00333     - 3 - Normal/test messages
00334     
00335     The default debug level is \b 3.  Set the level by sending a message like:
00336     \verbatim /debug/level 2 \endverbatim
00337    
00338     \par Usb
00339     The \b usb property determines whether debug messages will be sent over USB.  This is turned on
00340     by default.
00341 
00342     To set this to off, send a message like:
00343     \code /debug/usb 0 \endcode
00344    
00345     \par Udp
00346     The \b udp property determines whether debug messages will be sent over UDP.  This is turned on
00347     by default.
00348 
00349     To set this to off, send a message like:
00350     \code /debug/udp 0 \endcode
00351 */
00352 
00353 #include "osc.h"
00354 #include "string.h"
00355 #include "stdio.h"
00356 
00357 // OSC Interface 
00358 //const char* DebugOsc_GetName( void );
00359 //int DebugOsc_ReceiveMessage( int channel, char* message, int length );
00360 
00361 // Need a list of property names
00362 // MUST end in zero
00363 static char* DebugOsc_Name = "debug";
00364 static char* DebugOsc_PropertyNames[] = { "active", "level", "usb", "udp", 0 }; // must have a trailing 0
00365 
00366 int DebugOsc_PropertySet( int property, int value );
00367 int DebugOsc_PropertyGet( int property );
00368 
00369 // Returns the name of the subsystem
00370 const char* DebugOsc_GetName( )
00371 {
00372   return DebugOsc_Name;
00373 }
00374 
00375 // Now getting a message.  This is actually a part message, with the first
00376 // part (the subsystem) already parsed off.
00377 int DebugOsc_ReceiveMessage( int channel, char* message, int length )
00378 {
00379   return Osc_IntReceiverHelper( channel, message, length, 
00380                                 DebugOsc_Name,
00381                                 DebugOsc_PropertySet, DebugOsc_PropertyGet, 
00382                                 DebugOsc_PropertyNames );
00383 }
00384 
00385 // Set the index LED, property with the value
00386 int DebugOsc_PropertySet( int property, int value )
00387 {
00388   switch ( property )
00389   {
00390     case 0: 
00391       Debug_SetActive( value );
00392       break;      
00393     case 1:
00394       Debug_SetLevel( value );
00395       break;
00396     case 2:
00397       Debug_SetUsb( value );
00398       break;
00399     case 3:
00400       Debug_SetUdp( value );
00401       break;
00402   }
00403   return CONTROLLER_OK;
00404 }
00405 
00406 // Get the index LED, property
00407 int DebugOsc_PropertyGet( int property )
00408 {
00409   int value = 0;
00410   switch ( property )
00411   {
00412     case 0:
00413       value = Debug_GetActive( );
00414       break;
00415     case 1:
00416       value = Debug_GetLevel( );
00417       break;
00418     case 2:
00419       value = Debug_GetUsb( );
00420       break;  
00421     case 3:
00422       value = Debug_GetUdp( );
00423       break;  
00424   }
00425   return value;
00426 }
00427 
00428 #endif // OSC
00429 
00430 

The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.