use of ch.ethz.iks.slp.ServiceLocationException in project ecf by eclipse.
the class SLPDaemonImpl method newDaDiscovered.
/**
* get informed about a new discovered DA. Registers all services in the
* scopes of the new DA.
*
* @param advert
* the DA advertisement.
*/
public void newDaDiscovered(final DAAdvertisement advert) {
// so find all services within the scopes of the new DA:
for (Iterator iter = advert.scopeList.iterator(); iter.hasNext(); ) {
String scope = (String) iter.next();
List services = (List) registeredServices.get(scope.toLowerCase());
if (services != null) {
for (Iterator serviceIter = services.iterator(); serviceIter.hasNext(); ) {
// and try to register it with the new DA
try {
Service service = (Service) serviceIter.next();
ServiceRegistration reg = new ServiceRegistration(service.url, service.url.getServiceType(), Arrays.asList(new Object[] { scope }), SLPUtils.dictToAttrList(service.attributes), SLPCore.DEFAULT_LOCALE);
SLPCore.platform.logDebug("Registering " + service.url + " with new DA " + advert.url);
announceService(advert.url, reg);
} catch (ServiceLocationException e) {
SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
}
}
}
}
}
use of ch.ethz.iks.slp.ServiceLocationException in project ecf by eclipse.
the class SLPDaemonImpl method deregisterService.
/**
* deregister a service from the SLP framework. Deregisters from all DAs
* within the scopes and from the local service cache.
*
* @param dereg
* the service deregistration.
* @throws ServiceLocationException
*/
private void deregisterService(final ServiceDeregistration dereg) throws ServiceLocationException {
final String[] scopes = (String[]) registeredServices.keySet().toArray(new String[registeredServices.size()]);
for (int i = 0; i < scopes.length; i++) {
final List tmp = (List) registeredServices.get(scopes[i]);
final Service[] services = (Service[]) tmp.toArray(new Service[tmp.size()]);
for (int j = 0; j < services.length; j++) {
if (dereg.url.matches(services[j].url)) {
List daList = (List) SLPCore.dAs.get(scopes[i].toLowerCase());
if (daList != null) {
for (Iterator daIter = daList.iterator(); daIter.hasNext(); ) {
try {
String dA = (String) daIter.next();
dereg.address = InetAddress.getByName(dA);
dereg.port = SLPCore.SLP_RESERVED_PORT;
dereg.xid = SLPCore.nextXid();
if (SLPCore.CONFIG.getSecurityEnabled()) {
List spiList = (List) SLPCore.dASPIs.get(dA);
dereg.sign(spiList);
}
ReplyMessage reply = SLPCore.sendMessage(dereg, true);
if (reply.errorCode != 0) {
throw new ServiceLocationException((short) reply.errorCode, "Error during deregistration: " + reply.errorCode);
}
} catch (UnknownHostException uhe) {
throw new ServiceLocationException(ServiceLocationException.NETWORK_ERROR, uhe.getMessage());
}
}
}
synchronized (registeredServices) {
SLPUtils.removeValue(registeredServices, scopes[i], services[j]);
}
break;
}
}
}
}
use of ch.ethz.iks.slp.ServiceLocationException in project ecf by eclipse.
the class SLPDaemonImpl method handleMessage.
/**
* all incoming messages are handled here.
*
* @param msg
* the message to be processed.
* @return the reply if the handled message came in via TCP. Otherwise null
* will be returned.
* @throws ServiceLocationException
* for various reasons like authentication failures etc.
*/
public ReplyMessage handleMessage(final SLPMessage msg) throws ServiceLocationException {
if (msg == null) {
return null;
}
String via = msg.tcp ? " (tcp)" : " (udp)";
SLPCore.platform.logTraceMessage("RECEIVED (" + msg.address + ":" + msg.port + ") " + msg.toString() + via);
ReplyMessage reply = null;
switch(msg.funcID) {
case SLPMessage.SRVRQST:
ServiceRequest req = (ServiceRequest) msg;
List results = new ArrayList();
for (Iterator scopes = req.scopeList.iterator(); scopes.hasNext(); ) {
String scope = (String) scopes.next();
List services = (List) registeredServices.get(scope.toLowerCase());
if (services == null) {
continue;
}
for (Iterator srvs = services.iterator(); srvs.hasNext(); ) {
Service service = (Service) srvs.next();
if (service.url.getServiceType().matches(req.serviceType)) {
if (req.predicate == null) {
results.add(service.url);
continue;
}
if (req.predicate.match(service.attributes)) {
results.add(service.url);
}
}
}
}
/*
* if there is no result, don't send a reply. This causes the SA to
* get the same message at least two more times but the RFC strictly
* demands this for multicast requests
*/
if (results.size() == 0 && req.multicast) {
return null;
}
reply = new ServiceReply(req, results);
if (SLPCore.CONFIG.getSecurityEnabled()) {
((ServiceReply) reply).sign(req.spi);
}
return reply;
case SLPMessage.ATTRRQST:
AttributeRequest attreq = (AttributeRequest) msg;
List attResult = new ArrayList();
for (Iterator scopes = attreq.scopeList.iterator(); scopes.hasNext(); ) {
String scope = (String) scopes.next();
List services = (List) registeredServices.get(scope.toLowerCase());
if (services == null) {
continue;
}
// the request can either be for a ServiceURL or a ServiceType
Object reqService;
boolean fullurl = false;
if (attreq.url.indexOf("//") == -1) {
reqService = new ServiceType(attreq.url);
} else {
fullurl = true;
reqService = new ServiceURL(attreq.url, 0);
}
// the tag list has to be empty
if (attreq.spi.equals("") || (fullurl && attreq.tagList.isEmpty())) {
for (Iterator srvs = services.iterator(); srvs.hasNext(); ) {
Service service = (Service) srvs.next();
if (service.url.matches(reqService)) {
attResult.addAll(SLPUtils.findMatches(attreq.tagList, service.attributes));
}
}
}
}
reply = new AttributeReply(attreq, attResult);
if (SLPCore.CONFIG.getSecurityEnabled()) {
((AttributeReply) reply).sign(attreq.spi);
}
return reply;
case SLPMessage.SRVTYPERQST:
ServiceTypeRequest streq = (ServiceTypeRequest) msg;
ArrayList result = new ArrayList();
// iterate over scopes
for (Iterator scopeIter = streq.scopeList.iterator(); scopeIter.hasNext(); ) {
// iterate over the registered services
String scope = (String) scopeIter.next();
List services = ((List) registeredServices.get(scope.toLowerCase()));
if (services == null) {
continue;
}
for (Iterator iter = services.iterator(); iter.hasNext(); ) {
Service service = (Service) iter.next();
ServiceType type = service.url.getServiceType();
if (streq.namingAuthority.equals("*") || streq.namingAuthority.equals("") || type.getNamingAuthority().equals(streq.namingAuthority)) {
if (!result.contains(type)) {
result.add(type);
}
}
}
}
reply = new ServiceTypeReply(streq, result);
return reply;
case SLPMessage.SRVREG:
registerService((ServiceRegistration) msg);
reply = new ServiceAcknowledgement(msg, 0);
return reply;
case SLPMessage.SRVDEREG:
deregisterService((ServiceDeregistration) msg);
reply = new ServiceAcknowledgement(msg, 0);
return reply;
case SLPMessage.SRVACK:
final ReplyMessage rep = (ReplyMessage) msg;
if (rep.errorCode != 0) {
SLPCore.platform.logWarning(msg.address + " replied with error code " + rep.errorCode + " (" + rep + ")");
}
return null;
default:
// exception during parsing
throw new ServiceLocationException(ServiceLocationException.NOT_IMPLEMENTED, "The message type " + SLPMessage.getType(msg.funcID) + " is not implemented");
}
}
use of ch.ethz.iks.slp.ServiceLocationException in project ecf by eclipse.
the class SLPMessage method parse.
/**
* The RFC 2608 SLP message header:
*
* <pre>
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Version | Function-ID | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Length, contd.|O|F|R| reserved |Next Ext Offset|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Next Extension Offset, contd.| XID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Language Tag Length | Language Tag \
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* </pre>
*
* This method parses the header and then delegates the creation of the
* corresponding SLPMessage to the subclass that matches the funcID.
*
* @param senderAddr
* the address of the message sender.
* @param senderPort
* the port of the message sender.
* @param data
* the raw bytes of the message
* @param len
* the length of the byte array.
* @param tcp
* true if the message was received via TCP, false otherwise.
* @return a SLPMessage of the matching subtype.
* @throws ServiceLocationException
* in case of any parsing errors.
*/
static SLPMessage parse(final InetAddress senderAddr, final int senderPort, final DataInputStream in, final boolean tcp) throws ServiceLocationException, ProtocolException {
try {
// version
final int version = in.readByte();
if (version != VERSION) {
// funcID
in.readByte();
final int length = in.readShort();
byte[] drop = new byte[length - 4];
in.readFully(drop);
SLPCore.platform.logWarning("Dropped SLPv" + version + " message from " + senderAddr + ":" + senderPort);
}
// funcID
final byte funcID = in.readByte();
final int length = readInt(in, 3);
// slpFlags
final byte flags = (byte) (in.readShort() >> 8);
if (!tcp && (flags & 0x80) != 0) {
throw new ProtocolException();
}
// we don't process extensions, we simply ignore them
// extOffset
readInt(in, 3);
// XID
final short xid = in.readShort();
// Locale
final Locale locale = new Locale(in.readUTF(), "");
final SLPMessage msg;
// decide on the type of the message
switch(funcID) {
case DAADVERT:
msg = new DAAdvertisement(in);
break;
case SRVRQST:
msg = new ServiceRequest(in);
break;
case SRVRPLY:
msg = new ServiceReply(in);
break;
case ATTRRQST:
msg = new AttributeRequest(in);
break;
case ATTRRPLY:
msg = new AttributeReply(in);
break;
case SRVREG:
msg = new ServiceRegistration(in);
break;
case SRVDEREG:
msg = new ServiceDeregistration(in);
break;
case SRVACK:
msg = new ServiceAcknowledgement(in);
break;
case SRVTYPERQST:
msg = new ServiceTypeRequest(in);
break;
case SRVTYPERPLY:
msg = new ServiceTypeReply(in);
break;
default:
throw new ServiceLocationException(ServiceLocationException.PARSE_ERROR, "Message type " + getType(funcID) + " not supported");
}
// set the fields
msg.address = senderAddr;
msg.port = senderPort;
msg.tcp = tcp;
msg.multicast = ((flags & 0x2000) >> 13) == 1 ? true : false;
msg.xid = xid;
msg.funcID = funcID;
msg.locale = locale;
if (msg.getSize() != length) {
SLPCore.platform.logError("Length of " + msg + " should be " + length + ", read " + msg.getSize());
// throw new ServiceLocationException(
// ServiceLocationException.INTERNAL_SYSTEM_ERROR,
// "Length of " + msg + " should be " + length + ", read "
// + msg.getSize());
}
return msg;
} catch (ProtocolException pe) {
throw pe;
} catch (IOException ioe) {
SLPCore.platform.logError("Network Error", ioe);
throw new ServiceLocationException(ServiceLocationException.NETWORK_ERROR, ioe.getMessage());
}
}
use of ch.ethz.iks.slp.ServiceLocationException in project ecf by eclipse.
the class SLPMessage method readInt.
/**
* parse a numerical value that can be spanned over multiple bytes.
*
* @param input
* the data input stream.
* @param len
* the number of bytes to read.
* @return the int value.
* @throws ServiceLocationException
* in case of IO errors.
*/
private static int readInt(final DataInputStream input, final int len) throws ServiceLocationException {
try {
int value = 0;
for (int i = 0; i < len; i++) {
value <<= 8;
value += input.readByte() & 0xff;
}
return value;
} catch (IOException ioe) {
throw new ServiceLocationException(ServiceLocationException.PARSE_ERROR, ioe.getMessage());
}
}
Aggregations