Owl Positioning System: a Wi-Fi-based, infrastructure-centred indoor positioning system. http://owlps.pu-pm.univ-fcomte.fr/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

owlps.h 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * This file is part of the Owl Positioning System (OwlPS) project.
  3. * It is subject to the copyright notice and license terms in the
  4. * COPYRIGHT.t2t file found in the top-level directory of this
  5. * distribution and at
  6. * https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
  7. * No part of the OwlPS Project, including this file, may be copied,
  8. * modified, propagated, or distributed except according to the terms
  9. * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
  10. * distributed along with this file, either separately or by replacing
  11. * this notice by the COPYRIGHT.t2t file's contents.
  12. */
  13. /**
  14. * @file owlps.h
  15. * @brief OwlPS library
  16. *
  17. * libowlps is the library containing the code shared by most of the
  18. * OwlPS programs.
  19. */
  20. #ifndef _LIBOWLPS_H_
  21. #define _LIBOWLPS_H_
  22. #ifdef __cplusplus
  23. # include <cstdint>
  24. #else // __cplusplus
  25. # include <stdint.h>
  26. #endif // __cplusplus
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif // __cplusplus
  30. #include <stdbool.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <net/if.h>
  34. #include <netinet/in.h>
  35. #include <netinet/if_ether.h>
  36. /** @name Network ports */
  37. //@{
  38. /// Port on which the positioning and calibration requests are sent by
  39. /// the mobiles (or the listeners for autocalibration requests)
  40. #define OWL_DEFAULT_REQUEST_PORT 9900
  41. /// Port on which listeners and aggregator communicate
  42. #define OWL_DEFAULT_LISTENER_PORT 9901
  43. /// Port on which Aggregator and Positioner communicate
  44. #define OWL_DEFAULT_AGGREGATION_PORT 9902
  45. /// Port on which the aggregator listens for hello messages from the
  46. /// listeners
  47. #define OWL_DEFAULT_AUTOCALIBRATION_HELLO_PORT 9903
  48. /// Port on which the listeners listen for orders from the aggregator
  49. #define OWL_DEFAULT_AUTOCALIBRATION_ORDER_PORT 9904
  50. /// Port on which the mobile listens for its position
  51. #define OWL_DEFAULT_RESULT_PORT 9910
  52. //@}
  53. /** @name Miscellaneous informations */
  54. //@{
  55. #define OWL_LATEST_AGGREGATION_CSV_FORMAT 1
  56. //@}
  57. /// Directions
  58. enum owl_directions
  59. {
  60. owl_north = 1, ///< North direction
  61. owl_east, ///< East direction
  62. owl_south, ///< South direction
  63. owl_west ///< West direction
  64. } ;
  65. /// First [direction](@ref owl_direction)
  66. #define OWL_DIRECTION_MIN 1
  67. /// Last [direction](@ref owl_direction)
  68. #define OWL_DIRECTION_MAX 4
  69. /// Direction type
  70. typedef uint8_t owl_direction ;
  71. /// Timestamp structure
  72. /**
  73. * This timestamp structure is a clone of `struct timespec` (from
  74. * `time.h`), but with fixed-size fields.
  75. */
  76. struct _owl_timestamp
  77. {
  78. uint32_t tv_sec ; ///< Seconds
  79. uint32_t tv_nsec ; ///< Nanoseconds
  80. } ;
  81. /// Timestamp type
  82. typedef struct _owl_timestamp owl_timestamp ;
  83. /** @name String lengths */
  84. //@{
  85. /// Length of a owl_timestamp when converted to string
  86. /**
  87. * 22 = 10 digits, '.', 10 digits, '\0'
  88. */
  89. #define OWL_TIMESTAMP_STRLEN 22
  90. //@}
  91. /// Message sent by the Listener to the Aggregator
  92. /**
  93. * Message sent by the Listener to the Aggregator for each captured
  94. * request.
  95. *
  96. * TODO: This structure's size could be reduced from 60 to 52 byte by reordering
  97. * the fields by size.
  98. */
  99. struct _owl_captured_request
  100. {
  101. uint8_t type ; ///< Type of the captured request
  102. unsigned char __pad0; // 1 byte alignment
  103. uint16_t nb_packets ; ///< Number of packets for this request
  104. uint16_t packet_id ; ///< Number of the current packet
  105. uint8_t cp_mac_addr_bytes[ETHER_ADDR_LEN] ; ///< MAC of the listener
  106. uint8_t mobile_mac_addr_bytes[ETHER_ADDR_LEN] ; ///< MAC of the mobile
  107. uint8_t mobile_ip_addr_bytes[4] ; ///< IP of the mobile
  108. unsigned char __pad1[2]; // 2 bytes alignment
  109. owl_timestamp request_time ; ///< Timestamp on the mobile
  110. owl_timestamp capture_time ; ///< Timestamp of arrival on the listener
  111. int8_t ss_dbm ; ///< Signal strength measured by the listener (dBm)
  112. unsigned char __pad2[3]; // 3 bytes alignment
  113. /* Calibration data */
  114. float x_position ; ///< X coordinate
  115. float y_position ; ///< Y coordinate
  116. float z_position ; ///< Z coordinate
  117. owl_direction direction ; ///< Orientation of the mobile
  118. unsigned char __pad3[3]; // 3 bytes alignment
  119. } ;
  120. /// Captured request type
  121. typedef struct _owl_captured_request owl_captured_request ;
  122. /// Message sent by the Aggregator to the Positioner (request's data)
  123. /**
  124. * Message sent by the Aggregator to the Positioner containing
  125. * the main data of a request.
  126. *
  127. * TODO: This structure's size could be reduced from 44 to 36 bytes by
  128. * reordering the fields by size.
  129. */
  130. struct _owl_request
  131. {
  132. uint8_t type ; ///< Type of the request
  133. unsigned char __pad0; // 1 byte alignment
  134. uint16_t nb_packets ; ///< Number of packets sent for this request
  135. uint8_t mobile_mac_addr_bytes[ETHER_ADDR_LEN] ; ///< MAC of the mobile
  136. uint8_t mobile_ip_addr_bytes[4] ; ///< IP of the mobile
  137. unsigned char __pad1[2]; // 2 bytes alignment
  138. owl_timestamp request_time ; ///< Timestamp on the mobile
  139. uint16_t nb_info ; ///< Number of owl_request_info
  140. unsigned char __pad2[2]; // 2 bytes alignment
  141. /* Calibration data */
  142. float x_position ; ///< X coordinate
  143. float y_position ; ///< Y coordinate
  144. float z_position ; ///< Z coordinate
  145. owl_direction direction ; ///< Orientation of the mobile
  146. unsigned char __pad3[3]; // 3 bytes alignment
  147. } ;
  148. /// Aggregated request type
  149. typedef struct _owl_request owl_request ;
  150. /// Message sent by the Aggregator to the Positioner (signal strength)
  151. /**
  152. * Message sent by the Aggregator to the Positioner refering to
  153. * a request, indicating that a CP received the request with a given
  154. * signal strength.
  155. */
  156. struct _owl_request_info
  157. {
  158. uint16_t packet_id ; ///< Number of the current packet
  159. uint8_t cp_mac_addr_bytes[ETHER_ADDR_LEN] ; ///< MAC of the listener
  160. owl_timestamp capture_time ; ///< Timestamp of arrival on the listener
  161. int8_t ss_dbm ; ///< Signal strength measured by the listener (dBm)
  162. unsigned char __pad0[3]; // 3 bytes alignment
  163. } ;
  164. /// Aggregated request information type
  165. typedef struct _owl_request_info owl_request_info ;
  166. /// *Hello* message sent by the Listener to the Aggregator
  167. /**
  168. * This structure represents a *hello* message sent to the Aggregator by
  169. * each Listener to signal its presence.
  170. */
  171. struct _owl_autocalibration_hello
  172. {
  173. /// MAC address of the Listener
  174. uint8_t cp_mac_addr_bytes[ETHER_ADDR_LEN] ;
  175. } ;
  176. /// *Hello* message type
  177. typedef struct _owl_autocalibration_hello owl_autocalibration_hello ;
  178. /// Message sent to the Listener to order an emission
  179. /**
  180. * This structure represents a message sent by the Aggregator to a
  181. * Listener to order it to send an autocalibration request.
  182. */
  183. struct _owl_autocalibration_order
  184. {
  185. uint8_t order ; ///< Code of the order
  186. } ;
  187. /// Autocalibration order type
  188. typedef struct _owl_autocalibration_order owl_autocalibration_order ;
  189. /** @name Autocalibration order type identifiers */
  190. //@{
  191. #define AUTOCALIBRATION_ORDER_SEND 1
  192. //@}
  193. /** @name Request type identifiers */
  194. //@{
  195. /// "Normal" positioning request
  196. #define OWL_REQUEST_NORMAL 0
  197. /// Calibration request
  198. #define OWL_REQUEST_CALIBRATION 1
  199. /// Autocalibration request
  200. #define OWL_REQUEST_AUTOCALIBRATION 2
  201. /// Generated request (in Positioner)
  202. #define OWL_REQUEST_GENERATED 3
  203. /// Implicit positioning request
  204. #define OWL_REQUEST_IMPLICIT 10
  205. /// Undefined or unknown request type
  206. #define OWL_REQUEST_UNDEFINED 255
  207. //@}
  208. /* Don't forget to update the OWL_IS_REQUEST_TYPE macro below when you
  209. * change something here! */
  210. /** @name Wi-Fi channels' frequencies in MHz */
  211. //@{
  212. #define OWL_80211_MHZ_CHANNEL_1 2412
  213. #define OWL_80211_MHZ_CHANNEL_2 2417
  214. #define OWL_80211_MHZ_CHANNEL_3 2422
  215. #define OWL_80211_MHZ_CHANNEL_4 2427
  216. #define OWL_80211_MHZ_CHANNEL_5 2432
  217. #define OWL_80211_MHZ_CHANNEL_6 2437
  218. #define OWL_80211_MHZ_CHANNEL_7 2442
  219. #define OWL_80211_MHZ_CHANNEL_8 2447
  220. #define OWL_80211_MHZ_CHANNEL_9 2452
  221. #define OWL_80211_MHZ_CHANNEL_10 2457
  222. #define OWL_80211_MHZ_CHANNEL_11 2462
  223. #define OWL_80211_MHZ_CHANNEL_12 2467
  224. #define OWL_80211_MHZ_CHANNEL_13 2472
  225. #define OWL_80211_MHZ_CHANNEL_14 2477
  226. //@}
  227. /** @name Wi-Fi channels' frequencies in Hz */
  228. //@{
  229. #define OWL_80211_HZ_CHANNEL_1 2412000000ul
  230. #define OWL_80211_HZ_CHANNEL_2 2417000000ul
  231. #define OWL_80211_HZ_CHANNEL_3 2422000000ul
  232. #define OWL_80211_HZ_CHANNEL_4 2427000000ul
  233. #define OWL_80211_HZ_CHANNEL_5 2432000000ul
  234. #define OWL_80211_HZ_CHANNEL_6 2437000000ul
  235. #define OWL_80211_HZ_CHANNEL_7 2442000000ul
  236. #define OWL_80211_HZ_CHANNEL_8 2447000000ul
  237. #define OWL_80211_HZ_CHANNEL_9 2452000000ul
  238. #define OWL_80211_HZ_CHANNEL_10 2457000000ul
  239. #define OWL_80211_HZ_CHANNEL_11 2462000000ul
  240. #define OWL_80211_HZ_CHANNEL_12 2467000000ul
  241. #define OWL_80211_HZ_CHANNEL_13 2472000000ul
  242. #define OWL_80211_HZ_CHANNEL_14 2477000000ul
  243. //@}
  244. /** @name String lengths */
  245. //@{
  246. /// Length of a MAC address in string format (including '\0')
  247. #define OWL_ETHER_ADDR_STRLEN 18
  248. /// Maximum length of an algorithm name (including '\0')
  249. #define OWL_ALGORITHM_STRLEN 31
  250. /// Maximum length of an area name (including '\0')
  251. #define OWL_AREA_STRLEN 31
  252. /// Maximum length of a coordinate X, Y or Z (including '\0')
  253. #define OWL_COORDINATE_STRLEN 16
  254. //@}
  255. /* Global variables */
  256. /// Global variable used to handle end of loops
  257. extern bool owl_run ;
  258. /** @name Error codes */
  259. //@{
  260. /// Wrong program invokation (command-line arguments)
  261. #define OWL_ERR_BAD_USAGE 100
  262. /// Error when reading/parsing the configuration file
  263. #define OWL_ERR_CONFIG_FILE 101
  264. /* System */
  265. /// Error when creating a thread
  266. #define OWL_ERR_THREAD_CREATE 110
  267. /// Wrong signal received
  268. #define OWL_ERR_BAD_SIGNAL 111
  269. /* Network communication */
  270. /// Error when creating a socket
  271. #define OWL_ERR_SOCKET_CREATE 120
  272. /// Error when sending a message on a socket
  273. #define OWL_ERR_SOCKET_SEND 121
  274. /// Error when reading from a socket
  275. #define OWL_ERR_SOCKET_RECV 122
  276. /* Network interface / capture */
  277. /// Error when opening the capture interface
  278. #define OWL_ERR_IFACE_PCAP_OPEN 130
  279. /// Error when reading the interface Wi-Fi mode
  280. #define OWL_ERR_IFACE_MODE_GET 131
  281. /// Error when setting the interface Wi-Fi mode
  282. #define OWL_ERR_IFACE_MODE_SET 132
  283. //@}
  284. /* Macros */
  285. /// Converts a bool to the corresponding string
  286. #define OWL_BOOL_TO_STRING(B) ((B) ? "true" : "false")
  287. /// Make sure the given integer is a valid request type
  288. /**
  289. * True if `I` is a valid request type, false otherwise.
  290. * Do *not* pass an incremented number to this macro (e.g. type++ or
  291. * ++type). This shouldn't be a problem with a request type, though.
  292. */
  293. #define OWL_IS_REQUEST_TYPE(I) \
  294. ( (I) == OWL_REQUEST_NORMAL \
  295. || (I) == OWL_REQUEST_CALIBRATION \
  296. || (I) == OWL_REQUEST_AUTOCALIBRATION \
  297. || (I) == OWL_REQUEST_GENERATED \
  298. || (I) == OWL_REQUEST_IMPLICIT \
  299. || (I) == OWL_REQUEST_UNDEFINED)
  300. /* Function headers */
  301. /** @name Miscellaneous */
  302. //@{
  303. /// Converts a MAC address from bytes to string
  304. const char* owl_mac_bytes_to_string(const uint8_t *const mac_binary) ;
  305. /// Converts a MAC address from bytes to string
  306. void owl_mac_bytes_to_string_r(const uint8_t *const mac_binary,
  307. char mac_str[OWL_ETHER_ADDR_STRLEN]) ;
  308. /// Compares two MAC addresses
  309. bool owl_mac_equals(const uint8_t *const mac1,
  310. const uint8_t *const mac2) ;
  311. /// Converts a IEEE 802.11 frequency into a channel number
  312. uint_fast8_t owl_frequency_to_channel(const uint_fast16_t frequency) ;
  313. //@}
  314. /** @name Time */
  315. //@{
  316. /// Sleeps for a given amount of milliseconds
  317. int owl_msleep(uint32_t time_ms) ;
  318. /// Sets the `owl_timestamp` `now` to the current time
  319. int owl_timestamp_now(owl_timestamp *const now) ;
  320. /// Converts a `struct timespec` to an `owl_timestamp`
  321. void owl_timespec_to_timestamp(const struct timespec *const src,
  322. owl_timestamp *const dst) ;
  323. /// Converts a `struct timeval` to an `owl_timestamp`
  324. void owl_timeval_to_timestamp(const struct timeval *const src,
  325. owl_timestamp *const dst) ;
  326. /// Compares two `owl_timestamp`
  327. bool owl_timestamp_equals(const owl_timestamp *const d1,
  328. const owl_timestamp *const d2) ;
  329. /// Converts an `owl_timestamp` date value into milliseconds
  330. uint64_t owl_timestamp_to_ms(const owl_timestamp *const d) ;
  331. /// Converts an `owl_timestamp` date value into a printable string
  332. void owl_timestamp_to_string(const owl_timestamp *const src,
  333. char *const dst) ;
  334. /// Returns the time (in milliseconds) between two dates
  335. uint_fast32_t owl_time_elapsed_ms(const owl_timestamp *const d1,
  336. const owl_timestamp *const d2) ;
  337. /// Computes the time difference between two dates
  338. void owl_time_elapsed(const owl_timestamp *const d1,
  339. const owl_timestamp *const d2,
  340. owl_timestamp *const elapsed) ;
  341. //@}
  342. /** @name Endianness */
  343. //@{
  344. /// Changes the endianness of an `owl_timestamp` from host to network
  345. /// order
  346. void owl_hton_timestamp(owl_timestamp *const d) ;
  347. /// Changes the endianness of an `owl_timestamp` from network to host
  348. /// order
  349. void owl_ntoh_timestamp(owl_timestamp *const d) ;
  350. /// Changes the order of the bytes of a `float`
  351. float owl_swap_float(const float f) ;
  352. //@}
  353. /** @name Endianness-related macros */
  354. //@{
  355. /**
  356. * @def owl_htonf
  357. * @brief Changes the endianness of a `float` from host to network
  358. *
  359. * This macro converts the byte order of a `float` if needed, depending
  360. * on the endianness of the host, to adopt the endianness of the network.
  361. * To actually change the byte order, the owl_swap_float() function is
  362. * used.
  363. *
  364. * @def owl_ntohf
  365. * @brief Changes the endianness of a `float` from network to host
  366. *
  367. * This macro converts the byte order of a `float` encoded with a network
  368. * endianness to adopt the endianness of the host, if the two endianness
  369. * are different.
  370. * To actually change the byte order, the owl_swap_float() function is
  371. * used.
  372. */
  373. //@}
  374. #if __BYTE_ORDER == __BIG_ENDIAN
  375. # define owl_htonf(f) (f)
  376. # define owl_ntohf(f) (f)
  377. #else // __BYTE_ORDER == __BIG_ENDIAN
  378. # if __BYTE_ORDER == __LITTLE_ENDIAN
  379. # define owl_htonf(f) owl_swap_float(f)
  380. # define owl_ntohf(f) owl_swap_float(f)
  381. # else // __BYTE_ORDER == __LITTLE_ENDIAN
  382. # error "This program does not handle strange architectures."
  383. # endif // __BYTE_ORDER == __LITTLE_ENDIAN
  384. #endif // __BYTE_ORDER == __BIG_ENDIAN
  385. /** @name Network */
  386. //@{
  387. /// Opens a UDP transmission socket
  388. int owl_create_udp_trx_socket(const char *const server_address,
  389. const uint_fast16_t server_port,
  390. struct sockaddr *const server_description) ;
  391. /// Opens a UDP reception socket
  392. int owl_create_udp_listening_socket(const uint_fast16_t port) ;
  393. //@}
  394. /** @name Signals */
  395. //@{
  396. /// Generic signal handler for SIGINT
  397. void owl_sigint_handler(const int num) ;
  398. /// Generic signal handler for SIGTERM
  399. void owl_sigterm_handler(const int num) ;
  400. //@}
  401. /** @name Threads */
  402. //@{
  403. /// Closes the file descriptor `fd`
  404. void owl_close_fd(void *const fd) ;
  405. /// Closes the stream `file`
  406. void owl_close_file(void *const file) ;
  407. //@}
  408. #ifdef __cplusplus
  409. }
  410. #endif // __cplusplus
  411. #endif // _LIBOWLPS_H_