Add support to see if a peer has someone on hold, and fix a small bug with getting...
authorJoshua Colp <jcolp@digium.com>
Thu, 10 Aug 2006 02:41:20 +0000 (02:41 +0000)
committerJoshua Colp <jcolp@digium.com>
Thu, 10 Aug 2006 02:41:20 +0000 (02:41 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39500 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
devicestate.c

index 0aeb0f5..d3f7df7 100644 (file)
@@ -1031,6 +1031,7 @@ struct sip_peer {
        int callingpres;                /*!< Calling id presentation */
        int inUse;                      /*!< Number of calls in use */
        int inRinging;                  /*!< Number of calls ringing */
+       int onHold;                     /*!< Peer has someone on hold */
        int call_limit;                 /*!< Limit of concurrent calls */
        enum transfermodes allowtransfer;       /*! SIP Refer restriction scheme */
        char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
@@ -1282,7 +1283,7 @@ static int sip_devicestate(void *data);
 static int sip_poke_noanswer(void *data);
 static int sip_poke_peer(struct sip_peer *peer);
 static void sip_poke_all_peers(void);
-
+static void sip_peer_hold(struct sip_pvt *p, int hold);
 
 /*--- Applications, functions, CLI and manager command helpers */
 static const char *sip_nat_mode(const struct sip_pvt *p);
@@ -4916,29 +4917,33 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
                ast_set_read_format(p->owner, p->owner->readformat);
                ast_set_write_format(p->owner, p->owner->writeformat);
        }
+       
+       bridgepeer = ast_bridged_channel(p->owner);
 
-       if ((bridgepeer = ast_bridged_channel(p->owner))) {
-               /* We have a bridge */
-               /* Turn on/off music on hold if we are holding/unholding */
-               if (sin.sin_addr.s_addr && !sendonly) {
+       /* Turn on/off music on hold if we are holding/unholding */
+       if (sin.sin_addr.s_addr && !sendonly) {
+               /* Update peer state */
+               sip_peer_hold(p, 0);
+               if (bridgepeer)
                        ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
                
-                       /* Activate a re-invite */
-                       ast_queue_frame(p->owner, &ast_null_frame);
-               } else if (!sin.sin_addr.s_addr || sendonly) {
-                       /* No address for RTP, we're on hold */
+               /* Activate a re-invite */
+               ast_queue_frame(p->owner, &ast_null_frame);
+       } else if (!sin.sin_addr.s_addr || sendonly) {
+               /* Update peer state */
+               sip_peer_hold(p, 1);
+               /* No address for RTP, we're on hold */
+               if (bridgepeer)
                        ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
-                               S_OR(p->mohsuggest, NULL),
-                               !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-
-                       if (sendonly)
-                               ast_rtp_stop(p->rtp);
-                       /* RTCP needs to go ahead, even if we're on hold!!! */
-
-                       /* Activate a re-invite */
-                       ast_queue_frame(p->owner, &ast_null_frame);
-               }
-               /* guess we got a re-invite for changing media or IP - not hold/unhold */
+                                              S_OR(p->mohsuggest, NULL),
+                                              !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+               
+               if (sendonly)
+                       ast_rtp_stop(p->rtp);
+               /* RTCP needs to go ahead, even if we're on hold!!! */
+               
+               /* Activate a re-invite */
+               ast_queue_frame(p->owner, &ast_null_frame);
        }
 
        /* Manager Hold and Unhold events must be generated, if necessary */
@@ -6534,6 +6539,8 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full)
                pidfstate = "away";
                pidfnote = "Unavailable";
                break;
+       case AST_EXTENSION_ONHOLD:
+               break;
        case AST_EXTENSION_NOT_INUSE:
        default:
                /* Default setting */
@@ -7777,6 +7784,26 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
        return AUTH_CHALLENGE_SENT;
 }
 
+/*! \brief Change onhold state of a peer using a pvt structure */
+static void sip_peer_hold(struct sip_pvt *p, int hold)
+{
+       struct sip_peer *peer = find_peer(p->peername, NULL, 1);
+
+       if (!peer)
+               return;
+
+       /* If they put someone on hold, increment the value... otherwise decrement it */
+       if (hold)
+               peer->onHold++;
+       else
+               peer->onHold--;
+
+       /* Request device state update */
+       ast_device_state_changed("SIP/%s", peer->name);
+
+       return;
+}
+
 /*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
 \note  If you add an "hint" priority to the extension in the dial plan,
        you will get notifications on device state changes */
@@ -14578,7 +14605,9 @@ static int sip_devicestate(void *data)
                                        res = AST_DEVICE_INUSE;
                                else
                                        res = AST_DEVICE_NOT_INUSE;
-                               if (p->inRinging) {
+                               if (p->onHold)
+                                       res = AST_DEVICE_ONHOLD;
+                               else if (p->inRinging) {
                                        if (p->inRinging == p->inUse)
                                                res = AST_DEVICE_RINGING;
                                        else
index 40cd6c3..c434ce9 100644 (file)
@@ -51,8 +51,8 @@ static const char *devstatestring[] = {
        /* 3 AST_DEVICE_BUSY */         "Busy",         /*!< Busy */
        /* 4 AST_DEVICE_INVALID */      "Invalid",      /*!< Invalid - not known to Asterisk */
        /* 5 AST_DEVICE_UNAVAILABLE */  "Unavailable",  /*!< Unavailable (not registred) */
-       /* 6 AST_DEVICE_RINGING */      "Ringing"       /*!< Ring, ring, ring */
-       /* 7 AST_DEVICE_RINGINUSE */    "Ring+Inuse"    /*!< Ring and in use */
+       /* 6 AST_DEVICE_RINGING */      "Ringing",      /*!< Ring, ring, ring */
+       /* 7 AST_DEVICE_RINGINUSE */    "Ring+Inuse",   /*!< Ring and in use */
        /* 8 AST_DEVICE_ONHOLD */       "On Hold"       /*!< On Hold */
 };