1/*
2 *  Hamlib bindings - Rig interface
3 *  Copyright (c) 2001-2008 by Stephane Fillod
4 *
5 *
6 *   This library is free software; you can redistribute it and/or
7 *   modify it under the terms of the GNU Lesser General Public
8 *   License as published by the Free Software Foundation; either
9 *   version 2.1 of the License, or (at your option) any later version.
10 *
11 *   This library is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *   Lesser General Public License for more details.
15 *
16 *   You should have received a copy of the GNU Lesser General Public
17 *   License along with this library; if not, write to the Free Software
18 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21
22%inline %{
23
24typedef struct Rig {
25	RIG *rig;
26	struct rig_caps *caps;		/* shortcut to RIG->caps */
27	struct rig_state *state;	/* shortcut to RIG->state */
28	int error_status;
29	int do_exception;
30} Rig;
31
32typedef char * char_string;
33typedef channel_t * channel_t_p;
34typedef channel_t * const_channel_t_p;
35
36%}
37
38%extend channel {
39	channel(vfo_t vfo = RIG_VFO_CURR, int ch = 0) {
40		channel_t *chan;
41
42		chan = (channel_t*)malloc(sizeof(channel_t));
43		if (!chan)
44			return NULL;
45		memset(chan, 0, sizeof(channel_t));
46		chan->vfo = vfo;
47		chan->channel_num = ch;
48		return chan;
49	}
50	~channel (void) {
51		/* TODO: free ext_levels */
52		free(self);
53	}
54}
55
56%include "carrays.i"
57%array_class(struct channel, channelArray);
58%array_class(tone_t, toneArray);
59
60/*
61 * declare wrapper method with one argument besides RIG* and optional no target vfo
62 */
63#define METHOD1(f, t1) void f (t1 _##t1  _VFO_DECL) \
64				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1); }
65#define METHOD2(f, t1, t2) void f (t1 _##t1##_1, t2 _##t2##_2  _VFO_DECL) \
66				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1##_1, _##t2##_2); }
67#define METHOD2_INIT(f, t1, t2, i2) void f (t1 _##t1##_1, t2 _##t2##_2 = i2  _VFO_DECL) \
68				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1##_1, _##t2##_2); }
69#define METHOD3(f, t1) void f ( vfo_t vfo, t1 _##t1) \
70				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1); }
71#define METHOD3_INIT(f, t1, t2, t3, i3) void f (t1 _##t1##_1, t2 _##t2##_2, t3 _##t3##_3 = i3  _VFO_DECL) \
72				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1##_1, _##t2##_2, _##t3##_3); }
73#define METHOD4(f, t1) void f ( vfo_t vfo, t1 _##t1) \
74				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1); }
75#define METHOD4_INIT(f, t1, t2, t3, t4, i4) void f (t1 _##t1##_1, t2 _##t2##_2, t3 _##t3##_3, ##t4##_4 = i4  _VFO_DECL) \
76				{ self->error_status = rig_##f(self->rig  _VFO_ARG, _##t1##_1, _##t2##_2, _##t3##_3 _##t4##_4); }
77/*
78 * declare wrapper method with one output argument besides RIG* (no target vfo)
79 */
80#define METHOD1GET(f, t1) t1 f (void) \
81				{ t1 _##t1; self->error_status = rig_##f(self->rig, &_##t1); return _##t1; }
82
83/*
84 * declare wrapper method with one output argument besides RIG* and vfo
85 */
86#define METHOD1VGET(f, t1) t1 f (vfo_t vfo = RIG_VFO_CURR) \
87				{ t1 _##t1; self->error_status = rig_##f(self->rig, vfo, &_##t1); return _##t1; }
88
89#ifndef SWIGLUA
90#define METHODSIMPLESET(f, t1, fld, chk) void set_##f (setting_t stg, t1 fld  _VFO_DECL) \
91		{ value_t val = {0}; 	if (chk) {	\
92			self->error_status = -RIG_EINVAL;	/* invalid type */	\
93			return;	\
94		}	\
95		val.fld = fld;	\
96		self->error_status = rig_set_##f(self->rig  _VFO_ARG , stg, val);	\
97	}
98#else
99#define METHODSIMPLESET(f, t1, fld, chk) void set_##f (setting_t stg, t1 fld  _VFO_DECL) \
100		{ value_t val = {0}; 	\
101		if (chk) {	\
102			int ival = (int)fld;	\
103			val.i = fld;	\
104		}	\
105		else {	\
106		    val.fld = fld;	\
107		}	\
108		self->error_status = rig_set_##f(self->rig  _VFO_ARG , stg, val);	\
109	}
110#endif
111
112/*
113 * RIG_CONF_ extparm's type:
114 *   NUMERIC: val.f
115 *   COMBO: val.i, starting from 0
116 *   STRING: val.s
117 *   CHECKBUTTON: val.i 0/1
118 */
119
120#ifndef SWIGLUA
121#define METHODSUPERSET(f, t1, fld, chk) void set_##f (const char *name, t1 fld  _VFO_DECL) \
122		{ setting_t stg; value_t val = {0}; 	\
123		stg = rig_parse_##f(name);	\
124		if (!rig_has_set_##f(self->rig, stg)) {	\
125			const struct confparams *cfp;	\
126			cfp = rig_ext_lookup(self->rig, name);	\
127			if (!cfp) {	\
128				self->error_status = -RIG_EINVAL;	/* no such parameter */ \
129				return;	\
130			} \
131			switch (cfp->type) {	\
132			case RIG_CONF_NUMERIC:	\
133				val.fld = fld;	\
134				break;	\
135			case RIG_CONF_CHECKBUTTON:	\
136			case RIG_CONF_COMBO:		\
137				val.i = (int)fld;	\
138				break;	\
139			case RIG_CONF_STRING:		\
140				self->error_status = -RIG_EINVAL;	/* invalid type */	\
141				return;	\
142			default:	\
143				self->error_status = -RIG_ECONF;	\
144				return;	\
145			}	\
146			self->error_status = rig_set_ext_##f(self->rig  _VFO_ARG, cfp->token, val);	\
147			return;	\
148		}	\
149		if (chk) {	\
150			self->error_status = -RIG_EINVAL;	/* invalid type */	\
151			return;	\
152		}	\
153		val.fld = fld;	\
154		self->error_status = rig_set_##f(self->rig  _VFO_ARG , stg, val);	\
155	}
156#else
157#define METHODSUPERSET(f, t1, fld, chk) void set_##f (const char *name, t1 fld  _VFO_DECL) \
158		{ setting_t stg; value_t val = {0}; 	\
159		stg = rig_parse_##f(name);	\
160		if (!rig_has_set_##f(self->rig, stg)) {	\
161			const struct confparams *cfp;	\
162			cfp = rig_ext_lookup(self->rig, name);	\
163			if (!cfp) {	\
164				self->error_status = -RIG_EINVAL;	/* no such parameter */ \
165				return;	\
166			} \
167			switch (cfp->type) {	\
168			case RIG_CONF_NUMERIC:	\
169				val.fld = fld;	\
170				break;	\
171			case RIG_CONF_CHECKBUTTON:	\
172			case RIG_CONF_COMBO:		\
173				val.i = (int)fld;	\
174				break;	\
175			case RIG_CONF_STRING:		\
176				self->error_status = -RIG_EINVAL;	/* invalid type */	\
177				return;	\
178			default:	\
179				self->error_status = -RIG_ECONF;	\
180				return;	\
181			}	\
182			self->error_status = rig_set_ext_##f(self->rig  _VFO_ARG, cfp->token, val);	\
183			return;	\
184		}	\
185		if (chk) {	\
186		    int ival = (int)fld;	\
187		    val.i = ival;	\
188		}	\
189		else	{ \
190		    val.fld = fld;	\
191		}	\
192		self->error_status = rig_set_##f(self->rig  _VFO_ARG , stg, val);	\
193	}
194#endif
195
196#define METHODSTRSET(f) void set_##f (const char *name, const char *s  _VFO_DECL) \
197		{ value_t val = {0}; /* only ext_level/parm's can have string values */  \
198		const struct confparams *cfp; \
199		cfp = rig_ext_lookup(self->rig, name); \
200		if (!cfp) {	\
201			self->error_status = -RIG_EINVAL;	/* no such parameter */ \
202			return; \
203		} \
204		if (cfp->type != RIG_CONF_STRING) { \
205			self->error_status = -RIG_EINVAL;	/* invalid type */ \
206			return; \
207		} \
208		val.cs = s; \
209		self->error_status = rig_set_ext_##f(self->rig _VFO_ARG, cfp->token, val); \
210	}
211
212#define METHODSIMPLEGET(f, t1, fld, chk) t1 get_##f##_##fld (setting_t stg  _VFO_DECL) \
213		{ value_t val = {0}; 	if (chk) {	\
214			self->error_status = -RIG_EINVAL;	/* invalid type */	\
215			return val.fld;		/* undefined value */	\
216		}	\
217		self->error_status = rig_get_##f(self->rig  _VFO_ARG , stg, &val);	\
218		return val.fld;	\
219	}
220
221
222
223#define METHODSUPERGET(fct, t1, fld, chk) t1 get_##fct##_##fld(const char *name  _VFO_DECL) \
224		{ setting_t stg; value_t val = {0}; 	\
225		stg = rig_parse_##fct(name);	\
226		if (!rig_has_get_##fct(self->rig, stg)) {	\
227			const struct confparams *cfp;	\
228			cfp = rig_ext_lookup(self->rig, name);	\
229			if (!cfp) {	\
230				self->error_status = -RIG_EINVAL;	/* no such parameter */ \
231				return val.fld;		/* undefined */ \
232			} \
233			if (cfp->type == RIG_CONF_STRING) { \
234				self->error_status = -RIG_EINVAL;	\
235				return val.fld;	/* undefined */ \
236			}	\
237			self->error_status = rig_get_ext_##fct(self->rig  _VFO_ARG, cfp->token, &val);	\
238			switch (cfp->type) {	\
239			case RIG_CONF_NUMERIC:	\
240				return (t1)val.f;	\
241			case RIG_CONF_CHECKBUTTON:	\
242			case RIG_CONF_COMBO:		\
243				return (t1)val.i;	\
244			default:	\
245				self->error_status = -RIG_ECONF;	\
246				return val.fld;	/* undefined */ \
247			}	\
248		}	\
249		if (chk) {	\
250			self->error_status = -RIG_EINVAL;	/* invalid type */	\
251			return val.fld;	/* undefined */ \
252		}	\
253		self->error_status = rig_get_##fct(self->rig  _VFO_ARG , stg, &val);	\
254		return val.fld;	\
255	}
256
257#define METHODSTRGET(f) void get_##f (const char *name, char *returnstr  _VFO_DECL) \
258		{ value_t val = {0}; /* only ext_level/parm's can have string values */ \
259		const struct confparams *cfp; \
260		returnstr[0] = '\0'; \
261		cfp = rig_ext_lookup(self->rig, name); \
262		if (!cfp || cfp->type != RIG_CONF_STRING) {	\
263			self->error_status = -RIG_EINVAL;	/* no such parameter/invalid type */ \
264			return; \
265		} \
266		val.s = returnstr; \
267		self->error_status = rig_get_ext_##f(self->rig _VFO_ARG, cfp->token, &val); \
268	}
269
270
271/*
272 * string as return value
273 * NB: The %apply has to be outside the %extend,
274 * but the %cstring_bounded_output must be inside.
275 */
276%ignore MAX_RETURNSTR;
277#define MAX_RETURNSTR 256
278
279#ifndef SWIGJAVA
280%apply char *OUTPUT { char *returnstr };
281#endif
282
283/*
284 * Rig class alike
285 */
286%extend Rig {
287
288#ifndef SWIGLUA
289#ifndef SWIG_CSTRING_UNIMPL
290#ifndef SWIGJAVA
291	%cstring_bounded_output(char *returnstr, MAX_RETURNSTR);
292#endif
293#endif
294#endif
295
296	Rig(int rig_model) {
297		Rig *r;
298
299		r = (Rig*)malloc(sizeof(Rig));
300		if (!r)
301			return NULL;
302		r->rig = rig_init(rig_model);
303		if (!r->rig) {
304			free(r);
305			return NULL;
306		}
307		/* install shortcuts */
308		r->caps = r->rig->caps;
309		r->state = &r->rig->state;
310		r->do_exception = 0;	/* default is disabled */
311		r->error_status = RIG_OK;
312		return r;
313	}
314	~Rig () {
315		rig_cleanup(self->rig);
316		free(self);
317	}
318
319/*
320 * return code checking
321 */
322%exception {
323	arg1->error_status = RIG_OK;
324	$action
325	if (arg1->error_status != RIG_OK && arg1->do_exception)
326		SWIG_exception(SWIG_UnknownError, rigerror(arg1->error_status));
327}
328
329	void open () {
330		self->error_status = rig_open(self->rig);
331	}
332	void close () {
333		self->error_status = rig_close(self->rig);
334	}
335
336	/*
337	 * group all vfo, and non vfo apart
338	 */
339#define _VFO_ARG	,vfo
340#define _VFO_DECL	,vfo_t vfo = RIG_VFO_CURR
341
342	METHOD3(set_freq, freq_t)
343	METHOD2_INIT(set_mode, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL)
344	METHOD3(set_ptt, ptt_t)
345	METHOD3(set_rptr_shift, rptr_shift_t)
346	METHOD3(set_rptr_offs, shortfreq_t)
347	METHOD3(set_ctcss_tone, tone_t)
348	METHOD3(set_dcs_code, tone_t)
349	METHOD3(set_ctcss_sql, tone_t)
350	METHOD1(set_dcs_sql, tone_t)
351	METHOD3(set_split_freq, freq_t)
352	METHOD2_INIT(set_split_mode, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL)
353	METHOD3_INIT(set_split_freq_mode, freq_t, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL)
354	METHOD2(set_split_vfo, split_t, vfo_t)
355	METHOD3(set_rit, shortfreq_t)
356	METHOD3(set_xit, shortfreq_t)
357	METHOD3(set_ts, shortfreq_t)
358	METHOD2(set_ant, ant_t, value_t)
359	METHOD2(set_func, setting_t, int)
360	METHOD2(set_ext_func, token_t, int)
361	METHOD3(set_bank, int)
362	METHOD3(set_mem, int)
363	METHOD3(send_dtmf, const_char_string)
364	METHOD3(send_morse, const_char_string)
365	METHOD3(vfo_op, vfo_op_t)
366	METHOD2(scan, scan_t, int)
367	METHODSIMPLESET(level, int, i, RIG_LEVEL_IS_FLOAT(stg))
368	METHODSIMPLESET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg))
369	METHODSUPERSET(level, int, i, RIG_LEVEL_IS_FLOAT(stg))
370	METHODSUPERSET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg))
371	METHODSTRSET(level)
372	METHOD2(set_ext_level, token_t, value_t)
373
374	METHODSIMPLEGET(level, int, i, RIG_LEVEL_IS_FLOAT(stg))
375	METHODSIMPLEGET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg))
376	METHODSUPERGET(level, int, i, RIG_LEVEL_IS_FLOAT(stg))
377	METHODSUPERGET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg))
378	METHODSTRGET(level)
379
380	/*
381	 * these ones take no vfo arg
382	 */
383#undef _VFO_ARG
384#undef _VFO_DECL
385#define _VFO_ARG
386#define _VFO_DECL
387	METHOD1(set_vfo, vfo_t)		/* particular case */
388	METHOD1(set_powerstat, powerstat_t)
389	METHOD1(set_trn, int)
390	METHOD1(has_get_level, setting_t)
391	METHOD1(has_set_parm, setting_t)
392	METHOD1(has_set_func, setting_t)
393	METHOD1(reset, reset_t)
394	METHOD1(has_scan, scan_t)
395	METHOD1(has_vfo_op, vfo_op_t)
396	METHOD1(passband_normal, rmode_t)
397	METHOD1(passband_narrow, rmode_t)
398	METHOD1(passband_wide, rmode_t)
399
400	METHOD1(ext_token_lookup, const_char_string)	/* level & parm */
401	METHOD1(token_lookup, const_char_string)	/* conf */
402
403	METHOD2(set_conf, token_t, const_char_string)
404	METHOD2(set_ext_parm, token_t, value_t)
405
406	METHODSIMPLESET(parm, int, i, RIG_PARM_IS_FLOAT(stg))
407	METHODSIMPLESET(parm, float, f, !RIG_PARM_IS_FLOAT(stg))
408	METHODSUPERSET(parm, int, i, RIG_PARM_IS_FLOAT(stg))
409	METHODSUPERSET(parm, float, f, !RIG_PARM_IS_FLOAT(stg))
410	METHODSTRSET(parm)
411
412	METHODSIMPLEGET(parm, int, i, RIG_PARM_IS_FLOAT(stg))
413	METHODSIMPLEGET(parm, float, f, !RIG_PARM_IS_FLOAT(stg))
414	METHODSUPERGET(parm, int, i, RIG_PARM_IS_FLOAT(stg))
415	METHODSUPERGET(parm, float, f, !RIG_PARM_IS_FLOAT(stg))
416	METHODSTRGET(parm)
417
418
419	void set_conf(const char *name, const char *val) {
420		token_t tok = rig_token_lookup(self->rig, name);
421		if (tok == RIG_CONF_END)
422			self->error_status = -RIG_EINVAL;
423		else
424			self->error_status = rig_set_conf(self->rig, tok, val);
425	}
426
427
428
429	/* TODO: get_ext_parm_list, level, conf, .. */
430
431	/* get functions */
432
433	METHOD1VGET(get_freq, freq_t)
434	extern void get_mode(rmode_t * OUTPUT, pbwidth_t * OUTPUT, vfo_t vfo = RIG_VFO_CURR);
435	extern void get_split_mode(rmode_t * OUTPUT, pbwidth_t * OUTPUT, vfo_t vfo = RIG_VFO_CURR);
436	METHOD1GET(get_vfo, vfo_t)
437	METHOD1VGET(get_ptt, ptt_t)
438	METHOD1VGET(get_rptr_shift, rptr_shift_t)
439	METHOD1VGET(get_rptr_offs, shortfreq_t)
440	METHOD1VGET(get_ctcss_tone, tone_t)
441	METHOD1VGET(get_dcs_code, tone_t)
442	METHOD1VGET(get_ctcss_sql, tone_t)
443	METHOD1VGET(get_dcs_sql, tone_t)
444	METHOD1VGET(get_split_freq, freq_t)
445	void get_split_vfo(split_t *split, vfo_t *tx_vfo, vfo_t vfo = RIG_VFO_CURR)
446	{ self->error_status = rig_get_split_vfo(self->rig, vfo, split, tx_vfo); }
447
448	METHOD1VGET(get_rit, shortfreq_t)
449	METHOD1VGET(get_xit, shortfreq_t)
450	METHOD1VGET(get_ts, shortfreq_t)
451	extern void get_ant(ant_t *ant_rx, ant_t *ant_tx, ant_t *ant_curr, value_t * OUTPUT, ant_t ant, vfo_t vfo = RIG_VFO_CURR);
452    extern void get_vfo_info (int *satmode, split_t *split, pbwidth_t *width, rmode_t *mode, freq_t *freq, vfo_t vfo = RIG_VFO_CURR);
453	METHOD1VGET(get_mem, int)
454	METHOD1GET(get_powerstat, powerstat_t)
455	METHOD1GET(get_trn, int)
456	METHOD1VGET(get_dcd, dcd_t)
457
458	int mem_count(void) {
459		return rig_mem_count(self->rig);
460	}
461
462	const chan_t *lookup_mem_caps(int channel_num = RIG_MEM_CAPS_ALL)
463	{
464		return rig_lookup_mem_caps(self->rig, channel_num);
465	}
466
467	void set_channel(const struct channel *chan) {
468		self->error_status = rig_set_channel(self->rig, RIG_VFO_NONE, chan);
469	}
470
471	void get_channel(struct channel *chan, int read_only) {
472		self->error_status = rig_get_channel(self->rig, RIG_VFO_NONE, chan, read_only);
473		/* TODO: handle ext_level's */
474	}
475
476	void chan_clear(struct channel *chans, int nb_chans = 1) {
477		memset(chans, 0, sizeof(struct channel)*nb_chans);
478	}
479
480	void get_chan_all(struct channel *chans) {
481		self->error_status = rig_get_chan_all(self->rig, RIG_VFO_NONE, chans);
482		/* TODO: handle ext_level's */
483	}
484
485	/*
486	 * Rem: does swig has to be told that returned object need to be handled by gc?
487	 */
488	struct channel *get_chan_all(void);
489
490	/* get_channel() returns current VFO data
491	 * get_channel(10) returns content of memory #10
492	 * get_channel(0, RIG_VFO_A) returns VFO A data
493	 * Rem: does swig has to be told that returned object need to be handled by gc?
494	 */
495	struct channel *get_channel(int read_only, int channel_num = INT_MAX, vfo_t vfo = RIG_VFO_MEM) {
496		struct channel *chan;
497		chan = new_channel(channel_num != INT_MAX ? vfo : RIG_VFO_CURR, channel_num);
498		if (!chan)
499		{
500			self->error_status = -RIG_ENOMEM;
501			return NULL;
502		}
503		self->error_status = rig_get_channel(self->rig, RIG_VFO_NONE, chan, read_only);
504		/* TODO: copy ext_level's */
505		return chan;
506	}
507
508	void get_conf(token_t tok, char *returnstr) {
509		returnstr[0] = '\0';
510		self->error_status = rig_get_conf(self->rig, tok, returnstr);
511	}
512
513	void get_conf(const char *name, char *returnstr) {
514		returnstr[0] = '\0';
515		token_t tok = rig_token_lookup(self->rig, name);
516		if (tok == RIG_CONF_END)
517			self->error_status = -RIG_EINVAL;
518		else
519			self->error_status = rig_get_conf(self->rig, tok, returnstr);
520	}
521
522	void recv_dtmf(char *returnstr, vfo_t vfo = RIG_VFO_CURR) {
523		int len = MAX_RETURNSTR;
524		self->error_status = rig_recv_dtmf(self->rig, vfo, returnstr, &len);
525		returnstr[len] = '\0';
526	}
527	const char * get_info(void) {
528		const char *s;
529		s = rig_get_info(self->rig);
530		self->error_status = s ? RIG_OK : -RIG_EINVAL;
531		return s;
532	}
533
534	int get_func(setting_t func, vfo_t vfo = RIG_VFO_CURR) {
535		int status;
536		self->error_status = rig_get_func(self->rig, vfo, func, &status);
537		return status;
538	}
539
540	int get_ext_func(token_t func, vfo_t vfo = RIG_VFO_CURR) {
541		int status;
542		self->error_status = rig_get_ext_func(self->rig, vfo, func, &status);
543		return status;
544	}
545
546//#ifndef SWIGJAVA
547	/* TODO */
548	void get_level(setting_t level, vfo_t vfo = RIG_VFO_CURR)
549		{ value_t val = {0}; self->error_status = rig_get_level(self->rig, vfo, level, &val);
550			//if (RIG_LEVEL_IS_FLOAT(level))
551			/* TODO: dynamic casting */
552		}
553
554	void get_ext_level(token_t token, vfo_t vfo = RIG_VFO_CURR)
555		{ value_t val = {0}; self->error_status = rig_get_level(self->rig, vfo, token, &val);
556			//if (RIG_LEVEL_IS_FLOAT(level))
557			/* TODO: dynamic casting */
558		}
559
560	void get_parm(setting_t parm)
561		{ value_t val = {0}; self->error_status = rig_get_parm(self->rig, parm, &val);
562			//if (RIG_LEVEL_IS_FLOAT(parm))
563			/* TODO: dynamic casting */
564		}
565
566	void get_ext_parm(token_t parm)
567		{ value_t val = {0}; self->error_status = rig_get_parm(self->rig, parm, &val);
568			//if (RIG_LEVEL_IS_FLOAT(parm))
569			/* TODO: dynamic casting */
570		}
571
572//#endif
573
574};
575
576%{
577
578/*
579 * these ones return 2 values, here is a perl example:
580 * 	($mode, $width) = $rig->get_mode();
581 */
582void Rig_get_mode(Rig *self, rmode_t *mode, pbwidth_t *width, vfo_t vfo)
583{
584	self->error_status = rig_get_mode(self->rig, vfo, mode, width);
585}
586
587void Rig_get_split_mode(Rig *self, rmode_t *mode, pbwidth_t *width, vfo_t vfo)
588{
589	self->error_status = rig_get_split_mode(self->rig, vfo, mode, width);
590}
591
592/*
593 * these ones return 3 values
594 */
595void Rig_get_split_freq_mode(Rig *self, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width)
596{
597	self->error_status = rig_get_split_freq_mode(self->rig, vfo, tx_freq, tx_mode, tx_width);
598}
599
600
601/*
602 * these ones return 4 values
603 */
604void Rig_get_ant(Rig *self, ant_t *ant_rx, ant_t *ant_tx, ant_t *ant_curr, value_t *option, ant_t ant, vfo_t vfo)
605{
606	self->error_status = rig_get_ant(self->rig, vfo, ant, option, ant_curr, ant_tx, ant_rx);
607}
608void Rig_get_vfo_info (Rig *self, int *satmode, split_t *split, pbwidth_t *width, rmode_t *mode, freq_t *freq, vfo_t vfo)
609{
610    self->error_status = rig_get_vfo_info(self->rig, vfo, freq, mode, width, split, satmode);
611}
612
613
614struct channel *Rig_get_chan_all(Rig *self)
615{
616	struct channel *chans;
617	int nb_chans = rig_mem_count(self->rig);
618
619	/* TODO: memleak: typemap to release that memory */
620	chans = calloc(sizeof (struct channel), nb_chans);
621	if (!chans)
622	{
623		self->error_status = -RIG_ENOMEM;
624		return NULL;
625	}
626	self->error_status = rig_get_chan_all(self->rig, RIG_VFO_NONE, chans);
627	/* TODO: copy ext_level's */
628	return chans;
629}
630
631
632%}
633