]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ankh/server/src/main.cc
Inital import
[l4.git] / l4 / pkg / ankh / server / src / main.cc
1 #include <cstdio>
2 #include <cstring>
3 #include <cstdlib>
4 #include <iostream>
5 #include <time.h>
6 #include <boost/format.hpp>
7
8 #include <l4/re/env>
9 #include <l4/re/env>
10 #include <l4/re/namespace>
11 #include <l4/re/util/cap_alloc>
12 #include <l4/re/util/object_registry>
13 #include <l4/re/protocols>
14 #include <l4/re/util/meta>
15 #include <l4/cxx/ipc_server>
16 #include <l4/cxx/iostream>
17 #include <l4/cxx/l4iostream>
18 #include <l4/dde/linux26/dde26.h>
19
20 #include <l4/sys/debugger.h>
21 #include <l4/ankh/protocol>
22 #include <l4/ankh/packet_analyzer.h>
23 #include "session"
24 #include "device"
25 #include "linux_glue.h"
26
27 static L4Re::Util::Registry_server<> server;
28
29 int Ankh::ServerSession::dispatch(l4_umword_t, L4::Ipc_iostream &ios)
30 {
31         l4_msgtag_t t;
32         ios >> t;
33         int ret = -1;
34
35         if (t.label() != Ankh::Protocol::Ankh)
36                 return -L4_EBADPROTO;
37
38         L4::Opcode op;
39         ios >> op;
40
41         switch(op)
42         {
43                 case Ankh::Opcode::Activate:
44                         ret = shm_create();
45                         activate();
46                         break;
47
48                 case Ankh::Opcode::Deactivate:
49                         deactivate();
50                         break;
51
52                 default:
53                         std::cout << "Unknown op: " << op << "\n";
54                         ret = -L4_ENOSYS;
55         }
56
57         return ret;
58 }
59
60
61
62 class Ankh_server : public L4::Server_object
63 {
64         public: 
65                 int dispatch(l4_umword_t, L4::Ipc_iostream &ios);
66 };
67
68
69 int Ankh_server::dispatch(l4_umword_t, L4::Ipc_iostream &ios)
70 {
71         l4_msgtag_t t;
72         ios >> t;
73
74         switch (t.label()) {
75                 /*
76                  * Used by Ned to find out our supported protocols
77                  */
78                 case L4::Meta::Protocol:
79                         return L4Re::Util::handle_meta_request<L4::Factory>(ios);
80
81                 /*
82                  * Factory protocol to create new sessions
83                  */
84                 case L4::Factory::Protocol:
85                         {
86                                 unsigned long size = 250;
87                                 char buf[size];
88                                 memset(buf, 0, size);
89
90                                 unsigned op;
91                                 ios >> op;
92                                 if (op != 0)
93                                         return -L4_EINVAL;
94
95                                 L4::Ipc::Varg opt;
96                                 ios.get(&opt);
97
98                                 if (!opt.is_of<char const *>()) {
99                                         std::cerr << "[ERR] Parameter needs to be a string constant.\n";
100                                         return -L4_EINVAL;
101                                 }
102
103                                 strncpy(buf, opt.value<char const*>(), size);
104
105                                 Ankh::ServerSession *ret = Ankh::Session_factory::get()->create(buf);
106                                 if (ret != 0)
107                                 {
108                                         server.registry()->register_obj(ret);
109                                         ios << ret->obj_cap();
110                                         return L4_EOK;
111                                 }
112                                 else
113                                 {
114                                         L4::cerr << "Error creating Ankh session object.\n";
115                                         return -L4_ENOMEM;
116                                 }
117                         }
118                 default:
119                         std::cout << "Unknown protocol: " << t.label() << "\n";
120                         return -L4_ENOSYS;
121         }
122
123         return L4_EOK;
124 }
125
126 EXTERN_C void netdev_add(void *ptr)
127 {
128         Ankh::Device_manager::dev_mgr()->add_device(ptr);
129 }
130
131
132 EXTERN_C void enable_ux_self()
133 {
134         l4_thread_control_start();
135         l4_thread_control_ux_host_syscall(1);
136         l4_thread_control_commit(pthread_getl4cap(pthread_self()));
137 }
138
139
140 EXTERN_C int packet_deliver(void *packet, unsigned len, char const * const dev, unsigned local)
141 {
142 #if 0
143         static int callcount = 0;
144         if (++callcount >= 7500) {
145             L4Re::Env::env()->parent()->signal(0, 1);
146         }
147 #endif
148
149         assert(packet != 0);
150         unsigned cnt = 0;
151         int c = l4_debugger_global_id(pthread_getl4cap(pthread_self()));
152
153 #if 0
154         Ankh::Util::print_mac(static_cast<unsigned char*>(packet));
155         std::cout << " <- ";
156         Ankh::Util::print_mac(static_cast<unsigned char*>(packet)+6);
157         std::cout << std::endl;
158 #endif
159
160         Ankh::ServerSession *s = Ankh::Session_factory::get()->find_session_for_mac(
161                                        static_cast<const char * const>(packet), dev);
162         while (s != 0)
163         {
164                 if (cnt == 0) {
165                         if (s->debug()) {
166                                 packet_analyze(static_cast<char*>(packet), len);
167                         }
168                 }
169                 if (local)
170                         s->dev()->lock();
171                 s->deliver(static_cast<char*>(packet), len);
172                 if (local)
173                         s->dev()->unlock();
174                 ++cnt;
175                 s = Ankh::Session_factory::get()->find_session_for_mac(
176                           static_cast<const char * const>(packet), dev, s);
177         }
178
179         return cnt;
180 }
181
182 int main()
183 {
184         Ankh_server ankh;
185
186         int num_devs = open_network_devices(1);
187         std::cout << "Opened " << num_devs << " network devices.\n";
188         Ankh::Device_manager::dev_mgr()->dump_devices();
189
190         server.registry()->register_obj(&ankh, "ankh_service");
191         std::cout << "Registered @ registry.\n";
192
193         std::cout << "Gooood Morning Ankh-Morpoooooork! TID = 0x" << std::hex << l4_debugger_global_id(pthread_getl4cap(pthread_self())) << std::dec << "\n";
194         l4_debugger_set_object_name(pthread_getl4cap(pthread_self()), "ankh.main");
195
196         try
197         {
198                 server.loop();
199         }
200         catch (L4::Base_exception const &e)
201         {
202                 L4::cerr << "Error: " << e << '\n';
203                 return -1;
204         }
205         catch (std::exception const &e)
206         {
207                 std::cerr << "Error: " << e.what() << '\n';
208         }
209
210         return 0;
211 }