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 22class NetNotificationService : public DefaultUserNotificationService { 23public: 24 NetNotificationService(); 25 virtual ~NetNotificationService(); 26 27 void Notify(const KMessage& event); 28 29protected: 30 virtual void FirstAdded(); 31 virtual void LastRemoved(); 32}; 33 34static NetNotificationService sNotificationService; 35 36 37// #pragma mark - NetNotificationService 38 39 40NetNotificationService::NetNotificationService() 41 : DefaultUserNotificationService("network") 42{ 43} 44 45 46NetNotificationService::~NetNotificationService() 47{ 48} 49 50 51void 52NetNotificationService::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 64void 65NetNotificationService::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 74void 75NetNotificationService::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 85static status_t 86net_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 110static status_t 111send_notification(const KMessage* event) 112{ 113 sNotificationService.Notify(*event); 114 return B_OK; 115} 116 117 118static status_t 119notifications_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 145net_notifications_module_info sNotificationsModule = { 146 { 147 NET_NOTIFICATIONS_MODULE_NAME, 148 0, 149 notifications_std_ops 150 }, 151 152 send_notification 153}; 154 155module_info* modules[] = { 156 (module_info*)&sNotificationsModule, 157 NULL 158}; 159