/** * Copyright 2014 Comcast Cable Communications Management, LLC * * This file is part of CATS. * * CATS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CATS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CATS. If not, see <http://www.gnu.org/licenses/>. */ package com.comcast.cats.service.ir.redrat; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ejb.EJB; import javax.ejb.Stateless; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.comcast.cats.RemoteCommand; import com.comcast.cats.RemoteLayout; import com.comcast.cats.info.RemoteCommandSequence; import com.comcast.cats.ir.commands.CatsCommand; import com.comcast.cats.ir.commands.DelayCommand; import com.comcast.cats.ir.commands.PressKeyAndHoldCommand; import com.comcast.cats.ir.commands.PressKeyCommand; import com.comcast.cats.service.IRHardwareEnum; import com.comcast.cats.service.IrDevice; import com.comcast.cats.service.IrPort; import com.comcast.cats.service.RedRatManager; import com.comcast.cats.service.WebServiceReturn; import com.comcast.cats.service.WebServiceReturnEnum; /** * IrWebService implementation for Redrat devices. * * @author skurup00c * */ @Stateless public class RedRatIRServiceHandler implements RedRatIRServiceFacade { @EJB RedRatManager redratManager; /** * The regex used to extract the ir port #. */ private static final Pattern IR_PORT_PATTERN = Pattern.compile( "port=([1-9]$|1[0-6]$)" ); /** * The regular expression that should be used to validate a direct tune * channel. */ private static final Pattern CHANNEL_VALIDATOR = Pattern.compile( "\\d{1,4}" ); private static final Integer REPEAT_IR_COMMAND_DELAY = 100; private static final Logger logger = LoggerFactory.getLogger( RedRatIRServiceHandler.class ); @Override public boolean pressKey( URI path, String irKeySet, RemoteCommand command ) { logger.trace("RedRatIRServiceHandler pressKey "+path+" irKeySet "+irKeySet+" command "+command); boolean response = false; if(path != null && irKeySet != null && command != null){ IrPort irPort = getIrPort( path ); logger.debug( "irPort "+irPort ); if ( irPort != null ) { PressKeyCommand pressKeyCommand = new PressKeyCommand( command, irKeySet ); WebServiceReturn result = irPort.sendCommand( pressKeyCommand ); logger.debug( "result "+result ); response = ( result.getResult() == WebServiceReturnEnum.SUCCESS ); } } return response; } @Override public boolean pressKeyAndHold( URI path, String irKeySet, RemoteCommand command, Integer count ) { logger.trace( "IRServiceWSImpl : pressKeyAndHold path " + path + " irKeySet " + irKeySet + " command " + command + " count " + count ); boolean response = false; if(path != null && irKeySet != null && command != null && count >= 0){ IrPort irPort = getIrPort( path ); logger.debug( "irPort "+irPort ); if ( irPort != null ) { PressKeyAndHoldCommand pressKeyHoldCommand = new PressKeyAndHoldCommand( command, irKeySet, count ); WebServiceReturn result = irPort.sendCommand( pressKeyHoldCommand ); logger.debug( "result "+result ); response = ( result.getResult() == WebServiceReturnEnum.SUCCESS ); } } return response; } @Override public boolean pressKeys( URI path, String irKeySet, List< RemoteCommand > commands, int delayMillis ) { logger.trace( "IRServiceWSImpl : pressKeys path " + path + " irKeySet " + irKeySet + " commands " + commands + " delayMillis " + delayMillis ); boolean response = false; if(path != null && irKeySet != null && commands != null && delayMillis >= 0){ IrPort irPort = getIrPort( path ); logger.debug( "irPort "+irPort ); if ( irPort != null ) { CatsCommand catsCommand = new CatsCommand( "PressKeys" ); for ( RemoteCommand command : commands ) { catsCommand.add( new PressKeyCommand( command, irKeySet ) ).add( new DelayCommand( delayMillis ) ); } WebServiceReturn result = irPort.sendCommand( catsCommand ); logger.debug( "result "+result ); response = ( result.getResult() == WebServiceReturnEnum.SUCCESS ); } } return response; } @Override public boolean tune( URI path, String irKeySet, String channel, boolean autoTuneEnabled, int delayMillis ) { logger.trace( "IRServiceWSImpl : tune path " + path + " irKeySet " + irKeySet + " channel " + channel + " delayMillis " + delayMillis + " autoTuneEnabled " + autoTuneEnabled ); boolean retVal = false; if(channel != null){ List< RemoteCommand > commands = getRemoteCommandFromChannel( channel ); if ( commands == null || commands.size() == 0 ) { return false; } if ( !autoTuneEnabled ) { commands.add( RemoteCommand.SELECT ); } retVal = pressKeys( path, irKeySet, commands, delayMillis ); } return retVal; } @Override public List< RemoteLayout > getRemoteCommands( String irKeySet ) { return null; } @Override public boolean sendIR( URI path, String irCode ) { throw new UnsupportedOperationException( "RedRatIRServiceFacade.sendIR() is not supported" ); } @Override public boolean enterCustomKeySequence( URI path, String irKeySet, List< RemoteCommand > commands, List< Integer > repeatCount, List< Integer > delay ) { logger.trace( "IRServiceWSImpl : enterCustomKeySequence path " + path + " irKeySet " + irKeySet + " commands " + commands + " repeatCount " + repeatCount + " delay " + delay ); boolean retVal = true; if ( null == path || null == irKeySet || null == commands || null == repeatCount || null == delay ) { return false; } if ( commands.size() != repeatCount.size() ) { return false; } if ( commands.size() != delay.size() ) { return false; } IrPort irPort = getIrPort( path ); logger.debug( "irPort "+irPort ); if ( irPort != null ) { Iterator< RemoteCommand > commandIter = commands.iterator(); Iterator< Integer > repeatCountIetr = repeatCount.iterator(); Iterator< Integer > delayIterator = delay.iterator(); CatsCommand catsCommand = new CatsCommand( "enterCustomKeySequence" ); while ( commandIter.hasNext() ) { RemoteCommand command = commandIter.next(); Integer repCount = repeatCountIetr.next(); Integer delayMs = delayIterator.next(); if ( repCount > 0 ) { catsCommand.add( new PressKeyAndHoldCommand( command, irKeySet, repCount ) ); } else { catsCommand.add( new PressKeyCommand( command, irKeySet ) ); } if ( !retVal ) { break; } catsCommand.add( new DelayCommand( delayMs ) ); } WebServiceReturn result = irPort.sendCommand( catsCommand ); logger.debug( "result "+result ); retVal = ( result.getResult() == WebServiceReturnEnum.SUCCESS ); } return retVal; } @Override public boolean enterRemoteCommandSequence( URI path, String irKeySet, List< RemoteCommandSequence > commands ) { logger.trace( "IRServiceWSImpl : enterRemoteCommandSequence path " + path + " irKeySet " + irKeySet + " commands " + commands ); boolean retVal = true; if ( null == path || null == irKeySet || null == commands ) { return false; } if ( commands.size() <= 0 ) { return false; } IrPort irPort = getIrPort( path ); if ( irPort != null ) { Iterator< RemoteCommandSequence > commandIter = commands.iterator(); CatsCommand catsCommand = new CatsCommand( "enterCustomKeySequence" ); while ( commandIter.hasNext() ) { RemoteCommandSequence commandSeq = commandIter.next(); RemoteCommand command = commandSeq.getCommand(); Integer repeatCount = commandSeq.getRepeatCount(); Integer delay = commandSeq.getDelay(); if ( repeatCount == null || delay == null ) { retVal = false; break; } if ( repeatCount > 0 ) { catsCommand.add( new PressKeyAndHoldCommand( command, irKeySet, repeatCount ) ); } else { catsCommand.add( new PressKeyCommand( command, irKeySet ) ); } if ( !retVal ) { break; } catsCommand.add( new DelayCommand( delay ) ); } WebServiceReturn result = irPort.sendCommand( catsCommand ); logger.debug( "result "+result ); retVal = ( result.getResult() == WebServiceReturnEnum.SUCCESS ); } return retVal; } @Override public boolean sendText( URI path, String irKeySet, String stringToBeEntered ) { logger.trace( "IRServiceWSImpl : sendText path " + path + " irKeySet " + irKeySet + " stringToBeEntered " + stringToBeEntered ); boolean returnVal = false; try{ if ( null != stringToBeEntered && !stringToBeEntered.isEmpty() && path != null && irKeySet != null ) { char[] digits = stringToBeEntered.toCharArray(); List< RemoteCommand > commands = new ArrayList< RemoteCommand >(); for ( char digit : digits ) { commands.add( RemoteCommand.parse( Character.toString( digit ) ) ); } returnVal = pressKeys( path, irKeySet, commands, REPEAT_IR_COMMAND_DELAY ); } }catch (IllegalArgumentException e) { logger.warn( "sendText exception "+e.getMessage() ); } return returnVal; } @Override public List< com.comcast.cats.keymanager.domain.Remote > getRemotes() { throw new UnsupportedOperationException( "RedRatIRServiceFacade.getRemotes() is not supported" ); } @Override public String getVersion() { throw new UnsupportedOperationException( "RedRatIRServiceFacade.getVersion() is not supported" ); } private String getDeviceIP( URI path ) { return path.getHost(); } private int getDevicePort( URI path ) { final Matcher m = IR_PORT_PATTERN.matcher( path.getQuery() ); if ( !m.find() ) { throw new IllegalArgumentException( "The URI is missing the port parameter (a number between 1 an n where n is the number of ir ports installed" ); } return Integer.parseInt( m.group( 1 ) ); } private IRHardwareEnum getDeviceType( URI path ) { return IRHardwareEnum.getByValue( path.getScheme() ); } private IrPort getIrPort( URI path ) { String rrDeviceIp = getDeviceIP( path ); int port = getDevicePort( path ); IRHardwareEnum deviceType = getDeviceType( path ); IrDevice irDevice = null; IrPort irPort = null; switch ( deviceType ) { case IRNETBOXPRO3: try { irDevice = redratManager.getIrDevice( rrDeviceIp ); if ( irDevice != null ) { irPort = irDevice.getPort( port ); }else{ logger.warn("irDevice is null. Could not get irDevice from redratManager "+irDevice); } } catch ( ClassCastException e ) { // the box is not a redrat device. Dont send any commands. } } return irPort; } private List< RemoteCommand > getRemoteCommandFromChannel( String channel ) { if ( !CHANNEL_VALIDATOR.matcher( channel ).matches() ) { return null; } char[] digits = channel.toCharArray(); List< RemoteCommand > commands = new ArrayList< RemoteCommand >(); for ( char digit : digits ) { String dStr = new String(); dStr += digit; commands.add( RemoteCommand.parse( dStr ) ); } return commands; } @Override public List<RemoteLayout> getRemoteLayout(String remoteType) { return null; } }