blob: ffd9a79d2aa08080fbca69ee43f1688e921c8932 [file] [log] [blame]
Francesco Furfarid8bdb642006-04-04 23:33:40 +00001/*
2 * Copyright 2006 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.felix.upnp.basedriver.importer.core;
19
20
21import java.util.ArrayList;
22import java.util.Dictionary;
23import java.util.Enumeration;
24import java.util.Hashtable;
25import java.util.Iterator;
26import java.util.Vector;
27
28import org.cybergarage.http.HTTPRequest;
29import org.cybergarage.upnp.ControlPoint;
30import org.cybergarage.upnp.Device;
31import org.cybergarage.upnp.DeviceList;
32import org.cybergarage.upnp.Service;
33import org.cybergarage.upnp.ServiceList;
34import org.cybergarage.upnp.ServiceStateTable;
35import org.cybergarage.upnp.StateVariable;
36import org.cybergarage.upnp.device.NotifyListener;
37import org.cybergarage.upnp.device.SearchResponseListener;
38import org.cybergarage.upnp.event.NotifyRequest;
39import org.cybergarage.upnp.event.Property;
40import org.cybergarage.upnp.event.PropertyList;
41import org.cybergarage.upnp.ssdp.SSDPPacket;
42
43import org.osgi.framework.BundleContext;
44import org.osgi.framework.Constants;
45import org.osgi.framework.Filter;
46import org.osgi.framework.InvalidSyntaxException;
47import org.osgi.framework.ServiceEvent;
48import org.osgi.framework.ServiceListener;
49import org.osgi.framework.ServiceReference;
50import org.osgi.framework.ServiceRegistration;
51import org.osgi.service.upnp.UPnPDevice;
52import org.osgi.service.upnp.UPnPEventListener;
53import org.osgi.service.upnp.UPnPService;
54import org.osgi.service.upnp.UPnPStateVariable;
55
56import org.apache.felix.upnp.basedriver.Activator;
57import org.apache.felix.upnp.basedriver.importer.core.event.message.FirstMessage;
58import org.apache.felix.upnp.basedriver.importer.core.event.message.ListenerModified;
59import org.apache.felix.upnp.basedriver.importer.core.event.message.ListenerUnRegistration;
60import org.apache.felix.upnp.basedriver.importer.core.event.message.StateChanged;
61import org.apache.felix.upnp.basedriver.importer.core.event.structs.NotifierQueue;
62import org.apache.felix.upnp.basedriver.importer.core.event.structs.SubscriptionQueue;
63import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPDeviceImpl;
64import org.apache.felix.upnp.basedriver.importer.core.upnp.UPnPServiceImpl;
65import org.apache.felix.upnp.basedriver.importer.util.DictionaryProp;
66import org.apache.felix.upnp.basedriver.importer.util.ParseUSN;
67import org.apache.felix.upnp.extra.util.Converter;
68
69/**
70 * @author Matteo "matted" Demuru
71 * @author Stefano "Kismet" Lenzi
72 * @author Francesco Furfari
73 *
74 *
75 */
76public class MyCtrlPoint extends ControlPoint
77 implements
78 NotifyListener,
79 SearchResponseListener,
80 ServiceListener
81{
82 private BundleContext context;
83 private Hashtable devices;//key UDN value OsgideviceInfo(Osgi)
84 private SubscriptionQueue subQueue;
85 private NotifierQueue notifierQueue;
86
87 private final String UPNP_EVENT_LISTENER_FLTR =
88 "(" + Constants.OBJECTCLASS + "=" + UPnPEventListener.class.getName() + ")";
89 private final String UPNP_DEVICE_FLTR =
90 "(" + Constants.OBJECTCLASS + "=" + UPnPDevice.class.getName() + ")";
91 private final String EXPORT_FLTR =
92 "(" + UPnPDevice.UPNP_EXPORT + "=*" + ")";
93 private final String IMPORT_FLTR =
94 "(" + org.apache.felix.upnp.extra.util.Constants.UPNP_IMPORT + "=*" + ")";
95
96
97 public MyCtrlPoint(BundleContext context, SubscriptionQueue subQueue,
98 NotifierQueue notifierQueue) {
99 super();
100 this.context = context;
101 devices = new Hashtable();
102 addNotifyListener(this);
103 addSearchResponseListener(this);
104 try {
105 context.addServiceListener(this, UPNP_EVENT_LISTENER_FLTR);
106 } catch (InvalidSyntaxException e) {
107 e.printStackTrace();
108 }
109 this.subQueue = subQueue;
110 this.notifierQueue = notifierQueue;
111 }
112
113 public void httpRequestRecieved(HTTPRequest httpReq) {
114 Activator.logger.DEBUG("[Importer] httpRequestRecieved event");
115 Activator.logger.PACKET(httpReq.toString());
116
117 if (httpReq.isNotifyRequest() == true) {
118 Activator.logger.DEBUG("[Importer] Notify Request");
119 NotifyRequest notifyReq = new NotifyRequest(httpReq);
120 String uuid = notifyReq.getSID();
121 long seq = notifyReq.getSEQ();
122 PropertyList props = notifyReq.getPropertyList();
123// int propCnt = props.size();
124// Hashtable hash = new Hashtable();
125// for (int n = 0; n < propCnt; n++) {
126// Property prop = props.getProperty(n);
127// String varName = prop.getName();
128// String varValue = prop.getValue();
129// hash.put(varName, varValue);
130// }
131 newEventArrived(uuid, seq, props);
132 httpReq.returnOK();
133 return;
134 }
135
136 Activator.logger.DEBUG("BAD Request");
137 httpReq.returnBadRequest();
138
139 }
140
141
142 /*
143 * (non-Javadoc)
144 *
145 * @see org.cybergarage.upnp.ControlPoint#removeExpiredDevices()
146 *
147 */
148 public void removeExpiredDevices() {
149 DeviceList devList = getDeviceList();
150 int devCnt = devList.size();
151 for (int n = 0; n < devCnt; n++) {
152 Device dev = devList.getDevice(n);
153 if (dev.isExpired() == true) {
154 Activator.logger.DEBUG("[Importer] Expired device:"+ dev.getFriendlyName());
155 removeDevice(dev);
156 removeOSGiExpireDevice(dev);
157 }
158 }
159 }
160
161 /*
162 * (non-Javadoc)
163 *
164 * @see org.cybergarage.upnp.device.NotifyListener#deviceNotifyReceived(org.cybergarage.upnp.ssdp.SSDPPacket)
165 */
166 public void deviceNotifyReceived(SSDPPacket ssdpPacket) {
167 Activator.logger.DEBUG("[Importer] deviceNotifyReceived");
168 Activator.logger.PACKET(ssdpPacket.toString());
169 /*
170 * case is notify case isalive case new root crea e aggiungi il servizio
171 * in Osgi con tutta la stirpe case device or service controllo se
172 * esiste in OSGi se si nada, se no lo creo partendo dal root case
173 * byebye case root deregistro tutta la stirpe case device o service
174 * reinstanzio il root con le modifiche
175 *
176 */
177 /*
178 * if the packet is
179 * NOTIFY or ISALIVE or *new* ROOT then create and register the UPnPDevice and
180 * all the embeeded device too
181 * DEVICE or SERVICE then if they already exist in OSGi do nothing otherwise I'll create and
182 * register all the UPnPDevice need starting from the root device
183 * *root* BYEBYE then I'll unregister it and all its children from OSGi Framework
184 * *service* BYEBYE then I'll re-register the UPnPDevice that contain the service with the updated
185 * properties
186 * *device* BYEBYE then I'll re-register the UPnPDevice that contain the device with the updated
187 * properties and also unregister the UPnPDevice that has left
188 */
189 String usn = ssdpPacket.getUSN();
190 ParseUSN parseUSN = new ParseUSN(usn);
191 String udn = parseUSN.getUDN();
192
193 ServiceReference[] refs = null;
194 String filter = "(&" + UPNP_DEVICE_FLTR + EXPORT_FLTR+ ")";
195 try {
196 refs = context.getServiceReferences(UPnPDevice.class.getName(), filter);
197 } catch (InvalidSyntaxException e) {
198 e.printStackTrace();
199 }
200 if (refs != null) {
201 for (int i = 0; i < refs.length; i++) {
202 UPnPDevice dev = (UPnPDevice) context.getService(refs[i]);
203 Dictionary dic = dev.getDescriptions(null);
204 if (((String) dic.get(UPnPDevice.UDN)).equals(udn)) {
205 return;
206 }
207 }
208 }
209
210 if (ssdpPacket.isAlive()) {
211
212 Activator.logger.DEBUG("[Importer] ssdpPacket.isAlive");
213 if (devices.containsKey(udn)) {
214 Activator.logger.DEBUG("[Importer] Device already discovered");
215 if (parseUSN.isService()) {
216 doServiceUpdating(udn,parseUSN.getServiceType());
217 }
218 } else {
219 doDeviceRegistration(udn);
220 }
221
222 } else if (ssdpPacket.isByeBye()) {
223 Activator.logger.DEBUG("[Importer] ssdpPacket.isByeBye");
224
225 if (devices.containsKey(udn)) {
226 if (parseUSN.isDevice()) {
227 Activator.logger.DEBUG("[Importer] parseUSN.isDevice ...unregistering all the children devices ");
228
229 //unregistering all the children devices
230 UPnPDeviceImpl dev = ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
231 removeOSGiandUPnPDeviceHierarchy(dev);
232
233 } else if (parseUSN.isService()) {
234 Activator.logger.DEBUG("[Importer] parseUSN.isService ...registering modified device again ");
235 /*
236 * I have to unregister the UPnPDevice and register it again
237 * with the updated properties
238 */
239 UPnPDeviceImpl device =
240 ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
241 ServiceRegistration registar =
242 ((OSGiDeviceInfo) devices.get(udn)).getRegistration();
243 String[] oldServicesID =
244 (String[]) (device.getDescriptions(null).get(UPnPService.ID));
245 String[] oldServiceType =
246 (String[]) (device.getDescriptions(null).get(UPnPService.TYPE));
247
248 Device cyberDevice = findDeviceCtrl(this, udn);
249 Vector vec = new Vector();
250 for (int i = 0; i < oldServiceType.length; i++) {
251 Service ser = cyberDevice.getService(oldServicesID[i]);
252 if (!(ser.getServiceType().equals(parseUSN.getServiceType())))
253 {
254 vec.add(oldServicesID[i]);
255 }
256 }
257
258 //new serviceID
259 String[] actualServicesID = new String[vec.size()];
260 actualServicesID = (String[]) vec.toArray(new String[]{});
261
262 //new serviceType
263 String[] actualServiceType = new String[oldServiceType.length - 1];
264 vec.clear();
265 for (int i = 0; i < oldServiceType.length; i++) {
266 if (!(oldServiceType[i].equals(parseUSN.getServiceType())))
267 {
268 vec.add(oldServiceType[i]);
269 }
270 }
271 actualServiceType = (String[]) vec.toArray(new String[]{});
272
273 //unrigistering and registering again with the new properties
274 unregisterUPnPDevice(registar);
275 device.setProperty(UPnPService.ID, actualServicesID);
276 device.setProperty(UPnPService.TYPE, actualServiceType);
277 registerUPnPDevice(null, device, device.getDescriptions(null));
278 searchForListener(cyberDevice);
279 }
280 }
281 } else {
282 /*
283 * if it is a service means that it is beend delete when the
284 * owner was unregister so I can skip this bye-bye
285 */
286 }
287 }
288
289 public synchronized void removeOSGiandUPnPDeviceHierarchy(UPnPDeviceImpl dev)
290 {
291 /*
292 * remove all the UPnPDevice from the struct of local device recursively
293 */
294 String[] childrenUDN = (String[]) dev.getDescriptions(null).get(
295 UPnPDevice.CHILDREN_UDN);
296 if (childrenUDN == null) {
297 //non ha figli
298 //no children
299 unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev
300 .getDescriptions(null).get(UPnPDevice.UDN)))
301 .getRegistration());
302 devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
303 return;
304 }
305 for (int i = 0; i < childrenUDN.length; i++) {
306 if (devices.get(childrenUDN[i]) == null) {
307 continue;
308 } else {
309 removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices
310 .get(childrenUDN[i])).getOSGiDevice());
311 }
312 }
313 unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev.getDescriptions(
314 null).get(UPnPDevice.UDN))).getRegistration());
315 devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
316 }
317
318 public synchronized void removeOSGiExpireDevice(Device dev) {
319 /*
320 * unregistering root device with all its children device from OSGi
321 * deleting root device and all its children from struct that conatin
322 * a list of local device
323 */
324 removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices.get(dev
325 .getUDN())).getOSGiDevice());
326 }
327
328 public void registerUPnPDevice(Device dev, UPnPDeviceImpl upnpDev,
329 Dictionary prop) {
330 /*
331 * registering the new Device as OSGi UPnPDevice and then add
332 * ServiceRegistration and UPnPDevice reference to the hashtable
333 * that contains local devices
334 */
335 if (prop == null && upnpDev == null) {
336 UPnPDeviceImpl newDevice = new UPnPDeviceImpl(dev, context);
337 ServiceRegistration registration =
338 context.registerService(UPnPDevice.class.getName(),
339 newDevice,
340 newDevice.getDescriptions(null));
341 OSGiDeviceInfo deviceInfo =
342 new OSGiDeviceInfo(newDevice,registration);
343
344 String udn = (String) ((newDevice.getDescriptions(null)).get(UPnPDevice.UDN));
345 devices.put(udn, deviceInfo);
346 } else {
347 ServiceRegistration registration =
348 context.registerService(UPnPDevice.class.getName(), upnpDev, prop);
349 OSGiDeviceInfo deviceInfo =
350 new OSGiDeviceInfo(upnpDev, registration);
351 devices.put(upnpDev.getDescriptions(null).get(UPnPDevice.UDN),deviceInfo);
352 }
353 }
354
355
356 /*
357 * public void registerHierarchyUPnPDevice(Device dev) { registro il root
358 * con tutta la sua stirpe in osgi registerUPnPDevice(dev); DeviceList
359 * devList = dev.getDeviceList(); for (int i = 0; i < devList.size(); i++) {
360 * registerHierarchyUPnPDevice(devList.getDevice(i)); } }
361 */
362 public void unregisterUPnPDevice(ServiceRegistration registration) {
363 registration.unregister();
364
365 }
366
367 public Device findDeviceCtrl(ControlPoint ctrl, String udn) {
368 /*
369 * this return the device looking in all the struct
370 */
371
372 DeviceList devList = getDeviceList();
373 Device dev = null;
374 int i = 0;
375 while (i < devList.size() && (dev == null)) {
376 if (devList.getDevice(i).getUDN().equals(udn)) {
377 dev = devList.getDevice(i);
378 return dev;
379 }
380 dev = findDevice(udn, devList.getDevice(i));
381 i++;
382 }
383 return dev;
384 }
385
386 public Device findDevice(String udn, Device dev) {
387 /*
388 * look for the device if it exist, starting from the root on
389 * cyberlink struct
390 */
391 DeviceList devList = dev.getDeviceList();
392 Device aux = null;
393 for (int i = 0; i < devList.size(); i++) {
394 if (devList.getDevice(i).getUDN().equals(udn)) {
395 return devList.getDevice(i);
396 } else {
397 if((aux = findDevice(udn, devList.getDevice(i))) != null)
398 return aux;
399 }
400 }
401 return null;
402 }
403
404 /*
405 * (non-Javadoc)
406 *
407 * @see org.cybergarage.upnp.device.SearchResponseListener#deviceSearchResponseReceived(org.cybergarage.upnp.ssdp.SSDPPacket)
408 */
409 public void deviceSearchResponseReceived(SSDPPacket ssdpPacket) {
410 Activator.logger.DEBUG("[Importer] deviceSearchResponseReceived");
411 Activator.logger.PACKET(ssdpPacket.toString());
412
413 String usn = ssdpPacket.getUSN();
414 ParseUSN parseUSN = new ParseUSN(usn);
415 String udn = parseUSN.getUDN();
416
417 ServiceReference[] refs = null;
418
419 String filter = "(&" + UPNP_DEVICE_FLTR + EXPORT_FLTR + ")";
420
421 try {
422 refs = context.getServiceReferences(UPnPDevice.class.getName(),
423 filter);
424 } catch (InvalidSyntaxException e) {
425 e.printStackTrace();
426 }
427
428 if (refs != null) {
429 for (int i = 0; i < refs.length; i++) {
430 UPnPDevice dev = (UPnPDevice) context.getService(refs[i]);
431 Dictionary dic = dev.getDescriptions(null);
432 if (((String) dic.get(UPnPDevice.UDN)).equals(udn)) {
433 return;
434 }
435 }
436 }
437
438 if (devices.containsKey(udn)) {
439 Activator.logger.DEBUG("[Importer] Device already discovered");
440 /*
441 * Exist the registered device either in OSGi and
442 * hashtable of local device
443 */
444 if (parseUSN.isService()) {
445 doServiceUpdating(udn,parseUSN.getServiceType());
446 }
447 } else {
448 doDeviceRegistration(udn);
449 }
450
451 }
452 /*
453 * (non-Javadoc)
454 *
455 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
456 */
457 public void serviceChanged(ServiceEvent event) {
458 Activator.logger.DEBUG("[Importer] serviceChanged");
459 Activator.logger.DEBUG("Event::"+event.toString());
460
461 if (event.getType() == ServiceEvent.REGISTERED) {
462 /* check new listener registration */
463 ServiceReference serRef = event.getServiceReference();
464 Object obj = serRef.getProperty(UPnPEventListener.UPNP_FILTER);
465 /* obtain interested devices for the listener */
466 ServiceReference[] devicesRefs = null;
467 if (obj != null) {
468 Filter filter = (Filter) obj;
469 String filtra = filter.toString();
470 /*
471 * Avoid to implement the notification for device
472 * that are not been created by BaseDriver
473 */
474 String newfilter = "(&" + filtra + IMPORT_FLTR + ")";
475 //String newfilter = "(&" + filtra + "(!" + EXPORT_FLTR + ")" + ")";
476 //System.out.println(newfilter);
477 try {
478 devicesRefs = context.getServiceReferences(UPnPDevice.class
479 .getName(), newfilter);
480 } catch (InvalidSyntaxException e) {
481 e.printStackTrace();
482 }
483
484 if (devicesRefs != null) {/*
485 * solo se ci sono dei device
486 * compatibili
487 *
488 * only if there is a compatibile device
489 */
490 Dictionary dic = new DictionaryProp();
491 /* cerco i servizi che matchano */
492 for (int i = 0; i < devicesRefs.length; i++) {
493 UPnPDevice device = (UPnPDevice) context.getService(devicesRefs[i]);
494 dic.put(UPnPDevice.ID, device.getDescriptions(null).get(UPnPDevice.UDN));
495 dic.put(UPnPDevice.TYPE, device.getDescriptions(null).get(UPnPDevice.TYPE));
496 UPnPService[] services = device.getServices();
497 //TODO fare l'unget del servizio UPnPDevice??
498 //TODO do I have to do the unget of UPnPDevice??
499 if (services != null) {
500 for (int j = 0; j < services.length; j++) {
501 dic.put(UPnPService.ID, services[j].getId());
502 dic.put(UPnPService.TYPE, services[j].getType());
503 //TODO add method boolean serviceEvented() so we can remove the below cycle
504 UPnPStateVariable[] stateVars = services[j].getStateVariables();
505 boolean hasEventedVars = false;
506 for (int k = 0; k < stateVars.length && ! hasEventedVars; k++) {
507 hasEventedVars = stateVars[k].sendsEvents();
508 if (hasEventedVars) {
509 if(filter.match(dic)){
510 UPnPEventListener listener =
511 (UPnPEventListener) context.getService(serRef);
512 FirstMessage msg = new FirstMessage(
513 ((UPnPServiceImpl) services[j]).getCyberService(),
514 listener);
515 subQueue.enqueue(msg);
516 }
517 }
518 }
519 }
520 }
521 }
522 }
523 } else {/* obj==null (interested in all devices) */
524 try {
Francesco Furfarif9aba132006-06-02 18:25:02 +0000525 String newfilter = "(!" + EXPORT_FLTR+ ")";
Francesco Furfarid8bdb642006-04-04 23:33:40 +0000526 devicesRefs = context.getServiceReferences(UPnPDevice.class.getName(), newfilter);
527 } catch (InvalidSyntaxException e) {
528 e.printStackTrace();
529 }
530 if (devicesRefs != null) {/*
531 * solo se ci sono dei device
532 *
533 * only if there is a device
534 */
535
536 for (int i = 0; i < devicesRefs.length; i++) {
537 UPnPDevice device = (UPnPDevice) context
538 .getService(devicesRefs[i]);
539 UPnPService[] services = device.getServices();
540 //fare l'unget del servizio UPnPDevice??
541 //do I have to do the unget of UPnPDevice??
542 if (services != null) {
543 for (int j = 0; j < services.length; j++) {
544 UPnPStateVariable[] stateVars = services[j]
545 .getStateVariables();
546 boolean bool = false;
547 for (int k = 0; k < stateVars.length; k++) {
548 bool = stateVars[k].sendsEvents();
549 if (bool) {
550 break;
551 }
552 }
553 if (bool) {
554 UPnPEventListener listener =
555 (UPnPEventListener) context.getService(serRef);
556 FirstMessage msg = new FirstMessage(
557 ((UPnPServiceImpl) services[j]).getCyberService(),
558 listener);
559 subQueue.enqueue(msg);
560 }
561 }
562 }
563 }
564 }
565 }
566
567 } else if (event.getType() == ServiceEvent.MODIFIED) {
568 Vector newServices = new Vector();
569 ServiceReference serRef = event.getServiceReference();
570 Filter filter = (Filter) serRef.getProperty(UPnPEventListener.UPNP_FILTER);
571 UPnPEventListener listener = (UPnPEventListener) context.getService(serRef);
572 ServiceReference[] devicesRefs = null;
573
574 if (filter != null) {
575 try {
576 String filtra = filter.toString();
577 String newfilter = "(&" + filtra + "(!" + EXPORT_FLTR + ")" + ")";
578 devicesRefs = context.getServiceReferences(UPnPDevice.class.getName(), newfilter);
579 } catch (InvalidSyntaxException e) {
580 e.printStackTrace();
581 }
582 if (devicesRefs != null) {/*
583 * solo se ci sono dei device
584 * compatibili
585 *
586 * only if there is a compatibile device
587 */
588 Dictionary dic = new DictionaryProp();
589 /*
590 * cerco i servizi che matchano
591 *
592 * look for the service that match
593 */
594 for (int i = 0; i < devicesRefs.length; i++) {
595 UPnPDevice device = (UPnPDevice) context
596 .getService(devicesRefs[i]);
597 dic.put(UPnPDevice.ID, device.getDescriptions(null)
598 .get(UPnPDevice.UDN));
599 dic.put(UPnPDevice.TYPE, device.getDescriptions(null)
600 .get(UPnPDevice.TYPE));
601 UPnPService[] services = device.getServices();
602
603 //fare l'unget del servizio UPnPDevice??
604 //do I have to do the unget of UPnPDevice??
605 if (services != null) {
606 for (int j = 0; j < services.length; j++) {
607 dic.put(UPnPService.ID, services[j].getId());
608 dic
609 .put(UPnPService.TYPE, services[j]
610 .getType());
611
612 UPnPStateVariable[] stateVars = services[j]
613 .getStateVariables();
614 boolean hasEventedVars = false;
615 for (int k = 0; k < stateVars.length; k++) {
616 hasEventedVars = stateVars[k].sendsEvents();
617 if (hasEventedVars) {
618 break;
619 }
620 }
621 if (!hasEventedVars) {
622 continue;
623 }
624
625 boolean bool = filter.match(dic);
626 if (bool) {
627 newServices
628 .add(((UPnPServiceImpl) services[j])
629 .getCyberService());
630 }
631 }//for services
632 }//services ==null
633 }//for devicesRefs
634 ListenerModified msg = new ListenerModified(newServices,
635 listener);
636 subQueue.enqueue(msg);
637 }//devicesrefs !=null
638 } else {//interrested in all devices
639 try {
640
641 String newfilter = "(!(" + UPnPDevice.UPNP_EXPORT + "=*"
642 + ")" + ")";
643 devicesRefs = context.getServiceReferences(UPnPDevice.class
644 .getName(), newfilter);
645 } catch (InvalidSyntaxException e) {
646 e.printStackTrace();
647 }
648 if (devicesRefs != null) {/*
649 * solo se ci sono dei device
650 *
651 * only if there is a device
652 */
653
654 for (int i = 0; i < devicesRefs.length; i++) {
655 UPnPDevice device = (UPnPDevice) context
656 .getService(devicesRefs[i]);
657 UPnPService[] services = device.getServices();
658 //fare l'unget del servizio UPnPDevice??
659 //do I have to do the unget of UPnPDevice??
660 if (services != null) {
661 for (int j = 0; j < services.length; j++) {
662 UPnPStateVariable[] stateVars = services[j]
663 .getStateVariables();
664 boolean hasEventedVars = false;
665 for (int k = 0; k < stateVars.length; k++) {
666 hasEventedVars = stateVars[k].sendsEvents();
667 if (hasEventedVars) {
668 break;
669 }
670 }
671 if (hasEventedVars) {
672 newServices
673 .add(((UPnPServiceImpl) services[j])
674 .getCyberService());
675 }//hasEventedvars
676 }//for services
677 }//services !=null
678 }//for devicesRefs
679 subQueue
680 .enqueue(new ListenerModified(newServices, listener));
681 }//devicesRefs !=null
682
683 }
684
685 } else if (event.getType() == ServiceEvent.UNREGISTERING) {
686 UPnPEventListener listener = (UPnPEventListener) context
687 .getService(event.getServiceReference());
688 if (listener != null) {
689 ListenerUnRegistration msg = new ListenerUnRegistration(
690 listener);
691 subQueue.enqueue(msg);
692 }
693 context.ungetService(event.getServiceReference());
694 }
695 } /*
696 * (non-Javadoc)
697 *
698 * @see org.cybergarage.upnp.event.EventListener#eventNotifyReceived(java.lang.String,
699 * long, java.lang.String, java.lang.String)
700 */
701 /*
702 * public void eventNotifyReceived(String uuid, long seq, String varName,
703 * String value) { // TODO Auto-generated method stub StateChanged msg = new
704 * StateChanged(uuid, varName, value,seq);,serviceFromSid(uuid)
705 * notifierQueue.enqueue(msg); }
706 */
707
708 public Service serviceFromSid(String sid) {
709 Enumeration e = devices.elements();
710 Service cyberService = null;
711 while (e.hasMoreElements()) {
712 OSGiDeviceInfo deviceinfo = (OSGiDeviceInfo) e.nextElement();
713 UPnPDevice device = deviceinfo.getOSGiDevice();
714 UPnPService[] services = (UPnPService[]) device.getServices();
715 UPnPServiceImpl[] servicesImpl = new UPnPServiceImpl[services.length];
716 for (int i = 0; i < servicesImpl.length; i++) {
717 servicesImpl[i] = (UPnPServiceImpl) services[i];
718 }
719 for (int i = 0; i < servicesImpl.length; i++) {
720 cyberService = servicesImpl[i].getCyberService();
721 boolean bool = cyberService.isSubscribed();
722 if (bool) {
723 if (cyberService.getSID().equals(sid)) {
724 return cyberService;
725 }
726 }
727 }
728 }
729 return null;
730 }
731
732 /*
733 * (non-Javadoc)
734 *
735 * @see org.apache.felix.upnpbase.importer.MyEventListener#newEventArrived(java.lang.String,
736 * long, java.util.Dictionary)
737 */
738 public void newEventArrived(String uuid, long seq, PropertyList props) {
739 Activator.logger.DEBUG("[Importer] newEventArrived");
740 Service service = serviceFromSid(uuid);
741 if (service != null) {
742 int size = props.size();
743 Hashtable hash = new Hashtable();
744 for (int i = 0; i < size; i++) {
745 Property prop = props.getProperty(i);
746 String varName = prop.getName();
747 String varValue = prop.getValue();
748 String upnpType = service.getStateVariable(varName).getDataType();
749 Object valueObj;
750 try {
751 valueObj = Converter.parseString(varValue,upnpType);
752 } catch (Exception e) {
753 Activator.logger.ERROR("[Importer] Bad data value in Notify event: "
754 +"var name="+varName +" value="+varValue +" type="+upnpType + "\n"+e);
755 return;
756 }
757 hash.put(varName, valueObj);
758 }
759
760 Device device = service.getDevice();
761 StateChanged msg = new StateChanged(uuid, seq, hash, device, service);
762 notifierQueue.enqueue(msg);
763 }
764 }
765
766 public void doServiceUpdating(String udn,String serviceType){
767 Activator.logger.DEBUG("[Importer] check for service updating");
768 OSGiDeviceInfo deviceinfo = (OSGiDeviceInfo) devices.get(udn);
769 UPnPDeviceImpl device = deviceinfo.getOSGiDevice();
770 boolean isSerPresent = device.existServiceType(serviceType);
771 if (!isSerPresent) {
772 /*
773 * The serivice doesn't exist so it's new.
774 * Find the udn of owner device and re-register the owner
775 */
776 ServiceRegistration registar =
777 ((OSGiDeviceInfo) devices.remove(udn)).getRegistration();
778 String[] oldServicesID =
779 (String[]) device.getDescriptions(null).get(UPnPServiceImpl.ID);
780 String[] oldServicesType =
781 (String[]) device.getDescriptions(null).get(UPnPServiceImpl.TYPE);
782
783 //per via delle istanze multiple di un tipo di servizio
784 //to handle multiple instance of a serivice of the same type
785 Device cyberDevice = findDeviceCtrl(this, udn);
786 ServiceList serviceList = cyberDevice.getServiceList();
787 ArrayList newServicesID = new ArrayList();
788
789 for (int i = 0; i < serviceList.size(); i++) {
790 if (serviceList.getService(i).getServiceType()
791 .equals(serviceType))
792 {
793 newServicesID.add(serviceList.getService(i).getServiceID());
794 }
795 }
796
797 //adding the new servicesID
798 String[] currentServicesID =
799 new String[(oldServicesID.length + newServicesID.size())];
800 int endOld = 1;
801 for (int i = 0; i < oldServicesID.length; i++) {
802 currentServicesID[i] = oldServicesID[i];
803 endOld++;
804 }
805 int j = 0;
806 for (; endOld < currentServicesID.length; endOld++) {
807 currentServicesID[endOld] = (String) newServicesID.get(j);
808 j++;
809 }
810
811 //adding the new ServiceType
812 String[] currentServicesType = new String[oldServicesType.length + 1];
813 for (int i = 0; i < oldServicesType.length; i++) {
814 currentServicesType[i] = oldServicesType[i];
815 }
816 currentServicesType[currentServicesType.length - 1] = serviceType;
817
818
819 // unregistring the OSGi Device
820 // and setting new properties
821 unregisterUPnPDevice(registar);
822 device.setProperty(UPnPService.ID, currentServicesID);
823 device.setProperty(UPnPServiceImpl.TYPE,currentServicesType);
824
825 //registering the service with the updated properties
826 registerUPnPDevice(null, device, device.getDescriptions(null));
827 searchForListener(cyberDevice);
828 }
829 }
830
831 public void doDeviceRegistration(String udn,boolean checkDouble){
832 if(checkDouble){
833 try {
834 ServiceReference[] refs =
835 Activator.bc.getServiceReferences(
836 UPnPDevice.class.getName(),
837 "(" + UPnPDevice.UDN + "=" + udn + ")"
838 );
839 if(refs!=null)
840 return;
841 } catch (InvalidSyntaxException ignored) {
842 }
843 }
844 doDeviceRegistration(udn);
845 }
846
847 public void doDeviceRegistration(String udn){
848 /*
849 * registering the new device even if it is new root device or
850 * a new embedded device
851 */
852 Device dev = findDeviceCtrl(this, udn);
853 if (dev == null) {
854 Activator.logger.WARNING("Cyberlink notified packet from UDN:" +udn+ ", but Device instance doesn't exist in Cyberlink structs !");
855 }
856 if (dev != null) {
857 Activator.logger.INFO("[Importer] registering UPnPDevice UDN:"+dev.getFriendlyName());
858 registerUPnPDevice(dev, null, null);
859 searchForListener(dev);
860 /*
861 * now we can register all the device embedded device and service without
862 * recieving the NOTIFY
863 */
864 //XXX Think about this choice
865 for (Iterator i = dev.getDeviceList().iterator(); i.hasNext();) {
866 Device d = (Device) i.next();
867 doDeviceRegistration(d.getUDN(),true);
868 }
869 }
870 }
871
872 public void searchForListener(Device device) {
873 Activator.logger.DEBUG("[Importer] searching for UPnPEventListener");
874 ServiceReference[] listeners = null;
875 try {
876 listeners = context.getServiceReferences(UPnPEventListener.class.getName(), null);
877 } catch (InvalidSyntaxException e) {
878 // TODO Auto-generated catch block
879 e.printStackTrace();
880 }
881 if (listeners != null) {
882 String deviceID = device.getUDN();
883 String serviceID;
884 String deviceType = device.getDeviceType();
885 String serviceType;
886 Hashtable hash = new Hashtable();
887 hash.put(UPnPDevice.ID, deviceID);
888 hash.put(UPnPDevice.TYPE, deviceType);
889 ServiceList services = device.getServiceList();
890 Vector eventedSers = new Vector();
891
892 for (int i = 0; i < services.size(); i++) {
893 Service service = (Service) services.elementAt(i);
894 ServiceStateTable vars = service.getServiceStateTable();
895 for (int j = 0; j < vars.size(); j++) {
896 StateVariable var = (StateVariable) vars.elementAt(j);
897 if (var.isSendEvents()) {
898 eventedSers.add(service);
899 break;
900 }
901 }
902 }
903
904 for (int i = 0; i < listeners.length; i++) {
905 UPnPEventListener listener = (UPnPEventListener) context
906 .getService(listeners[i]);
907 Filter filter = (Filter) listeners[i]
908 .getProperty(UPnPEventListener.UPNP_FILTER);
909 if (filter == null) {
910 for (int j = 0; j < eventedSers.size(); j++) {
911 Service ser = (Service) eventedSers.elementAt(j);
912 subQueue.enqueue(new FirstMessage(ser, listener));
913 }
914 } else {
915 for (int j = 0; j < eventedSers.size(); j++) {
916 Service ser = (Service) eventedSers.elementAt(j);
917 serviceID = ser.getServiceID();
918 serviceType = ser.getServiceType();
919 hash.put(UPnPService.ID, serviceID);
920 hash.put(UPnPService.TYPE, serviceType);
921 boolean bool = filter.match(hash);
922 if (bool) {
923 subQueue.enqueue(new FirstMessage(ser, listener));
924 }
925
926 }
927 }
928
929 }
930
931 }
932 }
933}