With the newly introduced `ng_command_find()` lookup func.
Add the local `ng_command_def` and maintain via it.
Check whether:
- the handler has been defined
- the handler gets properly selected
- the command is defined (known)
Accordingly update the opmode of the command context.
By default define as `OP_OTHER` always.
For the case when no handler has been defined, introduce
the error reply "No handler found".
Accordingly trigger selected handler after
the command was found.
The main payoff here is that the command processing
flow becomes quite transparent and easy to maintain:
- parse command string
- lookup command definition
- set opmode from table
- call uniform handler
- shared error/success reply handling for all commands
Deprecate strhash based `__csh_lookup()`/`CSH_LOOKUP()`.
Accordingly adap the daemons's and tests Makefile,
remove the strhash objects with the normal control_ng one.
Additionally:
introduce the special `resultstr = "pong"` for the
ping command case, because all other commands have "ok".
Change-Id: Ifff7d7f61ae4d25fd220460f4485d794c9a7cbd5
Instead of the previous approach using the strhash,
introduce if-based lookup from `NG_COMMANDS`.
The usage of strhash is deprecated because it:
- forses string literals in switch cases, hence gives
no possibility to use variables
- makes then shortcuts using macro not possible to be used
- it makes the part with the command find and
actual commands definition duplicate, because
one has to maintain both of them when adding/removing commands
- switch is redundant and feels heavy, meanwhile the same
thing can be generated using marco based on `NG_COMMANDS`
introduced before, which are the main source of the truth
Newer approach:
- avoid usage of for/while cycles (because CPU consuming)
- sorts the lookup based on the cmd name (string) length,
what makes the command find efficient, because exlcludes
unnecessary comparisons
- uses the `memcmp()` at the very last
- for example, for the "offer" command it may run the `memcmp()`
only two times, because there are only two commands with
the length 5 our of supported 35 commands in list now
Additionally:
include `string.h` for `memcmp()` operations.
Change-Id: Iae70de87b88cd444ae162ba2b7c6aa7690731ee3
Introduce a common NG commands table `ng_command_defs`
for all type of things: OP enum, name, escaped name,
short name and most important the handler.
This table operates on and returns a dedicated struct `ng_command_def`,
which has all the information required on the command (like
all type of things mentioned above) and may have either
single-parameter or double-parameter signature (for cases with
the `addr` requiring commands such as the offer command).
Also add unified signatures for X and XA handlers,
they will be used later accordingly. Most of those use single-parameter,
and those exceptional use the second one.
Also add dummy plug-functions for ping and block/unblock silence media.
The ping one doesn't have any particular handler, but because a new
structure of NG commands wants to see a real declaration of the func
handler, just give it. For the block/unblock silence media, there aren't
even handling of commands in the control NG, they are just dummy OPs,
so fulfill the actual NG commands structure, and give them dummy funcs.
Change-Id: I2064ddca1595079959a6c6843119556a8b6bf5d5
Keep enum `ng_opmode` generated from the command list,
and also keep `ng_command_strings[]`, `ng_command_strings_esc[]`
and `ng_command_strings_short[]`.
And add the wrapper func name into the array, to be able
to appeal to it later, when processing any coming NG command.
Change-Id: I6aa725679d2405277f4497db46c3a8010d9ccd56
When iterating through medias, check whether there is something in;
- `->streams.head`
- `->selected_sfd`
- `->socket.local.address.family`
before to blidnly appeal to it.
If transform setup can ever produce incomplete media,
this might crash while building the response.
Change-Id: Ie75f20b111634ee3faa0af58c1eebfddbbcc843e
When iterating through the monologues medias while
looking for the media sink, filter those, which aren't audio.
Such a media type will likely have no audio subscriber,
and most probably will return with:
"There is no sink media capable of DTMF playback"
Change-Id: I86e64105e520f2a6f3ee9bbb0271830ae8d8cc69
For-cycle expects the `sink_ml` for setting the `call_media`
at the upper level of the cycle, but instead the `monologue`
is used, which is supposed to be used in the nested for-cycle.
Looks like a copy-paste typo. Major fix.
Change-Id: I225a51fde7fa8d10bac832ce5fc5444ee544e882
The loop is 1-based, but checks the outside
of bounds with `i <= 1`. If the length is 1 and
iterator is 1, this already fails.
Hence allow `i` to be 1, and also check it's not
beyound the media array length.
Change-Id: I9112fc88155fa53205c04ef35b00f6573b6816b3
No functional changes. Refactors are:
- use `UINT_MAX` instead of `-1`
- add definition `KERNEL_IDX_NONE = UINT_MAX`
- use `KERNEL_IDX_NONE` to se none value
- use `KERNEL_IDX_NONE` to check the none in conditions
Change-Id: I132d39607acd2c8d3b229bc3fba4d16e07e3d12c
In case when adding blob id, we allocate a list of things, like:
`AVFormatContext`, `AVIO` buffer, `AVIOContext`,
and we manage to copy it before returning an error.
On immediate failure this leaves the player
in a partially initialized state, just be explicit and
use the `media_player_coder_shutdown()` before to
return an error.
Change-Id: I9620e7b78f02e22d77f01bac3af6afc9dd5773fb
There seems to be a race condition with stream_fds/sockets being closed
while ICE checks are running at the same time, referencing the same
stream_fds. Solve this by holding a reference to the stream_fd in the
ICE pair object.
Additionally, add a check for a possibly closed socket when running
checks.
Closes#2113
Change-Id: I279a62d9e52cb1d409bcfda871766002aac4a758
The `name` is caller-owned, while the cache itself
also keeps a separate key object
in the `media_player_media_files_names`.
This can desynchronize the hash key and the list key.
Hence prefer using the owned key instead.
Change-Id: I9b85c306cc4e2c32675bada3dec0d049ff5645fe
`media_player_media_files_insert()` stores keys allocated
with `str_dup()`, but during the eviction,
the key is freed with `g_free()`. Use `str_free()` instead.
Change-Id: I17a8498f7cf850a3cc2015130d1aa689f3f7c553
The `media_player_expire_cache_entry()` appears
to use the `db_expire_us` instead of the `media_expire_us`.
Was most probably a copy-paste typo in the past,
just fix it.
Change-Id: I6a4938406a6fb43459c99a354616d5f5ce10bae2
The only caller of `media_player_get_cache_times()`
does comparisons based on microseconds, but the called
function to calculate `mtime` and `atime` does this in seconds.
Hence the result is used incorrectly, because it compares
that value against `rtpe_now - rtpe_config.db_expire_us`,
which is again in microseconds.
Change-Id: Iea4b5b1c6d36c202bdce477ee8147e84e1974210
The `OP_...` enum is meant to only represent commands list.
Then make the list from the NG commands macro
the actual source of truth for the enum count.
This eliminates human mistakes, when introducing a new command,
because no more need to update enum manually.
Additionally:
- move the command list macro to the header
- existing extern declarations remain untouched
- `OP_OTHER` remains sentinel
- eventually replace the manual enum with macro based one
Change-Id: I33d928367fe0a254571cb0b7d4aafe4445b30b77
Instead of keeping separate arrays (essentially it's
a duplication) for command strings, escaped strings
or short version of commands, just create one single
macro pattern, which keeps these as an array.
And then using designated array initializers,
use the marco pattern to generate accordingly
an array of the required type (usual strings,
those escaped or the short version of them).
This prevents the human mistakes, or at least
makes them less possible in case of new command
introduction.
Change-Id: I27271ed4852f95760424552ce66fc8bc340c76a3
The dict pretty printer advances from key to value
by `chld = chld->sibling` and then prints the `chld`.
If a malformed dict ever reaches this func
with an odd number of child nodes, this can dereference NULL.
Just add guard against NULL.
Change-Id: Ia24671a5eba06dda8c48515fd9dc45fe7a9ec371
If someone wants to stop the media for this particular monologue,
and it already has the MP allocated, which is marked for MoH,
then just ignore the stop media command.
This is to not let the play media/stop media procedures
overlap with potentially (previously) triggered MP via MoH.
Change-Id: If0bf4264b9c640b99f844efe5c2c8bc201a6ad16
Both the play media and the music on hold use
the `media_player::call_play_media_for_ml()` as an entrance
towards the `media_player::media_player_new()` and
`media_player::media_player_play_init()`.
Prevent allocation of new MoH over ongoing one,
as well as the `play media` command over ongoing MoH.
Otherwise a media player will be re-used to override
ongoing activity.
Explicit policy must be used:
First the MoH has to be stopped
by getting back to the SDP `sendrecv` state, before
any other MoH request, or play media request can be fulfilled.
Change-Id: Ia5fdc10cfa8f491109ade9a2225b182ccdaa4778
To show that player has been created.
Additionally: add one more log line
to track that the play media is being requested.
Change-Id: I4e8eb8f282654902a96bffb70c7c241e9c78b8d5
In order to understand whether is must be initialized.
And use a given parser pointer to do so. This can be native or
json parser.
Remove previously introduced bool param, which was used
for differentiation.
Change-Id: I6d0bb083fe4dea5625d40175c8978fffaca6d34f
There is a dedicated JSON parser, so use this.
Also leave some TODO'ers to think about adding own
`parser_arg` for JSON-like formatted data.
Change-Id: I5399ffb6ec74e88887b52fd63b96a8e44428c495
If already having the local ptr, then why not to use it,
instead of using directly the globally visible object.
In the `control_ng_process_payload()` add a pointer
to the `ng_parser_json` parser.
Change-Id: I9d656733991e2d99c18aa1cc6d705ed053f57f0a
When preparing a response, especially for the case of error,
we already make sure to init the resp ctx. So just add
a helper for this, because same routine used.
Also optionally init parser as native (dict) if required.
Some of the cases like data is <= 0 length, or
there has been not dict or JSON format spotted,
then init as native.
Change-Id: I7d13669075525b754e1950e3212b79800b20f85a