VOIP/SIP Call Hold related questions - sip

1) How many types of call holds are there in SIP/VOIP?
2) Does SDP parameter changes for reinvite during call hold?
3) Does RTP packets flow during call hold?

How many types of call holds are there in SIP/VOIP?
Two main types are recognised, Attended and Blind.
Attended is where you call and speak to the transfer destination first.
Blind is where you instruct the transferee to call the destination without the introduction.
Does SDP parameter changes for reinvite during call hold?
Normally yes. The media flow SDP attribute will typically change from sendrecv to sendonly/recvonly/inactive depending on how call hold is implemented.
Another common way to put a call on hold is to play on hold music and in that case the SDP may not need to change at all. It's a simple substitution of audio capture input for music.
Does RTP packets flow during call hold?
Depends on how the call hold is implemented. If the media flow attribute is used then RTP will normally stop flowing in one or both directions.
If it's done with music on hold RTP will keep flowing in the original manner.

Related

Is it possible to create and send a packet from a bpf program?

Idea:
The first way is to create a brand-new packet in the bpf program and send it to the specified receiver.
The second way is to copy a packet. To make it easy to distinguish, below I call the packet I get from copying as packet_copy. Then I can modify the packet_copy so it can be sent to the specified receiver, and the original packet will go through the normal path.
Try:
As to the first way, I have not found a suitable solution, but someone says that this way is not possible.
As to the second way, I found bpf_clone_redirect() as a possible solution. However, instead of getting the packet_copy from copying, we should directly modify the original packet (so that it can be redirected to the specified receiver) and then call bpf_clone_redirect to redirect it. I also need to undo the modification to restore the packet after calling bpf_clone_redirect because I want this packet to be processed normally rather than dropped.
Question:
As to the first way, I would like to know if it is feasible.
As to the second way, I wonder if it can be optimized, given that bpf_clone_redirect has its limitations.
The first way is to create a brand-new packet in the bpf program and send it to the specified receiver.
That is indeed not possible today. It would require dynamic memory allocation to allocate memory for the packet and a helper to then send the packet out. None of these are available in BPF today (v5.19).
However, instead of getting the packet_copy from copying, we should directly modify the original packet (so that it can be redirected to the specified receiver) and then call bpf_clone_redirect to redirect it. I also need to undo the modification to restore the packet after calling bpf_clone_redirect because I want this packet to be processed normally rather than dropped.
I don't know of a more efficient way in a single BPF program.
Depending on where in the stack you sit, you may however be able to use two BPF programs, with one doing the cloning and another one intercepting one of the copies after to modify it. I'm not convinced that would be more CPU efficient but it may be cleaner.

What is the difference between a protocol and an interface in general?

I understand an interface is a set of publicly exposed things that one system can use to interact with others systems. I'm reading about WEBRTC protocol and to understand what a protocol is I went to the Wikipedia definition. It says more or less that a protocol is a system of rules that allows two systems to communicate. Ain't that the same as interface? Maybe I'm not understanding one or both.
An interface defines how two entities may communicate. A protocol defines how they should communicate and what that communication means.
Here is an interface:
public interface ICommunicate
{
string SendMessageAndGetResponse(string message);
}
A protocol then might be:
Send "Hello", if you get back "Hi" then send "How are you?" and the response will be a status. If you get back anything other than "Hi" from the initial message then the system is not functioning properly and you must send the message "Reboot" which you'll then get back "Rebooted!" if successful and anything else for failure.
In general interface mean "The point of interconnection or contact between entities." and transferred to software it means "The connection between parts of software." and also "In object-oriented programming, a piece of code defining a set of operations that other code must implement." (Source)
In general protocol means "The official formulas which appeared at the beginning or end of certain official documents such as charters, papal bulls etc." and transferred to computers it means "A set of formal rules describing how to transmit or exchange data, especially across a network.". (Source)
So protocol focuses more on the data exchange, whereas interface focuses more on software interaction independent of any data exchange.
Of course, in the end, software interaction is most of the time a data exchange. Passing arguments to a function is a data exchange. Calling a method/function is not directly a data exchange but you need to imagine it like this: Instead of calling different functions:
c = add(a, b);
c = sub(a, b);
you could as well always call the same function and pass the desired functionality as argument:
c = func("add", a, b);
c = func("sub", a, b);
and that way the functionality becomes data as well.
The terms are somewhat interchangeable. E.g. some programming languages call it interface to focus on the pure interaction of components (classes, objects, etc.) and some call it protocol to focus on the data exchange between the components.
On a network, a protocol is how data is exchanged; think of IP protocol or TCP protocol. But if you have communication endpoints you talk to over a network to trigger functionality, e.g. a REST API, than the sum of all these endpoints and their parameters can be called an interface, while triggering one of the interface functions would be done via a HTTP request and HTTP is a protocol and defines how data is transferred.
I think in some ways the word 'interface' could also be used for this (especially as the I in API), but generally when talking about what we're sending over the wire, the common word is protocol.
When you dive deep enough into exact definitions of words, the meaning and difference can sometimes break down a bit.
But avoiding super exact semantics, API/Interface tends to be a bit higher level than protocol.

