diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 7a960922ddc76fdc063648dd95732cf7ad0ba9c6..3b5808e0463b07b46be01956cacd599023a6ef04 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -14919,7 +14919,7 @@ static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *messa static int manager_sipnotify(struct mansession *s, const struct message *m) { const char *channame = astman_get_header(m, "Channel"); - struct ast_variable *vars = astman_get_variables(m); + struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL); struct sip_pvt *p; struct ast_variable *header, *var; diff --git a/include/asterisk/config.h b/include/asterisk/config.h index 1f4ce2970cd9efa8aa2075e7676018f62cb6347c..dae4b5277aa86403c9a0334c49cdde8f2742c8cd 100644 --- a/include/asterisk/config.h +++ b/include/asterisk/config.h @@ -473,6 +473,16 @@ int ast_realtime_enabled(void); */ struct ast_variable *ast_variables_dup(struct ast_variable *var); +/*! + * \brief Reverse a variable list + * \param var the linked list of variables to reverse + * \return The head of the reversed variable list + * + * \note The variable list var is not preserved in this function and should + * not be used after reversing it. + */ +struct ast_variable *ast_variables_reverse(struct ast_variable *var); + /*! * \brief Free variable list * \param var the linked list of variables to free diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h index 257e939cf967035d0b6f8aba0e84a10be23fe7e1..e4c199f6481edef6bda935e578e8553afe22634c 100644 --- a/include/asterisk/manager.h +++ b/include/asterisk/manager.h @@ -257,9 +257,21 @@ int __ast_manager_event_multichan(int category, const char *event, int chancount /*! \brief Get header from mananger transaction */ const char *astman_get_header(const struct message *m, char *var); -/*! \brief Get a linked list of the Variable: headers */ +/*! \brief Get a linked list of the Variable: headers + * + * \note Order of variables is reversed from the order they are specified in + * the manager message + */ struct ast_variable *astman_get_variables(const struct message *m); +enum variable_orders { + ORDER_NATURAL, + ORDER_REVERSE +}; + +/*! \brief Get a linked list of the Variable: headers with order specified */ +struct ast_variable *astman_get_variables_order(const struct message *m, enum variable_orders order); + /*! \brief Send error in manager transaction */ void astman_send_error(struct mansession *s, const struct message *m, char *error); diff --git a/main/config.c b/main/config.c index c7cd867e75614e1bababa23d973093b8cd7ca4dc..8288fb380139c83ac7533f980501e375198664e9 100644 --- a/main/config.c +++ b/main/config.c @@ -561,6 +561,30 @@ struct ast_variable *ast_variables_dup(struct ast_variable *var) return cloned; } +struct ast_variable *ast_variables_reverse(struct ast_variable *var) +{ + struct ast_variable *var1, *var2; + + var1 = var; + + if (!var1 || !var1->next) { + return var1; + } + + var2 = var1->next; + var1->next = NULL; + + while (var2) { + struct ast_variable *next = var2->next; + + var2->next = var1; + var1 = var2; + var2 = next; + } + + return var1; +} + void ast_variables_destroy(struct ast_variable *v) { struct ast_variable *vn; diff --git a/main/manager.c b/main/manager.c index 5fd5d7a3a86e741c92dd316e88cd94b435c32571..7e03746283cc1fc20cd73c878719b15c0f96f223 100644 --- a/main/manager.c +++ b/main/manager.c @@ -2096,6 +2096,12 @@ static struct ast_variable *man_do_variable_value(struct ast_variable *head, con } struct ast_variable *astman_get_variables(const struct message *m) +{ + return astman_get_variables_order(m, ORDER_REVERSE); +} + +struct ast_variable *astman_get_variables_order(const struct message *m, + enum variable_orders order) { int varlen; int x; @@ -2112,6 +2118,10 @@ struct ast_variable *astman_get_variables(const struct message *m) head = man_do_variable_value(head, m->headers[x] + varlen); } + if (order == ORDER_NATURAL) { + head = ast_variables_reverse(head); + } + return head; }