blob: 1a7c0c31d92ee4c0569c52014f7bf95956eb5172 [file] [log] [blame]
Piotr Krysik902f4eb2017-09-19 08:04:33 +02001#!/usr/bin/env python2
2# -*- coding: utf-8 -*-
3
4# GR-GSM based transceiver
5# CTRL interface implementation
6#
7# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
8#
9# All Rights Reserved
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along
22# with this program; if not, write to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
Vadim Yanitskiy404842d2019-01-22 14:40:50 +070025from udp_link import UDPLink
Piotr Krysik902f4eb2017-09-19 08:04:33 +020026
Vadim Yanitskiyf237f1a2018-12-20 09:49:56 +070027class CTRLInterface(UDPLink):
Vadim Yanitskiy0e246372018-08-09 19:30:39 +070028 def handle_rx(self, data, remote):
Piotr Krysik902f4eb2017-09-19 08:04:33 +020029 if self.verify_req(data):
30 request = self.prepare_req(data)
31 rc = self.parse_cmd(request)
32
33 if type(rc) is tuple:
Vadim Yanitskiy0e246372018-08-09 19:30:39 +070034 self.send_response(request, remote, rc[0], rc[1])
Piotr Krysik902f4eb2017-09-19 08:04:33 +020035 else:
Vadim Yanitskiy0e246372018-08-09 19:30:39 +070036 self.send_response(request, remote, rc)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020037 else:
38 print("[!] Wrong data on CTRL interface")
39
40 def verify_req(self, data):
41 # Verify command signature
42 return data.startswith("CMD")
43
44 def prepare_req(self, data):
45 # Strip signature, paddings and \0
46 request = data[4:].strip().strip("\0")
47 # Split into a command and arguments
48 request = request.split(" ")
49 # Now we have something like ["TXTUNE", "941600"]
50 return request
51
52 def verify_cmd(self, request, cmd, argc):
53 # Check if requested command matches
54 if request[0] != cmd:
55 return False
56
57 # And has enough arguments
58 if len(request) - 1 != argc:
59 return False
60
61 # Check if all arguments are numeric
62 for v in request[1:]:
63 if not v.isdigit():
64 return False
65
66 return True
67
Vadim Yanitskiy0e246372018-08-09 19:30:39 +070068 def send_response(self, request, remote, response_code, params = None):
Piotr Krysik902f4eb2017-09-19 08:04:33 +020069 # Include status code, for example ["TXTUNE", "0", "941600"]
70 request.insert(1, str(response_code))
71
72 # Optionally append command specific parameters
73 if params is not None:
74 request += params
75
76 # Add the response signature, and join back to string
77 response = "RSP " + " ".join(request) + "\0"
78 # Now we have something like "RSP TXTUNE 0 941600"
Vadim Yanitskiy0e246372018-08-09 19:30:39 +070079 self.send(response, remote)
Piotr Krysik902f4eb2017-09-19 08:04:33 +020080
81 def parse_cmd(self, request):
82 raise NotImplementedError