blob: 42ddcdc341ee96abfaefb77b52ed299d99cc7f98 [file] [log] [blame]
Ole Troan5f9dcff2016-08-01 04:59:13 +02001#
2# Copyright (c) 2016 Cisco and/or its affiliates.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at:
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15#
16# Import C API shared object
17#
18from __future__ import print_function
19
Ole Troan1732fc12016-08-30 21:03:51 +020020import signal, os, sys
Ole Troan5f9dcff2016-08-01 04:59:13 +020021from struct import *
22
Ole Troan5f9dcff2016-08-01 04:59:13 +020023import vpp_api
24from vpp_api_base import *
25
26# Import API definitions. The core VPE API is imported into main namespace
27import memclnt
Ole Troan57c3d662016-09-12 22:00:32 +020028
29# Cheating a bit, importing it into this namespace as well as a module.
30import vpe
Ole Troan5f9dcff2016-08-01 04:59:13 +020031from vpe import *
Ole Troan5f9dcff2016-08-01 04:59:13 +020032
Ole Troan1732fc12016-08-30 21:03:51 +020033def eprint(*args, **kwargs):
34 print(*args, file=sys.stderr, **kwargs)
35
Ole Troan5f9dcff2016-08-01 04:59:13 +020036def msg_handler(msg):
37 if not msg:
Ole Troan1732fc12016-08-30 21:03:51 +020038 eprint('vpp_api.read failed')
Ole Troan5f9dcff2016-08-01 04:59:13 +020039 return
40
41 id = unpack('>H', msg[0:2])
Ole Troan5f9dcff2016-08-01 04:59:13 +020042 if id[0] == memclnt.VL_API_RX_THREAD_EXIT:
Ole Troan5f9dcff2016-08-01 04:59:13 +020043 return;
44
45 #
46 # Decode message and returns a tuple.
47 #
Ole Troan1732fc12016-08-30 21:03:51 +020048 try:
49 r = api_func_table[id[0]](msg)
50 except:
51 eprint('Message decode failed', id[0], api_func_table[id[0]])
52 raise
Ole Troan5f9dcff2016-08-01 04:59:13 +020053
54 if 'context' in r._asdict():
55 if r.context > 0:
56 context = r.context
57
58 #
59 # XXX: Call provided callback for event
60 # Are we guaranteed to not get an event during processing of other messages?
61 # How to differentiate what's a callback message and what not? Context = 0?
62 #
63 if not is_waiting_for_reply():
64 event_callback_call(r)
65 return
66
67 #
68 # Collect results until control ping
69 #
Ole Troan57c3d662016-09-12 22:00:32 +020070 if id[0] == VL_API_CONTROL_PING_REPLY:
Ole Troan5f9dcff2016-08-01 04:59:13 +020071 results_event_set(context)
72 waiting_for_reply_clear()
73 return
74 if not is_results_context(context):
Ole Troan1732fc12016-08-30 21:03:51 +020075 eprint('Not expecting results for this context', context)
Ole Troan5f9dcff2016-08-01 04:59:13 +020076 return
77 if is_results_more(context):
78 results_append(context, r)
79 return
80
81 results_set(context, r)
82 results_event_set(context)
83 waiting_for_reply_clear()
84
Ole Troan57c3d662016-09-12 22:00:32 +020085def handler(signum, frame):
86 print('Signal handler called with signal', signum)
87 raise IOError("Couldn't connect to VPP!")
88
Ole Troan5f9dcff2016-08-01 04:59:13 +020089def connect(name):
Ole Troan57c3d662016-09-12 22:00:32 +020090 # Set the signal handler
91 signal.signal(signal.SIGALRM, handler)
92
Ole Troan5f9dcff2016-08-01 04:59:13 +020093 signal.alarm(3) # 3 second
94 rv = vpp_api.connect(name, msg_handler)
95 signal.alarm(0)
Ole Troan5f9dcff2016-08-01 04:59:13 +020096
97 #
98 # Assign message id space for plugins
99 #
Ole Troan57c3d662016-09-12 22:00:32 +0200100 try:
101 plugin_map_plugins()
102 except:
103 return -1
Ole Troan5f9dcff2016-08-01 04:59:13 +0200104 return rv
105
106def disconnect():
107 rv = vpp_api.disconnect()
Ole Troan5f9dcff2016-08-01 04:59:13 +0200108 return rv
109
Ole Troan5f9dcff2016-08-01 04:59:13 +0200110def register_event_callback(callback):
111 event_callback_set(callback)
112
113def plugin_name_to_id(plugin, name_to_id_table, base):
114 try:
115 m = globals()[plugin]
116 except KeyError:
117 m = sys.modules[plugin]
Ole Troan57c3d662016-09-12 22:00:32 +0200118
Ole Troan5f9dcff2016-08-01 04:59:13 +0200119 for name in name_to_id_table:
120 setattr(m, name, name_to_id_table[name] + base)
121
122def plugin_map_plugins():
123 for p in plugins:
124 if p == 'memclnt' or p == 'vpe':
125 continue
126
127 #
128 # Find base
129 # Update api table
130 #
131 version = plugins[p]['version']
132 name = p + '_' + format(version, '08x')
Ole Troan57c3d662016-09-12 22:00:32 +0200133 r = memclnt.get_first_msg_id(name)
Ole Troan5f9dcff2016-08-01 04:59:13 +0200134 if r.retval != 0:
Ole Troan57c3d662016-09-12 22:00:32 +0200135 eprint('Failed getting first msg id for:', p, r, name)
136 raise
Ole Troan5f9dcff2016-08-01 04:59:13 +0200137
138 # Set base
139 base = r.first_msg_id
140 msg_id_base_set = plugins[p]['msg_id_base_set']
141 msg_id_base_set(base)
142 plugins[p]['base'] = base
143 func_table = plugins[p]['func_table']
144 i = r.first_msg_id
Ole Troan1732fc12016-08-30 21:03:51 +0200145 # Insert doesn't extend the table
146 if i + len(func_table) > len(api_func_table):
147 fill = [None] * (i + len(func_table) - len(api_func_table))
148 api_func_table.extend(fill)
Ole Troan5f9dcff2016-08-01 04:59:13 +0200149 for entry in func_table:
Ole Troan1732fc12016-08-30 21:03:51 +0200150 api_func_table[i] = entry
Ole Troan5f9dcff2016-08-01 04:59:13 +0200151 i += 1
152 plugin_name_to_id(p, plugins[p]['name_to_id_table'], base)
153
154#
155# Set up core API
156#
157memclnt.msg_id_base_set(1)
158plugins['memclnt']['base'] = 1
Ole Troan57c3d662016-09-12 22:00:32 +0200159
160# vpe
Ole Troan5f9dcff2016-08-01 04:59:13 +0200161msg_id_base_set(len(plugins['memclnt']['func_table']) + 1)
162plugins['vpe']['base'] = len(plugins['memclnt']['func_table']) + 1
163api_func_table = []
164api_func_table.append(None)
165api_func_table[1:] = plugins['memclnt']['func_table'] + plugins['vpe']['func_table']
166plugin_name_to_id('memclnt', plugins['memclnt']['name_to_id_table'], 1)
167plugin_name_to_id('vpe', plugins['vpe']['name_to_id_table'], plugins['vpe']['base'])
Ole Troan57c3d662016-09-12 22:00:32 +0200168plugin_name_to_id(__name__, plugins['vpe']['name_to_id_table'], plugins['vpe']['base'])