]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
In order to move away from nested function use, some changes to the recently introduced
authorSean Bright <sean@malleable.com>
Sun, 9 Nov 2008 01:59:59 +0000 (01:59 +0000)
committerSean Bright <sean@malleable.com>
Sun, 9 Nov 2008 01:59:59 +0000 (01:59 +0000)
ast_channel_search_locked need to be made.  Specifically, the caller needs to be able to
pass arbitrary data which in turn is passed to the callback.  This patch addresses all
of the nested functions currently in asterisk trunk.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@155590 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_directed_pickup.c
channels/chan_sip.c
include/asterisk/channel.h
main/channel.c
main/features.c

index deca8f3de5fa8e0a05c4d0feeb7067761d0270c0..7fb5f6fea47f6faee7c78ed835634a5eeeea8ccd 100644 (file)
@@ -169,17 +169,30 @@ static int pickup_by_channel(struct ast_channel *chan, char *pickup)
        return res;
 }
 
+struct pickup_criteria {
+       const char *exten;
+       const char *context;
+};
+
+static int find_by_exten(struct ast_channel *c, void *data)
+{
+       struct pickup_criteria *info = data;
+
+       return (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) &&
+               !strcasecmp(c->dialcontext, info->context) &&
+               can_pickup(c);
+}
+
 /* Attempt to pick up specified extension with context */
 static int pickup_by_exten(struct ast_channel *chan, const char *exten, const char *context)
 {
-       auto int find_by_exten(struct ast_channel *c);
-       int find_by_exten(struct ast_channel *c) {
-               return (!strcasecmp(c->macroexten, exten) || !strcasecmp(c->exten, exten)) &&
-                       !strcasecmp(c->dialcontext, context) &&
-                       can_pickup(c);
-       }
+       struct ast_channel *target = NULL;
+       struct pickup_criteria search = {
+               .exten = exten,
+               .context = context,
+       };
 
-       struct ast_channel *target = ast_channel_search_locked(find_by_exten);
+       target = ast_channel_search_locked(find_by_exten, &search);
 
        if (target) {
                int res = pickup_do(chan, target);
@@ -191,18 +204,20 @@ static int pickup_by_exten(struct ast_channel *chan, const char *exten, const ch
        return -1;
 }
 
+static int find_by_mark(struct ast_channel *c, void *data)
+{
+       const char *mark = data;
+       const char *tmp;
+
+       return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) &&
+               !strcasecmp(tmp, mark) &&
+               can_pickup(c);
+}
+
 /* Attempt to pick up specified mark */
 static int pickup_by_mark(struct ast_channel *chan, const char *mark)
 {
-       auto int find_by_mark(struct ast_channel *);
-       int find_by_mark(struct ast_channel *c) {
-               const char *tmp;
-               return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) &&
-                       !strcasecmp(tmp, mark) &&
-                       can_pickup(c);
-       }       
-
-       struct ast_channel *target = ast_channel_search_locked(find_by_mark);
+       struct ast_channel *target = ast_channel_search_locked(find_by_mark, (char *) mark);
 
        if (target) {
                int res = pickup_do(chan, target);
index 06d8d6f3ce9e2effe8084769edf9128fca03edd4..d3d79fd08686abd6e36b12426d0be6a1d0e1454c 100644 (file)
@@ -4421,6 +4421,26 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
        return peer;
 }
 
+/* Function to assist finding peers by name only */
+static int find_by_name(void *obj, void *arg, void *data, int flags)
+{
+       struct sip_peer *search = obj, *match = arg;
+       int *forcenamematch = data;
+
+       /* Usernames in SIP uri's are case sensitive. Domains are not */
+       if (strcmp(search->name, match->name)) {
+               return 0;
+       }
+
+       /* If we're only looking for name matches, we should avoid type=peer devices,
+          since these should not match on any name-based search */
+       if (*forcenamematch && search->onlymatchonip) {
+               return 0;
+       }
+
+       return CMP_MATCH | CMP_STOP;
+}
+
 /*! \brief Locate device by name or ip address 
  *     This is used on find matching device on name or ip/port.
        If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
@@ -4433,31 +4453,10 @@ static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int
 {
        struct sip_peer *p = NULL;
        struct sip_peer tmp_peer;
-       
-       /* Inline function to assist finding peers by name only */
-       auto int find_by_name(void *obj, void *arg, void *data, int flags);
-
-       int find_by_name(void *obj, void *arg, void *data, int flags)
-       {
-               struct sip_peer *search = obj, *match = arg;
-
-               /* Usernames in SIP uri's are case sensitive. Domains are not */
-               if (strcmp(search->name, match->name)) {
-                       return 0;
-               }
-
-               /* If we're only looking for name matches, we should avoid type=peer devices,
-                  since these should not match on any name-based search */
-               if (forcenamematch && search->onlymatchonip) {
-                       return 0;
-               }
-
-               return CMP_MATCH | CMP_STOP;
-       }
 
        if (peer) {
                ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
-               p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &tmp_peer, NULL, "ao2_find in peers table");
+               p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &tmp_peer, &forcenamematch, "ao2_find in peers table");
        } else if (sin) { /* search by addr? */
                tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
                tmp_peer.addr.sin_port = sin->sin_port;
@@ -9870,10 +9869,23 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi)
        
        /* Actually send the packet */
        transmit_invite(mwi->call, SIP_SUBSCRIBE, 0, 2);
