blob: 14217e18e0cf9d1511243b772325793ec2bc4fcf [file] [log] [blame]
Francesco Furfariec7e1752006-10-02 13:37:04 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
Francesco Furfarif2a67912006-07-17 17:08:02 +00009 *
Francesco Furfariec7e1752006-10-02 13:37:04 +000010 * http://www.apache.org/licenses/LICENSE-2.0
Francesco Furfarif2a67912006-07-17 17:08:02 +000011 *
Francesco Furfariec7e1752006-10-02 13:37:04 +000012 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
Francesco Furfarif2a67912006-07-17 17:08:02 +000018 */
19
20package org.apache.felix.upnp.basedriver.export;
21
22
23import org.cybergarage.upnp.Action;
24import org.cybergarage.upnp.AllowedValueList;
25import org.cybergarage.upnp.AllowedValueRange;
26import org.cybergarage.upnp.Argument;
27import org.cybergarage.upnp.ArgumentList;
28import org.cybergarage.upnp.Device;
29import org.cybergarage.upnp.Service;
30import org.cybergarage.upnp.StateVariable;
31import org.cybergarage.upnp.xml.DeviceData;
32import org.cybergarage.xml.Node;
33
34import org.osgi.framework.InvalidSyntaxException;
35import org.osgi.framework.ServiceReference;
36import org.osgi.service.upnp.UPnPAction;
37import org.osgi.service.upnp.UPnPDevice;
38import org.osgi.service.upnp.UPnPService;
39import org.osgi.service.upnp.UPnPStateVariable;
40
41import org.ungoverned.device.RootDescription;
42
43import org.apache.felix.upnp.basedriver.Activator;
44import org.apache.felix.upnp.extra.util.Converter;
45/*
Karl Paulsd312acc2007-06-18 20:38:33 +000046* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
Francesco Furfarif2a67912006-07-17 17:08:02 +000047*/
48public class BuildDevice {
49
50 private static Node buildRootNode(){
51 Node root = new Node(RootDescription.ROOT_ELEMENT);
52 root.setAttribute("xmlns",RootDescription.ROOT_ELEMENT_NAMESPACE);
53 Node spec = new Node(RootDescription.SPECVERSION_ELEMENT);
54 Node maj =new Node(RootDescription.MAJOR_ELEMENT);
55 maj.setValue("1");
56 Node min =new Node(RootDescription.MINOR_ELEMENT);
57 min.setValue("0");
58 spec.addNode(maj);
59 spec.addNode(min);
60 root.addNode(spec);
61 return root;
62 }
63
64 private static Device buildRootDeviceNode(Node root,ServiceReference sr){
65 Node dev = new Node(Device.ELEM_NAME);
66 root.addNode(dev);
67 DeviceData dd = new DeviceData();
68 dd.setDescriptionURI("/gen-desc.xml");
69 dev.setUserData(dd);
70 Device devUPnP = new Device(root,dev);
71
72
73 Object aux = sr.getProperty(UPnPDevice.TYPE);
74 if(aux==null){
75 devUPnP.setDeviceType(null);
76 }else if(aux instanceof String){
77 devUPnP.setDeviceType((String) aux);
78 }else if(aux instanceof String[]){
79 //The property key UPnP.device.type should be a String
80 String[] v = (String[]) aux;
81 int maxindex=0;
82 int max=Integer.parseInt(v[0].substring(v[0].lastIndexOf(":")+1));
83 int tmp;
84 for (int i = 1; i < v.length; i++) {
85 tmp=Integer.parseInt(v[i].substring(v[i].lastIndexOf(":")+1));
86 if(max<tmp){
87 max=tmp;
88 maxindex=i;
89 }
90 }
91 devUPnP.setDeviceType(v[maxindex]);
92 }
93
94 devUPnP.setFriendlyName((String) sr.getProperty(UPnPDevice.FRIENDLY_NAME));
95 devUPnP.setManufacture((String) sr.getProperty(UPnPDevice.MANUFACTURER));
96 devUPnP.setManufactureURL((String) sr.getProperty(UPnPDevice.MANUFACTURER_URL));
97 devUPnP.setModelDescription((String) sr.getProperty(UPnPDevice.MODEL_DESCRIPTION));
98 devUPnP.setModelName((String) sr.getProperty(UPnPDevice.MODEL_NAME));
99 devUPnP.setModelNumber((String) sr.getProperty(UPnPDevice.MODEL_NUMBER));
100 devUPnP.setModelURL((String) sr.getProperty(UPnPDevice.MODEL_URL));
101 devUPnP.setSerialNumber((String) sr.getProperty(UPnPDevice.SERIAL_NUMBER));
102 devUPnP.setUDN((String) sr.getProperty(UPnPDevice.UDN));
103 devUPnP.setUPC((String) sr.getProperty(UPnPDevice.UPC));
104
105 devUPnP.setLocation("/gen-desc.xml");
106
107 addServices("",devUPnP,sr);
108 addDevices("",devUPnP,sr);
109 devUPnP.setPresentationURL((String) sr.getProperty(UPnPDevice.PRESENTATION_URL));
110
111 return devUPnP;
112 }
113
114 private static void addDevices(String id,Device devUPnP, ServiceReference sr) {
115
116 String[] udns=(String[]) sr.getProperty(UPnPDevice.CHILDREN_UDN);
117 if(udns==null) {
118 return;
119 }
120 for (int i = 0; i < udns.length; i++) {
121 try {
122 ServiceReference[] aux = Activator.bc.getServiceReferences(
123 UPnPDevice.class.getName(),"("+UPnPDevice.UDN+"="+udns[i]+")"
124 );
125 if(aux==null || aux.length == 0)
126 continue;
127 //id=+"/device/"+i; // twa: wrong in recursion
128 //buildDevice(id,devUPnP,aux[0]); // twa: wrong in recursion
129 String localId = new StringBuffer(id).append("/device/").append(i).toString();
130 buildDevice(localId,devUPnP,aux[0]); // twa: better
131 } catch (InvalidSyntaxException ignored) {}
132 }
133 }
134
135 private static void buildDevice(String id,Device parent, ServiceReference sr) {
136 Node dev = new Node(Device.ELEM_NAME);
137 DeviceData dd = new DeviceData();
138 dd.setDescriptionURI(id+"/gen-desc.xml");
139 dev.setUserData(dd);
140
141 Device devUPnP = new Device(dev);
142
143 devUPnP.setFriendlyName((String) sr.getProperty(UPnPDevice.FRIENDLY_NAME));
144 devUPnP.setManufacture((String) sr.getProperty(UPnPDevice.MANUFACTURER));
145 devUPnP.setManufactureURL((String) sr.getProperty(UPnPDevice.MANUFACTURER_URL));
146 devUPnP.setModelDescription((String) sr.getProperty(UPnPDevice.MODEL_DESCRIPTION));
147 devUPnP.setModelName((String) sr.getProperty(UPnPDevice.MODEL_NAME));
148 devUPnP.setModelNumber((String) sr.getProperty(UPnPDevice.MODEL_NUMBER));
149 devUPnP.setModelURL((String) sr.getProperty(UPnPDevice.MODEL_URL));
150 devUPnP.setSerialNumber((String) sr.getProperty(UPnPDevice.SERIAL_NUMBER));
151 devUPnP.setUDN((String) sr.getProperty(UPnPDevice.UDN));
152 devUPnP.setUPC((String) sr.getProperty(UPnPDevice.UPC));
153 devUPnP.setLocation(id+"/gen-desc.xml");
154
155 addServices(id,devUPnP,sr);
156 addDevices(id,devUPnP,sr);
157
158 parent.addDevice(devUPnP); // twa: essential!!!!!!!
159 devUPnP.setPresentationURL((String) sr.getProperty(UPnPDevice.PRESENTATION_URL));
160
161 }
162
163 /**
164 * Method used to create a new Service in CyberLink world without creating the XML
165 *
166 * @param id ServiceId
167 * @param devUPnP the CyberLink device that where the new Service will be created
168 * @param sr ServiceReference to OSGi Device that used as source of the information
169 * for the creation of the device
170 */
171 private static void addServices(String id,Device devUPnP, ServiceReference sr) {
172 UPnPDevice devOSGi = (UPnPDevice) Activator.bc.getService(sr);
173
174 if( devOSGi == null) { //added by twa to prevent a null pointer exception
175 Activator.logger.WARNING("UPnP Device taht cotains serviceId="
176 +id+" is deregistered from the framework while is exported");
177 return;
178 }
179
180 UPnPService[] services = devOSGi.getServices();
181 if(services==null || services.length==0)
182 return;
183
184
185
186 for (int i = 0; i < services.length; i++) {
187 Service ser = new Service();
188 devUPnP.addService(ser);
189 ser.setServiceType(services[i].getType() );
190 ser.setServiceID(services[i].getId());
191 ser.setSCPDURL(id+"/service/"+i+"/gen-desc.xml");
192 ser.setDescriptionURL(id+"/service/"+i+"/gen-desc.xml");
193 ser.setControlURL(id+"/service/"+i+"/ctrl");
194 ser.setEventSubURL(id+"/service/"+i+"/event");
195
196 UPnPAction[] actions = services[i].getActions();
197 for (int j = 0; j < actions.length; j++) {
198 Action act = new Action(ser.getServiceNode());
199 act.setName(actions[j].getName());
200 ArgumentList al = new ArgumentList();
201
202 String[] names=actions[j].getInputArgumentNames();
203 if(names!=null){
204 for (int k = 0; k < names.length; k++) {
205 Argument a = new Argument();
206 a.setDirection(Argument.IN);
207 a.setName(names[k]);
208 a.setRelatedStateVariableName(
209 actions[j].getStateVariable(names[k]).getName()
210 );
211 al.add(a);
212 }
213 }
214 names=actions[j].getOutputArgumentNames();
215 if(names!=null){
216 for (int k = 0; k < names.length; k++) {
217 Argument a = new Argument();
218 a.setDirection(Argument.OUT);
219 a.setName(names[k]);
220 a.setRelatedStateVariableName(
221 actions[j].getStateVariable(names[k]).getName()
222 );
223 al.add(a);
224 }
225 }
226 act.setArgumentList(al);
227 ser.addAction(act);
228 }
229
230 UPnPStateVariable[] vars = services[i].getStateVariables();
231 for (int j = 0; j < vars.length; j++) {
232 StateVariable var = new StateVariable();
233 var.setDataType(vars[j].getUPnPDataType());
234 var.setName(vars[j].getName());
235 var.setSendEvents(vars[j].sendsEvents());
236 String[] values = vars[j].getAllowedValues();
237 if(values!=null){
238 AllowedValueList avl = new AllowedValueList(values);
239 var.setAllowedValueList(avl);
240 }else if(vars[j].getMaximum()!= null){
241 AllowedValueRange avr = new AllowedValueRange(
242 vars[j].getMaximum(),
243 vars[j].getMinimum(),
244 vars[j].getStep()
245 );
246 var.setAllowedValueRange(avr);
247 }
248 if(vars[j].getDefaultValue()!=null)
249 try {
250 var.setDefaultValue(Converter.toString(
251 vars[j].getDefaultValue(),vars[j].getUPnPDataType()
252 ));
253 } catch (Exception ignored) {
254 }
255 ser.addStateVariable(var);
256 }
257
258 Activator.bc.ungetService(sr);
259 }
260
261
262 }
263
264 public static Device createCyberLinkDevice(ServiceReference sr){
265 Node root = buildRootNode();
266 Device devUPnP = buildRootDeviceNode(root,sr);
267 return devUPnP;
268 }
269}