]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re/util/include/vcon_svr
update
[l4.git] / l4 / pkg / l4re / util / include / vcon_svr
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2011 Alexander Warg <warg@os.inf.tu-dresden.de>,
4  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
5  *               Adam Lackorzysnski <adam@os.inf.tu-dresden.de>
6  *     economic rights: Technische Universität Dresden (Germany)
7  *
8  * This file is part of TUD:OS and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  *
12  * As a special exception, you may use this file as part of a free software
13  * library without restriction.  Specifically, if other files instantiate
14  * templates or use macros or inline functions from this file, or you compile
15  * this file and link it with other files to produce an executable, this
16  * file does not by itself cause the resulting executable to be covered by
17  * the GNU General Public License.  This exception does not however
18  * invalidate any other reasons why the executable file might be covered by
19  * the GNU General Public License.
20  */
21 #pragma once
22
23 #include <l4/cxx/ipc_stream>
24
25 namespace L4Re { namespace Util {
26
27 /**
28  * \brief Console server template class.
29  * \ingroup api_l4re_util
30  *
31  * This template uses vcon_write() and vcon_read() to get and deliver data
32  * from the implementor.
33  *
34  * vcon_read() needs to return a value bigger than the given size to
35  * indicate that there's more data to read for the other end.
36  *
37  * vcon_write() gets the live data from the UTCB. Make sure to copy out the
38  * data before using the UTCB again.
39  *
40  * The size parameter of both function is given in bytes.
41  */
42 template< typename SVR >
43 class Vcon_svr
44 {
45 public:
46
47   /**
48    * \brief Server dispatch function.
49    *
50    * \param obj Server object ID to work on.
51    * \param ios Input/Output stream.
52    *
53    * \return error code.
54    */
55   int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
56
57   unsigned vcon_read(char *buf, unsigned size) throw();
58   void vcon_write(const char *buf, unsigned size) throw();
59   int vcon_set_attr(l4_vcon_attr_t const *) throw()
60   { return -L4_EOK; }
61   int vcon_get_attr(l4_vcon_attr_t *attr) throw()
62   {
63     attr->l_flags = attr->o_flags = attr->i_flags = 0;
64     return -L4_EOK;
65   }
66
67 private:
68   SVR const *this_vcon() const { return static_cast<SVR const *>(this); }
69   SVR *this_vcon() { return static_cast<SVR *>(this); }
70 };
71
72 template< typename SVR >
73 int
74 Vcon_svr<SVR>::dispatch(l4_umword_t, L4::Ipc_iostream &ios)
75 {
76   l4_msgtag_t tag;
77   ios >> tag;
78
79   if (tag.label() != L4_PROTO_LOG)
80     return -L4_EBADPROTO;
81
82   L4::Opcode op;
83   ios >> op;
84
85   switch (op)
86     {
87     case L4_VCON_WRITE_OP:
88         {
89           unsigned long size = 0;
90           char *buf = 0;
91           ios >> L4::Ipc::Buf_in<char>(buf, size);
92           this_vcon()->vcon_write(buf, size);
93           return -L4_ENOREPLY;
94         }
95     case L4_VCON_SET_ATTR_OP:
96         {
97           l4_vcon_attr_t a;
98           ios.get(a);
99           return this_vcon()->vcon_set_attr(&a);
100         }
101     case L4_VCON_GET_ATTR_OP:
102         {
103           l4_vcon_attr_t a;
104           int e = this_vcon()->vcon_get_attr(&a);
105           if (e == L4_EOK)
106             {
107               ios << l4_umword_t(0);
108               ios.put(a);
109             }
110           return e;
111         }
112     default:
113       break;
114     }
115
116   unsigned size = op >> 16;
117
118   if (size > (L4_UTCB_GENERIC_DATA_SIZE - 1) * sizeof(l4_utcb_mr()->mr[0]))
119     size = (L4_UTCB_GENERIC_DATA_SIZE - 1) * sizeof(l4_utcb_mr()->mr[0]);
120
121   char buf[size];
122   // Hmm, could we avoid the double copy here?
123   unsigned r = this_vcon()->vcon_read(buf, size);
124
125   // don't use stream operators, because we need to set eof bit!
126   ios.put(r > size ? size : r | 1UL << 31);
127   ios.put(buf, size);
128
129   return -L4_EOK;
130 }
131
132 }}