xref: /haiku/src/add-ons/kernel/network/notifications/notifications.cpp (revision 03187b607b2b5eec7ee059f1ead09bdba14991fb)
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