PageRenderTime 27ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/multimedia/mediatomb/samsung-mkv.patch

https://gitlab.com/pink-mist/slackbuilds
Patch | 445 lines | 430 code | 15 blank | 0 comment | 0 complexity | e246eefe36ad105eab8e377c3423c0d8 MD5 | raw file
  1. Workaround for Samsung Smart TV 2012 :
  2. - URI patch made by swiergot http://sourceforge.net/tracker/index.php?func=detail&aid=3532724&group_id=129766&atid=715782
  3. - per device content-type engine : change video/x-matroska with video/x-mkv for Samsung devices only
  4. --- a/tombupnp/upnp/src/genlib/miniserver/miniserver.c
  5. +++ b/tombupnp/upnp/src/genlib/miniserver/miniserver.c
  6. @@ -842,6 +842,8 @@
  7. return UPNP_E_INTERNAL_ERROR; // miniserver running
  8. }
  9. + ssdpdevices_init(&GlobalSsdpDevices);
  10. +
  11. miniSocket =
  12. ( MiniServerSockArray * ) malloc( sizeof( MiniServerSockArray ) );
  13. if( miniSocket == NULL )
  14. @@ -963,5 +965,8 @@
  15. }
  16. shutdown( sock, SD_BOTH );
  17. UpnpCloseSocket( sock );
  18. +
  19. + ssdpdevices_destroy(&GlobalSsdpDevices);
  20. +
  21. return 0;
  22. }
  23. --- a/tombupnp/upnp/src/genlib/net/http/webserver.c
  24. +++ b/tombupnp/upnp/src/genlib/net/http/webserver.c
  25. @@ -1211,6 +1211,7 @@
  26. *
  27. * Parameters:
  28. * IN http_message_t *req ; HTTP Request message
  29. +* IN SOCKINFO *info ; Socket info (fd with remote ip & port)
  30. * OUT enum resp_type *rtype ; Tpye of response
  31. * OUT membuffer *headers ;
  32. * OUT membuffer *filename ; Get filename from request document
  33. @@ -1230,6 +1231,7 @@
  34. ************************************************************************/
  35. static int
  36. process_request( IN http_message_t * req,
  37. + IN SOCKINFO *info,
  38. OUT enum resp_type *rtype,
  39. OUT membuffer * headers,
  40. OUT membuffer * filename,
  41. @@ -1473,6 +1475,19 @@
  42. goto error_handler;
  43. }
  44. + // change "x-matroska" by "x-mkv", for samsung devices only
  45. + char *newtype;
  46. + if((strcmp(finfo.content_type, "video/x-matroska")==0)) {
  47. + if(ssdpdevice_servermatch(&GlobalSsdpDevices, info->foreign_ip_addr.s_addr, "samsung")) {
  48. +// printf("Req from Samsung device : %s\n", finfo.content_type);
  49. + // change is made in two steps : free the previous string, malloc a new one
  50. + if((newtype= (char *) strdup("video/x-mkv"))) {
  51. + free(finfo.content_type);
  52. + finfo.content_type = newtype;
  53. + }
  54. + }
  55. + }
  56. +
  57. if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
  58. //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
  59. //Transfer-Encoding: chunked
  60. @@ -1800,7 +1815,7 @@
  61. //Process request should create the different kind of header depending on the
  62. //the type of request.
  63. ret =
  64. - process_request( req, &rtype, &headers, &filename, &xmldoc,
  65. + process_request( req, info, &rtype, &headers, &filename, &xmldoc,
  66. &RespInstr, &Fp);
  67. if( ret != UPNP_E_SUCCESS ) {
  68. // send error code
  69. --- a/tombupnp/upnp/src/genlib/net/uri/uri.c
  70. +++ b/tombupnp/upnp/src/genlib/net/uri/uri.c
  71. @@ -1042,7 +1042,8 @@
  72. out->path_type = REL_PATH;
  73. }
  74. - if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
  75. + //parse hostport only if scheme was found
  76. + if( ( begin_hostport > 0 ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
  77. && ( in[begin_hostport + 1] == '/' ) ) {
  78. begin_hostport += 2;
  79. @@ -1059,6 +1060,12 @@
  80. out->hostport.text.size = 0;
  81. out->hostport.text.buff = 0;
  82. begin_path = begin_hostport;
  83. +
  84. + //remove excessive leading slashes (fix for Samsung Smart TV 2012)
  85. + while( ( ( begin_path + 1 ) < max ) && ( in[begin_path] == '/' ) && ( in[begin_path + 1] == '/') ) {
  86. + begin_path++;
  87. + }
  88. +
  89. }
  90. begin_fragment =
  91. --- a/tombupnp/upnp/src/inc/ssdplib.h
  92. +++ b/tombupnp/upnp/src/inc/ssdplib.h
  93. @@ -161,9 +161,22 @@
  94. struct sockaddr_in dest_addr;
  95. } ssdp_thread_data;
  96. +typedef struct
  97. +{
  98. + ithread_mutex_t mutex;
  99. + LinkedList deviceslist;
  100. +} ssdpdevices_t;
  101. +
  102. +typedef struct
  103. +{
  104. + uint32_t s_addr;
  105. + char *serverdesc;
  106. +} ssdp_device_t;
  107. /* globals */
  108. +extern ssdpdevices_t GlobalSsdpDevices;
  109. +
  110. CLIENTONLY(extern SOCKET gSsdpReqSocket;);
  111. typedef int (*ParserFun)(char *, Event *);
  112. @@ -174,6 +187,64 @@
  113. //int AnalyzeCommand(char * szCommand, Event * Evt);
  114. /************************************************************************
  115. +* Function : ssdpdevices_free
  116. +*
  117. +* Parameters :
  118. +* void *d ;
  119. +*
  120. +* Description : Free memory allocated for each SSDP Device
  121. +*
  122. +* Return : void ;
  123. +*
  124. +* Note :
  125. +************************************************************************/
  126. +void ssdpdevice_free( void *d );
  127. +
  128. +/************************************************************************
  129. +* Function : ssdpdevice_compare
  130. +*
  131. +* Parameters :
  132. +* void* param1 ;
  133. +* void* param2 ;
  134. +*
  135. +* Description : Compare two SSDP devices by their ip address
  136. +*
  137. +* Return : int ;
  138. +*
  139. +* Note :
  140. +************************************************************************/
  141. +int ssdpdevice_compare( void *param1, void *param2 );
  142. +
  143. +/************************************************************************
  144. +* Function : ssdpdevices_init
  145. +*
  146. +* Parameters :
  147. +* INOUT ssdpdevices_t* s ; Array of SSDP Devices
  148. +*
  149. +* Description : Initialize and allocate memory for the array of SSDP devices
  150. +*
  151. +* Return : void ;
  152. +*
  153. +* Note :
  154. +************************************************************************/
  155. +
  156. +void ssdpdevices_init(ssdpdevices_t* s);
  157. +
  158. +/************************************************************************
  159. +* Function : ssdpdevices_destroy
  160. +*
  161. +* Parameters :
  162. +* INOUT ssdpdevices_t* msg ; Array of SSDP Devices
  163. +*
  164. +* Description : Free memory allocated for the Array of SSDP Devices
  165. +*
  166. +* Return : void ;
  167. +*
  168. +* Note :
  169. +************************************************************************/
  170. +void ssdpdevices_destroy( ssdpdevices_t *s );
  171. +
  172. +/************************************************************************
  173. * Function : Make_Socket_NoBlocking
  174. *
  175. * Parameters:
  176. --- a/tombupnp/upnp/src/ssdp/ssdp_server.c
  177. +++ b/tombupnp/upnp/src/ssdp/ssdp_server.c
  178. @@ -52,8 +52,231 @@
  179. #include "unixutil.h"
  180. #endif
  181. +#include <regex.h>
  182. +
  183. #define MAX_TIME_TOREAD 45
  184. +// global containing the array of devices
  185. +ssdpdevices_t GlobalSsdpDevices;
  186. +
  187. +/************************************************************************
  188. +* Function : ssdpdevices_free
  189. +*
  190. +* Parameters :
  191. +* void *msg ;
  192. +*
  193. +* Description : Free memory allocated for each SSDP Device
  194. +*
  195. +* Return : void ;
  196. +*
  197. +* Note :
  198. +************************************************************************/
  199. +void
  200. +ssdpdevice_free( void *d )
  201. +{
  202. + ssdp_device_t *sd = ( ssdp_device_t * ) d;
  203. +
  204. + free(sd->serverdesc);
  205. +
  206. + free( sd );
  207. +}
  208. +
  209. +/************************************************************************
  210. +* Function : ssdpdevice_compare
  211. +*
  212. +* Parameters :
  213. +* void* param1 ;
  214. +* void* param2 ;
  215. +*
  216. +* Description : Compare two SSDP devices by their ip address
  217. +*
  218. +* Return : int ;
  219. +*
  220. +* Note :
  221. +************************************************************************/
  222. +int
  223. +ssdpdevice_compare( void *param1,
  224. + void *param2 )
  225. +{
  226. + assert( param1 != NULL );
  227. + assert( param2 != NULL );
  228. +
  229. + return ( ( ssdp_device_t * ) param1 )->s_addr ==
  230. + ( ( ssdp_device_t * ) param2 )->s_addr;
  231. +}
  232. +
  233. +/************************************************************************
  234. +* Function : ssdpdevices_init
  235. +*
  236. +* Parameters :
  237. +* INOUT ssdpdevices_t* s ; Array of SSDP Devices
  238. +*
  239. +* Description : Initialize and allocate memory for the array of SSDP devices
  240. +*
  241. +* Return : void ;
  242. +*
  243. +* Note :
  244. +************************************************************************/
  245. +
  246. +void ssdpdevices_init(ssdpdevices_t* s) {
  247. + ithread_mutex_init( &s->mutex, NULL );
  248. + ListInit( &s->deviceslist, ssdpdevice_compare, ssdpdevice_free );
  249. +}
  250. +
  251. +/************************************************************************
  252. +* Function : ssdpdevices_destroy
  253. +*
  254. +* Parameters :
  255. +* INOUT ssdpdevices_t* s ; Array of SSDP Devices
  256. +*
  257. +* Description : Free memory allocated for the Array of SSDP Devices
  258. +*
  259. +* Return : void ;
  260. +*
  261. +* Note :
  262. +************************************************************************/
  263. +void
  264. +ssdpdevices_destroy( ssdpdevices_t *s )
  265. +{
  266. + int ret;
  267. +
  268. + assert( s != NULL );
  269. +
  270. + ithread_mutex_lock( &s->mutex );
  271. + ListDestroy( &s->deviceslist, 1 );
  272. + ithread_mutex_unlock( &s->mutex );
  273. +
  274. + ret = ithread_mutex_destroy( &s->mutex );
  275. + assert( ret == 0 );
  276. +
  277. +}
  278. +
  279. +/************************************************************************
  280. +* Function : create_device_node
  281. +*
  282. +* Parameters :
  283. +* IN uint32_t *ip4addr; IP Address
  284. +* IN membuffer *mbuf; Server descripton
  285. +*
  286. +* Description : Create a device structure and fill it with ip & description
  287. +*
  288. +* Return : ssdp_device_t *
  289. +*
  290. +* Note :
  291. +************************************************************************/
  292. +
  293. +ssdp_device_t *create_device(uint32_t ipaddr, membuffer *mbuf) {
  294. + ssdp_device_t *newd;
  295. + if( (newd = (ssdp_device_t *) malloc(sizeof(ssdp_device_t)))) {
  296. + if( ( newd->serverdesc = str_alloc ( mbuf->buf, mbuf->length) ) ) {
  297. + newd->s_addr = ipaddr;
  298. + return(newd);
  299. + }
  300. + free(newd);
  301. + }
  302. + return(NULL);
  303. +}
  304. +
  305. +
  306. +/************************************************************************
  307. +* Function : ssdpdevices_updatelist
  308. +*
  309. +* Parameters :
  310. +* INOUT ssdpdevices_t* s ; Array of SSDP Devices
  311. +* IN uint32_t *ip4addr; IP Address
  312. +* IN char *serverstr; Server descripton
  313. +*
  314. +* Description : Insert or update the list with given device
  315. +*
  316. +* Return : void ;
  317. +*
  318. +* Note :
  319. +************************************************************************/
  320. +void
  321. +ssdpdevices_updatelist( ssdpdevices_t *s, uint32_t ip4addr, membuffer *serverstr)
  322. +{
  323. + assert( s != NULL );
  324. + assert( ip4addr != 0 );
  325. + assert( serverstr != NULL );
  326. +
  327. + int found = 0;
  328. +
  329. + // Loop through each existing device
  330. + ithread_mutex_lock( &s->mutex );
  331. + LinkedList *l = &s->deviceslist;
  332. + ListNode *temp = NULL;
  333. + ssdp_device_t *d,*newd;
  334. + for (temp = ListHead(l);temp!=NULL;temp = ListNext(l,temp))
  335. + {
  336. + d=(ssdp_device_t *)temp->item;
  337. + if(d->s_addr == ip4addr) {
  338. + found = 1;
  339. + break;
  340. + }
  341. + }
  342. +
  343. + // Add the entry if necessary
  344. + if(!found) {
  345. + if( ( newd = create_device(ip4addr, serverstr))) {
  346. + ListAddTail( l, newd);
  347. + }
  348. + }
  349. + ithread_mutex_unlock( &s->mutex );
  350. +
  351. +}
  352. +
  353. +/************************************************************************
  354. +* Function : ssdpdevice_descmatch
  355. +*
  356. +* Parameters :
  357. +* IN ssdpdevices_t* s ; Array of SSDP Devices
  358. +* IN uint32_t ipaddr; Ip addres to check
  359. +* IN char *regexp; Regex to match
  360. +*
  361. +* Description : Check whether the device's description matches the given regex
  362. +*
  363. +* Return : int (1 = match, else no match)
  364. +*
  365. +* Note :
  366. +************************************************************************/
  367. +int
  368. +ssdpdevice_servermatch( ssdpdevices_t *s, uint32_t ip4addr, char *regex)
  369. +{
  370. + assert( s != NULL );
  371. + assert( ip4addr != 0 );
  372. + assert( regex != NULL );
  373. +
  374. + int ret = 0;
  375. + regex_t reg;
  376. +
  377. + if( regcomp(&reg, regex, REG_EXTENDED | REG_NOSUB | REG_ICASE) != 0) {
  378. + printf("Invalid regex : %s\n", regex);
  379. + return(0);
  380. + }
  381. +
  382. + // Loop through each existing device
  383. + ithread_mutex_lock( &s->mutex );
  384. + LinkedList *l = &s->deviceslist;
  385. + ListNode *temp = NULL;
  386. + ssdp_device_t *d;
  387. + for (temp = ListHead(l);temp!=NULL;temp = ListNext(l,temp))
  388. + {
  389. + d=(ssdp_device_t *)temp->item;
  390. + if(d->s_addr == ip4addr) {
  391. + // We found the ip addr, let's check if the desc contains the searched string
  392. + if(regexec(&reg, d->serverdesc, 0, NULL, 0) == 0) {
  393. + ret=1;
  394. + }
  395. + break;
  396. + }
  397. + }
  398. +
  399. + ithread_mutex_unlock( &s->mutex );
  400. + return(ret);
  401. +}
  402. +
  403. +
  404. +
  405. CLIENTONLY( SOCKET gSsdpReqSocket = 0;
  406. )
  407. @@ -756,6 +979,24 @@
  408. if( !valid_ssdp_msg( &parser->msg ) ) {
  409. goto error_handler;
  410. }
  411. +
  412. + // update liste of devices for each NOTIFY received
  413. +
  414. + if ( parser->msg.method == HTTPMETHOD_NOTIFY ) {
  415. +// printf( "SSDP recvd code NOTIFY = %d from %s\n", parser->msg.method, inet_ntoa(data->dest_addr.sin_addr));
  416. + LinkedList *g=&parser->msg.headers;
  417. + ListNode *temp = NULL;
  418. + http_header_t *h;
  419. + for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp))
  420. + {
  421. + h=(http_header_t *)temp->item;
  422. + if(strncasecmp(h->name.buf, "SERVER", h->name.length) == 0) {
  423. + ssdpdevices_updatelist(&GlobalSsdpDevices, data->dest_addr.sin_addr.s_addr, &h->value);
  424. + }
  425. + }
  426. +
  427. + }
  428. +
  429. return 0; //////// done; thread will free 'data'
  430. error_handler: