ieee80211softmac_event.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "ieee80211softmac_priv.h"
  2. /*
  3. * Event system
  4. * Also see comments in public header file
  5. *
  6. * Each event has associated to it
  7. * - an event type (see constants in public header)
  8. * - an event context (see below)
  9. * - the function to be called
  10. * - a context (extra parameter to call the function with)
  11. * - and the softmac struct
  12. *
  13. * The event context is private and can only be used from
  14. * within this module. Its meaning varies with the event
  15. * type:
  16. * SCAN_FINISHED: no special meaning
  17. * ASSOCIATED,
  18. * ASSOCIATE_FAILED,
  19. * ASSOCIATE_TIMEOUT,
  20. * AUTHENTICATED,
  21. * AUTH_FAILED,
  22. * AUTH_TIMEOUT: a pointer to the network struct
  23. * ...
  24. * Code within this module can use the event context to be only
  25. * called when the event is true for that specific context
  26. * as per above table.
  27. * If the event context is NULL, then the notification is always called,
  28. * regardless of the event context. The event context is not passed to
  29. * the callback, it is assumed that the context suffices.
  30. *
  31. * You can also use the event context only by setting the event type
  32. * to -1 (private use only), in which case you'll be notified
  33. * whenever the event context matches.
  34. */
  35. static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = {
  36. "scan finished",
  37. "associated",
  38. "associating failed",
  39. "associating timed out",
  40. "authenticated",
  41. "authenticating failed",
  42. "authenticating timed out",
  43. "associating failed because no suitable network was found",
  44. };
  45. static void
  46. ieee80211softmac_notify_callback(void *d)
  47. {
  48. struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d;
  49. kfree(d);
  50. event.fun(event.mac->dev, event.context);
  51. }
  52. int
  53. ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
  54. int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask)
  55. {
  56. struct ieee80211softmac_event *eventptr;
  57. unsigned long flags;
  58. if (event < -1 || event > IEEE80211SOFTMAC_EVENT_LAST)
  59. return -ENOSYS;
  60. if (!fun)
  61. return -EINVAL;
  62. eventptr = kmalloc(sizeof(struct ieee80211softmac_event), gfp_mask);
  63. if (!eventptr)
  64. return -ENOMEM;
  65. eventptr->event_type = event;
  66. INIT_WORK(&eventptr->work, ieee80211softmac_notify_callback, eventptr);
  67. eventptr->fun = fun;
  68. eventptr->context = context;
  69. eventptr->mac = mac;
  70. eventptr->event_context = event_context;
  71. spin_lock_irqsave(&mac->lock, flags);
  72. list_add(&eventptr->list, &mac->events);
  73. spin_unlock_irqrestore(&mac->lock, flags);
  74. return 0;
  75. }
  76. int
  77. ieee80211softmac_notify_gfp(struct net_device *dev,
  78. int event, notify_function_ptr fun, void *context, gfp_t gfp_mask)
  79. {
  80. struct ieee80211softmac_device *mac = ieee80211_priv(dev);
  81. if (event < 0 || event > IEEE80211SOFTMAC_EVENT_LAST)
  82. return -ENOSYS;
  83. return ieee80211softmac_notify_internal(mac, event, NULL, fun, context, gfp_mask);
  84. }
  85. EXPORT_SYMBOL_GPL(ieee80211softmac_notify_gfp);
  86. /* private -- calling all callbacks that were specified */
  87. void
  88. ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx)
  89. {
  90. struct ieee80211softmac_event *eventptr, *tmp;
  91. union iwreq_data wrqu;
  92. char *msg;
  93. if (event >= 0) {
  94. msg = event_descriptions[event];
  95. wrqu.data.length = strlen(msg);
  96. wireless_send_event(mac->dev, IWEVCUSTOM, &wrqu, msg);
  97. }
  98. if (!list_empty(&mac->events))
  99. list_for_each_entry_safe(eventptr, tmp, &mac->events, list) {
  100. if ((eventptr->event_type == event || eventptr->event_type == -1)
  101. && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
  102. list_del(&eventptr->list);
  103. schedule_work(&eventptr->work);
  104. }
  105. }
  106. }
  107. void
  108. ieee80211softmac_call_events(struct ieee80211softmac_device *mac, int event, void *event_ctx)
  109. {
  110. unsigned long flags;
  111. spin_lock_irqsave(&mac->lock, flags);
  112. ieee80211softmac_call_events_locked(mac, event, event_ctx);
  113. spin_unlock_irqrestore(&mac->lock, flags);
  114. }