1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /*! Provides the networking stack notification service. */ 7 8 #include <net_notifications.h> 9 10 #include <generic_syscall.h> 11 #include <Notifications.h> 12 #include <util/KMessage.h> 13 14 //#define TRACE_NOTIFICATIONS 15 #ifdef TRACE_NOTIFICATIONS 16 # define TRACE(x...) dprintf("\33[32mnet_notifications:\33[0m " x) 17 #else 18 # define TRACE(x...) ; 19 #endif 20 21 22 class NetNotificationService : public DefaultUserNotificationService { 23 public: 24 NetNotificationService(); 25 virtual ~NetNotificationService(); 26 27 void Notify(const KMessage& event); 28 29 protected: 30 virtual void FirstAdded(); 31 virtual void LastRemoved(); 32 }; 33 34 static NetNotificationService sNotificationService; 35 36 37 // #pragma mark - NetNotificationService 38 39 40 NetNotificationService::NetNotificationService() 41 : DefaultUserNotificationService("network") 42 { 43 } 44 45 46 NetNotificationService::~NetNotificationService() 47 { 48 } 49 50 51 void 52 NetNotificationService::Notify(const KMessage& event) 53 { 54 uint32 opcode = event.GetInt32("opcode", 0); 55 if (opcode == 0) 56 return; 57 58 TRACE("notify for %lx\n", opcode); 59 60 DefaultUserNotificationService::Notify(event, opcode); 61 } 62 63 64 void 65 NetNotificationService::FirstAdded() 66 { 67 // The reference counting doesn't work for us, as we'll have to 68 // ensure our module stays loaded. 69 module_info* dummy; 70 get_module(NET_NOTIFICATIONS_MODULE_NAME, &dummy); 71 } 72 73 74 void 75 NetNotificationService::LastRemoved() 76 { 77 // Give up the reference _AddListener() 78 put_module(NET_NOTIFICATIONS_MODULE_NAME); 79 } 80 81 82 // #pragma mark - User generic syscall 83 84 85 static status_t 86 net_notifications_control(const char *subsystem, uint32 function, void *buffer, 87 size_t bufferSize) 88 { 89 struct net_notifications_control control; 90 if (bufferSize != sizeof(struct net_notifications_control) 91 || function != NET_NOTIFICATIONS_CONTROL_WATCHING) 92 return B_BAD_VALUE; 93 if (user_memcpy(&control, buffer, 94 sizeof(struct net_notifications_control)) < B_OK) 95 return B_BAD_ADDRESS; 96 97 if (control.flags != 0) { 98 return sNotificationService.UpdateUserListener(control.flags, 99 control.port, control.token); 100 } 101 102 return sNotificationService.RemoveUserListeners(control.port, 103 control.token); 104 } 105 106 107 // #pragma mark - exported module API 108 109 110 static status_t 111 send_notification(const KMessage* event) 112 { 113 sNotificationService.Notify(*event); 114 return B_OK; 115 } 116 117 118 static status_t 119 notifications_std_ops(int32 op, ...) 120 { 121 switch (op) { 122 case B_MODULE_INIT: 123 TRACE("init\n"); 124 125 new(&sNotificationService) NetNotificationService(); 126 127 register_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, 128 net_notifications_control, 1, 0); 129 return B_OK; 130 131 case B_MODULE_UNINIT: 132 TRACE("uninit\n"); 133 134 unregister_generic_syscall(NET_NOTIFICATIONS_SYSCALLS, 1); 135 136 sNotificationService.~NetNotificationService(); 137 return B_OK; 138 139 default: 140 return B_ERROR; 141 } 142 } 143 144 145 net_notifications_module_info sNotificationsModule = { 146 { 147 NET_NOTIFICATIONS_MODULE_NAME, 148 0, 149 notifications_std_ops 150 }, 151 152 send_notification 153 }; 154 155 module_info* modules[] = { 156 (module_info*)&sNotificationsModule, 157 NULL 158 }; 159