Refactor Python agent
[lttng-ust.git] / liblttng-ust-python-agent / lttngust / cmd.py
CommitLineData
de4dee04
PP
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2015 - Philippe Proulx <pproulx@efficios.com>
4# Copyright (C) 2014 - David Goulet <dgoulet@efficios.com>
5#
6# This library is free software; you can redistribute it and/or modify it under
7# the terms of the GNU Lesser General Public License as published by the Free
8# Software Foundation; version 2.1 of the License.
9#
10# This library is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13# details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this library; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19from __future__ import unicode_literals
20import lttngust.debug as dbg
21import struct
22
23
24# server command header
25_server_cmd_header_struct = struct.Struct('>QII')
26
27
28# server command header size
29_SERVER_CMD_HEADER_SIZE = _server_cmd_header_struct.size
30
31
32class _ServerCmdHeader(object):
33 def __init__(self, data_size, cmd_id, cmd_version):
34 self.data_size = data_size
35 self.cmd_id = cmd_id
36 self.cmd_version = cmd_version
37
38
39def _server_cmd_header_from_data(data):
40 try:
41 data_size, cmd_id, cmd_version = _server_cmd_header_struct.unpack(data)
42 except (Exception) as e:
43 dbg._pdebug('cannot decode command header: {}'.format(e))
44 return None
45
46 return _ServerCmdHeader(data_size, cmd_id, cmd_version)
47
48
49class _ServerCmd(object):
50 def __init__(self, header):
51 self.header = header
52
53 @classmethod
54 def from_data(cls, header, data):
55 raise NotImplementedError()
56
57
58class _ServerCmdList(_ServerCmd):
59 @classmethod
60 def from_data(cls, header, data):
61 return cls(header)
62
63
64class _ServerCmdEnable(_ServerCmd):
65 _NAME_OFFSET = 8
66 _loglevel_struct = struct.Struct('>II')
67
68 def __init__(self, header, loglevel, loglevel_type, name):
69 super(self.__class__, self).__init__(header)
70 self.loglevel = loglevel
71 self.loglevel_type = loglevel_type
72 self.name = name
73
74 @classmethod
75 def from_data(cls, header, data):
76 try:
77 loglevel, loglevel_type = cls._loglevel_struct.unpack_from(data)
78 data_name = data[cls._loglevel_struct.size:]
79 name = data_name.rstrip(b'\0').decode()
80
81 return cls(header, loglevel, loglevel_type, name)
82 except (Exception) as e:
83 dbg._pdebug('cannot decode enable command: {}'.format(e))
84 return None
85
86
87class _ServerCmdDisable(_ServerCmd):
88 def __init__(self, header, name):
89 super(self.__class__, self).__init__(header)
90 self.name = name
91
92 @classmethod
93 def from_data(cls, header, data):
94 try:
95 name = data.rstrip(b'\0').decode()
96
97 return cls(header, name)
98 except (Exception) as e:
99 dbg._pdebug('cannot decode disable command: {}'.format(e))
100 return None
101
102
103class _ServerCmdRegistrationDone(_ServerCmd):
104 @classmethod
105 def from_data(cls, header, data):
106 return cls(header)
107
108
109_SERVER_CMD_ID_TO_SERVER_CMD = {
110 1: _ServerCmdList,
111 2: _ServerCmdEnable,
112 3: _ServerCmdDisable,
113 4: _ServerCmdRegistrationDone,
114}
115
116
117def _server_cmd_from_data(header, data):
118 if header.cmd_id not in _SERVER_CMD_ID_TO_SERVER_CMD:
119 return None
120
121 return _SERVER_CMD_ID_TO_SERVER_CMD[header.cmd_id].from_data(header, data)
122
123
124_CLIENT_CMD_REPLY_STATUS_SUCCESS = 1
125_CLIENT_CMD_REPLY_STATUS_INVALID_CMD = 2
126
127
128class _ClientCmdReplyHeader(object):
129 _payload_struct = struct.Struct('>I')
130
131 def __init__(self, status_code=_CLIENT_CMD_REPLY_STATUS_SUCCESS):
132 self.status_code = status_code
133
134 def get_data(self):
135 return self._payload_struct.pack(self.status_code)
136
137
138class _ClientCmdReplyEnable(_ClientCmdReplyHeader):
139 pass
140
141
142class _ClientCmdReplyDisable(_ClientCmdReplyHeader):
143 pass
144
145
146class _ClientCmdReplyList(_ClientCmdReplyHeader):
147 _nb_events_struct = struct.Struct('>I')
148 _data_size_struct = struct.Struct('>I')
149
150 def __init__(self, names, status_code=_CLIENT_CMD_REPLY_STATUS_SUCCESS):
151 super(self.__class__, self).__init__(status_code)
152 self.names = names
153
154 def get_data(self):
155 upper_data = super(self.__class__, self).get_data()
156 nb_events_data = self._nb_events_struct.pack(len(self.names))
157 names_data = bytes()
158
159 for name in self.names:
160 names_data += name.encode() + b'\0'
161
162 data_size_data = self._data_size_struct.pack(len(names_data))
163
164 return upper_data + data_size_data + nb_events_data + names_data
165
166
167class _ClientRegisterCmd(object):
168 _payload_struct = struct.Struct('>IIII')
169
170 def __init__(self, domain, pid, major, minor):
171 self.domain = domain
172 self.pid = pid
173 self.major = major
174 self.minor = minor
175
176 def get_data(self):
177 return self._payload_struct.pack(self.domain, self.pid, self.major,
178 self.minor)
This page took 0.028524 seconds and 4 git commands to generate.