How can I invoke UART_Receive_IT() automatically when I receive a data?

I am new to STM32 and freertos. I need to write a program to send and receive data from a module via UART port. I have to send(Transmit) a data to that module(for eg. M66). Then I would return to do some other tasks. once the M66 send a response to that, my seial-port-receive-function(HAL_UART_Receive_IT) has to be invoked and receive that response. How can I achieve this?
The way HAL_UART_Receive_IT works is that you configure it to receive specified amount of data into given buffer. You give it your buffer to which it'll read received data and number of bytes you want to receive. It then starts receiving data. Once exactly this amount of data is received, a callback function HAL_UART_RxCpltCallback gets called (from IRQ) where you can do whatever you want with this data, e.g. add it to some kind of queue for later processing in the task context.
If I was to express my experiences related to working with HAL's UART module is that it's not the greatest one for generic use where you don't know the amount of data you expect to receive in advance. In the case of M66 modem you mention, this will happen all the time.
To solve this you have two choices:
Simply don't use HAL functions at all in case of UART, other than the initialization functions. Implement your own UART interrupt handler (most of the code can be copied from handler in HAL) where upon receiving data you place received bytes in a receive byte queue handled in your RTOS task. In this task you implement protocol parsing. This is the approach I use personally.
If you really want to use HAL but also work with a module that sends varying amount of data, call HAL_UART_Receive_IT and specify that you want to receive 1 byte each time. This will work, but will be (potentially much) slower than the first approach. Assuming you'll later want to implement some tcp/ip communication (you mentioned M66 GPRS module) you probably don't want to do it this way.
You should try the following way.
Enable UARTX Rx interrupt in NVIC.
Set Interrupt priority.
Unmask Interrupt request in EXTI.
Then use USARTX Interrupt Handler Function Define in you Vector.
Whenever the data is received from USARTX this function get automatically called and you can copy data from USARTX Receive Data Register.
I would rather suggest another approach. You probably want to archive higher speeds (lets say 921600 bods) and the interrupt way is fat to slow for it.
You need to implement the DMA transmition with the data end detection features. Run your USART in the DMA mode in the circular mode. You will have two events to serve. The first one is the DMA end of thransmition interrupt (then you copy the data from the current tail pointer to the end of the buffer to avoid data override) and USART IDLE interrupt - this will detect the end of the receive.

Force writing only-read register #Modbus

I was wondering,
Is there anyway to force writing on a 'Read-Only' Modbus Register?
Does defining a Register as a 'Read-Only' is secure enough or can be bypassed??
Thanks for the answers!
The correct way to define a "read-only" analog variable in Modbus is to map it as an input register. There is no function code defined in Modbus to write to an input register.
For historical reasons, several vendors maps all their variables as holding registers, which are theoretically read/write, i.e, there's a Write Multiple Registers function. Whenever they map a read only variable as a holding register, they must assert that the write functions fail. However, there's no standard exception code for this, as a holding register should be read/write. This is only one of Modbus' idiosyncrasies.
Getting back to your question, if you map your variable as an input register, you can be sure that the protocol will not allow a master to write to it. If, for interoperability issues you map it as a holding register, the protocol will allow the master to use a write funcion to change its value, and it is up to you to block in your device implementation.

What is a callback?

Is it a function?
Is it a function being called from the source?
Or, is it a function being returned from the destination?
Or, is it just executing a function at the destination?
Or, is it a value returned from a function passed to the destination?
A callback is the building block of asynchronous processing.
Think of it this way: when you call someone and they don't answer, you leave a message and your phone number. Later on, the person calls you back based on the phone number you left.
A callback works in a similar manner.
You ask an API for a long running operation and you provide a method from within your code to be called with the result of the operation. The API does its work and when the result is ready, it calls your callback method.
From the great Wikipedia:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
Said another way, when you pass a callback to your method, it's as if you are providing additional instructions (e.g., what you should do next). An attempt at making a simple human example follows:
Paint this wall this shade of green (where "paint" is analagous to the method called, while "wall" and "green" are similar to arguments).
When you have finished painting, call me at this number to let me know that you're done and I'll tell you what to do next.
In terms of practical applications, one place where you will sometimes see callbacks is in situations with asynchronous message passing. You might want to register a particular message as an item of interest for class B.
However, without something like a callback, there's no obvious way for class A to know that class B has received the message. With a callback, you can tell class B, here's the message that I want you to listen for and this is the method in class A that I want you to call when you receive it.
Here is a Java example of a callback from a related question.