1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/system_wrappers/include/trace.h"
12 #include "webrtc/voice_engine/dtmf_inband_queue.h"
13 
14 namespace webrtc {
15 
DtmfInbandQueue(int32_t id)16 DtmfInbandQueue::DtmfInbandQueue(int32_t id):
17     _id(id),
18     _DtmfCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
19     _nextEmptyIndex(0)
20 {
21     memset(_DtmfKey,0, sizeof(_DtmfKey));
22     memset(_DtmfLen,0, sizeof(_DtmfLen));
23     memset(_DtmfLevel,0, sizeof(_DtmfLevel));
24 }
25 
~DtmfInbandQueue()26 DtmfInbandQueue::~DtmfInbandQueue()
27 {
28     delete &_DtmfCritsect;
29 }
30 
31 int
AddDtmf(uint8_t key,uint16_t len,uint8_t level)32 DtmfInbandQueue::AddDtmf(uint8_t key, uint16_t len, uint8_t level)
33 {
34     CriticalSectionScoped lock(&_DtmfCritsect);
35 
36     if (_nextEmptyIndex >= kDtmfInbandMax)
37     {
38         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_id,-1),
39                    "DtmfInbandQueue::AddDtmf() unable to add Dtmf tone");
40         return -1;
41     }
42     int32_t index = _nextEmptyIndex;
43     _DtmfKey[index] = key;
44     _DtmfLen[index] = len;
45     _DtmfLevel[index] = level;
46     _nextEmptyIndex++;
47     return 0;
48 }
49 
50 int8_t
NextDtmf(uint16_t * len,uint8_t * level)51 DtmfInbandQueue::NextDtmf(uint16_t* len, uint8_t* level)
52 {
53     CriticalSectionScoped lock(&_DtmfCritsect);
54 
55     if(!PendingDtmf())
56     {
57         return -1;
58     }
59     int8_t nextDtmf = _DtmfKey[0];
60     *len=_DtmfLen[0];
61     *level=_DtmfLevel[0];
62 
63     memmove(&(_DtmfKey[0]), &(_DtmfKey[1]),
64             _nextEmptyIndex*sizeof(uint8_t));
65     memmove(&(_DtmfLen[0]), &(_DtmfLen[1]),
66             _nextEmptyIndex*sizeof(uint16_t));
67     memmove(&(_DtmfLevel[0]), &(_DtmfLevel[1]),
68             _nextEmptyIndex*sizeof(uint8_t));
69 
70     _nextEmptyIndex--;
71     return nextDtmf;
72 }
73 
74 bool
PendingDtmf()75 DtmfInbandQueue::PendingDtmf()
76 {
77     CriticalSectionScoped lock(&_DtmfCritsect);
78     return _nextEmptyIndex > 0;
79 }
80 
81 void
ResetDtmf()82 DtmfInbandQueue::ResetDtmf()
83 {
84     CriticalSectionScoped lock(&_DtmfCritsect);
85     _nextEmptyIndex = 0;
86 }
87 
88 }  // namespace webrtc
89