HAVi (Home Audio Visual Interoperability Architecture) is concerned with the following home devices
class TV {
Tuner tuner;
Display display;
}
class TV_code_unit {
TV tv; // device controller
Tuner tuner; // functional unit
Display display; // functional unit
install() {
install(tv);
install(tuner);
install(display)
}
}
GUID
(globally unique identifier) to identify
devices independent of these bus resets
swHandle
GUID
and the swHandle
Attribute {
Class // 1 bit private or system
Name // 31 bit integer id
Size // size in bytes of value
Value
}
struct SimpleQuery {
AttributeName attr;
sequence<octet> compareValue;
CompOperation compareOp;
}
DCMClient
FCMClient
VCRClient
,
ClockClient
or TunerClient
Methods applicable to an entire device
getDeviceClass()
one of FAV, IAV, BAV
getDeviceManufacturer()
getFcmCount()
number of FCM modules
getFCMSeidList()
list of FCM SEIDs
nativeCommand()
send a native (non-HAVi) command
to the device
Methods applicable to functional modules in a device
getFCMType()
getPowerState()
canWink()
can it "flash" or "blink"?
wink()
getWorstCaseStartupTime()
play()
stop()
record()
fastForward()
eject()
getFormat()
current media format
getCapability()
formats supported by device
selectService()
tune to a service
getServiceList()
possible services
getService()
info about currently
tuned service
Message {
DestSEID
SourceSEID
MessageType // simple, reliable
MessageLength
MessageBody
}
msg_reliable_ack
or msg_reliable_noack
for failure
Connection
object
FCMPlug
java.awt
is used, with additional
classes such as a "remote control" input object
List
, TextArea
etc are gone
Point
, Rectangle
remain
(This is pretty much the subset needed to implement Swing)
KEY_PRESSED
,
KEY_RELEASED
events
VK_CHANNEL_UP
VK_VOLUME_DOWN
VK_POWER
import org.havi.constants.*;
import org.havi.types.*;
import org.havi.system.*;
import org.havi.fcm.constants.*;
import org.havi.fcm.types.*;
import org.havi.fcm.avdisc.*;
import org.havi.fcm.vcr.*;
public class NaivePVR {
static final int TIMEOUT = 10000; // in milliseconds
SoftwareElement se = new SoftwareElement();
RegistryLocalClient registryClient; = = new RegistryLocalClient(se);
SEID vcrSeid;
SEID avDiscSeid;
StreamManagerLocalClient streamManagerClient;
FcmClient vcrFcmClient;
FcmClient avDiscFcmClient;
VcrClient vcrClient;
AvDiscClient avDiscClient;
Connection recordingConnection;
FcmPlug avDiscFcmInputPlug;
FcmPlug avDiscFcmOutputPlug;
public NaivePVR() {
vcrSeid = findSeid(ConstSoftwareElementType.VCR_FCM);
acDisvSewid = findSeid(ConstSoftwareElementType.AVDISC_FCM);
// create necessary clients
try {
streamManagerClient = new StreamManagerLocalClient(se);
vcrFcmClient = new FcmClient (se, vcrSeid);
avDiscFcmClient = new FcmClient (se, avDiscSeid);
vcrClient = new VcrClient (se, vcrSeid);
avDiscClient = new AvDiscClient (se, avDiscSeid);
}
catch (Exception e) {
e.printStackTrace();
}
}
public SEID findSeid(int seType) {
try {
SEID[] seids = findAllSEs(seType);
if (seids.length >= 1)
return seids[0];
else
return 0;
} catch(Exception e) {
// ??
}
return 0;
}
/***********************************************************************
* Locates all SEs of a specified type on the home network.
*/
public SEID[] findAllSEs(int seType) throws HaviException,
HaviInvalidValueException {
SimpleQuery sq;
HaviByteArrayOutputStream hbaos = new HaviByteArrayOutputStream();
sq = new SimpleQuery();
sq.setAttributeName(ConstAttributeName.ATT_SE_TYPE);
hbaos.reset();
hbaos.writeInt(seType);
sq.setCompareValue(hbaos);
sq.setCompareOperation(ConstComparisonOperator.EQU);
// This will hold the return value from the registry after
// getElementSync is called
SEIDSeqHolder seidSequence = new SEIDSeqHolder();
registryClient.getElementSync(TIMEOUT, sq, seidSequence);
SEID[] seidList = seidSequence.getValue();
return seidList;
} // findAllSEs
/**************************************************************************/
/* This should be the first method to be called after creating the PVR
* object. At this point all the necessary stream connections will be
* created and after successful connections are established the 'live
* program will be under 'PVR' mode.
*
* A 'live stream' connection will first be established between the VCR
* and the AvDisc. The AvDisc will be recording the content from the VCR.
*/
public void start() throws Exception {
// set up a connection to record to the intermediate storage device from the input source
recordingConnection = makeConnection (vcrFcmClient,
avDiscFcmClient);
if (recordingConnection == null) {
throw new Exception("Unable to establish connection between Vcr and AvDisc ! :-(");
}
// get the FcmPlug information from the connection
avDiscFcmInputPlug = recordingConnection.getSink();
vcrFcmOutputPlug = recordingConnection.getSource();
// start recording on avdisc
avDiscClient.recordSync(TIMEOUT,
ConstAvDiscRecordingMode.NORMAL,
avDiscFcmInputPlug.getPlugNum(),
(short)0, // listNumber
(short)0, // indexNumber
null, // recordingTime
(long)0); // recordingSize
// start playing the input source (vcr)
vcrClient.playSync(TIMEOUT);
}
/***********************************************************************/
public Connection makeConnection(FcmClient srcFcm,
FcmClient destFcm) {
Connection connection = null;
try {
ConnectionHint connectionHint;
ConnectionIdHolder connectionHolder;
FcmPlug srcFcmOutputPlug = getFcmPlug(srcFcm,
ConstDirection.OUT);
FcmPlug destFcmInputPlug = getFcmPlug(destFcm,
ConstDirection.IN);
connectionHint = new ConnectionHint (false, // anyTransport,
true, // anyStreamType,
true, // anyTransmissionFormat,
true, // anyChannel,
ConstTransportType.IEC61883, // specific transport type ,
null, // specific StreamType stype,
null, // TransmissionFormat tformat,
null); // Channel channel
ConnectionIdHolder ch = new ConnectionIdHolder();
streamManagerClient.flowToSync(TIMEOUT, false, srcFcmOutputPlug,
destFcmInputPlug, connectionHint, ch);
ConnectionId connectionId = ch.getValue();
connection = new Connection();
streamManagerClient.getConnectionSync(TIMEOUT,connectionId, connection);
}
catch (Exception e) {
e.printStackTrace();
}
return(connection);
}
/***********************************************************************/
public FcmPlug getFcmPlug(FcmClient fcmClient, int direction)
{
FcmPlug fcmPlug = null;
try {
// first get the Huid of the fcm
HUIDHolder fcmHuidHolder = new HUIDHolder();
fcmClient.getHuidSync (TIMEOUT, fcmHuidHolder);
HUID fcmHuid = fcmHuidHolder.getValue();
// get the TargetId from the HUID
TargetId targetId = fcmHuid.getTargetId();
// take the first plug, we should be able to
// use this since we have the FCM reserved
fcmPlug = new FcmPlug (targetId, direction, (short)0);
}
catch (Exception e) {
e.printStackTrace();
}
return(fcmPlug);
}
}