ISSUE IN DETAIL
specific case : call transfer (NB: i cant change existing architecture)
When Agent 1 transfers a call to Agent 2, the SIP protocol handles this via a REFER message. Asterisk receives this and must tear down the media path to Agent 1 and establish a new one to Agent 2.
To do this, Asterisk creates a Local/ channel
I learned that by design newly spawned Local/ channels do not inherit or have any idea about channel variables (like CALLERID(num) or CALLERID(name)) from the parent channel
THE FLOW
Agent 2 is say 102-5
The Local/ channel enters from-internal (or similar) context looking for 102-5. Because of how FreePBX includes custom files, it hits the custom wildcard pattern in /etc/asterisk/extensions_custom.conf: exten => _[+0-9].,8,Gosub(subDial-context,start,1(...))
The Gosub command jumps the execution into a new context (subDial-context) and changes the current extension variable (${EXTEN}) to the literal string "start".
Execution reaches exten => start,3,Dial(${ARG3},${ARG4},${ARG5}). Asterisk prepares to generate the outgoing SIP INVITE packet to Agent 2 over the WebRTC WebSocket. The PJSIP/SIP channel driver needs to populate the From header. It checks the current channel for a CALLERID value. It finds nothing (null). So its hardcoded fallback behavior is to use the current ${EXTEN} variable as the Caller ID. Since you forced ${EXTEN} is"start" on line 1 of the Gosub, Asterisk constructs the header: From: <sip:start@...>.
Any solution to this issue(urgent)
because the local channel it lands directly in this context from from-internal (similar contexts in FreePBX) , it has amnesia of the channel variable
This is expected behavior of Local/ channel. It does not inherit channel variables from the parent channel, so CallerID becomes empty during REFER-based transfers.
In your case, the issue is caused by Local channel creation + context switch (Gosub), which resets variables and leads to fallback like ${EXTEN}.
Fix is to explicitly pass or reset CallerID using Set(CALLERID(num)=...) before Dial or inside the new context, or pass variables via U() / b() arguments.
I don’t believe this is true. I suspect you have incorrectly analysed the way that attended transfers are handled. Note that phones often implement blind transfers as though they were attended.
I suspect the real situation here is that Agent A’s phone starts a new call to Agent B’s phone. At that point Asterisk has no reason to believe it isn’t an independent, second line, call, from A to B. The transfer is then completed by agent A issuing REFER/Replaces. The Replaces tells Asterisk the calls are related, but it is now too late, as the caller ID has already been sent to B.
If B is capable of connected line updates, and Asterisk is properly configured for them, once B answers, Asterisk Re-Invites with updated information (as P-Asserted-Identity, or Remote-Party-ID, not as an updated From header.
If you use the feature code transfer mechanism, Asterisk does know that it is getting an attended transfer, so does provide the caller ID that was incoming to A.
Some phones do blind transfers by monitoring the feedback on an attended transfer, and issuing a REFER/Replaces, when the B answers.
Local channel implementation has changed significantly since I was familiar with the code, but I’m pretty sure that I would have seen complaints if the propagation of caller ID had been broken.