Files
libupnp/upnp/sample/tvctrlpt/linux/tv_ctrlpt_main.c
2010-11-17 23:35:07 -02:00

392 lines
12 KiB
C

/*******************************************************************************
*
* 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 "tv_ctrlpt.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/*! 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 {
/* the string */
const char *str;
/* the command */
int cmdnum;
/* the number of arguments */
int numargs;
/* the args */
const char *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, "<devnum>"},
{"PowerOn", POWON, 2, "<devnum>"},
{"PowerOff", POWOFF, 2, "<devnum>"},
{"SetChannel", SETCHAN, 3, "<devnum> <channel (int)>"},
{"SetVolume", SETVOL, 3, "<devnum> <volume (int)>"},
{"SetColor", SETCOL, 3, "<devnum> <color (int)>"},
{"SetTint", SETTINT, 3, "<devnum> <tint (int)>"},
{"SetContrast", SETCONT, 3, "<devnum> <contrast (int)>"},
{"SetBrightness", SETBRT, 3, "<devnum> <brightness (int)>"},
{"CtrlAction", CTRLACTION, 2, "<devnum> <action (string)>"},
{"PictAction", PICTACTION, 2, "<devnum> <action (string)>"},
{"CtrlGetVar", CTRLGETVAR, 2, "<devnum> <varname (string)>"},
{"PictGetVar", PICTGETVAR, 2, "<devnum> <varname (string)>"},
{"Exit", EXITCMD, 1, ""}
};
/*!
* \brief Prints a string to standard out.
*/
void linux_print(const char *format, ...)
{
va_list argList;
va_start(argList, format);
vfprintf(stdout, format, argList);
fflush(stdout);
va_end(argList);
}
/*!
* \brief Print help info for this application.
*/
void TvCtrlPointPrintShortHelp(void)
{
SampleUtil_Print(
"Commands:\n"
" Help\n"
" HelpFull\n"
" ListDev\n"
" Refresh\n"
" PrintDev <devnum>\n"
" PowerOn <devnum>\n"
" PowerOff <devnum>\n"
" SetChannel <devnum> <channel>\n"
" SetVolume <devnum> <volume>\n"
" SetColor <devnum> <color>\n"
" SetTint <devnum> <tint>\n"
" SetContrast <devnum> <contrast>\n"
" SetBrightness <devnum> <brightness>\n"
" CtrlAction <devnum> <action>\n"
" PictAction <devnum> <action>\n"
" CtrlGetVar <devnum> <varname>\n"
" PictGetVar <devnum> <action>\n"
" Exit\n");
}
void TvCtrlPointPrintLongHelp(void)
{
SampleUtil_Print(
"\n"
"******************************\n"
"* TV Control Point Help Info *\n"
"******************************\n"
"\n"
"This sample control point application automatically searches\n"
"for and subscribes to the services of television device emulator\n"
"devices, described in the tvdevicedesc.xml description document.\n"
"It also registers itself as a tv device.\n"
"\n"
"Commands:\n"
" Help\n"
" Print this help info.\n"
" ListDev\n"
" Print the current list of TV Device Emulators that this\n"
" control point is aware of. Each device is preceded by a\n"
" device number which corresponds to the devnum argument of\n"
" commands listed below.\n"
" Refresh\n"
" Delete all of the devices from the device list and issue new\n"
" search request to rebuild the list from scratch.\n"
" PrintDev <devnum>\n"
" Print the state table for the device <devnum>.\n"
" e.g., 'PrintDev 1' prints the state table for the first\n"
" device in the device list.\n"
" PowerOn <devnum>\n"
" Sends the PowerOn action to the Control Service of\n"
" device <devnum>.\n"
" PowerOff <devnum>\n"
" Sends the PowerOff action to the Control Service of\n"
" device <devnum>.\n"
" SetChannel <devnum> <channel>\n"
" Sends the SetChannel action to the Control Service of\n"
" device <devnum>, requesting the channel to be changed\n"
" to <channel>.\n"
" SetVolume <devnum> <volume>\n"
" Sends the SetVolume action to the Control Service of\n"
" device <devnum>, requesting the volume to be changed\n"
" to <volume>.\n"
" SetColor <devnum> <color>\n"
" Sends the SetColor action to the Control Service of\n"
" device <devnum>, requesting the color to be changed\n"
" to <color>.\n"
" SetTint <devnum> <tint>\n"
" Sends the SetTint action to the Control Service of\n"
" device <devnum>, requesting the tint to be changed\n"
" to <tint>.\n"
" SetContrast <devnum> <contrast>\n"
" Sends the SetContrast action to the Control Service of\n"
" device <devnum>, requesting the contrast to be changed\n"
" to <contrast>.\n"
" SetBrightness <devnum> <brightness>\n"
" Sends the SetBrightness action to the Control Service of\n"
" device <devnum>, requesting the brightness to be changed\n"
" to <brightness>.\n"
" CtrlAction <devnum> <action>\n"
" Sends an action request specified by the string <action>\n"
" to the Control Service of device <devnum>. This command\n"
" only works for actions that have no arguments.\n"
" (e.g., \"CtrlAction 1 IncreaseChannel\")\n"
" PictAction <devnum> <action>\n"
" Sends an action request specified by the string <action>\n"
" to the Picture Service of device <devnum>. This command\n"
" only works for actions that have no arguments.\n"
" (e.g., \"PictAction 1 DecreaseContrast\")\n"
" CtrlGetVar <devnum> <varname>\n"
" Requests the value of a variable specified by the string <varname>\n"
" from the Control Service of device <devnum>.\n"
" (e.g., \"CtrlGetVar 1 Volume\")\n"
" PictGetVar <devnum> <action>\n"
" Requests the value of a variable specified by the string <varname>\n"
" from the Picture Service of device <devnum>.\n"
" (e.g., \"PictGetVar 1 Tint\")\n"
" Exit\n"
" Exits the control point application.\n");
}
/*!
* \briefPrint the list of valid command line commands to the user
*/
void TvCtrlPointPrintCommands()
{
int i;
int numofcmds = (sizeof cmdloop_cmdlist) / sizeof (cmdloop_commands);
SampleUtil_Print("Valid Commands:\n");
for (i = 0; i < numofcmds; ++i) {
SampleUtil_Print(" %-14s %s\n",
cmdloop_cmdlist[i].str, cmdloop_cmdlist[i].args);
}
SampleUtil_Print("\n");
}
/*!
* \brief Function that receives commands from the user at the command prompt
* during the lifetime of the device, and calls the appropriate
* functions for those commands.
*/
void *TvCtrlPointCommandLoop(void *args)
{
char cmdline[100];
while (1) {
SampleUtil_Print("\n>> ");
fgets(cmdline, 100, stdin);
TvCtrlPointProcessCommand(cmdline);
}
return NULL;
args = args;
}
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;
int 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'\n");
return TV_SUCCESS;
}
if (invalidargs) {
SampleUtil_Print("Invalid arguments; try 'Help'\n");
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 (validargs == 3)
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 (validargs == 3)
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 (validargs == 3)
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 (validargs == 3)
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'\n");
break;
}
if(invalidargs)
SampleUtil_Print("Invalid args in command; see 'Help'\n");
return TV_SUCCESS;
}
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;
rc = TvCtrlPointStart(linux_print, NULL);
if (rc != TV_SUCCESS) {
SampleUtil_Print("Error starting UPnP TV Control Point\n");
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
rc = TvCtrlPointStop();
return rc;
argc = argc;
argv = argv;
}