View Javadoc

1   package org.rpi.main;
2   
3   import java.awt.image.BufferedImage;
4   import java.io.BufferedReader;
5   import java.io.ByteArrayOutputStream;
6   import java.io.File;
7   import java.io.FileWriter;
8   import java.io.IOException;
9   import java.io.InputStreamReader;
10  import java.net.InetAddress;
11  import java.net.URL;
12  import java.util.List;
13  import java.util.concurrent.ConcurrentHashMap;
14  import java.util.regex.Matcher;
15  import java.util.regex.Pattern;
16  
17  import javax.imageio.ImageIO;
18  
19  import org.apache.log4j.Logger;
20  import org.openhome.net.core.DebugLevel;
21  import org.openhome.net.core.DeviceStack;
22  import org.openhome.net.core.IMessageListener;
23  import org.openhome.net.core.InitParams;
24  import org.openhome.net.core.Library;
25  import org.openhome.net.device.DvDevice;
26  import org.openhome.net.device.DvDeviceFactory;
27  import org.openhome.net.device.IDvDeviceListener;
28  import org.openhome.net.device.IResourceManager;
29  import org.openhome.net.device.IResourceWriter;
30  import org.rpi.config.Config;
31  import org.rpi.os.OSManager;
32  import org.rpi.player.PlayManager;
33  import org.rpi.plugingateway.PluginGateWay;
34  import org.rpi.providers.PrvAVTransport;
35  import org.rpi.providers.PrvConnectionManager;
36  import org.rpi.providers.PrvInfo;
37  import org.rpi.providers.PrvPlayList;
38  import org.rpi.providers.PrvProduct;
39  import org.rpi.providers.PrvRadio;
40  import org.rpi.providers.PrvReceiver;
41  import org.rpi.providers.PrvRenderingControl;
42  import org.rpi.providers.PrvTime;
43  import org.rpi.providers.PrvVolume;
44  import org.rpi.radio.ChannelReader;
45  import org.rpi.sources.Source;
46  import org.rpi.sources.SourceReader;
47  import org.rpi.utils.NetworkUtils;
48  
49  public class SimpleDevice implements IResourceManager, IDvDeviceListener, IMessageListener {
50  
51  	private Logger log = Logger.getLogger(SimpleDevice.class);
52  	private DvDevice iDevice = null;
53  	private Library lib = null;
54  
55  	private PrvConnectionManager iConnectionManager = null;
56  	private PrvVolume iVolume = null;
57  	private PrvPlayList iPlayList = null;
58  	private PrvProduct iProduct = null;
59  	private PrvInfo iInfo = null;
60  	private PrvTime iTime = null;
61  	private PrvRadio iRadio =  null;
62  	private PrvReceiver iReceiver = null;
63  	private PrvAVTransport iAVTransport = null;
64  	private PrvRenderingControl iRenderingControl = null;
65  
66  	private PlayManager iPlayer = PlayManager.getInstance();
67  
68  	//private PluginManager pm = null;
69  
70  
71  	/***
72  	 * Constructor for our Simple Device
73  	 */
74  	public SimpleDevice() {
75  		PluginGateWay.getInstance().setSimpleDevice(this);
76  		log.debug("Creating Simple Device version: " + Config.version);
77  		// System.loadLibrary("ohNetJni");
78  		//Call the OSManager to set our path to the libohNet libraries
79  		OSManager.getInstance();
80  
81  		InitParams initParams = new InitParams();
82  		initParams.setLogOutput(new OpenHomeLogger());
83  		if (Config.port > 0) {
84  			initParams.setDvServerPort(Config.port);
85  		}
86  		// initParams.setDvEnableBonjour();
87  		initParams.setFatalErrorHandler(this);
88  
89  		lib = Library.create(initParams);
90  		lib.setDebugLevel(getDebugLevel(Config.debug));
91  		StringBuffer sb = new StringBuffer();
92  
93  		DeviceStack ds = lib.startDv();
94  		String friendly_name = Config.friendly_name.replace(":", " ");
95  		String iDeviceName = "device-" + friendly_name + "-" + NetworkUtils.getHostName() + "-MediaRenderer";
96  		iDevice = new DvDeviceFactory(ds).createDeviceStandard(iDeviceName, this);
97  		log.debug("Created StandardDevice: " + iDevice.getUdn());
98  		sb.append("<icon>");
99  		sb.append("<minetype>image/png</minetype>");
100 		sb.append("<width>240</width>");
101 		sb.append("<height>240</height>");
102 		sb.append("<depth>24</depth>");
103 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer240.png</url>");
104 		sb.append("</icon>");
105 		sb.append("<icon>");
106 		sb.append("<minetype>image/jpeg</minetype>");
107 		sb.append("<width>240</width>");
108 		sb.append("<height>240</height>");
109 		sb.append("<depth>24</depth>");
110 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer240.jpg</url>");
111 		sb.append("</icon>");
112 		sb.append("<icon>");
113 		sb.append("<minetype>image/png</minetype>");
114 		sb.append("<width>120</width>");
115 		sb.append("<height>120</height>");
116 		sb.append("<depth>24</depth>");
117 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer120.png</url>");
118 		sb.append("</icon>");
119 		sb.append("<icon>");
120 		sb.append("<minetype>image/jpeg</minetype>");
121 		sb.append("<width>120</width>");
122 		sb.append("<height>120</height>");
123 		sb.append("<depth>24</depth>");
124 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer120.jpg</url>");
125 		sb.append("</icon>");
126 		sb.append("<icon>");
127 		sb.append("<minetype>image/png</minetype>");
128 		sb.append("<width>50</width>");
129 		sb.append("<height>50</height>");
130 		sb.append("<depth>24</depth>");
131 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer50.png</url>");
132 		sb.append("</icon>");
133 		sb.append("<icon>");
134 		sb.append("<minetype>image/jpeg</minetype>");
135 		sb.append("<width>50</width>");
136 		sb.append("<height>50</height>");
137 		sb.append("<depth>24</depth>");
138 		sb.append("<url>/" + iDeviceName + "/Upnp/resource/org/rpi/image/mediaplayer50.jpg</url>");
139 		sb.append("</icon>");
140 		iDevice.setAttribute("Upnp.IconList", sb.toString());
141 
142 		// iDevice.setAttribute("Upnp.Domain", "openhome-org");
143 		iDevice.setAttribute("Upnp.Domain", "schemas-upnp-org");
144 		iDevice.setAttribute("Upnp.Type", "MediaRenderer");
145 		iDevice.setAttribute("Upnp.Version", "1");
146 		iDevice.setAttribute("Upnp.FriendlyName", Config.friendly_name);
147 		iDevice.setAttribute("Upnp.Manufacturer", "Made in Manchester");
148 		iDevice.setAttribute("Upnp.ModelName", "Open Home Java Renderer: v" + Config.version);
149 		iDevice.setAttribute("Upnp.ModelDescription", "'We Made History Not Money' - Tony Wilson..");
150 		// iDevice.setAttribute("Upnp.IconList" , sb.toString());
151 		// iDevice.setAttribute("Upnp.ModelUri", "www.google.co.uk");
152 		// iDevice.setAttribute("Upnp.ModelImageUri","http://upload.wikimedia.org/wikipedia/en/thumb/0/04/Joy_Division.JPG/220px-Joy_Division.JPG");
153 
154 		iConnectionManager = new PrvConnectionManager(iDevice);
155 		iProduct = new PrvProduct(iDevice);
156 		iVolume = new PrvVolume(iDevice);
157 		iPlayList = new PrvPlayList(iDevice);
158 		iInfo = new PrvInfo(iDevice);
159 		iTime = new PrvTime(iDevice);
160 		iRadio = new PrvRadio(iDevice);
161 		//iInput = new PrvRadio(iDevice);
162 		if (Config.enableReceiver) {
163 			iReceiver = new PrvReceiver(iDevice);
164 		}
165 		if (Config.enableAVTransport) {
166 			iAVTransport = new PrvAVTransport(iDevice);
167 			iRenderingControl = new PrvRenderingControl(iDevice);
168 		}
169 
170 		try {
171 			ChannelReader cr = new ChannelReader();
172 			iRadio.addChannels(cr.getChannels());
173 		} catch (Exception e) {
174 			log.error("Error Reading Radio Channels");
175 		}
176 		
177 		try{
178 			SourceReader sr = new SourceReader();
179 			ConcurrentHashMap<String, Source> sources = sr.getSources();
180 			if(sources.size()==0)
181 			{
182 				Source playlist = new Source("PlayList","Playlist","-99");
183 				sources.put(playlist.getName(),playlist);
184 				Source radio = new Source("Radio","Radio","-99");
185 				sources.put(radio.getName(),radio);
186 				if(Config.enableReceiver)
187 				{
188 					Source reciever = new Source("Receiver", "Receiver", "-99");
189 					sources.put(reciever.getName(), reciever);
190 				}
191 			}
192 			PluginGateWay.getInstance().setSources(sources);
193 			PluginGateWay.getInstance().setDefaultSourcePin(sr.getDefaultPin());
194 			for(String key : sources.keySet())
195 			{
196 				Source s = sources.get(key);
197 				log.debug("Adding Source: " +s.toString());
198 				iProduct.addSource(Config.friendly_name, s.getName(), s.getType(), true);
199 			}
200 			iProduct.updateCurrentSource();
201 			
202 		}
203 		catch(Exception e)
204 		{
205 			log.error("Error Reading Input Sources");
206 		}
207 
208 		iDevice.setEnabled();
209 		log.debug("Device Enabled UDN: " + iDevice.getUdn());
210 		iProduct.setSourceByname("PlayList");
211 		OSManager.getInstance().loadPlugins();
212 	}
213 
214 
215 
216 
217 
218 	private int getDebugLevel(String sLevel) {
219 		if (sLevel.equalsIgnoreCase("NONE")) {
220 			return DebugLevel.None.intValue();
221 		} else if (sLevel.equalsIgnoreCase("TRACE")) {
222 			return DebugLevel.Trace.intValue();
223 		} else if (sLevel.equalsIgnoreCase("NETWORK")) {
224 			return DebugLevel.Network.intValue();
225 		} else if (sLevel.equalsIgnoreCase("TIMER")) {
226 			return DebugLevel.Timer.intValue();
227 		} else if (sLevel.equalsIgnoreCase("SsdpMulticast")) {
228 			return DebugLevel.SsdpMulticast.intValue();
229 		} else if (sLevel.equalsIgnoreCase("SsdpUnicast")) {
230 			return DebugLevel.SsdpUnicast.intValue();
231 		} else if (sLevel.equalsIgnoreCase("Http")) {
232 			return DebugLevel.Http.intValue();
233 		} else if (sLevel.equalsIgnoreCase("Device")) {
234 			return DebugLevel.Device.intValue();
235 		} else if (sLevel.equalsIgnoreCase("XmlFetch")) {
236 			return DebugLevel.XmlFetch.intValue();
237 		} else if (sLevel.equalsIgnoreCase("Service")) {
238 			return DebugLevel.Service.intValue();
239 		} else if (sLevel.equalsIgnoreCase("Event")) {
240 			return DebugLevel.Event.intValue();
241 		} else if (sLevel.equalsIgnoreCase("Topology")) {
242 			return DebugLevel.Topology.intValue();
243 		} else if (sLevel.equalsIgnoreCase("DvInvocation")) {
244 			return DebugLevel.DvInvocation.intValue();
245 		} else if (sLevel.equalsIgnoreCase("DvInvocation")) {
246 			return DebugLevel.DvInvocation.intValue();
247 		} else if (sLevel.equalsIgnoreCase("DvEvent")) {
248 			return DebugLevel.DvEvent.intValue();
249 		} else if (sLevel.equalsIgnoreCase("DvWebSocket")) {
250 			return DebugLevel.DvWebSocket.intValue();
251 		} else if (sLevel.equalsIgnoreCase("Bonjour")) {
252 			return DebugLevel.Bonjour.intValue();
253 		} else if (sLevel.equalsIgnoreCase("DvDevice")) {
254 			return DebugLevel.DvDevice.intValue();
255 		} else if (sLevel.equalsIgnoreCase("Error")) {
256 			return DebugLevel.Error.intValue();
257 		} else if (sLevel.equalsIgnoreCase("All")) {
258 			return DebugLevel.All.intValue();
259 		} else if (sLevel.equalsIgnoreCase("Verbose")) {
260 			return DebugLevel.Verbose.intValue();
261 		}
262 		return DebugLevel.None.intValue();
263 	}
264 
265 	public void attachShutDownHook() {
266 		Runtime.getRuntime().addShutdownHook(new Thread() {
267 			@Override
268 			public void run() {
269 				log.debug("Shutdown Hook, Start of Shutdown");
270 				dispose();
271 			}
272 		});
273 		log.debug("Shut Down Hook Attached.");
274 	}
275 
276 	public void dispose() {
277 
278 		try {
279 			OSManager.getInstance().dispose();
280 		} catch (Exception e) {
281 
282 		}
283 
284 		if (iPlayer != null) {
285 			log.info("Destroying IPlayer");
286 			try {
287 				iPlayer.destroy();
288 				log.info("Destroyed IPlayer");
289 			} catch (Exception e) {
290 				log.error("Error Destroying IPlayer", e);
291 			}
292 		}
293 
294 		if (iDevice != null) {
295 			log.info("Destroying device");
296 
297 			try {
298 				iDevice.destroy();
299 				log.info("Destroyed device");
300 			} catch (Exception e) {
301 				log.error("Error Destroying Device", e);
302 			}
303 		}
304 
305 		if (iConnectionManager != null) {
306 			log.info("Destroying ConnectionManager");
307 			try {
308 				iConnectionManager.dispose();
309 				log.info("Destroyed ConnectionManager");
310 			} catch (Exception e) {
311 				log.error("Error Destroying ConnectionManager", e);
312 			}
313 		}
314 
315 		if (iPlayList != null) {
316 			log.info("Destroying PlayList");
317 			try {
318 				iPlayList.dispose();
319 				log.info("Destroyed PlayList");
320 			} catch (Exception e) {
321 				log.error("Error Destroying PlayList", e);
322 			}
323 		}
324 
325 		if (iVolume != null) {
326 			log.info("Destroying Volume");
327 			try {
328 				iVolume.dispose();
329 				log.info("Destroyed Volume");
330 			} catch (Exception e) {
331 				log.error("Error Destroying Volume", e);
332 			}
333 		}
334 
335 		if (iProduct != null) {
336 			log.info("Destroying Product");
337 			try {
338 				iProduct.dispose();
339 				log.info("Destroyed Product");
340 			} catch (Exception e) {
341 				log.error("Error Destroying Product", e);
342 			}
343 		}
344 
345 		if (iInfo != null) {
346 			log.info("Destroying Info");
347 			try {
348 				iInfo.dispose();
349 				log.info("Destroyed Info");
350 			} catch (Exception e) {
351 				log.error("Error Destroying Info", e);
352 			}
353 		}
354 
355 		if (iTime != null) {
356 			log.info("Destroying Time");
357 			try {
358 				iTime.dispose();
359 				log.info("Destroyed Time");
360 			} catch (Exception e) {
361 				log.error("Error Destroying Time", e);
362 			}
363 
364 		}
365 
366 		if (iRadio != null) {
367 			log.info("Destroying Radio");
368 			try {
369 				iRadio.dispose();
370 				log.info("Destroyed Radio");
371 			} catch (Exception e) {
372 				log.error("Error Destroying Radio", e);
373 			}
374 
375 		}
376 
377 		if (iReceiver != null) {
378 			log.info("Destroying Receiver");
379 			try {
380 				iReceiver.dispose();
381 				log.info("Destroyed Receiver");
382 			} catch (Exception e) {
383 				log.error("Error Destroying Receiver", e);
384 			}
385 
386 		}
387 
388 		if (iAVTransport != null) {
389 			log.info("Destroying AVTransport");
390 			try {
391 				iAVTransport.dispose();
392 				log.info("Destroyed AVTransport");
393 			} catch (Exception e) {
394 				log.error("Error Destroying AVTransport", e);
395 			}
396 
397 		}
398 
399 		if (iRenderingControl != null) {
400 			log.info("Destroying RenderingControl");
401 			try {
402 				iRenderingControl.dispose();
403 				log.info("Destroyed RenderingControl");
404 			} catch (Exception e) {
405 				log.error("Error Destroying RenderingControl", e);
406 			}
407 
408 		}
409 
410 		if (lib != null) {
411 			try {
412 				log.info("Attempting to Close DeviceStack");
413 				lib.close();
414 				log.info("Closed DeviceStack");
415 			} catch (Exception e) {
416 				log.error("Error Closing DeviceStack", e);
417 			}
418 		}
419 
420 	}
421 
422 	@Override
423 	public void writeResource(String resource_name, int arg1, List<String> arg2, IResourceWriter writer) {
424 		log.info("writeResource Called: " + resource_name);
425 		try {
426 			resource_name = "/" + resource_name;
427 			URL url = this.getClass().getResource(resource_name);
428 			BufferedImage image = ImageIO.read(url);
429 			ByteArrayOutputStream baos = new ByteArrayOutputStream();
430 			String fileType = "image/png";
431 			String format = "png";
432 			if (resource_name.toUpperCase().endsWith("JPG")) {
433 				format = "jpg";
434 				fileType = "image/jpeg";
435 			}
436 			ImageIO.write(image, format, baos);
437 			int length = baos.toByteArray().length;
438 			writer.writeResourceBegin(length, fileType);
439 			writer.writeResource(baos.toByteArray(), length);
440 			writer.writeResourceEnd();
441 		} catch (IOException e) {
442 			log.error("Error Writing Resource: " + resource_name, e);
443 		}
444 
445 	}
446 
447 	private void writeFile(String s) {
448 		try {
449 			File newTextFile = new File("C:/temp/thetextfile.txt");
450 
451 			FileWriter fw = new FileWriter(newTextFile);
452 			fw.write(s);
453 			fw.close();
454 
455 		} catch (IOException iox) {
456 			// do stuff with exception
457 			iox.printStackTrace();
458 		}
459 	}
460 
461 	public PrvVolume getCustomVolume() {
462 		return iVolume;
463 	}
464 
465 	@Override
466 	public void deviceDisabled() {
467 		log.info("Device has been Disabled");
468 		dispose();
469 	}
470 
471 	@Override
472 	public void message(String paramString) {
473 		log.fatal("Fatal Error: " + paramString);
474 	}
475 	
476 	/**
477 	 * Get the Product Provider
478 	 * @return
479 	 */
480 	public PrvProduct getProduct()
481 	{
482 		return iProduct;
483 	}
484 }