Test Failed
Push — master ( d4cdd3...569253 )
by Vyacheslav
03:17 queued 01:50
created

goagi.*AGI.SetMusic   A

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
package goagi
2
3
import (
4
	"fmt"
5
)
6
7
// Command sends command as string to the AGI and returns response valus with
8
// text response
9
func (agi *AGI) Command(cmd string) (Response, error) {
10
	return agi.execute(cmd+"\n", false)
11
}
12
13
// Answer executes AGI command "ANSWER"
14
// Answers channel if not already in answer state.
15
func (agi *AGI) Answer() (Response, error) {
16
	return agi.execute("ANSWER\n", true)
17
}
18
19
// AsyncAGIBreak Interrupts Async AGI
20
//	Interrupts expected flow of Async AGI commands and returns control
21
// to previous source (typically, the PBX dialplan).
22
func (agi *AGI) AsyncAGIBreak() (Response, error) {
23
	return agi.execute("ASYNCAGI BREAK\n", true)
24
}
25
26
// ChannelStatus returns status of the connected channel.
27
//
28
// If no channel name is given (empty line) then returns the status of the current channel.
29
//
30
//Return values:
31
//	0 - Channel is down and available.
32
//	1 - Channel is down, but reserved.
33
//	2 - Channel is off hook.
34
//	3 - Digits (or equivalent) have been dialed.
35
//	4 - Line is ringing.
36
//	5 - Remote end is ringing.
37
//	6 - Line is up.
38
//	7 - Line is busy.
39
func (agi *AGI) ChannelStatus(channel string) (Response, error) {
40
	cmd := fmt.Sprintf("CHANNEL STATUS %s\n", channel)
41
	return agi.execute(cmd, true)
42
}
43
44
// ControlStreamFile sends audio file on channel and allows the listener
45
// to control the stream.
46
//	Send the given file, allowing playback to be controlled by the given digits, if any.
47
// Use double quotes for the digits if you wish none to be permitted. If offsetms
48
// is provided then the audio will seek to offsetms before play starts.
49
//	Example:
50
//	agi.ControlStreamFile("prompt_en", "19", "3000", "#", "0", "#", "1600")
51
//	agi.ControlStreamFile("prompt_en", "")
52
//	agi.ControlStreamFile("prompt_en", "19", "", "", "", "#", "1600")
53
//CONTROL STREAM FILE FILENAME ESCAPE_DIGITS
54
//SKIPMS FFCHAR REWCHR PAUSECHR OFFSETMS
55
func (agi *AGI) ControlStreamFile(filename, digits string, args ...string) (Response, error) {
56
	cmd := fmt.Sprintf("CONTROL STREAM FILE %s %q", filename, digits)
57
58
	if len(args) > 5 {
59
		return nil, ErrAGI.Msg("Too many arguments. Unknown args: %v", args[5:])
60
	}
61
62
	for _, v := range args {
63
		cmd = fmt.Sprintf("%s %q", cmd, v)
64
	}
65
66
	cmd = fmt.Sprintf("%s\n", cmd)
67
	return agi.execute(cmd, false)
68
}
69
70
// DatabaseDel deletes an entry in the Asterisk database for a given family and key.
71
//	Returns status and error if fails.
72
func (agi *AGI) DatabaseDel(family, key string) (Response, error) {
73
	cmd := fmt.Sprintf("DATABASE DEL %s %s\n", family, key)
74
	return agi.execute(cmd, true)
75
}
76
77
// DatabaseDelTree deletes a family or specific keytree within a family in the Asterisk database.
78
func (agi *AGI) DatabaseDelTree(family, keytree string) (Response, error) {
79
	cmd := fmt.Sprintf("DATABASE DELTREE %s %s\n", family, keytree)
80
	return agi.execute(cmd, true)
81
}
82
83
// DatabaseGet Retrieves an entry in the Asterisk database for a given family and key.
84
//	Returns value as string or error if failed or value not set
85
//  Response.Value() for result
86
func (agi *AGI) DatabaseGet(family, key string) (Response, error) {
87
	cmd := fmt.Sprintf("DATABASE GET %s %s\n", family, key)
88
	return agi.execute(cmd, true)
89
}
90
91
// DatabasePut adds or updates an entry in the Asterisk database for
92
// a given family, key, and value.
93
func (agi *AGI) DatabasePut(family, key, val string) (Response, error) {
94
	cmd := fmt.Sprintf("DATABASE PUT %s %s %s\n", family, key, val)
95
	return agi.execute(cmd, true)
96
}
97
98
// Exec executes application with given options.
99
func (agi *AGI) Exec(app, opts string) (Response, error) {
100
	cmd := fmt.Sprintf("EXEC %s %q\n", app, opts)
101
	return agi.execute(cmd, true)
102
}
103
104
// GetData Stream the given file, and receive DTMF data.
105
// Note: when timeout is 0 then Asterisk will use 6 secods.
106
// Note: Asterisk has strange way to handle get data response.
107
// Contrary to other responses, where result has numeric value,
108
// here asterisk puts DTMF to sent by user to result and this value
109
// may contain "#" and "*".
110
// To get DTMF sent by user use Response.Data()
111
// Response.Value() will contain "timeout" if user has not terminated
112
// input with "#"
113
func (agi *AGI) GetData(file string, timeout, maxdigit int) (Response, error) {
114
	cmd := fmt.Sprintf("GET DATA %s %d %d\n", file, timeout, maxdigit)
115
	resp, err := agi.execute(cmd, false)
116
	if err != nil {
117
		return nil, err
118
	}
119
	// special get data result treatment
120
	if resp.Result() == -1 || resp.Code() != codeSucc {
121
		return resp, nil
122
	}
123
124
	r := resp.(*responseSuccess)
125
	r.result = 0
126
	r.data = scanResultStrFromRaw(r.raw)
127
	return r, nil
128
}
129
130
// GetFullVariable evaluates a channel expression
131
func (agi *AGI) GetFullVariable(name, channel string) (Response, error) {
132
	cmd := "GET FULL VARIABLE"
133
	if channel == "" {
134
		cmd = fmt.Sprintf("%s %s\n", cmd, name)
135
	} else {
136
		cmd = fmt.Sprintf("%s %s %s\n", cmd, name, channel)
137
	}
138
	return agi.execute(cmd, true)
139
}
140
141
// GetOption Stream file, prompt for DTMF, with timeout.
142
//	Behaves similar to STREAM FILE but used with a timeout option.
143
//	Returns digit pressed, offset and error
144
func (agi *AGI) GetOption(filename, digits string, timeout int32) (Response, error) {
145
	cmd := fmt.Sprintf("GET OPTION %s %q %d\n", filename, digits, timeout)
146
	return agi.execute(cmd, false)
147
}
148
149
// GetVariable Gets a channel variable.
150
func (agi *AGI) GetVariable(name string) (Response, error) {
151
	cmd := fmt.Sprintf("GET VARIABLE %s\n", name)
152
	return agi.execute(cmd, true)
153
}
154
155
// Hangup a channel.
156
//	Hangs up the specified channel. If no channel name is given, hangs up the current channel
157
func (agi *AGI) Hangup(channel ...string) (Response, error) {
158
	cmd := "HANGUP"
159
160
	if len(channel) > 0 {
161
		cmd = fmt.Sprintf("%s %s\n", cmd, channel[0])
162
	} else {
163
		cmd = fmt.Sprintf("%s\n", cmd)
164
	}
165
	return agi.execute(cmd, true)
166
}
167
168
// ReceiveChar Receives one character from channels supporting it.
169
//	Most channels do not support the reception of text. Returns the decimal value of
170
// the character if one is received, or 0 if the channel does not support text reception.
171
//	timeout - The maximum time to wait for input in milliseconds, or 0 for infinite.
172
// Returns result -1 on error or char byte
173
func (agi *AGI) ReceiveChar(timeout int) (Response, error) {
174
	cmd := fmt.Sprintf("RECEIVE CHAR %d\n", timeout)
175
	return agi.execute(cmd, false)
176
}
177
178
// ReceiveText Receives text from channels supporting it.
179
//	timeout - The timeout to be the maximum time to wait for input in milliseconds, or 0 for infinite.
180
func (agi *AGI) ReceiveText(timeout int) (Response, error) {
181
	cmd := fmt.Sprintf("RECEIVE TEXT %d\n", timeout)
182
	return agi.execute(cmd, false)
183
}
184
185
// RecordFile Record to a file until a given dtmf digit in the sequence is received.
186
// The format will specify what kind of file will be recorded. The timeout is the
187
// maximum record time in milliseconds, or -1 for no timeout.
188
//	offset samples is optional, and, if provided, will seek to the offset without
189
// exceeding the end of the file.
190
//	beep causes Asterisk to play a beep to the channel that is about to be recorded.
191
//	silence is the number of seconds of silence allowed before the function returns
192
// despite the lack of dtmf digits or reaching timeout.
193
//	silence is the number of seconds of silence that are permitted before the
194
// recording is terminated, regardless of the escape_digits or timeout arguments
195
// If interupted by DTMF, digits will be available in Response.Data()
196
func (agi *AGI) RecordFile(file, format, escDigits string,
197
	timeout, offset int, beep bool, silence int) (Response, error) {
198
199
	cmd := "RECORD FILE"
200
	cmd = fmt.Sprintf("%s %s %s %q %d", cmd, file, format, escDigits, timeout)
201
	if offset > 0 {
202
		cmd = fmt.Sprintf("%s %d", cmd, offset)
203
	}
204
	if beep {
205
		cmd = fmt.Sprintf("%s BEEP", cmd)
206
	}
207
	if silence > 0 {
208
		cmd = fmt.Sprintf("%s s=%d", cmd, silence)
209
	}
210
	cmd = fmt.Sprintf("%s\n", cmd)
211
212
	resp, err := agi.execute(cmd, false)
213
	if err != nil {
214
		return nil, err
215
	}
216
217
	if resp.Value() != "dtmf" {
218
		return resp, nil
219
	}
220
221
	r := resp.(*responseSuccess)
222
	r.result = 1
223
	r.data = scanResultStrFromRaw(r.raw)
224
225
	return r, nil
226
}
227
228
// SayAlpha says a given character string, returning early if any of the given
229
// DTMF digits are received on the channel.
230
func (agi *AGI) SayAlpha(number, escDigits string) (Response, error) {
231
	cmd := fmt.Sprintf("SAY ALPHA %s %q\n", number, escDigits)
232
	return agi.execute(cmd, false)
233
}
234
235
// SayDate say a given date, returning early if any of the given DTMF digits
236
// are received on the channel
237
func (agi *AGI) SayDate(date, escDigits string) (Response, error) {
238
	cmd := fmt.Sprintf("SAY DATE %s %q\n", date, escDigits)
239
	return agi.execute(cmd, false)
240
}
241
242
// SayDatetime say a given time, returning early if any of the given DTMF
243
// digits are received on the channel
244
func (agi *AGI) SayDatetime(time, escDigits, format, timezone string) (Response, error) {
245
	cmd := fmt.Sprintf("SAY DATETIME %s %q %q %q\n", time, escDigits, format, timezone)
246
	return agi.execute(cmd, false)
247
}
248
249
// SayDigits say a given digit string, returning early if any of the given
250
// DTMF digits are received on the channel
251
func (agi *AGI) SayDigits(number, escDigits string) (Response, error) {
252
	cmd := fmt.Sprintf("SAY DIGITS %s %q\n", number, escDigits)
253
	return agi.execute(cmd, false)
254
}
255
256
// SayNumber say a given digit string, returning early if any of the given
257
// DTMF digits are received on the channel
258
func (agi *AGI) SayNumber(number, escDigits string) (Response, error) {
259
	cmd := fmt.Sprintf("SAY NUMBER %s %q\n", number, escDigits)
260
	return agi.execute(cmd, false)
261
}
262
263
// SayPhonetic say a given character string with phonetics, returning early
264
// if any of the given DTMF digits are received on the channel
265
func (agi *AGI) SayPhonetic(str, escDigits string) (Response, error) {
266
	cmd := fmt.Sprintf("SAY PHONETIC %s %q\n", str, escDigits)
267
	return agi.execute(cmd, false)
268
}
269
270
// SayTime say a given time, returning early if any of the given DTMF digits
271
// are received on the channel
272
func (agi *AGI) SayTime(time, escDigits string) (Response, error) {
273
	cmd := fmt.Sprintf("SAY TIME %s %q\n", time, escDigits)
274
	return agi.execute(cmd, false)
275
}
276
277
// SendImage Sends the given image on a channel. Most channels do not support
278
// the transmission of images.
279
func (agi *AGI) SendImage(image string) (Response, error) {
280
	cmd := fmt.Sprintf("SEND IMAGE %q\n", image)
281
	return agi.execute(cmd, false)
282
}
283
284
// SendText Sends the given text on a channel. Most channels do not support
285
// the transmission of text.
286
func (agi *AGI) SendText(text string) (Response, error) {
287
	cmd := fmt.Sprintf("SEND TEXT %q\n", text)
288
	return agi.execute(cmd, false)
289
}
290
291
// SetAutoHangup Cause the channel to automatically hangup at time seconds in the future.
292
// Setting to 0 will cause the autohangup feature to be disabled on this channel.
293
func (agi *AGI) SetAutoHangup(seconds int) (Response, error) {
294
	cmd := fmt.Sprintf("SET AUTOHANGUP %d\n", seconds)
295
	return agi.execute(cmd, true)
296
}
297
298
// SetCallerid Changes the callerid of the current channel.
299
func (agi *AGI) SetCallerid(clid string) (Response, error) {
300
	cmd := fmt.Sprintf("SET CALLERID %q\n", clid)
301
	return agi.execute(cmd, true)
302
}
303
304
// SetContext Sets the context for continuation upon exiting the application.
305
func (agi *AGI) SetContext(ctx string) (Response, error) {
306
	cmd := fmt.Sprintf("SET CONTEXT %s\n", ctx)
307
	return agi.execute(cmd, true)
308
}
309
310
// SetExtension Changes the extension for continuation upon exiting the application.
311
func (agi *AGI) SetExtension(ext string) (Response, error) {
312
	cmd := fmt.Sprintf("SET EXTENSION %s\n", ext)
313
	return agi.execute(cmd, true)
314
}
315
316
// SetMusic Enables/Disables the music on hold generator. If class is not specified,
317
// then the default music on hold class will be used.
318
func (agi *AGI) SetMusic(enable bool, class string) (Response, error) {
319
	cmd := "SET MUSIC"
320
321
	if enable {
322
		cmd = fmt.Sprintf("%s on", cmd)
323
	} else {
324
		cmd = fmt.Sprintf("%s off", cmd)
325
	}
326
327
	cmd = fmt.Sprintf("%s %q\n", cmd, class)
328
	return agi.execute(cmd, true)
329
}
330
331
// SetPriority Changes the priority for continuation upon exiting the application.
332
// The priority must be a valid priority or label.
333
func (agi *AGI) SetPriority(priority string) (Response, error) {
334
	cmd := fmt.Sprintf("SET PRIORITY %s\n", priority)
335
	return agi.execute(cmd, true)
336
}
337
338
// SetVariable Sets a variable to the current channel.
339
func (agi *AGI) SetVariable(name, value string) (Response, error) {
340
	cmd := fmt.Sprintf("SET VARIABLE %s %q\n", name, value)
341
	return agi.execute(cmd, true)
342
}
343
344
// StreamFile Send the given file, allowing playback to be interrupted by the given
345
// digits, if any.
346
func (agi *AGI) StreamFile(file, escDigits string, offset int) (Response, error) {
347
	cmd := fmt.Sprintf("STREAM FILE %s %q %d\n", file, escDigits, offset)
348
	return agi.execute(cmd, false)
349
}
350
351
// TDDMode Enable/Disable TDD transmission/reception on a channel.
352
//	Modes: on, off, mate, tdd
353
func (agi *AGI) TDDMode(mode string) (Response, error) {
354
	cmd := "TDD MODE"
355
	switch mode {
356
	case "on", "off", "mate", "tdd":
357
		cmd = fmt.Sprintf("%s %s\n", cmd, mode)
358
	default:
359
		cmd = fmt.Sprintf("%s off\n", cmd)
360
	}
361
	return agi.execute(cmd, false)
362
}
363
364
// Verbose Sends message to the console via verbose message system.
365
// level is the verbose level (1-4)
366
func (agi *AGI) Verbose(msg string, level ...int) (Response, error) {
367
	cmd := fmt.Sprintf("VERBOSE %q", msg)
368
	lvl := 1
369
	if level != nil {
370
		if level[0] > 0 && level[0] < 5 {
371
			lvl = level[0]
372
		}
373
	}
374
	cmd = fmt.Sprintf("%s %d\n", cmd, lvl)
375
	return agi.execute(cmd, true)
376
}
377
378
// WaitForDigit Waits up to timeout *milliseconds* for channel to receive a DTMF digit.
379
// Use -1 for the timeout value if you desire the call to block indefinitely.
380
//	Return digit pressed as string or error
381
func (agi *AGI) WaitForDigit(timeout int) (Response, error) {
382
	cmd := fmt.Sprintf("WAIT FOR DIGIT %d\n", timeout)
383
	return agi.execute(cmd, false)
384
}
385