ssdplib.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. #ifndef SSDPLIB_H
  2. #define SSDPLIB_H
  3. /**************************************************************************
  4. *
  5. * Copyright (c) 2000-2003 Intel Corporation
  6. * All rights reserved.
  7. * Copyright (C) 2011-2012 France Telecom All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are met:
  11. *
  12. * - Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. * - Redistributions in binary form must reproduce the above copyright notice,
  15. * this list of conditions and the following disclaimer in the documentation
  16. * and/or other materials provided with the distribution.
  17. * - Neither name of Intel Corporation nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
  25. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  29. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. *
  33. **************************************************************************/
  34. /*!
  35. * \defgroup SSDPlib SSDP Library
  36. *
  37. * @{
  38. *
  39. * \file
  40. */
  41. #include "httpparser.h"
  42. #include "httpreadwrite.h"
  43. #include "miniserver.h"
  44. #include "UpnpInet.h"
  45. #include <sys/types.h>
  46. #include <signal.h>
  47. #include <setjmp.h>
  48. #include <errno.h>
  49. #ifdef WIN32
  50. #else /* WIN32 */
  51. #include <syslog.h>
  52. #ifndef __APPLE__
  53. #include <netinet/in_systm.h>
  54. #include <netinet/ip.h>
  55. #include <netinet/ip_icmp.h>
  56. #endif /* __APPLE__ */
  57. #include <sys/time.h>
  58. #endif /* WIN32 */
  59. /*! Enumeration to define all different types of ssdp searches */
  60. typedef enum SsdpSearchType {
  61. /*! Unknown search command. */
  62. SSDP_SERROR = -1,
  63. SSDP_ALL,
  64. SSDP_ROOTDEVICE,
  65. SSDP_DEVICEUDN,
  66. SSDP_DEVICETYPE,
  67. SSDP_SERVICE
  68. } SType;
  69. #define BUFSIZE (size_t)2500
  70. #define SSDP_IP "239.255.255.250"
  71. #define SSDP_IPV6_LINKLOCAL "FF02::C"
  72. #define SSDP_IPV6_SITELOCAL "FF05::C"
  73. #define SSDP_PORT 1900
  74. #define NUM_TRY 3
  75. #define THREAD_LIMIT 50
  76. #define COMMAND_LEN 300
  77. /*! can be overwritten by configure CFLAGS argument. */
  78. #ifndef X_USER_AGENT
  79. /*! @name X_USER_AGENT
  80. * The {\tt X_USER_AGENT} constant specifies the value of the X-User-Agent:
  81. * HTTP header. The value "redsonic" is needed for the DSM-320. See
  82. * https://sourceforge.net/forum/message.php?msg_id=3166856 for more
  83. * information
  84. */
  85. #define X_USER_AGENT "redsonic"
  86. #endif
  87. /*! Error codes. */
  88. #define NO_ERROR_FOUND 0
  89. #define E_REQUEST_INVALID -3
  90. #define E_RES_EXPIRED -4
  91. #define E_MEM_ALLOC -5
  92. #define E_HTTP_SYNTEX -6
  93. #define E_SOCKET -7
  94. #define RQST_TIMEOUT 20
  95. /*! Structure to store the SSDP information */
  96. typedef struct SsdpEventStruct {
  97. enum SsdpSearchType RequestType;
  98. int ErrCode;
  99. int MaxAge;
  100. int Mx;
  101. char UDN[LINE_SIZE];
  102. char DeviceType[LINE_SIZE];
  103. /* NT or ST */
  104. char ServiceType[LINE_SIZE];
  105. char Location[LINE_SIZE];
  106. char HostAddr[LINE_SIZE];
  107. char Os[LINE_SIZE];
  108. char Ext[LINE_SIZE];
  109. char Date[LINE_SIZE];
  110. struct sockaddr *DestAddr;
  111. void * Cookie;
  112. } SsdpEvent;
  113. typedef void (* SsdpFunPtr)(SsdpEvent *);
  114. typedef struct TData
  115. {
  116. int Mx;
  117. void * Cookie;
  118. char * Data;
  119. struct sockaddr_storage DestAddr;
  120. } ThreadData;
  121. typedef struct ssdpsearchreply
  122. {
  123. int MaxAge;
  124. UpnpDevice_Handle handle;
  125. struct sockaddr_storage dest_addr;
  126. SsdpEvent event;
  127. } SsdpSearchReply;
  128. typedef struct ssdpsearcharg
  129. {
  130. int timeoutEventId;
  131. char * searchTarget;
  132. void *cookie;
  133. enum SsdpSearchType requestType;
  134. } SsdpSearchArg;
  135. typedef struct
  136. {
  137. http_parser_t parser;
  138. struct sockaddr_storage dest_addr;
  139. } ssdp_thread_data;
  140. /* globals */
  141. #ifdef INCLUDE_CLIENT_APIS
  142. extern SOCKET gSsdpReqSocket4;
  143. #ifdef UPNP_ENABLE_IPV6
  144. extern SOCKET gSsdpReqSocket6;
  145. #endif /* UPNP_ENABLE_IPV6 */
  146. #endif /* INCLUDE_CLIENT_APIS */
  147. typedef int (*ParserFun)(char *, SsdpEvent *);
  148. /*!
  149. * \name SSDP Server Functions
  150. *
  151. * @{
  152. */
  153. /*!
  154. * \brief Sends SSDP advertisements, replies and shutdown messages.
  155. *
  156. * \return UPNP_E_SUCCESS if successful else appropriate error.
  157. */
  158. int AdvertiseAndReply(
  159. /* [in] -1 = Send shutdown, 0 = send reply, 1 = Send Advertisement. */
  160. int AdFlag,
  161. /* [in] Device handle. */
  162. UpnpDevice_Handle Hnd,
  163. /* [in] Search type for sending replies. */
  164. enum SsdpSearchType SearchType,
  165. /* [in] Destination address. */
  166. struct sockaddr *DestAddr,
  167. /* [in] Device type. */
  168. char *DeviceType,
  169. /* [in] Device UDN. */
  170. char *DeviceUDN,
  171. /* [in] Service type. */
  172. char *ServiceType,
  173. /* [in] Advertisement age. */
  174. int Exp);
  175. /*!
  176. * \brief Fills the fields of the event structure like DeviceType, Device UDN
  177. * and Service Type.
  178. *
  179. * \return 0 if successful else -1.
  180. */
  181. int unique_service_name(
  182. /* [in] Service Name string. */
  183. char *cmd,
  184. /* [out] The SSDP event structure partially filled by all the
  185. * function. */
  186. SsdpEvent *Evt);
  187. /*!
  188. * \brief This function figures out the type of the SSDP search in the in the
  189. * request.
  190. *
  191. * \return enum SsdpSearchType. Returns appropriate search type,
  192. * else returns SSDP_ERROR
  193. */
  194. enum SsdpSearchType ssdp_request_type1(
  195. /* [in] command came in the ssdp request. */
  196. char *cmd);
  197. /*!
  198. * \brief Starts filling the SSDP event structure based upon the
  199. * request received.
  200. *
  201. * \return 0 on success; -1 on error.
  202. */
  203. int ssdp_request_type(
  204. /* [in] command came in the ssdp request. */
  205. char *cmd,
  206. /* [out] The event structure partially filled by this function. */
  207. SsdpEvent *Evt);
  208. /*!
  209. * \brief This function reads the data from the ssdp socket.
  210. */
  211. void readFromSSDPSocket(
  212. /* [in] SSDP socket. */
  213. SOCKET socket);
  214. /*!
  215. * \brief Creates the IPv4 and IPv6 ssdp sockets required by the
  216. * control point and device operation.
  217. *
  218. * \return UPNP_E_SUCCESS if successful else returns appropriate error.
  219. */
  220. int get_ssdp_sockets(
  221. /* [out] Array of SSDP sockets. */
  222. MiniServerSockArray *out);
  223. /* @} SSDP Server Functions */
  224. /*!
  225. * \name SSDP Control Point Functions
  226. *
  227. * @{
  228. */
  229. /*!
  230. * \brief This function handles the ssdp messages from the devices. These
  231. * messages includes the search replies, advertisement of device coming alive
  232. * and bye byes.
  233. */
  234. void ssdp_handle_ctrlpt_msg(
  235. /* [in] SSDP message from the device. */
  236. http_message_t *hmsg,
  237. /* [in] Address of the device. */
  238. struct sockaddr_storage *dest_addr,
  239. /* [in] timeout kept by the control point while sending search message.
  240. * Only in search reply. */
  241. int timeout,
  242. /* [in] Cookie stored by the control point application. This cookie will
  243. * be returned to the control point in the callback.
  244. * Only in search reply. */
  245. void *cookie);
  246. /*!
  247. * \brief Creates and send the search request for a specific URL.
  248. *
  249. * This function implements the search request of the discovery phase.
  250. * A M-SEARCH request is sent on the SSDP channel for both IPv4 and
  251. * IPv6 addresses. The search target(ST) is required and must be one of
  252. * the following:
  253. * \li "ssdp:all" : Search for all devices and services.
  254. * \li "ssdp:rootdevice" : Search for root devices only.
  255. * \li "uuid:<device-uuid>" : Search for a particular device.
  256. * \li "urn:schemas-upnp-org:device:<deviceType:v>"
  257. * \li "urn:schemas-upnp-org:service:<serviceType:v>"
  258. * \li "urn:<domain-name>:device:<deviceType:v>"
  259. * \li "urn:<domain-name>:service:<serviceType:v>"
  260. *
  261. * \return 1 if successful else appropriate error.
  262. */
  263. int SearchByTarget(
  264. /* [in] Number of seconds to wait, to collect all the responses. */
  265. int Mx,
  266. /* [in] Search target. */
  267. char *St,
  268. /* [in] Cookie provided by control point application. This cokie will
  269. * be returned to application in the callback. */
  270. void *Cookie);
  271. /* @} SSDP Control Point Functions */
  272. /*!
  273. * \name SSDP Device Functions
  274. *
  275. * @{
  276. */
  277. /*!
  278. * \brief Wrapper function to reply the search request coming from the
  279. * control point.
  280. *
  281. * \return always return NULL
  282. */
  283. void *advertiseAndReplyThread(
  284. /* [in] Structure containing the search request. */
  285. void *data);
  286. /*!
  287. * \brief Handles the search request. It does the sanity checks of the
  288. * request and then schedules a thread to send a random time reply
  289. * (random within maximum time given by the control point to reply).
  290. */
  291. #ifdef INCLUDE_DEVICE_APIS
  292. void ssdp_handle_device_request(
  293. /* [in] . */
  294. http_message_t *hmsg,
  295. /* [in] . */
  296. struct sockaddr_storage *dest_addr);
  297. #else /* INCLUDE_DEVICE_APIS */
  298. static UPNP_INLINE void ssdp_handle_device_request(
  299. /* [in] . */
  300. http_message_t *hmsg,
  301. /* [in] . */
  302. struct sockaddr_storage *dest_addr) {}
  303. #endif /* INCLUDE_DEVICE_APIS */
  304. /*!
  305. * \brief Creates the device advertisement request based on the input
  306. * parameter, and send it to the multicast channel.
  307. *
  308. * \return UPNP_E_SUCCESS if successful else appropriate error.
  309. */
  310. int DeviceAdvertisement(
  311. /* [in] type of the device. */
  312. char *DevType,
  313. /* [in] flag to indicate if the device is root device. */
  314. int RootDev,
  315. /* [in] UDN. */
  316. char *Udn,
  317. /* [in] Location URL. */
  318. char *Location,
  319. /* [in] Service duration in sec. */
  320. int Duration,
  321. /* [in] Device address family. */
  322. int AddressFamily,
  323. /* [in] PowerState as defined by UPnP Low Power. */
  324. int PowerState,
  325. /* [in] SleepPeriod as defined by UPnP Low Power. */
  326. int SleepPeriod,
  327. /* [in] RegistrationState as defined by UPnP Low Power. */
  328. int RegistrationState);
  329. /*!
  330. * \brief Creates the reply packet based on the input parameter, and send it
  331. * to the client addesss given in its input parameter DestAddr.
  332. *
  333. * \return UPNP_E_SUCCESS if successful else appropriate error.
  334. */
  335. int SendReply(
  336. /* [in] destination IP address. */
  337. struct sockaddr *DestAddr,
  338. /* [in] Device type. */
  339. char *DevType,
  340. /* [in] 1 means root device 0 means embedded device. */
  341. int RootDev,
  342. /* [in] Device UDN. */
  343. char *Udn,
  344. /* [in] Location of Device description document. */
  345. char *Location,
  346. /* [in] Life time of this device. */
  347. int Duration,
  348. /* [in] . */
  349. int ByType,
  350. /* [in] PowerState as defined by UPnP Low Power. */
  351. int PowerState,
  352. /* [in] SleepPeriod as defined by UPnP Low Power. */
  353. int SleepPeriod,
  354. /* [in] RegistrationState as defined by UPnP Low Power. */
  355. int RegistrationState);
  356. /*!
  357. * \brief Creates the reply packet based on the input parameter, and send it
  358. * to the client address given in its input parameter DestAddr.
  359. *
  360. * \return UPNP_E_SUCCESS if successful else appropriate error.
  361. */
  362. int DeviceReply(
  363. /* [in] destination IP address. */
  364. struct sockaddr *DestAddr,
  365. /* [in] Device type. */
  366. char *DevType,
  367. /* [in] 1 means root device 0 means embedded device. */
  368. int RootDev,
  369. /* [in] Device UDN. */
  370. char *Udn,
  371. /* [in] Location of Device description document. */
  372. char *Location,
  373. /* [in] Life time of this device. */
  374. int Duration,
  375. /* [in] PowerState as defined by UPnP Low Power. */
  376. int PowerState,
  377. /* [in] SleepPeriod as defined by UPnP Low Power. */
  378. int SleepPeriod,
  379. /* [in] RegistrationState as defined by UPnP Low Power. */
  380. int RegistrationState);
  381. /*!
  382. * \brief Creates the advertisement packet based on the input parameter,
  383. * and send it to the multicast channel.
  384. *
  385. * \return UPNP_E_SUCCESS if successful else appropriate error.
  386. */
  387. int ServiceAdvertisement(
  388. /* [in] Device UDN. */
  389. char *Udn,
  390. /* [in] Service Type. */
  391. char *ServType,
  392. /* [in] Location of Device description document. */
  393. char *Location,
  394. /* [in] Life time of this device. */
  395. int Duration,
  396. /* [in] Device address family. */
  397. int AddressFamily,
  398. /* [in] PowerState as defined by UPnP Low Power. */
  399. int PowerState,
  400. /* [in] SleepPeriod as defined by UPnP Low Power. */
  401. int SleepPeriod,
  402. /* [in] RegistrationState as defined by UPnP Low Power. */
  403. int RegistrationState);
  404. /*!
  405. * \brief Creates the advertisement packet based on the input parameter,
  406. * and send it to the multicast channel.
  407. *
  408. * \return UPNP_E_SUCCESS if successful else appropriate error.
  409. */
  410. int ServiceReply(
  411. /* [in] . */
  412. struct sockaddr *DestAddr,
  413. /* [in] Service Type. */
  414. char *ServType,
  415. /* [in] Device UDN. */
  416. char *Udn,
  417. /* [in] Location of Device description document. */
  418. char *Location,
  419. /* [in] Life time of this device. */
  420. int Duration,
  421. /* [in] PowerState as defined by UPnP Low Power. */
  422. int PowerState,
  423. /* [in] SleepPeriod as defined by UPnP Low Power. */
  424. int SleepPeriod,
  425. /* [in] RegistrationState as defined by UPnP Low Power. */
  426. int RegistrationState);
  427. /*!
  428. * \brief Creates a HTTP service shutdown request packet and sends it to the
  429. * multicast channel through RequestHandler.
  430. *
  431. * \return UPNP_E_SUCCESS if successful else appropriate error.
  432. */
  433. int ServiceShutdown(
  434. /* [in] Device UDN. */
  435. char *Udn,
  436. /* [in] Service Type. */
  437. char *ServType,
  438. /* [in] Location of Device description document. */
  439. char *Location,
  440. /* [in] Service duration in sec. */
  441. int Duration,
  442. /* [in] Device address family. */
  443. int AddressFamily,
  444. /* [in] PowerState as defined by UPnP Low Power. */
  445. int PowerState,
  446. /* [in] SleepPeriod as defined by UPnP Low Power. */
  447. int SleepPeriod,
  448. /* [in] RegistrationState as defined by UPnP Low Power. */
  449. int RegistrationState);
  450. /*!
  451. * \brief Creates a HTTP device shutdown request packet and send it to the
  452. * multicast channel through RequestHandler.
  453. *
  454. * \return UPNP_E_SUCCESS if successful else appropriate error.
  455. */
  456. int DeviceShutdown(
  457. /* [in] Device Type. */
  458. char *DevType,
  459. /* [in] 1 means root device. */
  460. int RootDev,
  461. /* [in] Device UDN. */
  462. char *Udn,
  463. /* [in] Location URL. */
  464. char *Location,
  465. /* [in] Device duration in sec. */
  466. int Duration,
  467. /* [in] Device address family. */
  468. int AddressFamily,
  469. /* [in] PowerState as defined by UPnP Low Power. */
  470. int PowerState,
  471. /* [in] SleepPeriod as defined by UPnP Low Power. */
  472. int SleepPeriod,
  473. /* [in] RegistrationState as defined by UPnP Low Power. */
  474. int RegistrationState);
  475. /* @} SSDP Device Functions */
  476. /* @} SSDPlib SSDP Library */
  477. #endif /* SSDPLIB_H */