-       
+
        return 0;
 }
 
+struct caller_criteria {
+       const char *exten;
+       const char *context;
+};
+
+static int find_calling_channel(struct ast_channel *c, void *data) {
+       struct caller_criteria *info = data;
+
+       return (c->pbx &&
+                       (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) &&
+                       !strcasecmp(c->context, info->context));
+}
+
 /*! \brief Used in the SUBSCRIBE notification subsystem (RFC3265) */
 static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout)
 {
@@ -10039,14 +10051,13 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
                           callee must be dialing the same extension that is being monitored.  Simply dialing
                           the hint'd device is not sufficient. */
                        if (global_notifycid) {
-                               auto int find_calling_channel(struct ast_channel *c);
-                               int find_calling_channel(struct ast_channel *c) {
-                                       return (c->pbx &&
-                                                       (!strcasecmp(c->macroexten, p->exten) || !strcasecmp(c->exten, p->exten)) &&
-                                                       !strcasecmp(c->context, p->context));
-                               }
+                               struct ast_channel *caller = NULL;
+                               struct caller_criteria data = {
+                                       .exten = p->exten,
+                                       .context = p->context,
+                               };
 
-                               struct ast_channel *caller = ast_channel_search_locked(find_calling_channel);
+                               caller = ast_channel_search_locked(find_calling_channel, &data);
 
                                if (caller) {
                                        local_display = ast_strdupa(caller->cid.cid_name);
index c1423462eba93effe12899a9bdb6f766f1df8323..64aaca069dda47a71010a8e237b21db68892a8e6 100644 (file)
@@ -1185,9 +1185,10 @@ struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *c
  * return 0 if there is no match, and non-zero if there is.
  * \param is_match callback executed on each channel until non-zero is returned, or we
  *        run out of channels to search.
+ * \param data data passed to the is_match callback during each invocation.
  * \return Returns the matched channel, or NULL if no channel was matched.
  */
-struct ast_channel *ast_channel_search_locked(int (*is_match)(struct ast_channel *));
+struct ast_channel *ast_channel_search_locked(int (*is_match)(struct ast_channel *, void *), void *data);
 
 /*! ! \brief Waits for a digit
  * \param c channel to wait for a digit on
index ec253ae0466f19de1e3b9680dec973c2471a81d0..b5a4054a4589ffff400288fdb9dc7dc326bbeb8b 100644 (file)
@@ -1227,14 +1227,14 @@ struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *c
 }
 
 /*! \brief Search for a channel based on the passed channel matching callback (first match) and return it, locked */
-struct ast_channel *ast_channel_search_locked(int (*is_match)(struct ast_channel *))
+struct ast_channel *ast_channel_search_locked(int (*is_match)(struct ast_channel *, void *), void *data)
 {
        struct ast_channel *c = NULL;
 
        AST_RWLIST_RDLOCK(&channels);
        AST_RWLIST_TRAVERSE(&channels, c, chan_list) {
                ast_channel_lock(c);
-               if (is_match(c)) {
+               if (is_match(c, data)) {
                        break;
                }
                ast_channel_unlock(c);
index ed13ee4fc74fc50a38dcce52568d860b15688e85..932f1b8a122ec878ef56154c0e1dcac10d4300c3 100644 (file)
@@ -3987,6 +3987,18 @@ static int manager_park(struct mansession *s, const struct message *m)
        return 0;
 }
 
+static int find_channel_by_group(struct ast_channel *c, void *data) {
+       struct ast_channel *chan = data;
+
+       return !c->pbx &&
+               /* Accessing 'chan' here is safe without locking, because there is no way for
+                  the channel do disappear from under us at this point.  pickupgroup *could*
+                  change while we're here, but that isn't a problem. */
+               (c != chan) &&
+               (chan->pickupgroup & c->callgroup) &&
+               ((c->_state == AST_STATE_RINGING) || (c->_state == AST_STATE_RING));
+}
+
 /*!
  * \brief Pickup a call
  * \param chan channel that initiated pickup.
@@ -3997,15 +4009,7 @@ static int manager_park(struct mansession *s, const struct message *m)
 */
 int ast_pickup_call(struct ast_channel *chan)
 {
-       auto int find_channel_by_group(struct ast_channel *);
-       int find_channel_by_group(struct ast_channel *c) {
-               return !c->pbx &&
-                       (c != chan) &&
-                       (chan->pickupgroup & c->callgroup) &&
-                       ((c->_state == AST_STATE_RINGING) ||
-                        (c->_state == AST_STATE_RING));
-       }
-       struct ast_channel *cur = ast_channel_search_locked(find_channel_by_group);
+       struct ast_channel *cur = ast_channel_search_locked(find_channel_by_group, chan);
 
        if (cur) {
                int res = -1;