In my main extension routing, I pattern match for a numbers 700-799 and send them into call-park. When a user transfers a call to 700, some bookkeeping is done (two tables track 1) available spots, 2) in use spots and which account owns them). The bookkeeping is done to put security on who can and cannot unpark calls.
My problem arises from a quark of Park(). According to Digium, Park() retains control of the “h” extension for stability reasons. This means that if the parkee hangs up, I cannot handle “h” in the conventional sense.
My workaround was to Place a Goto to a context that would automatically do hangup bookkeeping (as a substitute for not being able to handle “h”). As you can see, I call this right before my Park(). The problem is that sure, force-free-park is called, and the Wait begins to execute, but the func_odbc bookkeeping that follows it NEVER executes. Why is this? Thanks.
[call-park]
;***
; NOTES
; This context manages parking of calls and
; access to the parking lot.
;***
include => parkedcalls
exten => _700, 1, NoOp(=-=-=- ${EXTEN}@${CONTEXT} -=-=-=)
;Check out a free parking spot and associate it
; with a given account, then park it:
exten => _700, n, Set(PARKINGEXTEN=${VOIP_GetAvailableParkingSpot()})
exten => _700, n, Set(VOIP_DeleteAvailableParkingSpot(${PARKINGEXTEN})=)
exten => _700, n, Set(VOIP_AddParkedCall(${PARKINGEXTEN},${HASH(account,id)})=)
; Here is where the problem is:
exten => _700, n, Goto(force-free-park,${PARKINGEXTEN},1)
exten => _700, n, Park(45000,call-park-timeout,${PARKINGEXTEN},1,,)
exten => _700, n, Hangup()
exten => _7XX, 1, NoOp(=-=-=- ${EXTEN}@${CONTEXT} -=-=-=)
;Ensure cross-account unparking does not happen,
; then check the parking spot back in:
exten => _7XX, n, Set(verified=${VOIP_VerifyParkedCall(${EXTEN},${HASH(account,id)})})
exten => _7XX, n, GotoIf($["${verified}" != "1"]?NOT_VERIFIED)
exten => _7XX, n, Set(VOIP_AddAvailableParkingSpot(${EXTEN})=)
exten => _7XX, n, Set(VOIP_DeleteParkedCall(${EXTEN})=)
exten => _7XX, n, ParkedCall(${EXTEN},)
exten => _7XX, n, Hangup()
;Convey error to a user that attempts cross-account
; unparking:
exten => _7XX, n(NOT_VERIFIED), Playback(sorry)
exten => _7XX, n, Playback(the-number-u-dialed)
exten => _7XX, n, Playback(is-curntly-unavail)
exten => _7XX, n, Hangup()
[force-free-park]
;In the case that the parkee has hung up, we want to
; force the freeing of the parking spot. This is necessary
; because the Park() application captures the "h" extension
; which prevents handling hangups in the conventional way.
exten => _7XX, 1, NoOp(=-=-=- ${EXTEN}@${CONTEXT} -=-=-=)
exten => _7XX, n, Wait(45)
; The below code is NEVER executed:
exten => _7XX, n, Set(VOIP_AddAvailableParkingSpot(${EXTEN})=)
exten => _7XX, n, Set(VOIP_DeleteParkedCall(${EXTEN})=)
exten => _7XX, n, Hangup()
[call-park-timeout]
;***
; NOTES
; This context manages the handling of parked calls
; that are not unparked in a timely fashion.
;***
; Code to call back and connect the parked
; extension to the extension that parked them