Package org.apache.felix.upnp.basedriver.importer.core

Source Code of org.apache.felix.upnp.basedriver.importer.core.MyCtrlPoint

/*
* 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.basedriver.util.Converter;

/*
* @author <a href="mailto:dev@felix.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.basedriver.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;
  }

  synchronized 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");

            synchronized (devices) {   

        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);
          }
        }
       
      }//synchronized(devices)
    } else {
      /*
       * if it is a service means that it has deleted when the
       * owner was unregister so I can skip this bye-bye
       *
       * //TODO Understand the comment
       *
       */
    }
  }
   
  public synchronized void removeOSGiandUPnPDeviceHierarchy(final UPnPDeviceImpl dev)
    {
    /*
     * remove all the UPnPDevice from the struct of local device recursively
     */
    final String udn = (String) dev.getDescriptions(null).get(UPnPDevice.UDN);
   
    if(devices.containsKey(udn) == false){
      Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") already removed");
      return;
    }   
   
    String[] childrenUDN = (String[]) dev.getDescriptions(null).get(
        UPnPDevice.CHILDREN_UDN);

    if (childrenUDN == null) {
      //no children     
      unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(udn)).getRegistration());
      Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") deleted");
      devices.remove(udn);
      return;
    } else {
      for (int i = 0; i < childrenUDN.length; i++) {
        if (devices.get(childrenUDN[i]) != null) {
          removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices.get(childrenUDN[i])).getOSGiDevice());
        }
      }
      unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(udn)).getRegistration());
      Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") deleted");
      devices.remove(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();
            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);                     
                    }
                  }
                }
              }
            }
                        context.ungetService(devicesRefs[i]);
          }
        }
      } 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();
            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);
                }
              }
            }
                        context.ungetService(devicesRefs[i]);
          }
        }
      }

    } 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();

            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
            context.ungetService(devicesRefs[i]);
          }//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();
            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
                        context.ungetService(devicesRefs[i]);
          }//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
            //TODO Check if null to the first paramaters is correct or it requires the reference to the cyberdomo upnp device
            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 synchronized void doDeviceRegistration(String udn){
        /*
         * registering the new device either if it is new root device or
         * a new embedded device
         */
        Device dev = findDeviceCtrl(this, udn);
        if (dev == null) {
          /*
           * In this case the UPnP SDK notifies us that a ssdp:alive has arrived,
           * but,  because the no root device ssdp:alive packet has recieved by the UPnP SDK
           * no Device is present in the UPnP SDK device list.
           */
            Activator.logger.INFO("Cyberlink notified packet from UDN:" +udn+ ", but Device instance doesn't exist in Cyberlink structs! It will be Ignored");           
        }else if(devices.containsKey(udn) == false) {
            Activator.logger.INFO("[Importer] registering UPnPDevice:"+dev.getFriendlyName()+"("+dev.getUDN()+")" );
            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);
      }
        }else if(devices.containsKey(udn) == true) {
          Activator.logger.INFO("[Importer] UPnPDevice UDN::"+dev.getFriendlyName()+"("+dev.getUDN()+") already registered Skipping");
        }
    }
   
  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));
            }

          }
        }

      }

    }
  }
}
TOP

Related Classes of org.apache.felix.upnp.basedriver.importer.core.MyCtrlPoint

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.