Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
1f8ae708
Commit
1f8ae708
authored
5 years ago
by
Sean Bright
Browse files
Options
Downloads
Patches
Plain Diff
res_musiconhold: Use a vector instead of custom array allocation
Change-Id: Ic476a56608b1820ca93dcf68d10cd76fc0b94141
parent
4018e883
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
res/res_musiconhold.c
+55
-87
55 additions, 87 deletions
res/res_musiconhold.c
with
55 additions
and
87 deletions
res/res_musiconhold.c
+
55
−
87
View file @
1f8ae708
...
@@ -171,12 +171,8 @@ struct mohclass {
...
@@ -171,12 +171,8 @@ struct mohclass {
char
announcement
[
256
];
char
announcement
[
256
];
char
mode
[
80
];
char
mode
[
80
];
char
digit
;
char
digit
;
/*! A dynamically sized array to hold the list of filenames in "files" mode */
/*! A vector of filenames in "files" mode */
char
**
filearray
;
struct
ast_vector_string
files
;
/*! The current size of the filearray */
int
allowed_files
;
/*! The current number of files loaded into the filearray */
int
total_files
;
unsigned
int
flags
;
unsigned
int
flags
;
/*! The format from the MOH source, not applicable to "files" mode */
/*! The format from the MOH source, not applicable to "files" mode */
struct
ast_format
*
format
;
struct
ast_format
*
format
;
...
@@ -318,6 +314,7 @@ static int ast_moh_files_next(struct ast_channel *chan)
...
@@ -318,6 +314,7 @@ static int ast_moh_files_next(struct ast_channel *chan)
{
{
struct
moh_files_state
*
state
=
ast_channel_music_state
(
chan
);
struct
moh_files_state
*
state
=
ast_channel_music_state
(
chan
);
int
tries
;
int
tries
;
size_t
file_count
;
/* Discontinue a stream if it is running already */
/* Discontinue a stream if it is running already */
if
(
ast_channel_stream
(
chan
))
{
if
(
ast_channel_stream
(
chan
))
{
...
@@ -335,7 +332,8 @@ static int ast_moh_files_next(struct ast_channel *chan)
...
@@ -335,7 +332,8 @@ static int ast_moh_files_next(struct ast_channel *chan)
state
->
announcement
=
0
;
state
->
announcement
=
0
;
}
}
if
(
!
state
->
class
->
total_files
)
{
file_count
=
AST_VECTOR_SIZE
(
&
state
->
class
->
files
);
if
(
!
file_count
)
{
ast_log
(
LOG_WARNING
,
"No files available for class '%s'
\n
"
,
state
->
class
->
name
);
ast_log
(
LOG_WARNING
,
"No files available for class '%s'
\n
"
,
state
->
class
->
name
);
return
-
1
;
return
-
1
;
}
}
...
@@ -343,15 +341,15 @@ static int ast_moh_files_next(struct ast_channel *chan)
...
@@ -343,15 +341,15 @@ static int ast_moh_files_next(struct ast_channel *chan)
if
(
state
->
pos
==
0
&&
ast_strlen_zero
(
state
->
save_pos_filename
))
{
if
(
state
->
pos
==
0
&&
ast_strlen_zero
(
state
->
save_pos_filename
))
{
/* First time so lets play the file. */
/* First time so lets play the file. */
state
->
save_pos
=
-
1
;
state
->
save_pos
=
-
1
;
}
else
if
(
state
->
save_pos
>=
0
&&
state
->
save_pos
<
state
->
class
->
total_files
&&
!
strcmp
(
state
->
class
->
file
array
[
state
->
save_pos
]
,
state
->
save_pos_filename
))
{
}
else
if
(
state
->
save_pos
>=
0
&&
state
->
save_pos
<
file_count
&&
!
strcmp
(
AST_VECTOR_GET
(
&
state
->
class
->
file
s
,
state
->
save_pos
)
,
state
->
save_pos_filename
))
{
/* If a specific file has been saved confirm it still exists and that it is still valid */
/* If a specific file has been saved confirm it still exists and that it is still valid */
state
->
pos
=
state
->
save_pos
;
state
->
pos
=
state
->
save_pos
;
state
->
save_pos
=
-
1
;
state
->
save_pos
=
-
1
;
}
else
if
(
ast_test_flag
(
state
->
class
,
MOH_SORTMODE
)
==
MOH_RANDOMIZE
)
{
}
else
if
(
ast_test_flag
(
state
->
class
,
MOH_SORTMODE
)
==
MOH_RANDOMIZE
)
{
/* Get a random file and ensure we can open it */
/* Get a random file and ensure we can open it */
for
(
tries
=
0
;
tries
<
20
;
tries
++
)
{
for
(
tries
=
0
;
tries
<
20
;
tries
++
)
{
state
->
pos
=
ast_random
()
%
state
->
class
->
total_files
;
state
->
pos
=
ast_random
()
%
file_count
;
if
(
ast_fileexists
(
state
->
class
->
file
array
[
state
->
pos
]
,
NULL
,
NULL
)
>
0
)
{
if
(
ast_fileexists
(
AST_VECTOR_GET
(
&
state
->
class
->
file
s
,
state
->
pos
)
,
NULL
,
NULL
)
>
0
)
{
break
;
break
;
}
}
}
}
...
@@ -360,29 +358,29 @@ static int ast_moh_files_next(struct ast_channel *chan)
...
@@ -360,29 +358,29 @@ static int ast_moh_files_next(struct ast_channel *chan)
}
else
{
}
else
{
/* This is easy, just increment our position and make sure we don't exceed the total file count */
/* This is easy, just increment our position and make sure we don't exceed the total file count */
state
->
pos
++
;
state
->
pos
++
;
state
->
pos
%=
state
->
class
->
total_files
;
state
->
pos
%=
file_count
;
state
->
save_pos
=
-
1
;
state
->
save_pos
=
-
1
;
state
->
samples
=
0
;
state
->
samples
=
0
;
}
}
for
(
tries
=
0
;
tries
<
state
->
class
->
total_files
;
++
tries
)
{
for
(
tries
=
0
;
tries
<
file_count
;
++
tries
)
{
if
(
ast_openstream_full
(
chan
,
state
->
class
->
file
array
[
state
->
pos
]
,
ast_channel_language
(
chan
),
1
))
{
if
(
ast_openstream_full
(
chan
,
AST_VECTOR_GET
(
&
state
->
class
->
file
s
,
state
->
pos
)
,
ast_channel_language
(
chan
),
1
))
{
break
;
break
;
}
}
ast_log
(
LOG_WARNING
,
"Unable to open file '%s': %s
\n
"
,
state
->
class
->
file
array
[
state
->
pos
]
,
strerror
(
errno
));
ast_log
(
LOG_WARNING
,
"Unable to open file '%s': %s
\n
"
,
AST_VECTOR_GET
(
&
state
->
class
->
file
s
,
state
->
pos
)
,
strerror
(
errno
));
state
->
pos
++
;
state
->
pos
++
;
state
->
pos
%=
state
->
class
->
total_files
;
state
->
pos
%=
file_count
;
}
}
if
(
tries
==
state
->
class
->
total_files
)
{
if
(
tries
==
file_count
)
{
return
-
1
;
return
-
1
;
}
}
/* Record the pointer to the filename for position resuming later */
/* Record the pointer to the filename for position resuming later */
ast_copy_string
(
state
->
save_pos_filename
,
state
->
class
->
file
array
[
state
->
pos
]
,
sizeof
(
state
->
save_pos_filename
));
ast_copy_string
(
state
->
save_pos_filename
,
AST_VECTOR_GET
(
&
state
->
class
->
file
s
,
state
->
pos
)
,
sizeof
(
state
->
save_pos_filename
));
ast_debug
(
1
,
"%s Opened file %d '%s'
\n
"
,
ast_channel_name
(
chan
),
state
->
pos
,
state
->
class
->
filearray
[
state
->
pos
]
);
ast_debug
(
1
,
"%s Opened file %d '%s'
\n
"
,
ast_channel_name
(
chan
),
state
->
pos
,
state
->
save_pos_filename
);
if
(
state
->
samples
)
{
if
(
state
->
samples
)
{
size_t
loc
;
size_t
loc
;
...
@@ -490,6 +488,7 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
...
@@ -490,6 +488,7 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
{
{
struct
moh_files_state
*
state
;
struct
moh_files_state
*
state
;
struct
mohclass
*
class
=
params
;
struct
mohclass
*
class
=
params
;
size_t
file_count
;
state
=
ast_channel_music_state
(
chan
);
state
=
ast_channel_music_state
(
chan
);
if
(
!
state
&&
(
state
=
ast_calloc
(
1
,
sizeof
(
*
state
))))
{
if
(
!
state
&&
(
state
=
ast_calloc
(
1
,
sizeof
(
*
state
))))
{
...
@@ -505,14 +504,16 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
...
@@ -505,14 +504,16 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
}
}
}
}
file_count
=
AST_VECTOR_SIZE
(
&
class
->
files
);
/* Resume MOH from where we left off last time or start from scratch? */
/* Resume MOH from where we left off last time or start from scratch? */
if
(
state
->
save_total
!=
class
->
total_files
||
strcmp
(
state
->
name
,
class
->
name
)
!=
0
)
{
if
(
state
->
save_total
!=
file_count
||
strcmp
(
state
->
name
,
class
->
name
)
!=
0
)
{
/* Start MOH from scratch. */
/* Start MOH from scratch. */
ao2_cleanup
(
state
->
origwfmt
);
ao2_cleanup
(
state
->
origwfmt
);
ao2_cleanup
(
state
->
mohwfmt
);
ao2_cleanup
(
state
->
mohwfmt
);
memset
(
state
,
0
,
sizeof
(
*
state
));
memset
(
state
,
0
,
sizeof
(
*
state
));
if
(
ast_test_flag
(
class
,
MOH_RANDOMIZE
)
&&
class
->
total_files
)
{
if
(
ast_test_flag
(
class
,
MOH_RANDOMIZE
)
&&
file_count
)
{
state
->
pos
=
ast_random
()
%
class
->
total_files
;
state
->
pos
=
ast_random
()
%
file_count
;
}
}
}
}
...
@@ -522,7 +523,7 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
...
@@ -522,7 +523,7 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params)
ao2_replace
(
state
->
mohwfmt
,
ast_channel_writeformat
(
chan
));
ao2_replace
(
state
->
mohwfmt
,
ast_channel_writeformat
(
chan
));
/* For comparison on restart of MOH (see above) */
/* For comparison on restart of MOH (see above) */
ast_copy_string
(
state
->
name
,
class
->
name
,
sizeof
(
state
->
name
));
ast_copy_string
(
state
->
name
,
class
->
name
,
sizeof
(
state
->
name
));
state
->
save_total
=
class
->
total_files
;
state
->
save_total
=
file_count
;
moh_post_start
(
chan
,
class
->
name
);
moh_post_start
(
chan
,
class
->
name
);
...
@@ -1131,45 +1132,6 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
...
@@ -1131,45 +1132,6 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
}
}
}
}
static
int
moh_add_file
(
struct
mohclass
*
class
,
const
char
*
filepath
)
{
if
(
!
class
->
allowed_files
)
{
class
->
filearray
=
ast_calloc
(
1
,
INITIAL_NUM_FILES
*
sizeof
(
*
class
->
filearray
));
if
(
!
class
->
filearray
)
{
return
-
1
;
}
class
->
allowed_files
=
INITIAL_NUM_FILES
;
}
else
if
(
class
->
total_files
==
class
->
allowed_files
)
{
char
**
new_array
;
new_array
=
ast_realloc
(
class
->
filearray
,
class
->
allowed_files
*
sizeof
(
*
class
->
filearray
)
*
2
);
if
(
!
new_array
)
{
return
-
1
;
}
class
->
filearray
=
new_array
;
class
->
allowed_files
*=
2
;
}
class
->
filearray
[
class
->
total_files
]
=
ast_strdup
(
filepath
);
if
(
!
class
->
filearray
[
class
->
total_files
])
{
return
-
1
;
}
class
->
total_files
++
;
return
0
;
}
static
int
moh_sort_compare
(
const
void
*
i1
,
const
void
*
i2
)
{
char
*
s1
,
*
s2
;
s1
=
((
char
**
)
i1
)[
0
];
s2
=
((
char
**
)
i2
)[
0
];
return
strcasecmp
(
s1
,
s2
);
}
static
int
moh_scan_files
(
struct
mohclass
*
class
)
{
static
int
moh_scan_files
(
struct
mohclass
*
class
)
{
DIR
*
files_DIR
;
DIR
*
files_DIR
;
...
@@ -1178,7 +1140,7 @@ static int moh_scan_files(struct mohclass *class) {
...
@@ -1178,7 +1140,7 @@ static int moh_scan_files(struct mohclass *class) {
char
filepath
[
PATH_MAX
];
char
filepath
[
PATH_MAX
];
char
*
ext
;
char
*
ext
;
struct
stat
statbuf
;
struct
stat
statbuf
;
int
i
;
int
res
;
if
(
class
->
dir
[
0
]
!=
'/'
)
{
if
(
class
->
dir
[
0
]
!=
'/'
)
{
snprintf
(
dir_path
,
sizeof
(
dir_path
),
"%s/%s"
,
ast_config_AST_DATA_DIR
,
class
->
dir
);
snprintf
(
dir_path
,
sizeof
(
dir_path
),
"%s/%s"
,
ast_config_AST_DATA_DIR
,
class
->
dir
);
...
@@ -1192,12 +1154,11 @@ static int moh_scan_files(struct mohclass *class) {
...
@@ -1192,12 +1154,11 @@ static int moh_scan_files(struct mohclass *class) {
return
-
1
;
return
-
1
;
}
}
for
(
i
=
0
;
i
<
class
->
total_files
;
i
++
)
{
AST_VECTOR_RESET
(
&
class
->
files
,
ast_free
);
ast_free
(
class
->
filearray
[
i
]);
}
class
->
total_files
=
0
;
while
((
files_dirent
=
readdir
(
files_DIR
)))
{
while
((
files_dirent
=
readdir
(
files_DIR
)))
{
char
*
filepath_copy
;
/* The file name must be at least long enough to have the file type extension */
/* The file name must be at least long enough to have the file type extension */
if
((
strlen
(
files_dirent
->
d_name
)
<
4
))
if
((
strlen
(
files_dirent
->
d_name
)
<
4
))
continue
;
continue
;
...
@@ -1222,20 +1183,32 @@ static int moh_scan_files(struct mohclass *class) {
...
@@ -1222,20 +1183,32 @@ static int moh_scan_files(struct mohclass *class) {
*
ext
=
'\0'
;
*
ext
=
'\0'
;
/* if the file is present in multiple formats, ensure we only put it into the list once */
/* if the file is present in multiple formats, ensure we only put it into the list once */
for
(
i
=
0
;
i
<
class
->
total_files
;
i
++
)
if
(
AST_VECTOR_GET_CMP
(
&
class
->
files
,
&
filepath
[
0
],
!
strcmp
))
{
if
(
!
strcmp
(
filepath
,
class
->
filearray
[
i
]))
continue
;
break
;
}
if
(
i
==
class
->
total_files
)
{
filepath_copy
=
ast_strdup
(
filepath
);
if
(
moh_add_file
(
class
,
filepath
))
if
(
!
filepath_copy
)
{
break
;
break
;
}
if
(
ast_test_flag
(
class
,
MOH_SORTALPHA
))
{
res
=
AST_VECTOR_ADD_SORTED
(
&
class
->
files
,
filepath_copy
,
strcasecmp
);
}
else
{
res
=
AST_VECTOR_APPEND
(
&
class
->
files
,
filepath_copy
);
}
if
(
res
)
{
ast_free
(
filepath_copy
);
break
;
}
}
}
}
closedir
(
files_DIR
);
closedir
(
files_DIR
);
if
(
ast_test_flag
(
class
,
MOH_SORTALPHA
))
qsort
(
&
class
->
filearray
[
0
],
class
->
total_files
,
sizeof
(
char
*
),
moh_sort_compare
);
AST_VECTOR_COMPACT
(
&
class
->
files
);
return
class
->
total_files
;
return
AST_VECTOR_SIZE
(
&
class
->
files
);
}
}
static
int
init_files_class
(
struct
mohclass
*
class
)
static
int
init_files_class
(
struct
mohclass
*
class
)
...
@@ -1420,6 +1393,7 @@ static struct mohclass *_moh_class_malloc(const char *file, int line, const char
...
@@ -1420,6 +1393,7 @@ static struct mohclass *_moh_class_malloc(const char *file, int line, const char
class
->
format
=
ao2_bump
(
ast_format_slin
);
class
->
format
=
ao2_bump
(
ast_format_slin
);
class
->
srcfd
=
-
1
;
class
->
srcfd
=
-
1
;
class
->
kill_delay
=
100000
;
class
->
kill_delay
=
100000
;
AST_VECTOR_INIT
(
&
class
->
files
,
0
);
}
}
return
class
;
return
class
;
...
@@ -1614,7 +1588,7 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
...
@@ -1614,7 +1588,7 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
}
}
if
(
!
state
||
!
state
->
class
||
strcmp
(
mohclass
->
name
,
state
->
class
->
name
))
{
if
(
!
state
||
!
state
->
class
||
strcmp
(
mohclass
->
name
,
state
->
class
->
name
))
{
if
(
mohclass
->
total_
files
)
{
if
(
AST_VECTOR_SIZE
(
&
mohclass
->
files
)
)
{
res
=
ast_activate_generator
(
chan
,
&
moh_file_stream
,
mohclass
);
res
=
ast_activate_generator
(
chan
,
&
moh_file_stream
,
mohclass
);
}
else
{
}
else
{
res
=
ast_activate_generator
(
chan
,
&
mohgen
,
mohclass
);
res
=
ast_activate_generator
(
chan
,
&
mohgen
,
mohclass
);
...
@@ -1693,14 +1667,8 @@ static void moh_class_destructor(void *obj)
...
@@ -1693,14 +1667,8 @@ static void moh_class_destructor(void *obj)
class
->
srcfd
=
-
1
;
class
->
srcfd
=
-
1
;
}
}
if
(
class
->
filearray
)
{
AST_VECTOR_RESET
(
&
class
->
files
,
ast_free
);
int
i
;
AST_VECTOR_FREE
(
&
class
->
files
);
for
(
i
=
0
;
i
<
class
->
total_files
;
i
++
)
{
ast_free
(
class
->
filearray
[
i
]);
}
ast_free
(
class
->
filearray
);
class
->
filearray
=
NULL
;
}
if
(
class
->
timer
)
{
if
(
class
->
timer
)
{
ast_timer_close
(
class
->
timer
);
ast_timer_close
(
class
->
timer
);
...
@@ -1885,13 +1853,13 @@ static char *handle_cli_moh_show_files(struct ast_cli_entry *e, int cmd, struct
...
@@ -1885,13 +1853,13 @@ static char *handle_cli_moh_show_files(struct ast_cli_entry *e, int cmd, struct
for
(;
(
class
=
ao2_t_iterator_next
(
&
i
,
"Show files iterator"
));
mohclass_unref
(
class
,
"Unref iterator in moh show files"
))
{
for
(;
(
class
=
ao2_t_iterator_next
(
&
i
,
"Show files iterator"
));
mohclass_unref
(
class
,
"Unref iterator in moh show files"
))
{
int
x
;
int
x
;
if
(
!
class
->
total_
files
)
{
if
(
!
AST_VECTOR_SIZE
(
&
class
->
files
)
)
{
continue
;
continue
;
}
}
ast_cli
(
a
->
fd
,
"Class: %s
\n
"
,
class
->
name
);
ast_cli
(
a
->
fd
,
"Class: %s
\n
"
,
class
->
name
);
for
(
x
=
0
;
x
<
class
->
total_
files
;
x
++
)
{
for
(
x
=
0
;
x
<
AST_VECTOR_SIZE
(
&
class
->
files
)
;
x
++
)
{
ast_cli
(
a
->
fd
,
"
\t
File: %s
\n
"
,
class
->
file
array
[
x
]
);
ast_cli
(
a
->
fd
,
"
\t
File: %s
\n
"
,
AST_VECTOR_GET
(
&
class
->
file
s
,
x
)
);
}
}
}
}
ao2_iterator_destroy
(
&
i
);
ao2_iterator_destroy
(
&
i
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment