[OpenSER-Devel] dialog callbacks: mi enhancements
Dan Pascu
dan at ag-projects.com
Thu Apr 17 19:11:59 CEST 2008
1. Why does it need to be a callback? Can't it be a query function made
available through the dialog API? I mean if it is a callback at which
point is it called and why do you need it to call back?
2. Maybe it makes sense to have a generic query function, not some MI
specific one, considering that other modules sitting on top of dialog may
need to query dialog internals.
On Thursday 17 April 2008, Ovidiu Sas wrote:
> Hello all,
>
>
> For modules sitting on top of the dialog module it is not possible to
> retrieve the call specific context out of a callback, mostly because
> the pointer to the context is stored inside the dialog callback
> structure.
>
> It would make sense to enhance the existing dialog callbacks with a
> new one that will be used by the mi commands to list the call specific
> context of the data that is hold by the module that is sitting on top
> of the dialog module.
>
> An example is the sst module. The call specific context is:
> typedef struct sst_info_st {
> enum sst_flags requester;
> enum sst_flags supported;
> unsigned int interval;
> } sst_info_t;
>
>
> It would make sense to create a new mi command for the dialog module
> (like dlg_enhanced_list) that will print in addition to the dialog
> context, the context of each module that registered an mi callback
> with the dialog module.
>
>
> Here's the proposed architecture:
> MI changes:
> - enhance the MI API to build an mi node out of the mi tree structure
> - enhance the MI API to insert a sibling node into the mi tree
> structure dialog changes:
> - new callback: DLGCB_MI_CTX_QUERY (callback for mi query commands),
> sst changes:
> - register for a DLGCB_MI_CTX_QUERY, create a node with the sst
> params and pass the pointer to the node back to the dialog module (the
> dialog module is responsible for inserting the node into the mi tree
> structure).
>
> The major change is in the dialog module. The DLGCB_MI_CTX_QUERY
> callback will provide a pointer for storing the pointer to the nodes
> that are to be provided by the DLGCB_MI_CTX_QUERY callback consumers.
> Each consumer of the DLGCB_MI_CTX_QUERY callback, will create a node
> (using the new MI API) and if it is the first one that is in the list
> of DLGCB_MI_CTX_QUERY callback consumers, it will simply store the
> pointer to the node in the pointer provided by the DLGCB_MI_CTX_QUERY
> callback. If the consumer of the DLGCB_MI_CTX_QUERY callback, is not
> the first one in the list of DLGCB_MI_CTX_QUERY callback consumers, it
> will create it's own node and it will append to the existing node
> (created by a previous consumer) and in the end we will have a list of
> chained nodes.
> After all the DLGCB_MI_CTX_QUERY callbacks are executed, the dialog
> module will insert the list of chains into the existing tree.
>
> If a DLGCB_MI_CTX_QUERY callback consumers encounter an error during
> the construction of it's node, it should simply free up the allocated
> memory (if any) and return.
>
>
> required changes:
>
> New callback structure:
> struct dlg_cb_params {
> struct sip_msg* msg;
> unsigned int direction;
> void **param;
> void **x_param; // <== new extra param for storing the
> pointer to the mi_node
> };
>
>
> Pass the extra param while calling the run_dlg_callbacks:
> void run_dlg_callbacks( int type , struct dlg_cell *dlg, struct sip_msg
> *msg, unsigned int dir, void** x_param);
>
>
> Calling the actual callback from the mi dialog function and insert the
> chain of nodes provided by the DLGCB_MI_CTX_QUERY callback consumers:
> cb_node=NULL;
> run_dlg_callbacks( DLGCB_MI_CTX_QUERY, dlg, NULL, DLG_DIR_NONE,
> (void **)&cb_node );
> /* No need to check for NULL cb_node. */
> /* It is done inside add_mi_sibling_node(). */
> add_mi_sibling_node( node1, cb_node);
>
>
>
> Note: The existing API provided by the dialog module is unchanged.
>
>
> Here's a skeleton example for a DLGCB_MI_CTX_QUERY callback consumer:
> void my_dialog_mi_ctx_query_CB(struct dlg_cell *did, int type, struct
> dlg_cb_params * params)
> {
> struct mi_node* node;
> struct mi_node* head_node = (struct mi_node *)(*(params->x_param));
> struct mi_attr* attr;
>
> node = create_mi_node("my_module", 9, "", 0, MI_DUP_VALUE);
> if (node==NULL) {
> LM_ERR("oom\n");
> return;
> }
>
> attr = add_mi_attr(node, MI_DUP_VALUE, "requester_flags", 15, p, len);
> if(attr == NULL)
> goto error;
>
> if (head_node) {
> /* Previous node present, adding this one to the list. */
> add_mi_sibling_node( head_node, node);
> } else {
> /* No previous node, inserting this one. */
> *(params->x_param) = (void*)node;
> }
>
> return;
> error:
> free_mi_node(node);
> return;
> }
>
>
>
> Comments? Thoughts? Alternative solutions?
>
>
>
> Regards,
> Ovidiu Sas
>
> _______________________________________________
> Devel mailing list
> Devel at lists.openser.org
> http://lists.openser.org/cgi-bin/mailman/listinfo/devel
--
Dan
More information about the Devel
mailing list