* Add device icon support.
This commit is contained in:
		@@ -16,6 +16,8 @@
 | 
				
			|||||||
#include "upnpglobalvars.h"
 | 
					#include "upnpglobalvars.h"
 | 
				
			||||||
#include "upnpdescstrings.h"
 | 
					#include "upnpdescstrings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef DESC_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char * const upnptypes[] =
 | 
					static const char * const upnptypes[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"string",
 | 
						"string",
 | 
				
			||||||
@@ -101,7 +103,7 @@ static const struct XMLElt rootDesc[] =
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	{root_device, INITHELPER(1,2)},
 | 
						{root_device, INITHELPER(1,2)},
 | 
				
			||||||
	{"specVersion", INITHELPER(3,2)},
 | 
						{"specVersion", INITHELPER(3,2)},
 | 
				
			||||||
	{"device", INITHELPER(5,13)},
 | 
						{"device", INITHELPER(5,14)},
 | 
				
			||||||
	{"/major", "1"},
 | 
						{"/major", "1"},
 | 
				
			||||||
	{"/minor", "0"},
 | 
						{"/minor", "0"},
 | 
				
			||||||
	{"/deviceType", "urn:schemas-upnp-org:device:MediaServer:1"},
 | 
						{"/deviceType", "urn:schemas-upnp-org:device:MediaServer:1"},
 | 
				
			||||||
@@ -116,10 +118,35 @@ static const struct XMLElt rootDesc[] =
 | 
				
			|||||||
	{"/UDN", uuidvalue},	/* required */
 | 
						{"/UDN", uuidvalue},	/* required */
 | 
				
			||||||
	{"/dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\"", "DMS-1.50"},
 | 
						{"/dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\"", "DMS-1.50"},
 | 
				
			||||||
	{"/presentationURL", presentationurl},	/* recommended */
 | 
						{"/presentationURL", presentationurl},	/* recommended */
 | 
				
			||||||
	{"serviceList", INITHELPER(18,3)},
 | 
						{"iconList", INITHELPER(19,4)},
 | 
				
			||||||
	{"service", INITHELPER(21,5)},
 | 
						{"serviceList", INITHELPER(43,3)},
 | 
				
			||||||
	{"service", INITHELPER(26,5)},
 | 
						{"icon", INITHELPER(23,5)},
 | 
				
			||||||
	{"service", INITHELPER(31,5)},
 | 
						{"icon", INITHELPER(28,5)},
 | 
				
			||||||
 | 
						{"icon", INITHELPER(33,5)},
 | 
				
			||||||
 | 
						{"icon", INITHELPER(38,5)},
 | 
				
			||||||
 | 
						{"/mimetype", "image/png"},
 | 
				
			||||||
 | 
						{"/width", "48"},
 | 
				
			||||||
 | 
						{"/height", "48"},
 | 
				
			||||||
 | 
						{"/depth", "32"},
 | 
				
			||||||
 | 
						{"/url", "/icons/sm.png"},
 | 
				
			||||||
 | 
						{"/mimetype", "image/png"},
 | 
				
			||||||
 | 
						{"/width", "120"},
 | 
				
			||||||
 | 
						{"/height", "120"},
 | 
				
			||||||
 | 
						{"/depth", "32"},
 | 
				
			||||||
 | 
						{"/url", "/icons/lrg.png"},
 | 
				
			||||||
 | 
						{"/mimetype", "image/jpeg"},
 | 
				
			||||||
 | 
						{"/width", "48"},
 | 
				
			||||||
 | 
						{"/height", "48"},
 | 
				
			||||||
 | 
						{"/depth", "32"},
 | 
				
			||||||
 | 
						{"/url", "/icons/sm.jpg"},
 | 
				
			||||||
 | 
						{"/mimetype", "image/jpeg"},
 | 
				
			||||||
 | 
						{"/width", "120"},
 | 
				
			||||||
 | 
						{"/height", "120"},
 | 
				
			||||||
 | 
						{"/depth", "32"},
 | 
				
			||||||
 | 
						{"/url", "/icons/lrg.jpg"},
 | 
				
			||||||
 | 
						{"service", INITHELPER(46,5)},
 | 
				
			||||||
 | 
						{"service", INITHELPER(51,5)},
 | 
				
			||||||
 | 
						{"service", INITHELPER(56,5)},
 | 
				
			||||||
	{"/serviceType", "urn:schemas-upnp-org:service:ContentDirectory:1"},
 | 
						{"/serviceType", "urn:schemas-upnp-org:service:ContentDirectory:1"},
 | 
				
			||||||
	{"/serviceId", "urn:upnp-org:serviceId:ContentDirectory"},
 | 
						{"/serviceId", "urn:upnp-org:serviceId:ContentDirectory"},
 | 
				
			||||||
	{"/controlURL", CONTENTDIRECTORY_CONTROLURL},
 | 
						{"/controlURL", CONTENTDIRECTORY_CONTROLURL},
 | 
				
			||||||
@@ -530,7 +557,9 @@ genXML(char * str, int * len, int * tmplen,
 | 
				
			|||||||
			return str;
 | 
								return str;
 | 
				
			||||||
		if(eltname[0] == '/')
 | 
							if(eltname[0] == '/')
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */
 | 
								#ifdef DESC_DEBUG
 | 
				
			||||||
 | 
								printf("DBG: <%s>%s<%s>\n", eltname+1, p[i].data, eltname);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
			str = strcat_char(str, len, tmplen, '<');
 | 
								str = strcat_char(str, len, tmplen, '<');
 | 
				
			||||||
			str = strcat_str(str, len, tmplen, eltname+1);
 | 
								str = strcat_str(str, len, tmplen, eltname+1);
 | 
				
			||||||
			str = strcat_char(str, len, tmplen, '>');
 | 
								str = strcat_char(str, len, tmplen, '>');
 | 
				
			||||||
@@ -545,10 +574,14 @@ genXML(char * str, int * len, int * tmplen,
 | 
				
			|||||||
					return str;
 | 
										return str;
 | 
				
			||||||
				i = ++(pile[top].i);
 | 
									i = ++(pile[top].i);
 | 
				
			||||||
				j = pile[top].j;
 | 
									j = pile[top].j;
 | 
				
			||||||
				/*printf("  pile[%d]\t%d %d\n", top, i, j); */
 | 
									#ifdef DESC_DEBUG
 | 
				
			||||||
 | 
									printf("DBG:  pile[%d]\t%d %d\n", top, i, j); 
 | 
				
			||||||
 | 
									#endif
 | 
				
			||||||
				if(i==j)
 | 
									if(i==j)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					/*printf("</%s>\n", pile[top].eltname); */
 | 
										#ifdef DESC_DEBUG
 | 
				
			||||||
 | 
										printf("DBG: i==j, </%s>\n", pile[top].eltname); 
 | 
				
			||||||
 | 
										#endif
 | 
				
			||||||
					str = strcat_char(str, len, tmplen, '<');
 | 
										str = strcat_char(str, len, tmplen, '<');
 | 
				
			||||||
					str = strcat_char(str, len, tmplen, '/');
 | 
										str = strcat_char(str, len, tmplen, '/');
 | 
				
			||||||
					s = pile[top].eltname;
 | 
										s = pile[top].eltname;
 | 
				
			||||||
@@ -563,7 +596,9 @@ genXML(char * str, int * len, int * tmplen,
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/*printf("<%s>\n", eltname); */
 | 
								#ifdef DESC_DEBUG
 | 
				
			||||||
 | 
								printf("DBG: [%d] <%s>\n", i, eltname); 
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
			str = strcat_char(str, len, tmplen, '<');
 | 
								str = strcat_char(str, len, tmplen, '<');
 | 
				
			||||||
			str = strcat_str(str, len, tmplen, eltname);
 | 
								str = strcat_str(str, len, tmplen, eltname);
 | 
				
			||||||
			str = strcat_char(str, len, tmplen, '>');
 | 
								str = strcat_char(str, len, tmplen, '>');
 | 
				
			||||||
@@ -573,7 +608,9 @@ genXML(char * str, int * len, int * tmplen,
 | 
				
			|||||||
			i = (unsigned)p[k].data & 0xffff;
 | 
								i = (unsigned)p[k].data & 0xffff;
 | 
				
			||||||
			j = i + ((unsigned)p[k].data >> 16);
 | 
								j = i + ((unsigned)p[k].data >> 16);
 | 
				
			||||||
			top++;
 | 
								top++;
 | 
				
			||||||
			/*printf(" +pile[%d]\t%d %d\n", top, i, j); */
 | 
								#ifdef DESC_DEBUG
 | 
				
			||||||
 | 
								printf("DBG: +pile[%d]\t%d %d\n", top, i, j); 
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
			pile[top].i = i;
 | 
								pile[top].i = i;
 | 
				
			||||||
			pile[top].j = j;
 | 
								pile[top].j = j;
 | 
				
			||||||
			pile[top].eltname = eltname;
 | 
								pile[top].eltname = eltname;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								upnphttp.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								upnphttp.c
									
									
									
									
									
								
							@@ -46,6 +46,8 @@
 | 
				
			|||||||
//#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much?
 | 
					//#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much?
 | 
				
			||||||
#define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much?
 | 
					#define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "icons.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct upnphttp * 
 | 
					struct upnphttp * 
 | 
				
			||||||
New_upnphttp(int s)
 | 
					New_upnphttp(int s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -599,15 +601,25 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
 | 
				
			|||||||
				printf("TiVo request: %c\n", *(HttpUrl+12));
 | 
									printf("TiVo request: %c\n", *(HttpUrl+12));
 | 
				
			||||||
				Send404(h);
 | 
									Send404(h);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									printf("Invalid TiVo request! %s\n", HttpUrl+12);
 | 
				
			||||||
 | 
									Send404(h);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
#if 0 //JPEG_RESIZE
 | 
					#if 0 //JPEG_RESIZE
 | 
				
			||||||
		else if(strncmp(HttpUrl, "/Resized/", 7) == 0)
 | 
							else if(strncmp(HttpUrl, "/Resized/", 9) == 0)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			SendResp_resizedimg(h, HttpUrl+7);
 | 
								SendResp_resizedimg(h, HttpUrl+9);
 | 
				
			||||||
			CloseSocket_upnphttp(h);
 | 
								CloseSocket_upnphttp(h);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
							else if(strncmp(HttpUrl, "/icons/", 7) == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SendResp_icon(h, HttpUrl+7);
 | 
				
			||||||
 | 
								CloseSocket_upnphttp(h);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			DPRINTF(E_WARN, L_HTTP, "%s not found, responding ERROR 404\n", HttpUrl);
 | 
								DPRINTF(E_WARN, L_HTTP, "%s not found, responding ERROR 404\n", HttpUrl);
 | 
				
			||||||
@@ -876,6 +888,69 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					SendResp_icon(struct upnphttp * h, char * icon)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char * header;
 | 
				
			||||||
 | 
						char * data;
 | 
				
			||||||
 | 
						int size;
 | 
				
			||||||
 | 
						char mime[12];
 | 
				
			||||||
 | 
						char date[30];
 | 
				
			||||||
 | 
						time_t curtime = time(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( strcmp(icon, "sm.png") == 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DPRINTF(E_DEBUG, L_HTTP, "Sending small PNG icon\n");
 | 
				
			||||||
 | 
							data = (char *)png_sm;
 | 
				
			||||||
 | 
							size = sizeof(png_sm)-1;
 | 
				
			||||||
 | 
							strcpy(mime, "image/png");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if( strcmp(icon, "lrg.png") == 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DPRINTF(E_DEBUG, L_HTTP, "Sending large PNG icon\n");
 | 
				
			||||||
 | 
							data = (char *)png_lrg;
 | 
				
			||||||
 | 
							size = sizeof(png_lrg)-1;
 | 
				
			||||||
 | 
							strcpy(mime, "image/png");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if( strcmp(icon, "sm.jpg") == 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DPRINTF(E_DEBUG, L_HTTP, "Sending small JPEG icon\n");
 | 
				
			||||||
 | 
							data = (char *)jpeg_sm;
 | 
				
			||||||
 | 
							size = sizeof(jpeg_sm)-1;
 | 
				
			||||||
 | 
							strcpy(mime, "image/jpeg");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if( strcmp(icon, "lrg.jpg") == 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DPRINTF(E_DEBUG, L_HTTP, "Sending large JPEG icon\n");
 | 
				
			||||||
 | 
							data = (char *)jpeg_lrg;
 | 
				
			||||||
 | 
							size = sizeof(jpeg_lrg)-1;
 | 
				
			||||||
 | 
							strcpy(mime, "image/jpeg");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DPRINTF(E_WARN, L_HTTP, "Invalid icon request: %s\n", icon);
 | 
				
			||||||
 | 
							Send404(h);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
 | 
				
			||||||
 | 
						asprintf(&header, "HTTP/1.1 200 OK\r\n"
 | 
				
			||||||
 | 
								  "Content-Type: %s\r\n"
 | 
				
			||||||
 | 
								  "Content-Length: %d\r\n"
 | 
				
			||||||
 | 
								  "Connection: close\r\n"
 | 
				
			||||||
 | 
								  "Date: %s\r\n"
 | 
				
			||||||
 | 
								  "Server: RAIDiator/4.1, UPnP/1.0, MiniDLNA/1.0\r\n\r\n",
 | 
				
			||||||
 | 
								  mime, size, date);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( (send_data(h, header, strlen(header)) == 0) && (h->req_command != EHead) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							send_data(h, data, size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(header);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
SendResp_albumArt(struct upnphttp * h, char * object)
 | 
					SendResp_albumArt(struct upnphttp * h, char * object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -124,6 +124,8 @@ BuildResp2_upnphttp(struct upnphttp * h, int respcode,
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
SendResp_upnphttp(struct upnphttp *);
 | 
					SendResp_upnphttp(struct upnphttp *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					SendResp_icon(struct upnphttp *, char * url);
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
SendResp_albumArt(struct upnphttp *, char * url);
 | 
					SendResp_albumArt(struct upnphttp *, char * url);
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user