event.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2007 - 2008, Digium, Inc.
  5. *
  6. * Russell Bryant <russell@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Internal generic event system
  21. *
  22. * \author Russell Bryant <russell@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include "asterisk/_private.h"
  30. #include "asterisk/event.h"
  31. #include "asterisk/linkedlists.h"
  32. #include "asterisk/dlinkedlists.h"
  33. #include "asterisk/lock.h"
  34. #include "asterisk/utils.h"
  35. #include "asterisk/unaligned.h"
  36. #include "asterisk/utils.h"
  37. #include "asterisk/taskprocessor.h"
  38. #include "asterisk/astobj2.h"
  39. #include "asterisk/cli.h"
  40. /*!
  41. * \brief An event information element
  42. *
  43. * \note The format of this structure is important. Since these events may
  44. * be sent directly over a network, changing this structure will break
  45. * compatibility with older versions. However, at this point, this code
  46. * has not made it into a release, so it is still fair game for change.
  47. */
  48. struct ast_event_ie {
  49. enum ast_event_ie_type ie_type:16;
  50. /*! Total length of the IE payload */
  51. uint16_t ie_payload_len;
  52. unsigned char ie_payload[0];
  53. } __attribute__((packed));
  54. /*!
  55. * \brief The payload for a string information element
  56. */
  57. struct ast_event_ie_str_payload {
  58. /*! \brief A hash calculated with ast_str_hash(), to speed up comparisons */
  59. uint32_t hash;
  60. /*! \brief The actual string, null terminated */
  61. char str[1];
  62. } __attribute__((packed));
  63. /*!
  64. * \brief An event
  65. *
  66. * An ast_event consists of an event header (this structure), and zero or
  67. * more information elements defined by ast_event_ie.
  68. *
  69. * \note The format of this structure is important. Since these events may
  70. * be sent directly over a network, changing this structure will break
  71. * compatibility with older versions. However, at this point, this code
  72. * has not made it into a release, so it is still fair game for change.
  73. */
  74. struct ast_event {
  75. /*! Event type */
  76. enum ast_event_type type:16;
  77. /*! Total length of the event */
  78. uint16_t event_len:16;
  79. /*! The data payload of the event, made up of information elements */
  80. unsigned char payload[0];
  81. } __attribute__((packed));
  82. struct ast_event_ie_val {
  83. AST_LIST_ENTRY(ast_event_ie_val) entry;
  84. enum ast_event_ie_type ie_type;
  85. enum ast_event_ie_pltype ie_pltype;
  86. union {
  87. uint32_t uint;
  88. struct {
  89. uint32_t hash;
  90. const char *str;
  91. };
  92. void *raw;
  93. } payload;
  94. size_t raw_datalen;
  95. };
  96. /*!
  97. * \brief Event Names
  98. */
  99. static const char * const event_names[AST_EVENT_TOTAL] = {
  100. [AST_EVENT_ALL] = "All",
  101. [AST_EVENT_CUSTOM] = "Custom",
  102. [AST_EVENT_MWI] = "MWI",
  103. [AST_EVENT_SUB] = "Subscription",
  104. [AST_EVENT_UNSUB] = "Unsubscription",
  105. [AST_EVENT_DEVICE_STATE] = "DeviceState",
  106. [AST_EVENT_DEVICE_STATE_CHANGE] = "DeviceStateChange",
  107. [AST_EVENT_CEL] = "CEL",
  108. [AST_EVENT_SECURITY] = "Security",
  109. [AST_EVENT_NETWORK_CHANGE] = "NetworkChange",
  110. [AST_EVENT_PRESENCE_STATE] = "PresenceState",
  111. [AST_EVENT_ACL_CHANGE] = "ACLChange",
  112. [AST_EVENT_PING] = "Ping",
  113. };
  114. /*!
  115. * \brief IE payload types and names
  116. */
  117. static const struct ie_map {
  118. enum ast_event_ie_pltype ie_pltype;
  119. const char *name;
  120. } ie_maps[AST_EVENT_IE_TOTAL] = {
  121. [AST_EVENT_IE_NEWMSGS] = { AST_EVENT_IE_PLTYPE_UINT, "NewMessages" },
  122. [AST_EVENT_IE_OLDMSGS] = { AST_EVENT_IE_PLTYPE_UINT, "OldMessages" },
  123. [AST_EVENT_IE_MAILBOX] = { AST_EVENT_IE_PLTYPE_STR, "Mailbox" },
  124. [AST_EVENT_IE_UNIQUEID] = { AST_EVENT_IE_PLTYPE_UINT, "UniqueID" },
  125. [AST_EVENT_IE_EVENTTYPE] = { AST_EVENT_IE_PLTYPE_UINT, "EventType" },
  126. [AST_EVENT_IE_EXISTS] = { AST_EVENT_IE_PLTYPE_UINT, "Exists" },
  127. [AST_EVENT_IE_DEVICE] = { AST_EVENT_IE_PLTYPE_STR, "Device" },
  128. [AST_EVENT_IE_STATE] = { AST_EVENT_IE_PLTYPE_UINT, "State" },
  129. [AST_EVENT_IE_CONTEXT] = { AST_EVENT_IE_PLTYPE_STR, "Context" },
  130. [AST_EVENT_IE_EID] = { AST_EVENT_IE_PLTYPE_RAW, "EntityID" },
  131. [AST_EVENT_IE_CEL_EVENT_TYPE] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventType" },
  132. [AST_EVENT_IE_CEL_EVENT_TIME] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTime" },
  133. [AST_EVENT_IE_CEL_EVENT_TIME_USEC] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTimeUSec" },
  134. [AST_EVENT_IE_CEL_USEREVENT_NAME] = { AST_EVENT_IE_PLTYPE_STR, "CELUserEventName" },
  135. [AST_EVENT_IE_CEL_CIDNAME] = { AST_EVENT_IE_PLTYPE_STR, "CELCIDName" },
  136. [AST_EVENT_IE_CEL_CIDNUM] = { AST_EVENT_IE_PLTYPE_STR, "CELCIDNum" },
  137. [AST_EVENT_IE_CEL_EXTEN] = { AST_EVENT_IE_PLTYPE_STR, "CELExten" },
  138. [AST_EVENT_IE_CEL_CONTEXT] = { AST_EVENT_IE_PLTYPE_STR, "CELContext" },
  139. [AST_EVENT_IE_CEL_CHANNAME] = { AST_EVENT_IE_PLTYPE_STR, "CELChanName" },
  140. [AST_EVENT_IE_CEL_APPNAME] = { AST_EVENT_IE_PLTYPE_STR, "CELAppName" },
  141. [AST_EVENT_IE_CEL_APPDATA] = { AST_EVENT_IE_PLTYPE_STR, "CELAppData" },
  142. [AST_EVENT_IE_CEL_AMAFLAGS] = { AST_EVENT_IE_PLTYPE_UINT, "CELAMAFlags" },
  143. [AST_EVENT_IE_CEL_ACCTCODE] = { AST_EVENT_IE_PLTYPE_STR, "CELAcctCode" },
  144. [AST_EVENT_IE_CEL_UNIQUEID] = { AST_EVENT_IE_PLTYPE_STR, "CELUniqueID" },
  145. [AST_EVENT_IE_CEL_USERFIELD] = { AST_EVENT_IE_PLTYPE_STR, "CELUserField" },
  146. [AST_EVENT_IE_CEL_CIDANI] = { AST_EVENT_IE_PLTYPE_STR, "CELCIDani" },
  147. [AST_EVENT_IE_CEL_CIDRDNIS] = { AST_EVENT_IE_PLTYPE_STR, "CELCIDrdnis" },
  148. [AST_EVENT_IE_CEL_CIDDNID] = { AST_EVENT_IE_PLTYPE_STR, "CELCIDdnid" },
  149. [AST_EVENT_IE_CEL_PEER] = { AST_EVENT_IE_PLTYPE_STR, "CELPeer" },
  150. [AST_EVENT_IE_CEL_LINKEDID] = { AST_EVENT_IE_PLTYPE_STR, "CELLinkedID" },
  151. [AST_EVENT_IE_CEL_PEERACCT] = { AST_EVENT_IE_PLTYPE_STR, "CELPeerAcct" },
  152. [AST_EVENT_IE_CEL_EXTRA] = { AST_EVENT_IE_PLTYPE_STR, "CELExtra" },
  153. [AST_EVENT_IE_SECURITY_EVENT] = { AST_EVENT_IE_PLTYPE_UINT, "SecurityEvent" },
  154. [AST_EVENT_IE_EVENT_VERSION] = { AST_EVENT_IE_PLTYPE_UINT, "EventVersion" },
  155. [AST_EVENT_IE_SERVICE] = { AST_EVENT_IE_PLTYPE_STR, "Service" },
  156. [AST_EVENT_IE_MODULE] = { AST_EVENT_IE_PLTYPE_STR, "Module" },
  157. [AST_EVENT_IE_ACCOUNT_ID] = { AST_EVENT_IE_PLTYPE_STR, "AccountID" },
  158. [AST_EVENT_IE_SESSION_ID] = { AST_EVENT_IE_PLTYPE_STR, "SessionID" },
  159. [AST_EVENT_IE_SESSION_TV] = { AST_EVENT_IE_PLTYPE_STR, "SessionTV" },
  160. [AST_EVENT_IE_ACL_NAME] = { AST_EVENT_IE_PLTYPE_STR, "ACLName" },
  161. [AST_EVENT_IE_LOCAL_ADDR] = { AST_EVENT_IE_PLTYPE_STR, "LocalAddress" },
  162. [AST_EVENT_IE_REMOTE_ADDR] = { AST_EVENT_IE_PLTYPE_STR, "RemoteAddress" },
  163. [AST_EVENT_IE_EVENT_TV] = { AST_EVENT_IE_PLTYPE_STR, "EventTV" },
  164. [AST_EVENT_IE_REQUEST_TYPE] = { AST_EVENT_IE_PLTYPE_STR, "RequestType" },
  165. [AST_EVENT_IE_REQUEST_PARAMS] = { AST_EVENT_IE_PLTYPE_STR, "RequestParams" },
  166. [AST_EVENT_IE_AUTH_METHOD] = { AST_EVENT_IE_PLTYPE_STR, "AuthMethod" },
  167. [AST_EVENT_IE_SEVERITY] = { AST_EVENT_IE_PLTYPE_STR, "Severity" },
  168. [AST_EVENT_IE_EXPECTED_ADDR] = { AST_EVENT_IE_PLTYPE_STR, "ExpectedAddress" },
  169. [AST_EVENT_IE_CHALLENGE] = { AST_EVENT_IE_PLTYPE_STR, "Challenge" },
  170. [AST_EVENT_IE_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "Response" },
  171. [AST_EVENT_IE_EXPECTED_RESPONSE] = { AST_EVENT_IE_PLTYPE_STR, "ExpectedResponse" },
  172. [AST_EVENT_IE_RECEIVED_CHALLENGE] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedChallenge" },
  173. [AST_EVENT_IE_RECEIVED_HASH] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedHash" },
  174. [AST_EVENT_IE_USING_PASSWORD] = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" },
  175. [AST_EVENT_IE_ATTEMPTED_TRANSPORT] = { AST_EVENT_IE_PLTYPE_STR, "AttemptedTransport" },
  176. [AST_EVENT_IE_CACHABLE] = { AST_EVENT_IE_PLTYPE_UINT, "Cachable" },
  177. [AST_EVENT_IE_PRESENCE_PROVIDER] = { AST_EVENT_IE_PLTYPE_STR, "PresenceProvider" },
  178. [AST_EVENT_IE_PRESENCE_STATE] = { AST_EVENT_IE_PLTYPE_UINT, "PresenceState" },
  179. [AST_EVENT_IE_PRESENCE_SUBTYPE] = { AST_EVENT_IE_PLTYPE_STR, "PresenceSubtype" },
  180. [AST_EVENT_IE_PRESENCE_MESSAGE] = { AST_EVENT_IE_PLTYPE_STR, "PresenceMessage" },
  181. };
  182. const char *ast_event_get_type_name(const struct ast_event *event)
  183. {
  184. enum ast_event_type type;
  185. type = ast_event_get_type(event);
  186. if ((unsigned int)type >= ARRAY_LEN(event_names)) {
  187. ast_log(LOG_ERROR, "Invalid event type - '%u'\n", type);
  188. return "";
  189. }
  190. return event_names[type];
  191. }
  192. const char *ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
  193. {
  194. if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
  195. ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
  196. return "";
  197. }
  198. return ie_maps[ie_type].name;
  199. }
  200. enum ast_event_ie_pltype ast_event_get_ie_pltype(enum ast_event_ie_type ie_type)
  201. {
  202. if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
  203. ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
  204. return AST_EVENT_IE_PLTYPE_UNKNOWN;
  205. }
  206. return ie_maps[ie_type].ie_pltype;
  207. }
  208. size_t ast_event_get_size(const struct ast_event *event)
  209. {
  210. size_t res;
  211. res = ntohs(event->event_len);
  212. return res;
  213. }
  214. /*! \brief Subscription event check list. */
  215. struct ast_ev_check_list {
  216. AST_LIST_HEAD_NOLOCK(, ast_event_ie_val) ie_vals;
  217. };
  218. int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
  219. {
  220. int res = 0;
  221. iterator->event_len = ast_event_get_size(event);
  222. iterator->event = event;
  223. if (iterator->event_len >= sizeof(*event) + sizeof(struct ast_event_ie)) {
  224. iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) );
  225. } else {
  226. iterator->ie = NULL;
  227. res = -1;
  228. }
  229. return res;
  230. }
  231. int ast_event_iterator_next(struct ast_event_iterator *iterator)
  232. {
  233. iterator->ie = (struct ast_event_ie *) ( ((char *) iterator->ie) + sizeof(*iterator->ie) + ntohs(iterator->ie->ie_payload_len));
  234. return ((iterator->event_len <= (((char *) iterator->ie) - ((char *) iterator->event))) ? -1 : 0);
  235. }
  236. enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator)
  237. {
  238. return ntohs(iterator->ie->ie_type);
  239. }
  240. uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator)
  241. {
  242. return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
  243. }
  244. const char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
  245. {
  246. const struct ast_event_ie_str_payload *str_payload;
  247. str_payload = (struct ast_event_ie_str_payload *) iterator->ie->ie_payload;
  248. return str_payload ? str_payload->str : NULL;
  249. }
  250. static void *event_iterator_get_ie_raw(struct ast_event_iterator *iterator)
  251. {
  252. return iterator->ie->ie_payload;
  253. }
  254. enum ast_event_type ast_event_get_type(const struct ast_event *event)
  255. {
  256. return ntohs(event->type);
  257. }
  258. uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
  259. {
  260. const uint32_t *ie_val;
  261. ie_val = ast_event_get_ie_raw(event, ie_type);
  262. return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
  263. }
  264. const char *ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
  265. {
  266. const struct ast_event_ie_str_payload *str_payload;
  267. str_payload = ast_event_get_ie_raw(event, ie_type);
  268. return str_payload ? str_payload->str : NULL;
  269. }
  270. const void *ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type)
  271. {
  272. struct ast_event_iterator iterator;
  273. int res;
  274. for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
  275. if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
  276. return event_iterator_get_ie_raw(&iterator);
  277. }
  278. }
  279. return NULL;
  280. }
  281. static uint16_t event_iterator_get_ie_raw_payload_len(struct ast_event_iterator *iterator)
  282. {
  283. return ntohs(iterator->ie->ie_payload_len);
  284. }
  285. uint16_t ast_event_get_ie_raw_payload_len(const struct ast_event *event, enum ast_event_ie_type ie_type)
  286. {
  287. struct ast_event_iterator iterator;
  288. int res;
  289. for (res = ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
  290. if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
  291. return event_iterator_get_ie_raw_payload_len(&iterator);
  292. }
  293. }
  294. return 0;
  295. }
  296. int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_type,
  297. const char *str)
  298. {
  299. struct ast_event_ie_str_payload *str_payload;
  300. size_t payload_len;
  301. payload_len = sizeof(*str_payload) + strlen(str);
  302. str_payload = ast_alloca(payload_len);
  303. strcpy(str_payload->str, str);
  304. str_payload->hash = ast_str_hash(str);
  305. return ast_event_append_ie_raw(event, ie_type, str_payload, payload_len);
  306. }
  307. int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
  308. uint32_t data)
  309. {
  310. data = htonl(data);
  311. return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
  312. }
  313. int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type,
  314. uint32_t flags)
  315. {
  316. flags = htonl(flags);
  317. return ast_event_append_ie_raw(event, ie_type, &flags, sizeof(flags));
  318. }
  319. int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
  320. const void *data, size_t data_len)
  321. {
  322. struct ast_event_ie *ie;
  323. struct ast_event *old_event;
  324. unsigned int extra_len;
  325. uint16_t event_len;
  326. event_len = ntohs((*event)->event_len);
  327. extra_len = sizeof(*ie) + data_len;
  328. old_event = *event;
  329. *event = ast_realloc(*event, event_len + extra_len);
  330. if (!*event) {
  331. ast_free(old_event);
  332. return -1;
  333. }
  334. ie = (struct ast_event_ie *) ( ((char *) *event) + event_len );
  335. ie->ie_type = htons(ie_type);
  336. ie->ie_payload_len = htons(data_len);
  337. memcpy(ie->ie_payload, data, data_len);
  338. (*event)->event_len = htons(event_len + extra_len);
  339. return 0;
  340. }
  341. struct ast_event *ast_event_new(enum ast_event_type type, ...)
  342. {
  343. va_list ap;
  344. struct ast_event *event;
  345. enum ast_event_ie_type ie_type;
  346. struct ast_event_ie_val *ie_val;
  347. AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
  348. /* Invalid type */
  349. if (type >= AST_EVENT_TOTAL) {
  350. ast_log(LOG_WARNING, "Someone tried to create an event of invalid "
  351. "type '%u'!\n", type);
  352. return NULL;
  353. }
  354. va_start(ap, type);
  355. for (ie_type = va_arg(ap, enum ast_event_ie_type);
  356. ie_type != AST_EVENT_IE_END;
  357. ie_type = va_arg(ap, enum ast_event_ie_type))
  358. {
  359. struct ast_event_ie_val *ie_value = ast_alloca(sizeof(*ie_value));
  360. int insert = 0;
  361. memset(ie_value, 0, sizeof(*ie_value));
  362. ie_value->ie_type = ie_type;
  363. ie_value->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
  364. switch (ie_value->ie_pltype) {
  365. case AST_EVENT_IE_PLTYPE_UINT:
  366. ie_value->payload.uint = va_arg(ap, uint32_t);
  367. insert = 1;
  368. break;
  369. case AST_EVENT_IE_PLTYPE_BITFLAGS:
  370. ie_value->payload.uint = va_arg(ap, uint32_t);
  371. insert = 1;
  372. break;
  373. case AST_EVENT_IE_PLTYPE_STR:
  374. ie_value->payload.str = va_arg(ap, const char *);
  375. insert = 1;
  376. break;
  377. case AST_EVENT_IE_PLTYPE_RAW:
  378. {
  379. void *data = va_arg(ap, void *);
  380. size_t datalen = va_arg(ap, size_t);
  381. ie_value->payload.raw = ast_alloca(datalen);
  382. memcpy(ie_value->payload.raw, data, datalen);
  383. ie_value->raw_datalen = datalen;
  384. insert = 1;
  385. break;
  386. }
  387. case AST_EVENT_IE_PLTYPE_UNKNOWN:
  388. case AST_EVENT_IE_PLTYPE_EXISTS:
  389. break;
  390. }
  391. if (insert) {
  392. AST_LIST_INSERT_TAIL(&ie_vals, ie_value, entry);
  393. } else {
  394. ast_log(LOG_WARNING, "Unsupported PLTYPE(%d)\n", ie_value->ie_pltype);
  395. }
  396. }
  397. va_end(ap);
  398. if (!(event = ast_calloc(1, sizeof(*event)))) {
  399. return NULL;
  400. }
  401. event->type = htons(type);
  402. event->event_len = htons(sizeof(*event));
  403. AST_LIST_TRAVERSE(&ie_vals, ie_val, entry) {
  404. switch (ie_val->ie_pltype) {
  405. case AST_EVENT_IE_PLTYPE_STR:
  406. ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
  407. break;
  408. case AST_EVENT_IE_PLTYPE_UINT:
  409. ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
  410. break;
  411. case AST_EVENT_IE_PLTYPE_BITFLAGS:
  412. ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
  413. break;
  414. case AST_EVENT_IE_PLTYPE_RAW:
  415. ast_event_append_ie_raw(&event, ie_val->ie_type,
  416. ie_val->payload.raw, ie_val->raw_datalen);
  417. break;
  418. case AST_EVENT_IE_PLTYPE_EXISTS:
  419. case AST_EVENT_IE_PLTYPE_UNKNOWN:
  420. break;
  421. }
  422. /* realloc inside one of the append functions failed */
  423. if (!event) {
  424. return NULL;
  425. }
  426. }
  427. if (!ast_event_get_ie_raw(event, AST_EVENT_IE_EID)) {
  428. /* If the event is originating on this server, add the server's
  429. * entity ID to the event. */
  430. ast_event_append_eid(&event);
  431. }
  432. return event;
  433. }
  434. int ast_event_append_eid(struct ast_event **event)
  435. {
  436. return ast_event_append_ie_raw(event, AST_EVENT_IE_EID,
  437. &ast_eid_default, sizeof(ast_eid_default));
  438. }
  439. void ast_event_destroy(struct ast_event *event)
  440. {
  441. ast_free(event);
  442. }
  443. size_t ast_event_minimum_length(void)
  444. {
  445. return sizeof(struct ast_event);
  446. }