"Fossies" - the Fresh Open Source Software Archive

Member "minidlna-1.3.0/clients.c" (24 Nov 2020, 7930 Bytes) of package /linux/privat/minidlna-1.3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "clients.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.2.1_vs_1.3.0.

    1 /* MiniDLNA media server
    2  * Copyright (C) 2013-2017  NETGEAR
    3  *
    4  * This file is part of MiniDLNA.
    5  *
    6  * MiniDLNA is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License version 2 as
    8  * published by the Free Software Foundation.
    9  *
   10  * MiniDLNA is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
   17  */
   18 #include <stdio.h>
   19 #include <string.h>
   20 #include <time.h>
   21 
   22 #include "clients.h"
   23 #include "event.h"
   24 #include "getifaddr.h"
   25 #include "log.h"
   26 
   27 struct client_type_s client_types[] =
   28 {
   29     { 0,
   30       0,
   31       "Unknown",
   32       NULL,
   33       EMatchNone
   34     },
   35 
   36     { EXbox,
   37       FLAG_MIME_AVI_AVI | FLAG_MS_PFS,
   38       "Xbox 360",
   39       "Xbox/",
   40       EUserAgent
   41     },
   42 
   43     { EPS3,
   44       FLAG_DLNA | FLAG_MIME_AVI_DIVX,
   45       "PLAYSTATION 3",
   46       "PLAYSTATION",
   47       EUserAgent
   48     },
   49 
   50     { EPS3,
   51       FLAG_DLNA | FLAG_MIME_AVI_DIVX,
   52       "PLAYSTATION 3",
   53       "PLAYSTATION 3",
   54       EXAVClientInfo
   55     },
   56 
   57     /* User-Agent: DLNADOC/1.50 SEC_HHP_[PC]LPC001/1.0  MS-DeviceCaps/1024 */
   58     /* This is AllShare running on a PC.  We don't want to respond with Samsung
   59      * capabilities, or Windows (and AllShare) might get grumpy. */
   60     { 0,
   61       FLAG_DLNA,
   62       "AllShare",
   63       "SEC_HHP_[PC]",
   64       EUserAgent
   65     },
   66 
   67     { ESamsungBDJ5500,
   68       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE | FLAG_CAPTION_RES | FLAG_SKIP_DLNA_PN,
   69       "Samsung BD J5500",
   70       "[BD]J5500",
   71       EUserAgent
   72     },
   73 
   74     /* Samsung Series [CDE] BDPs and TVs must be separated, or some of our
   75      * advertised extra features trigger a folder browsing bug on BDPs. */
   76     /* User-Agent: DLNADOC/1.50 SEC_HHP_BD-D5100/1.0 */
   77     { ESamsungSeriesCDEBDP,
   78       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE,
   79       "Samsung Series [CDEF] BDP",
   80       "SEC_HHP_BD",
   81       EUserAgent
   82     },
   83 
   84     /* Samsung Series [Q] TVs work wit milliseconds for bookmarks */
   85     /* User-Agent: DLNADOC/1.50 SEC_HHP_[TV] Samsung Q7 Series (49)/1.0 */
   86     { ESamsungSeriesQ,
   87       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE | FLAG_SAMSUNG_DCM10 | FLAG_CAPTION_RES | FLAG_CONVERT_MS,
   88       "Samsung Series [Q]",
   89       "SEC_HHP_[TV] Samsung Q",
   90       EUserAgent
   91     },
   92 
   93     /* User-Agent: DLNADOC/1.50 SEC_HHP_[TV]UE40D7000/1.0 */
   94     /* User-Agent: DLNADOC/1.50 SEC_HHP_ Family TV/1.0 */
   95     /* USER-AGENT: DLNADOC/1.50 SEC_HHP_[TV] UE65JU7000/1.0 UPnP/1.0 */
   96     { ESamsungSeriesCDE,
   97       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE | FLAG_SAMSUNG_DCM10 | FLAG_CAPTION_RES,
   98       "Samsung Series [CDEFJ]",
   99       "SEC_HHP_",
  100       EUserAgent
  101     },
  102 
  103     { ESamsungSeriesA,
  104       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE,
  105       "Samsung Series A",
  106       "SamsungWiselinkPro",
  107       EUserAgent
  108     },
  109 
  110     { ESamsungSeriesB,
  111       FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE,
  112       "Samsung Series B",
  113       "Samsung DTV DMR",
  114       EModelName
  115     },
  116 
  117     /* User-Agent: Panasonic MIL DLNA CP UPnP/1.0 DLNADOC/1.50 */
  118     { EPanasonic,
  119       FLAG_DLNA | FLAG_FORCE_SORT,
  120       "Panasonic",
  121       "Panasonic",
  122       EUserAgent
  123     },
  124 
  125     /* User-Agent: IPI/1.0 UPnP/1.0 DLNADOC/1.50 */
  126     { ENetFrontLivingConnect,
  127       FLAG_DLNA | FLAG_FORCE_SORT | FLAG_CAPTION_RES,
  128       "NetFront Living Connect",
  129       "IPI/1",
  130       EUserAgent
  131     },
  132 
  133     { EDenonReceiver,
  134       FLAG_DLNA,
  135       "Denon Receiver",
  136       "bridgeCo-DMP/3",
  137       EUserAgent
  138     },
  139 
  140     { EFreeBox,
  141       FLAG_RESIZE_THUMBS,
  142       "FreeBox",
  143       "fbxupnpav/",
  144       EUserAgent
  145     },
  146 
  147     { EPopcornHour,
  148       FLAG_MIME_FLAC_FLAC,
  149       "Popcorn Hour",
  150       "SMP8634",
  151       EUserAgent
  152     },
  153 
  154     /* X-AV-Client-Info: av=5.0; cn="Sony Corporation"; mn="Blu-ray Disc Player"; mv="2.0" */
  155     /* X-AV-Client-Info: av=5.0; cn="Sony Corporation"; mn="BLU-RAY HOME THEATRE SYSTEM"; mv="2.0"; */
  156     /* Sony SMP-100 needs the same treatment as their BDP-S370 */
  157     /* X-AV-Client-Info: av=5.0; cn="Sony Corporation"; mn="Media Player"; mv="2.0" */
  158     { ESonyBDP,
  159       FLAG_DLNA,
  160       "Sony BDP",
  161       "mv=\"2.0\"",
  162       EXAVClientInfo
  163     },
  164 
  165     /* USER-AGENT: Linux/2.6.35 UPnP/1.0 DLNADOC/1.50 INTEL_NMPR/2.0 LGE_DLNA_SDK/1.6.0 */
  166     { ELGNetCastDevice,
  167       FLAG_DLNA | FLAG_CAPTION_RES | FLAG_MIME_FLAC_FLAC,
  168       "LG",
  169       "LGE_DLNA_SDK/1.6.0",
  170       EUserAgent
  171     },
  172 
  173     /* User-Agent: Linux/2.6.31-1.0 UPnP/1.0 DLNADOC/1.50 INTEL_NMPR/2.0 LGE_DLNA_SDK/1.5.0 */
  174     { ELGDevice,
  175       FLAG_DLNA | FLAG_CAPTION_RES | FLAG_MIME_FLAC_FLAC,
  176       "LG",
  177       "LGE_DLNA_SDK",
  178       EUserAgent
  179     },
  180 
  181     /* X-AV-Client-Info: av=5.0; cn="Sony Corporation"; mn="BRAVIA KDL-40EX503"; mv="1.7"; */
  182     { ESonyBravia,
  183       FLAG_DLNA,
  184       "Sony Bravia",
  185       "BRAVIA",
  186       EXAVClientInfo
  187     },
  188 
  189     /* X-AV-Client-Info: av=5.0; hn=""; cn="Sony Corporation"; mn="INTERNET TV NSX-40GT 1"; mv="0.1"; */
  190     { ESonyInternetTV,
  191       FLAG_DLNA,
  192       "Sony Internet TV",
  193       "INTERNET TV",
  194       EXAVClientInfo
  195     },
  196 
  197     { ENetgearEVA2000,
  198       FLAG_MS_PFS | FLAG_RESIZE_THUMBS,
  199       "EVA2000",
  200       "Verismo,",
  201       EUserAgent
  202     },
  203 
  204     { EDirecTV,
  205       FLAG_RESIZE_THUMBS,
  206       "DirecTV",
  207       "DIRECTV ",
  208       EUserAgent
  209     },
  210 
  211     { EToshibaTV,
  212       FLAG_DLNA,
  213       "Toshiba TV",
  214       "UPnP/1.0 DLNADOC/1.50 Intel_SDK_for_UPnP_devices/1.2",
  215       EUserAgent
  216     },
  217 
  218     { EHyundaiTV,
  219       FLAG_DLNA,
  220       "Hyundai TV",
  221       "HYUNDAITV",
  222       EFriendlyName
  223     },
  224 
  225     { ERokuSoundBridge,
  226       FLAG_MS_PFS | FLAG_AUDIO_ONLY | FLAG_MIME_WAV_WAV | FLAG_FORCE_SORT,
  227       "Roku SoundBridge",
  228       "Roku SoundBridge",
  229       EModelName
  230     },
  231 
  232     { EMarantzDMP,
  233       FLAG_DLNA | FLAG_MIME_WAV_WAV,
  234       "marantz DMP",
  235       "marantz DMP",
  236       EFriendlyNameSSDP
  237     },
  238 
  239     { EMediaRoom,
  240       FLAG_MS_PFS,
  241       "MS MediaRoom",
  242       "Microsoft-IPTV-Client",
  243       EUserAgent
  244     },
  245 
  246     { ELifeTab,
  247       FLAG_MS_PFS,
  248       "LIFETAB",
  249       "LIFETAB",
  250       EFriendlyName
  251     },
  252 
  253     { EAsusOPlay,
  254       FLAG_DLNA | FLAG_MIME_AVI_AVI | FLAG_CAPTION_RES,
  255       "Asus OPlay Mini/Mini+",
  256       "O!Play",
  257       EUserAgent
  258     },
  259 
  260     { EBubbleUPnP,
  261       FLAG_CAPTION_RES,
  262       "BubbleUPnP",
  263       "BubbleUPnP",
  264       EUserAgent
  265     },
  266 
  267     { EMovian,
  268       FLAG_CAPTION_RES,
  269       "Movian",
  270       "Movian",
  271       EUserAgent
  272     },
  273 
  274     { EKodi,
  275       FLAG_DLNA | FLAG_MIME_AVI_AVI | FLAG_CAPTION_RES,
  276       "Kodi",
  277       "Kodi",
  278       EUserAgent
  279     },
  280 
  281     { 0,
  282       FLAG_DLNA | FLAG_MIME_AVI_AVI,
  283       "Windows",
  284       "FDSSDP",
  285       EUserAgent
  286     },
  287 
  288     { 0,
  289       0,
  290       "TiVo",
  291       "TvHttpClient",
  292       EUserAgent
  293     },
  294 
  295     { EStandardDLNA150,
  296       FLAG_DLNA | FLAG_MIME_AVI_AVI,
  297       "Generic DLNA 1.5",
  298       "DLNADOC/1.50",
  299       EUserAgent
  300     },
  301 
  302     { EStandardUPnP,
  303       0,
  304       "Generic UPnP 1.0",
  305       "UPnP/1.0",
  306       EUserAgent
  307     },
  308 
  309     { 0, 0, NULL, 0 }
  310 };
  311 
  312 struct client_cache_s clients[CLIENT_CACHE_SLOTS];
  313 
  314 struct client_cache_s *
  315 SearchClientCache(struct in_addr addr, int quiet)
  316 {
  317     int i;
  318 
  319     for (i = 0; i < CLIENT_CACHE_SLOTS; i++)
  320     {
  321         if (clients[i].addr.s_addr == addr.s_addr)
  322         {
  323             /* Invalidate this client cache if it's older than 1 hour */
  324             if ((time(NULL) - clients[i].age) > 3600)
  325             {
  326                 unsigned char mac[6];
  327                 if (get_remote_mac(addr, mac) == 0 &&
  328                     memcmp(mac, clients[i].mac, 6) == 0)
  329                 {
  330                     /* Same MAC as last time when we were able to identify the client,
  331                      * so extend the timeout by another hour. */
  332                     clients[i].age = time(NULL);
  333                 }
  334                 else
  335                 {
  336                     memset(&clients[i], 0, sizeof(struct client_cache_s));
  337                     return NULL;
  338                 }
  339             }
  340             if (!quiet)
  341                 DPRINTF(E_DEBUG, L_HTTP, "Client found in cache. [%s/entry %d]\n",
  342                     clients[i].type->name, i);
  343             return &clients[i];
  344         }
  345     }
  346 
  347     return NULL;
  348 }
  349 
  350 struct client_cache_s *
  351 AddClientCache(struct in_addr addr, int type)
  352 {
  353     int i;
  354 
  355     for (i = 0; i < CLIENT_CACHE_SLOTS; i++)
  356     {
  357         if (clients[i].addr.s_addr)
  358             continue;
  359         get_remote_mac(addr, clients[i].mac);
  360         clients[i].addr = addr;
  361         clients[i].type = &client_types[type];
  362         clients[i].age = time(NULL);
  363         DPRINTF(E_DEBUG, L_HTTP, "Added client [%s/%s/%02X:%02X:%02X:%02X:%02X:%02X] to cache slot %d.\n",
  364                     client_types[type].name, inet_ntoa(clients[i].addr),
  365                     clients[i].mac[0], clients[i].mac[1], clients[i].mac[2],
  366                     clients[i].mac[3], clients[i].mac[4], clients[i].mac[5], i);
  367         return &clients[i];
  368     }
  369 
  370     return NULL;
  371 }