/******************************************************************************* * * Copyright (c) 2000-2003 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither name of Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ #include "sample_util.h" #include "upnp_tv_ctrlpt.h" #include "upnp_tv_device.h" #include #include /* Tags for valid commands issued at the command prompt */ enum cmdloop_tvcmds { PRTHELP = 0, PRTFULLHELP, POWON, POWOFF, SETCHAN, SETVOL, SETCOL, SETTINT, SETCONT, SETBRT, CTRLACTION, PICTACTION, CTRLGETVAR, PICTGETVAR, PRTDEV, LSTDEV, REFRESH, EXITCMD }; /* Data structure for parsing commands from the command line */ struct cmdloop_commands { char *str; /* the string */ int cmdnum; /* the command */ int numargs; /* the number of arguments */ char *args; /* the args */ } cmdloop_commands; /* Mappings between command text names, command tag, and required command arguments for command line commands */ static struct cmdloop_commands cmdloop_cmdlist[] = { {"Help", PRTHELP, 1, ""}, {"HelpFull", PRTFULLHELP, 1, ""}, {"ListDev", LSTDEV, 1, ""}, {"Refresh", REFRESH, 1, ""}, {"PrintDev", PRTDEV, 2, ""}, {"PowerOn", POWON, 2, ""}, {"PowerOff", POWOFF, 2, ""}, {"SetChannel", SETCHAN, 3, " "}, {"SetVolume", SETVOL, 3, " "}, {"SetColor", SETCOL, 3, " "}, {"SetTint", SETTINT, 3, " "}, {"SetContrast", SETCONT, 3, " "}, {"SetBrightness", SETBRT, 3, " "}, {"CtrlAction", CTRLACTION, 2, " "}, {"PictAction", PICTACTION, 2, " "}, {"CtrlGetVar", CTRLGETVAR, 2, " "}, {"PictGetVar", PICTGETVAR, 2, " "}, {"Exit", EXITCMD, 1, ""} }; void linux_print( const char *string ) { puts( string ); } /******************************************************************************** * TvCtrlPointPrintHelp * * Description: * Print help info for this application. ********************************************************************************/ void TvCtrlPointPrintShortHelp( void ) { SampleUtil_Print( "Commands:" ); SampleUtil_Print( " Help" ); SampleUtil_Print( " HelpFull" ); SampleUtil_Print( " ListDev" ); SampleUtil_Print( " Refresh" ); SampleUtil_Print( " PrintDev " ); SampleUtil_Print( " PowerOn " ); SampleUtil_Print( " PowerOff " ); SampleUtil_Print( " SetChannel " ); SampleUtil_Print( " SetVolume " ); SampleUtil_Print( " SetColor " ); SampleUtil_Print( " SetTint " ); SampleUtil_Print( " SetContrast " ); SampleUtil_Print( " SetBrightness " ); SampleUtil_Print( " CtrlAction " ); SampleUtil_Print( " PictAction " ); SampleUtil_Print( " CtrlGetVar " ); SampleUtil_Print( " PictGetVar " ); SampleUtil_Print( " Exit" ); } void TvCtrlPointPrintLongHelp( void ) { SampleUtil_Print( "" ); SampleUtil_Print( "******************************" ); SampleUtil_Print( "* TV Control Point Help Info *" ); SampleUtil_Print( "******************************" ); SampleUtil_Print( "" ); SampleUtil_Print( "This sample control point application automatically searches" ); SampleUtil_Print( "for and subscribes to the services of television device emulator" ); SampleUtil_Print( "devices, described in the tvdevicedesc.xml description document." ); SampleUtil_Print( "It also registers itself as a tv device." ); SampleUtil_Print( "" ); SampleUtil_Print( "Commands:" ); SampleUtil_Print( " Help" ); SampleUtil_Print( " Print this help info." ); SampleUtil_Print( " ListDev" ); SampleUtil_Print( " Print the current list of TV Device Emulators that this" ); SampleUtil_Print( " control point is aware of. Each device is preceded by a" ); SampleUtil_Print( " device number which corresponds to the devnum argument of" ); SampleUtil_Print( " commands listed below." ); SampleUtil_Print( " Refresh" ); SampleUtil_Print( " Delete all of the devices from the device list and issue new" ); SampleUtil_Print( " search request to rebuild the list from scratch." ); SampleUtil_Print( " PrintDev " ); SampleUtil_Print( " Print the state table for the device ." ); SampleUtil_Print( " e.g., 'PrintDev 1' prints the state table for the first" ); SampleUtil_Print( " device in the device list." ); SampleUtil_Print( " PowerOn " ); SampleUtil_Print( " Sends the PowerOn action to the Control Service of" ); SampleUtil_Print( " device ." ); SampleUtil_Print( " PowerOff " ); SampleUtil_Print( " Sends the PowerOff action to the Control Service of" ); SampleUtil_Print( " device ." ); SampleUtil_Print( " SetChannel " ); SampleUtil_Print( " Sends the SetChannel action to the Control Service of" ); SampleUtil_Print( " device , requesting the channel to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " SetVolume " ); SampleUtil_Print( " Sends the SetVolume action to the Control Service of" ); SampleUtil_Print( " device , requesting the volume to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " SetColor " ); SampleUtil_Print( " Sends the SetColor action to the Control Service of" ); SampleUtil_Print( " device , requesting the color to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " SetTint " ); SampleUtil_Print( " Sends the SetTint action to the Control Service of" ); SampleUtil_Print( " device , requesting the tint to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " SetContrast " ); SampleUtil_Print( " Sends the SetContrast action to the Control Service of" ); SampleUtil_Print( " device , requesting the contrast to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " SetBrightness " ); SampleUtil_Print( " Sends the SetBrightness action to the Control Service of" ); SampleUtil_Print( " device , requesting the brightness to be changed" ); SampleUtil_Print( " to ." ); SampleUtil_Print( " CtrlAction " ); SampleUtil_Print( " Sends an action request specified by the string " ); SampleUtil_Print( " to the Control Service of device . This command" ); SampleUtil_Print( " only works for actions that have no arguments." ); SampleUtil_Print( " (e.g., \"CtrlAction 1 IncreaseChannel\")" ); SampleUtil_Print( " PictAction " ); SampleUtil_Print( " Sends an action request specified by the string " ); SampleUtil_Print( " to the Picture Service of device . This command" ); SampleUtil_Print( " only works for actions that have no arguments." ); SampleUtil_Print( " (e.g., \"PictAction 1 DecreaseContrast\")" ); SampleUtil_Print( " CtrlGetVar " ); SampleUtil_Print( " Requests the value of a variable specified by the string " ); SampleUtil_Print( " from the Control Service of device ." ); SampleUtil_Print( " (e.g., \"CtrlGetVar 1 Volume\")" ); SampleUtil_Print( " PictGetVar " ); SampleUtil_Print( " Requests the value of a variable specified by the string " ); SampleUtil_Print( " from the Picture Service of device ." ); SampleUtil_Print( " (e.g., \"PictGetVar 1 Tint\")" ); SampleUtil_Print( " Exit" ); SampleUtil_Print( " Exits the control point application." ); } /******************************************************************************** * TvCtrlPointPrintCommands * * Description: * Print the list of valid command line commands to the user * * Parameters: * None * ********************************************************************************/ void TvCtrlPointPrintCommands() { int i; int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands ); SampleUtil_Print( "Valid Commands:" ); for( i = 0; i < numofcmds; i++ ) { SampleUtil_Print( " %-14s %s", cmdloop_cmdlist[i].str, cmdloop_cmdlist[i].args ); } SampleUtil_Print( "" ); } /******************************************************************************** * TvCtrlPointCommandLoop * * Description: * Function that receives commands from the user at the command prompt * during the lifetime of the control point, and calls the appropriate * functions for those commands. * * Parameters: * None * ********************************************************************************/ void * TvCtrlPointCommandLoop( void *args ) { char cmdline[100]; while( 1 ) { SampleUtil_Print( "\n>> " ); fgets( cmdline, 100, stdin ); TvCtrlPointProcessCommand( cmdline ); } return NULL; } int TvCtrlPointProcessCommand( char *cmdline ) { char cmd[100]; char strarg[100]; int arg_val_err = -99999; int arg1 = arg_val_err; int arg2 = arg_val_err; int cmdnum = -1; int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands ); int cmdfound = 0; int i, rc; int invalidargs = 0; int validargs; validargs = sscanf( cmdline, "%s %d %d", cmd, &arg1, &arg2 ); for( i = 0; i < numofcmds; i++ ) { if( strcasecmp( cmd, cmdloop_cmdlist[i].str ) == 0 ) { cmdnum = cmdloop_cmdlist[i].cmdnum; cmdfound++; if( validargs != cmdloop_cmdlist[i].numargs ) invalidargs++; break; } } if( !cmdfound ) { SampleUtil_Print( "Command not found; try 'Help'" ); return TV_SUCCESS; } if( invalidargs ) { SampleUtil_Print( "Invalid arguments; try 'Help'" ); return TV_SUCCESS; } switch ( cmdnum ) { case PRTHELP: TvCtrlPointPrintShortHelp(); break; case PRTFULLHELP: TvCtrlPointPrintLongHelp(); break; case POWON: TvCtrlPointSendPowerOn( arg1 ); break; case POWOFF: TvCtrlPointSendPowerOff( arg1 ); break; case SETCHAN: TvCtrlPointSendSetChannel( arg1, arg2 ); break; case SETVOL: TvCtrlPointSendSetVolume( arg1, arg2 ); break; case SETCOL: TvCtrlPointSendSetColor( arg1, arg2 ); break; case SETTINT: TvCtrlPointSendSetTint( arg1, arg2 ); break; case SETCONT: TvCtrlPointSendSetContrast( arg1, arg2 ); break; case SETBRT: TvCtrlPointSendSetBrightness( arg1, arg2 ); break; case CTRLACTION: /* re-parse commandline since second arg is string */ validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg ); if( 3 == validargs ) TvCtrlPointSendAction( TV_SERVICE_CONTROL, arg1, strarg, NULL, NULL, 0 ); else invalidargs++; break; case PICTACTION: /* re-parse commandline since second arg is string */ validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg ); if( 3 == validargs ) TvCtrlPointSendAction( TV_SERVICE_PICTURE, arg1, strarg, NULL, NULL, 0 ); else invalidargs++; break; case CTRLGETVAR: /* re-parse commandline since second arg is string */ validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg ); if( 3 == validargs ) TvCtrlPointGetVar( TV_SERVICE_CONTROL, arg1, strarg ); else invalidargs++; break; case PICTGETVAR: /* re-parse commandline since second arg is string */ validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg ); if( 3 == validargs ) TvCtrlPointGetVar( TV_SERVICE_PICTURE, arg1, strarg ); else invalidargs++; break; case PRTDEV: TvCtrlPointPrintDevice( arg1 ); break; case LSTDEV: TvCtrlPointPrintList(); break; case REFRESH: TvCtrlPointRefresh(); break; case EXITCMD: rc = TvCtrlPointStop(); exit( rc ); break; default: SampleUtil_Print( "Command not implemented; see 'Help'" ); break; } if( invalidargs ) SampleUtil_Print( "Invalid args in command; see 'Help'" ); return TV_SUCCESS; } int device_main( int argc, char **argv ) { unsigned int portTemp = 0; char *ip_address = NULL, *desc_doc_name = NULL, *web_dir_path = NULL; unsigned int port = 0; int i = 0; SampleUtil_Initialize( linux_print ); /* Parse options */ for( i = 1; i < argc; i++ ) { if( strcmp( argv[i], "-ip" ) == 0 ) { ip_address = argv[++i]; } else if( strcmp( argv[i], "-port" ) == 0 ) { sscanf( argv[++i], "%u", &portTemp ); } else if( strcmp( argv[i], "-desc" ) == 0 ) { desc_doc_name = argv[++i]; } else if( strcmp( argv[i], "-webdir" ) == 0 ) { web_dir_path = argv[++i]; } else if( strcmp( argv[i], "-help" ) == 0 ) { SampleUtil_Print( "Usage: %s -ip ipaddress -port port" " -desc desc_doc_name -webdir web_dir_path" " -help (this message)\n", argv[0] ); SampleUtil_Print( "\tipaddress: IP address of the device" " (must match desc. doc)\n" ); SampleUtil_Print( "\t\te.g.: 192.168.0.4\n" ); SampleUtil_Print( "\tport: Port number to use for " "receiving UPnP messages (must match desc. doc)\n" ); SampleUtil_Print( "\t\te.g.: 5431\n" ); SampleUtil_Print ( "\tdesc_doc_name: name of device description document\n" ); SampleUtil_Print( "\t\te.g.: tvcombodesc.xml\n" ); SampleUtil_Print ( "\tweb_dir_path: Filesystem path where web files " "related to the device are stored\n" ); SampleUtil_Print( "\t\te.g.: /upnp/sample/web\n" ); return 1; } } port = ( unsigned short )portTemp; return TvDeviceStart( ip_address, port, desc_doc_name, web_dir_path, linux_print ); } int main( int argc, char **argv ) { int rc; ithread_t cmdloop_thread; #ifdef WIN32 #else int sig; sigset_t sigs_to_catch; #endif int code; device_main(argc, argv); rc = TvCtrlPointStart( linux_print, NULL ); if( rc != TV_SUCCESS ) { SampleUtil_Print( "Error starting UPnP TV Control Point" ); return rc; } /* start a command loop thread */ code = ithread_create( &cmdloop_thread, NULL, TvCtrlPointCommandLoop, NULL ); #ifdef WIN32 ithread_join(cmdloop_thread, NULL); #else /* Catch Ctrl-C and properly shutdown */ sigemptyset( &sigs_to_catch ); sigaddset( &sigs_to_catch, SIGINT ); sigwait( &sigs_to_catch, &sig ); SampleUtil_Print( "Shutting down on signal %d...\n", sig ); #endif TvDeviceStop(); rc = TvCtrlPointStop(); return rc; }