blob: 1e93656ebe9f8a232a07b7d40326cf167f4940d8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.upnp.basedriver.importer.core;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import org.cybergarage.http.HTTPRequest;
import org.cybergarage.upnp.ControlPoint;
import org.cybergarage.upnp.Device;
import org.cybergarage.upnp.DeviceList;
import org.cybergarage.upnp.Service;
import org.cybergarage.upnp.ServiceList;
import org.cybergarage.upnp.ServiceStateTable;
import org.cybergarage.upnp.StateVariable;
import org.cybergarage.upnp.device.NotifyListener;
import org.cybergarage.upnp.device.SearchResponseListener;
import org.cybergarage.upnp.event.NotifyRequest;
import org.cybergarage.upnp.event.Property;
import org.cybergarage.upnp.event.PropertyList;
import org.cybergarage.upnp.ssdp.SSDPPacket;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.upnp.UPnPDevice;
import org.osgi.service.upnp.UPnPEventListener;
import org.osgi.service.upnp.UPnPService;
import org.osgi.service.upnp.UPnPStateVariable;
import org.apache.felix.upnp.basedriver.Activator;
import org.apache.felix.upnp.basedriver.importer.core.event.message.FirstMessage;
import org.apache.felix.upnp.basedriver.importer.core.event.message.ListenerModified;
import org.apache.felix.upnp.basedriver.importer.core.event.message.ListenerUnRegistration;
import org.apache.felix.upnp.basedriver.importer.core.event.message.StateChanged;
import org.apache.felix.upnp.basedriver.importer.core.event.structs.NotifierQueue;
import org.apache.felix.upnp.basedriver.importer.core.event.structs.SubscriptionQueue;
import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPDeviceImpl;
import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPServiceImpl;
import org.apache.felix.upnp.basedriver.importer.util.ParseUSN;
import org.apache.felix.upnp.extra.util.Converter;
/*
* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
*/
public class MyCtrlPoint extends ControlPoint
implements
NotifyListener,
SearchResponseListener,
ServiceListener
{
private BundleContext context;
private Hashtable devices;//key UDN value OsgideviceInfo(Osgi)
private SubscriptionQueue subQueue;
private NotifierQueue notifierQueue;
private final String UPNP_EVENT_LISTENER_FLTR =
"(" + Constants.OBJECTCLASS + "=" + UPnPEventListener.class.getName() + ")";
private final String UPNP_DEVICE_FLTR =
"(" + Constants.OBJECTCLASS + "=" + UPnPDevice.class.getName() + ")";
private final String EXPORT_FLTR =
"(" + UPnPDevice.UPNP_EXPORT + "=*" + ")";
private final String IMPORT_FLTR =
"(" + org.apache.felix.upnp.extra.util.Constants.UPNP_IMPORT + "=*" + ")";
public MyCtrlPoint(BundleContext context, SubscriptionQueue subQueue,
NotifierQueue notifierQueue) {
super();
this.context = context;
devices = new Hashtable();
addNotifyListener(this);
addSearchResponseListener(this);
try {
context.addServiceListener(this, UPNP_EVENT_LISTENER_FLTR);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
this.subQueue = subQueue;
this.notifierQueue = notifierQueue;
}
public void httpRequestRecieved(HTTPRequest httpReq) {
Activator.logger.DEBUG("[Importer] httpRequestRecieved event");
Activator.logger.PACKET(httpReq.toString());
if (httpReq.isNotifyRequest() == true) {
Activator.logger.DEBUG("[Importer] Notify Request");
NotifyRequest notifyReq = new NotifyRequest(httpReq);
String uuid = notifyReq.getSID();
long seq = notifyReq.getSEQ();
PropertyList props = notifyReq.getPropertyList();
// int propCnt = props.size();
// Hashtable hash = new Hashtable();
// for (int n = 0; n < propCnt; n++) {
// Property prop = props.getProperty(n);
// String varName = prop.getName();
// String varValue = prop.getValue();
// hash.put(varName, varValue);
// }
newEventArrived(uuid, seq, props);
httpReq.returnOK();
return;
}
Activator.logger.DEBUG("BAD Request");
httpReq.returnBadRequest();
}
/*
* (non-Javadoc)
*
* @see org.cybergarage.upnp.ControlPoint#removeExpiredDevices()
*
*/
public void removeExpiredDevices() {
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
if (dev.isExpired() == true) {
Activator.logger.DEBUG("[Importer] Expired device:"+ dev.getFriendlyName());
removeDevice(dev);
removeOSGiExpireDevice(dev);
}
}
}
/*
* (non-Javadoc)
*
* @see org.cybergarage.upnp.device.NotifyListener#deviceNotifyReceived(org.cybergarage.upnp.ssdp.SSDPPacket)
*/
public void deviceNotifyReceived(SSDPPacket ssdpPacket) {
Activator.logger.DEBUG("[Importer] deviceNotifyReceived");
Activator.logger.PACKET(ssdpPacket.toString());
/*
* if the packet is
* NOTIFY or ISALIVE or *new* ROOT then create and register the UPnPDevice and
* all the embeeded device too
* DEVICE or SERVICE then if they already exist in OSGi do nothing otherwise I'll create and
* register all the UPnPDevice need starting from the root device
* *root* BYEBYE then I'll unregister it and all its children from OSGi Framework
* *service* BYEBYE then I'll re-register the UPnPDevice that contain the service with the updated
* properties
* *device* BYEBYE then I'll re-register the UPnPDevice that contain the device with the updated
* properties and also unregister the UPnPDevice that has left
*/
String usn = ssdpPacket.getUSN();
ParseUSN parseUSN = new ParseUSN(usn);
String udn = parseUSN.getUDN();
ServiceReference[] refs = null;
String filter = "(&" + UPNP_DEVICE_FLTR + EXPORT_FLTR+ ")";
try {
refs = context.getServiceReferences(UPnPDevice.class.getName(), filter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (refs != null) {
for (int i = 0; i < refs.length; i++) {
UPnPDevice dev = (UPnPDevice) context.getService(refs[i]);
Dictionary dic = dev.getDescriptions(null);
if (((String) dic.get(UPnPDevice.UDN)).equals(udn)) {
return;
}
}
}
if (ssdpPacket.isAlive()) {
Activator.logger.DEBUG("[Importer] ssdpPacket.isAlive");
if (devices.containsKey(udn)) {
Activator.logger.DEBUG("[Importer] Device already discovered");
if (parseUSN.isService()) {
doServiceUpdating(udn,parseUSN.getServiceType());
}
} else {
doDeviceRegistration(udn);
}
} else if (ssdpPacket.isByeBye()) {
Activator.logger.DEBUG("[Importer] ssdpPacket.isByeBye");
if (devices.containsKey(udn)) {
if (parseUSN.isDevice()) {
Activator.logger.DEBUG("[Importer] parseUSN.isDevice ...unregistering all the children devices ");
//unregistering all the children devices
UPnPDeviceImpl dev = ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
removeOSGiandUPnPDeviceHierarchy(dev);
} else if (parseUSN.isService()) {
Activator.logger.DEBUG("[Importer] parseUSN.isService ...registering modified device again ");
/*
* I have to unregister the UPnPDevice and register it again
* with the updated properties
*/
UPnPDeviceImpl device =
((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
ServiceRegistration registar =
((OSGiDeviceInfo) devices.get(udn)).getRegistration();
String[] oldServicesID =
(String[]) (device.getDescriptions(null).get(UPnPService.ID));
String[] oldServiceType =
(String[]) (device.getDescriptions(null).get(UPnPService.TYPE));
Device cyberDevice = findDeviceCtrl(this, udn);
Vector vec = new Vector();
for (int i = 0; i < oldServiceType.length; i++) {
Service ser = cyberDevice.getService(oldServicesID[i]);
if (!(ser.getServiceType().equals(parseUSN.getServiceType())))
{
vec.add(oldServicesID[i]);
}
}
//new serviceID
String[] actualServicesID = new String[vec.size()];
actualServicesID = (String[]) vec.toArray(new String[]{});
//new serviceType
String[] actualServiceType = new String[oldServiceType.length - 1];
vec.clear();
for (int i = 0; i < oldServiceType.length; i++) {
if (!(oldServiceType[i].equals(parseUSN.getServiceType())))
{
vec.add(oldServiceType[i]);
}
}
actualServiceType = (String[]) vec.toArray(new String[]{});
//unrigistering and registering again with the new properties
unregisterUPnPDevice(registar);
device.setProperty(UPnPService.ID, actualServicesID);
device.setProperty(UPnPService.TYPE, actualServiceType);
registerUPnPDevice(null, device, device.getDescriptions(null));
searchForListener(cyberDevice);
}
}
} else {
/*
* if it is a service means that it is beend delete when the
* owner was unregister so I can skip this bye-bye
*/
}
}
public synchronized void removeOSGiandUPnPDeviceHierarchy(UPnPDeviceImpl dev)
{
/*
* remove all the UPnPDevice from the struct of local device recursively
*/
String[] childrenUDN = (String[]) dev.getDescriptions(null).get(
UPnPDevice.CHILDREN_UDN);
if (childrenUDN == null) {
//no children
unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev
.getDescriptions(null).get(UPnPDevice.UDN)))
.getRegistration());
devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
return;
}
for (int i = 0; i < childrenUDN.length; i++) {
if (devices.get(childrenUDN[i]) == null) {
continue;
} else {
removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices
.get(childrenUDN[i])).getOSGiDevice());
}
}
unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev.getDescriptions(
null).get(UPnPDevice.UDN))).getRegistration());
devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
}
public synchronized void removeOSGiExpireDevice(Device dev) {
/*
* unregistering root device with all its children device from OSGi
* deleting root device and all its children from struct that conatin
* a list of local device
*/
removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices.get(dev
.getUDN())).getOSGiDevice());
}
public void registerUPnPDevice(Device dev, UPnPDeviceImpl upnpDev,
Dictionary prop) {
/*
* registering the new Device as OSGi UPnPDevice and then add
* ServiceRegistration and UPnPDevice reference to the hashtable
* that contains local devices
*/
if (prop == null && upnpDev == null) {
UPnPDeviceImpl newDevice = new UPnPDeviceImpl(dev, context);
ServiceRegistration registration =
context.registerService(UPnPDevice.class.getName(),
newDevice,
newDevice.getDescriptions(null));
OSGiDeviceInfo deviceInfo =
new OSGiDeviceInfo(newDevice,registration);
String udn = (String) ((newDevice.getDescriptions(null)).get(UPnPDevice.UDN));
devices.put(udn, deviceInfo);
} else {
ServiceRegistration registration =
context.registerService(UPnPDevice.class.getName(), upnpDev, prop);
OSGiDeviceInfo deviceInfo =
new OSGiDeviceInfo(upnpDev, registration);
devices.put(upnpDev.getDescriptions(null).get(UPnPDevice.UDN),deviceInfo);
}
}
public void unregisterUPnPDevice(ServiceRegistration registration) {
registration.unregister();
}
public Device findDeviceCtrl(ControlPoint ctrl, String udn) {
/*
* this return the device looking in all the struct
*/
DeviceList devList = getDeviceList();
Device dev = null;
int i = 0;
while (i < devList.size() && (dev == null)) {
if (devList.getDevice(i).getUDN().equals(udn)) {
dev = devList.getDevice(i);
return dev;
}
dev = findDevice(udn, devList.getDevice(i));
i++;
}
return dev;
}
public Device findDevice(String udn, Device dev) {
/*
* look for the device if it exist, starting from the root on
* cyberlink struct
*/
DeviceList devList = dev.getDeviceList();
Device aux = null;
for (int i = 0; i < devList.size(); i++) {
if (devList.getDevice(i).getUDN().equals(udn)) {
return devList.getDevice(i);
} else {
if((aux = findDevice(udn, devList.getDevice(i))) != null)
return aux;
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.cybergarage.upnp.device.SearchResponseListener#deviceSearchResponseReceived(org.cybergarage.upnp.ssdp.SSDPPacket)
*/
public void deviceSearchResponseReceived(SSDPPacket ssdpPacket) {
Activator.logger.DEBUG("[Importer] deviceSearchResponseReceived");
Activator.logger.PACKET(ssdpPacket.toString());
String usn = ssdpPacket.getUSN();
ParseUSN parseUSN = new ParseUSN(usn);
String udn = parseUSN.getUDN();
ServiceReference[] refs = null;
String filter = "(&" + UPNP_DEVICE_FLTR + EXPORT_FLTR + ")";
try {
refs = context.getServiceReferences(UPnPDevice.class.getName(),
filter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (refs != null) {
for (int i = 0; i < refs.length; i++) {
UPnPDevice dev = (UPnPDevice) context.getService(refs[i]);
Dictionary dic = dev.getDescriptions(null);
if (((String) dic.get(UPnPDevice.UDN)).equals(udn)) {
return;
}
}
}
if (devices.containsKey(udn)) {
Activator.logger.DEBUG("[Importer] Device already discovered");
/*
* Exist the registered device either in OSGi and
* hashtable of local device
*/
if (parseUSN.isService()) {
doServiceUpdating(udn,parseUSN.getServiceType());
}
} else {
doDeviceRegistration(udn);
}
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
*/
public void serviceChanged(ServiceEvent event) {
Activator.logger.DEBUG("[Importer] serviceChanged");
Activator.logger.DEBUG("Event::"+event.toString());
if (event.getType() == ServiceEvent.REGISTERED) {
/* check new listener registration */
ServiceReference serRef = event.getServiceReference();
Object obj = serRef.getProperty(UPnPEventListener.UPNP_FILTER);
/* obtain interested devices for the listener */
ServiceReference[] devicesRefs = null;
if (obj != null) {
Filter filter = (Filter) obj;
String filtra = filter.toString();
/*
* Avoid to implement the notification for device
* that are not been created by BaseDriver
*/
String newfilter = "(&" + filtra + IMPORT_FLTR + ")";
//String newfilter = "(&" + filtra + "(!" + EXPORT_FLTR + ")" + ")";
//System.out.println(newfilter);
try {
devicesRefs = context.getServiceReferences(UPnPDevice.class
.getName(), newfilter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (devicesRefs != null) {/*
*
* only if there is a compatibile device
*/
Dictionary dic = new Hashtable();
for (int i = 0; i < devicesRefs.length; i++) {
UPnPDevice device = (UPnPDevice) context.getService(devicesRefs[i]);
dic.put(UPnPDevice.ID, device.getDescriptions(null).get(UPnPDevice.UDN));
dic.put(UPnPDevice.TYPE, device.getDescriptions(null).get(UPnPDevice.TYPE));
UPnPService[] services = device.getServices();
//TODO do I have to do the unget of UPnPDevice??
if (services != null) {
for (int j = 0; j < services.length; j++) {
dic.put(UPnPService.ID, services[j].getId());
dic.put(UPnPService.TYPE, services[j].getType());
//TODO add method boolean serviceEvented() so we can remove the below cycle
UPnPStateVariable[] stateVars = services[j].getStateVariables();
boolean hasEventedVars = false;
for (int k = 0; k < stateVars.length && ! hasEventedVars; k++) {
hasEventedVars = stateVars[k].sendsEvents();
if (hasEventedVars) {
if(filter.match(dic)){
UPnPEventListener listener =
(UPnPEventListener) context.getService(serRef);
FirstMessage msg = new FirstMessage(
((UPnPServiceImpl) services[j]).getCyberService(),
listener);
subQueue.enqueue(msg);
}
}
}
}
}
}
}
} else {/* obj==null (interested in all devices) */
try {
String newfilter = "(!" + EXPORT_FLTR+ ")";
devicesRefs = context.getServiceReferences(UPnPDevice.class.getName(), newfilter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (devicesRefs != null) {/*
*
* only if there is a device
*/
for (int i = 0; i < devicesRefs.length; i++) {
UPnPDevice device = (UPnPDevice) context
.getService(devicesRefs[i]);
UPnPService[] services = device.getServices();
//do I have to do the unget of UPnPDevice??
if (services != null) {
for (int j = 0; j < services.length; j++) {
UPnPStateVariable[] stateVars = services[j]
.getStateVariables();
boolean bool = false;
for (int k = 0; k < stateVars.length; k++) {
bool = stateVars[k].sendsEvents();
if (bool) {
break;
}
}
if (bool) {
UPnPEventListener listener =
(UPnPEventListener) context.getService(serRef);
FirstMessage msg = new FirstMessage(
((UPnPServiceImpl) services[j]).getCyberService(),
listener);
subQueue.enqueue(msg);
}
}
}
}
}
}
} else if (event.getType() == ServiceEvent.MODIFIED) {
Vector newServices = new Vector();
ServiceReference serRef = event.getServiceReference();
Filter filter = (Filter) serRef.getProperty(UPnPEventListener.UPNP_FILTER);
UPnPEventListener listener = (UPnPEventListener) context.getService(serRef);
ServiceReference[] devicesRefs = null;
if (filter != null) {
try {
String filtra = filter.toString();
String newfilter = "(&" + filtra + "(!" + EXPORT_FLTR + ")" + ")";
devicesRefs = context.getServiceReferences(UPnPDevice.class.getName(), newfilter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (devicesRefs != null) {/*
*
* only if there is a compatibile device
*/
Dictionary dic = new Hashtable();
/*
* look for the service that match
*/
for (int i = 0; i < devicesRefs.length; i++) {
UPnPDevice device = (UPnPDevice) context
.getService(devicesRefs[i]);
dic.put(UPnPDevice.ID, device.getDescriptions(null)
.get(UPnPDevice.UDN));
dic.put(UPnPDevice.TYPE, device.getDescriptions(null)
.get(UPnPDevice.TYPE));
UPnPService[] services = device.getServices();
//do I have to do the unget of UPnPDevice??
if (services != null) {
for (int j = 0; j < services.length; j++) {
dic.put(UPnPService.ID, services[j].getId());
dic.put(UPnPService.TYPE, services[j].getType());
UPnPStateVariable[] stateVars = services[j]
.getStateVariables();
boolean hasEventedVars = false;
for (int k = 0; k < stateVars.length; k++) {
hasEventedVars = stateVars[k].sendsEvents();
if (hasEventedVars) {
break;
}
}
if (!hasEventedVars) {
continue;
}
boolean bool = filter.match(dic);
if (bool) {
newServices
.add(((UPnPServiceImpl) services[j])
.getCyberService());
}
}//for services
}//services ==null
}//for devicesRefs
ListenerModified msg = new ListenerModified(newServices,
listener);
subQueue.enqueue(msg);
}//devicesrefs !=null
} else {//interrested in all devices
try {
String newfilter = "(!(" + UPnPDevice.UPNP_EXPORT + "=*"
+ ")" + ")";
devicesRefs = context.getServiceReferences(UPnPDevice.class
.getName(), newfilter);
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
if (devicesRefs != null) {/*
* only if there is a device
*/
for (int i = 0; i < devicesRefs.length; i++) {
UPnPDevice device = (UPnPDevice) context
.getService(devicesRefs[i]);
UPnPService[] services = device.getServices();
//do I have to do the unget of UPnPDevice??
if (services != null) {
for (int j = 0; j < services.length; j++) {
UPnPStateVariable[] stateVars = services[j]
.getStateVariables();
boolean hasEventedVars = false;
for (int k = 0; k < stateVars.length; k++) {
hasEventedVars = stateVars[k].sendsEvents();
if (hasEventedVars) {
break;
}
}
if (hasEventedVars) {
newServices
.add(((UPnPServiceImpl) services[j])
.getCyberService());
}//hasEventedvars
}//for services
}//services !=null
}//for devicesRefs
subQueue
.enqueue(new ListenerModified(newServices, listener));
}//devicesRefs !=null
}
} else if (event.getType() == ServiceEvent.UNREGISTERING) {
UPnPEventListener listener = (UPnPEventListener) context
.getService(event.getServiceReference());
if (listener != null) {
ListenerUnRegistration msg = new ListenerUnRegistration(
listener);
subQueue.enqueue(msg);
}
context.ungetService(event.getServiceReference());
}
} /*
* (non-Javadoc)
*
* @see org.cybergarage.upnp.event.EventListener#eventNotifyReceived(java.lang.String,
* long, java.lang.String, java.lang.String)
*/
/*
* public void eventNotifyReceived(String uuid, long seq, String varName,
* String value) { // TODO Auto-generated method stub StateChanged msg = new
* StateChanged(uuid, varName, value,seq);,serviceFromSid(uuid)
* notifierQueue.enqueue(msg); }
*/
public Service serviceFromSid(String sid) {
Enumeration e = devices.elements();
Service cyberService = null;
while (e.hasMoreElements()) {
OSGiDeviceInfo deviceinfo = (OSGiDeviceInfo) e.nextElement();
UPnPDevice device = deviceinfo.getOSGiDevice();
UPnPService[] services = (UPnPService[]) device.getServices();
UPnPServiceImpl[] servicesImpl = new UPnPServiceImpl[services.length];
for (int i = 0; i < servicesImpl.length; i++) {
servicesImpl[i] = (UPnPServiceImpl) services[i];
}
for (int i = 0; i < servicesImpl.length; i++) {
cyberService = servicesImpl[i].getCyberService();
boolean bool = cyberService.isSubscribed();
if (bool) {
if (cyberService.getSID().equals(sid)) {
return cyberService;
}
}
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.apache.felix.upnpbase.importer.MyEventListener#newEventArrived(java.lang.String,
* long, java.util.Dictionary)
*/
public void newEventArrived(String uuid, long seq, PropertyList props) {
Activator.logger.DEBUG("[Importer] newEventArrived");
Service service = serviceFromSid(uuid);
if (service != null) {
int size = props.size();
Hashtable hash = new Hashtable();
for (int i = 0; i < size; i++) {
Property prop = props.getProperty(i);
String varName = prop.getName();
String varValue = prop.getValue();
String upnpType = service.getStateVariable(varName).getDataType();
Object valueObj;
try {
valueObj = Converter.parseString(varValue,upnpType);
} catch (Exception e) {
Activator.logger.ERROR("[Importer] Bad data value in Notify event: "
+"var name="+varName +" value="+varValue +" type="+upnpType + "\n"+e);
return;
}
hash.put(varName, valueObj);
}
Device device = service.getDevice();
StateChanged msg = new StateChanged(uuid, seq, hash, device, service);
notifierQueue.enqueue(msg);
}
}
public void doServiceUpdating(String udn,String serviceType){
Activator.logger.DEBUG("[Importer] check for service updating");
OSGiDeviceInfo deviceinfo = (OSGiDeviceInfo) devices.get(udn);
UPnPDeviceImpl device = deviceinfo.getOSGiDevice();
boolean isSerPresent = device.existServiceType(serviceType);
if (!isSerPresent) {
/*
* The serivice doesn't exist so it's new.
* Find the udn of owner device and re-register the owner
*/
ServiceRegistration registar =
((OSGiDeviceInfo) devices.remove(udn)).getRegistration();
String[] oldServicesID =
(String[]) device.getDescriptions(null).get(UPnPServiceImpl.ID);
String[] oldServicesType =
(String[]) device.getDescriptions(null).get(UPnPServiceImpl.TYPE);
//to handle multiple instance of a serivice of the same type
Device cyberDevice = findDeviceCtrl(this, udn);
ServiceList serviceList = cyberDevice.getServiceList();
ArrayList newServicesID = new ArrayList();
for (int i = 0; i < serviceList.size(); i++) {
if (serviceList.getService(i).getServiceType()
.equals(serviceType))
{
newServicesID.add(serviceList.getService(i).getServiceID());
}
}
//adding the new servicesID
String[] currentServicesID =
new String[(oldServicesID.length + newServicesID.size())];
int endOld = 1;
for (int i = 0; i < oldServicesID.length; i++) {
currentServicesID[i] = oldServicesID[i];
endOld++;
}
int j = 0;
for (; endOld < currentServicesID.length; endOld++) {
currentServicesID[endOld] = (String) newServicesID.get(j);
j++;
}
//adding the new ServiceType
String[] currentServicesType = new String[oldServicesType.length + 1];
for (int i = 0; i < oldServicesType.length; i++) {
currentServicesType[i] = oldServicesType[i];
}
currentServicesType[currentServicesType.length - 1] = serviceType;
// unregistring the OSGi Device
// and setting new properties
unregisterUPnPDevice(registar);
device.setProperty(UPnPService.ID, currentServicesID);
device.setProperty(UPnPServiceImpl.TYPE,currentServicesType);
//registering the service with the updated properties
registerUPnPDevice(null, device, device.getDescriptions(null));
searchForListener(cyberDevice);
}
}
public void doDeviceRegistration(String udn,boolean checkDouble){
if(checkDouble){
try {
ServiceReference[] refs =
Activator.bc.getServiceReferences(
UPnPDevice.class.getName(),
"(" + UPnPDevice.UDN + "=" + udn + ")"
);
if(refs!=null)
return;
} catch (InvalidSyntaxException ignored) {
}
}
doDeviceRegistration(udn);
}
public void doDeviceRegistration(String udn){
/*
* registering the new device even if it is new root device or
* a new embedded device
*/
Device dev = findDeviceCtrl(this, udn);
if (dev == null) {
Activator.logger.WARNING("Cyberlink notified packet from UDN:" +udn+ ", but Device instance doesn't exist in Cyberlink structs !");
}
if (dev != null) {
Activator.logger.INFO("[Importer] registering UPnPDevice UDN:"+dev.getFriendlyName());
registerUPnPDevice(dev, null, null);
searchForListener(dev);
/*
* now we can register all the device embedded device and service without
* recieving the NOTIFY
*/
//XXX Think about this choice
for (Iterator i = dev.getDeviceList().iterator(); i.hasNext();) {
Device d = (Device) i.next();
doDeviceRegistration(d.getUDN(),true);
}
}
}
public void searchForListener(Device device) {
Activator.logger.DEBUG("[Importer] searching for UPnPEventListener");
ServiceReference[] listeners = null;
try {
listeners = context.getServiceReferences(UPnPEventListener.class.getName(), null);
} catch (InvalidSyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (listeners != null) {
String deviceID = device.getUDN();
String serviceID;
String deviceType = device.getDeviceType();
String serviceType;
Hashtable hash = new Hashtable();
hash.put(UPnPDevice.ID, deviceID);
hash.put(UPnPDevice.TYPE, deviceType);
ServiceList services = device.getServiceList();
Vector eventedSers = new Vector();
for (int i = 0; i < services.size(); i++) {
Service service = (Service) services.elementAt(i);
ServiceStateTable vars = service.getServiceStateTable();
for (int j = 0; j < vars.size(); j++) {
StateVariable var = (StateVariable) vars.elementAt(j);
if (var.isSendEvents()) {
eventedSers.add(service);
break;
}
}
}
for (int i = 0; i < listeners.length; i++) {
UPnPEventListener listener = (UPnPEventListener) context
.getService(listeners[i]);
Filter filter = (Filter) listeners[i]
.getProperty(UPnPEventListener.UPNP_FILTER);
if (filter == null) {
for (int j = 0; j < eventedSers.size(); j++) {
Service ser = (Service) eventedSers.elementAt(j);
subQueue.enqueue(new FirstMessage(ser, listener));
}
} else {
for (int j = 0; j < eventedSers.size(); j++) {
Service ser = (Service) eventedSers.elementAt(j);
serviceID = ser.getServiceID();
serviceType = ser.getServiceType();
hash.put(UPnPService.ID, serviceID);
hash.put(UPnPService.TYPE, serviceType);
boolean bool = filter.match(hash);
if (bool) {
subQueue.enqueue(new FirstMessage(ser, listener));
}
}
}
}
}
}
}