17:39
[skypekit:skypekit.git] / skypekit_2.0.0.190_29281_CB30 / interfaces / skype / cpp_embedded / documentation / html / tutorial__5_8cpp-example.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
5 <title>SkypeKit C++ Wrapper: Main Page</title>
6 <link href="tabs.css" rel="stylesheet" type="text/css"/>
7 <link href="islander.css" rel="stylesheet" type="text/css"/>
8 </head>
9 <body>
10 <img src="..\skypekit.png" align="right">
11 <!-- Generated by Doxygen 1.6.2 -->
12 <script type="text/javascript">
13 <!--
14 function changeDisplayState (e){
15   var num=this.id.replace(/[^[0-9]/g,'');
16   var button=this.firstChild;
17   var sectionDiv=document.getElementById('dynsection'+num);
18   if (sectionDiv.style.display=='none'||sectionDiv.style.display==''){
19     sectionDiv.style.display='block';
20     button.src='open.gif';
21   }else{
22     sectionDiv.style.display='none';
23     button.src='closed.gif';
24   }
25 }
26 function initDynSections(){
27   var divs=document.getElementsByTagName('div');
28   var sectionCounter=1;
29   for(var i=0;i<divs.length-1;i++){
30     if(divs[i].className=='dynheader'&&divs[i+1].className=='dynsection'){
31       var header=divs[i];
32       var section=divs[i+1];
33       var button=header.firstChild;
34       if (button!='IMG'){
35         divs[i].insertBefore(document.createTextNode(' '),divs[i].firstChild);
36         button=document.createElement('img');
37         divs[i].insertBefore(button,divs[i].firstChild);
38       }
39       header.style.cursor='pointer';
40       header.onclick=changeDisplayState;
41       header.id='dynheader'+sectionCounter;
42       button.src='closed.gif';
43       section.id='dynsection'+sectionCounter;
44       section.style.display='none';
45       section.style.marginLeft='14px';
46       sectionCounter++;
47     }
48   }
49 }
50 window.onload = initDynSections;
51 -->
52 </script>
53 <div class="navigation" id="top">
54   <div class="tabs">
55     <ul>
56       <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
57       <li><a href="annotated.html"><span>Classes</span></a></li>
58       <li><a href="files.html"><span>Files</span></a></li>
59       <li><a href="examples.html"><span>Examples</span></a></li>
60     </ul>
61   </div>
62 </div>
63 <div class="contents">
64 <h1>tutorial_5.cpp</h1><h2><a class="anchor" id="Step5">
65 C++ Tutorial Step 5: Picking up incoming calls and catching voice activity notifications</a></h2>
66 <p>In this step of the tutorial, we finally get around to voice calls. We'll write a small SkypeKit client that </p>
67 <ul>
68 <li>selects default audio device. </li>
69 <li>waits for incoming calls . picks them up </li>
70 <li>if there's audio coming in from any of the remote parties, prints audio volume levels</li>
71 </ul>
72 <h3><a class="anchor" id="Step5Walkthrough">
73 Code Walkthrough</a></h3>
74 <p>To catch an incoming call, we override the OnConversationListChange callback of the <a class="el" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a> class. The callback gets fired on conversation list changes, with following arguments:.</p>
75 <div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> <a name="a0"></a><a class="code" href="class_skype.html#aa598df73a5ea412c30441e597fcbdb11">Skype::OnConversationListChange</a>(
76         <span class="keyword">const</span> <a name="_a1"></a><a class="code" href="class_conversation_ref.html" title="Reference to an Conversation class instance, equivalent to Conversation::Ref.">ConversationRef</a> &amp;conversation,
77         <span class="keyword">const</span> <a class="code" href="class_conversation.html#a0eb196dd7006e1e37ba1c246c30d6183">Conversation::LIST_TYPE</a> &amp;type,
78         <span class="keyword">const</span> <span class="keywordtype">bool</span> &amp;added)
79 </pre></div><p>To catch calls, we check all conversation list changes and see if the type argument is set to <a class="el" href="class_conversation.html#a0eb196dd7006e1e37ba1c246c30d6183a0b24b475845c969751f905f569a3b63c">Conversation::LIVE_CONVERSATIONS</a>. AFter that we can examine Livestatus property of the conversation. Particularly, we are interested in these three values:</p>
80 <ul>
81 <li><a class="el" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa123514d0921715cb2882899c32dd44fe">Conversation::RINGING_FOR_ME</a> - for detecting incoming calls (and accepting them). </li>
82 <li><a class="el" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa32af02c79b904609c269e86f28a86bd8">Conversation::IM_LIVE</a> - for detecting when the call actually obtains live status (NB! this is not instantaneous!). </li>
83 <li><a class="el" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8facd6e7d0bed121f4a6e47aae2f9fcfb13">Conversation::RECENTLY_LIVE</a> - for detecting when a call is hanged up.</li>
84 </ul>
85 <p>First, the RINGING_FOR_ME event. In case of an incoming call, we will obviously be interested in who is the caller. We cannot assume here that the caller is a single contact/participant. It could well be that we are being added to a conference call that has more than one live participant already.</p>
86 <div class="fragment"><pre class="fragment">        <span class="keywordflow">if</span> (LiveStatus == <a name="a2"></a><a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa123514d0921715cb2882899c32dd44fe">Conversation::RINGING_FOR_ME</a>)
87         {
88             <a name="_a3"></a><a class="code" href="class_participant_refs.html" title="list of references to Participant class instances, equivalent to Participant::Refs...">ParticipantRefs</a> CallerList;
89             conversation-&gt;GetParticipants(CallerList, <a name="a4"></a><a class="code" href="class_conversation.html#a3b9a94385c62856673e211120ea2ca7badaf9ba258a630895b4eb1055ad619adf">Conversation::OTHER_CONSUMERS</a>);
90             <a name="_a5"></a><a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> PartList = <span class="stringliteral">&quot;&quot;</span>;
91             <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; CallerList.<a name="a6"></a><a class="code" href="class_s_e_ref_list.html#a6abe33cebf6e934cb268c4e667d3e601">size</a>(); I++)
92             {
93                 PartList = PartList + <span class="stringliteral">&quot; &quot;</span> + (<span class="keyword">const</span> <span class="keywordtype">char</span>*)CallerList[I]-&gt;GetProp(<a name="a7"></a><a class="code" href="class_participant.html#a0789ec8e8c2faea38a444800004be26dae6efd49f53150606b810cd7caf6ba9a4">Participant::P_IDENTITY</a>);
94             };
95
96             <span class="keywordflow">if</span> (!IsLiveSessionUp)
97             {
98                 printf(<span class="stringliteral">&quot;Incoming call from: %s \n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)PartList);
99                 conversation-&gt;JoinLiveSession();
100             }
101             <span class="keywordflow">else</span>
102             {
103                 printf(<span class="stringliteral">&quot;Another call is coming in from : %s \n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)PartList);
104                 printf(<span class="stringliteral">&quot;As we already have a live session up, we will reject it. \n&quot;</span>);
105                 conversation-&gt;LeaveLiveSession(<span class="keyword">true</span>);
106             };
107         };
108 </pre></div><p>Also, with <a class="el" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a> we can only have one "live" conversation at any time. There can be a conference with multiple participants, but only one conversation in a <a class="el" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a> instance can be live. The correct way of doing this would involve checking <a class="el" href="class_skype.html#a787819d0f0415a4d755c7ebd0b440554">Skype::GetConversationList</a> with the LIVE_CONVERSATIONS filter. The lazy way is to use a global bool, as we will do in this example. The IsLiveSessionUp variable is set to true if the LOCAL_LIVESTATUS value is set to <a class="el" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa32af02c79b904609c269e86f28a86bd8">Conversation::IM_LIVE</a> and to false when it's set to RECENTLY_LIVE.</p>
109 <div class="fragment"><pre class="fragment">    <span class="keywordflow">if</span> (LiveStatus == <a name="a8"></a><a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa32af02c79b904609c269e86f28a86bd8">Conversation::IM_LIVE</a>)
110     {
111         printf(<span class="stringliteral">&quot;Live session is up.\n&quot;</span>);
112         IsLiveSessionUp = <span class="keyword">true</span>;
113     };
114
115     <span class="keywordflow">if</span> (LiveStatus == <a name="a9"></a><a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8facd6e7d0bed121f4a6e47aae2f9fcfb13">Conversation::RECENTLY_LIVE</a>)
116     {
117         printf(<span class="stringliteral">&quot;Call finished.\n&quot;</span>);
118         IsLiveSessionUp = <span class="keyword">false</span>;
119     };
120 </pre></div><p>We have now completed our first objective - the client is picking up incoming calls, refusing calls when one is already up, and displaying a notification when the call ends.</p>
121 <p>Our second objective was displaying voice activity events. For this we need to derive our own <a class="el" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a> class and catch changes to the <a class="el" href="class_participant.html#a0789ec8e8c2faea38a444800004be26dae09cf97d97304778a53f913955d6bd4d">Participant::P_SOUND_LEVEL</a> property. This property can have integer values ranging from 0 to 10.</p>
122 <p>The customized <a class="el" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a> class would looks like this:</p>
123 <div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyParticipant : <span class="keyword">public</span> <a name="_a10"></a><a class="code" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a>
124 {
125 <span class="keyword">public</span>:
126     <span class="keyword">typedef</span> <a name="_a11"></a><a class="code" href="struct_d_ref.html" title="Used for downcast the skypekit references to references to you own derived classes...">DRef&lt;MyParticipant, Participant&gt;</a> Ref;
127     MyParticipant(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a name="_a12"></a><a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root);
128     ~MyParticipant() {};
129
130     <span class="keywordtype">void</span> <a name="a13"></a><a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">OnChange</a>(<span class="keywordtype">int</span> prop);
131 };
132
133 MyParticipant::MyParticipant(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root) : <a class="code" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a>(oid, root) {};
134
135 <span class="keywordtype">void</span> <a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">MyParticipant::OnChange</a>(<span class="keywordtype">int</span> prop)
136 {
137     <span class="keywordflow">if</span> (prop == <a name="a14"></a><a class="code" href="class_participant.html#a0789ec8e8c2faea38a444800004be26dae09cf97d97304778a53f913955d6bd4d">Participant::P_SOUND_LEVEL</a>)
138     {
139         <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> Name;
140         uint SoundLevel;
141         GetPropIdentity(Name);
142         GetPropSoundLevel(SoundLevel);
143         printf(<span class="stringliteral">&quot;%s sound level = %d\n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)Name, SoundLevel);
144     };
145 };
146 </pre></div><p>Note that this property change event fires only for remote participants - you will not get those events for your own voice activities.</p>
147 <p>Now onto selecting audio devices. Note that this part is not actually mandatory for picking up calls. However, it may happen that the SkypeKit audio engine fails to pick correct audio devices for you, so it makes sense to cover this topic here as well.</p>
148 <p>Firstly, there are three audio devices that the SkypeKit audio engine is interested in - output (speakers/headsets), input (microphone) and the PCM (or notification device). That one is basically an output device as well. It is used for various notification sounds, such as ringtones and other audible notification sounds. Having it separately enables you to have phone ringing on a different device from normal headset.</p>
149 <p>On your machine, there are two sorts of audio devices: audio in (microphones) and audio out (playback).</p>
150 <p>To query lists of those devices, there are two <a class="el" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a> class methods: GetAvailableOutputDevices and GetAvailableRecordingDevices. Both these return three SEStringLists.</p>
151 <ul>
152 <li>First of them is list of device handles. These can be used as arguments to other audio related commands, such as <a class="el" href="class_skype.html#a494bec4b1496140065202c946802b32c">Skype::SelectSoundDevices</a> </li>
153 <li>Second list will contain descriptive device name. </li>
154 <li>Third list contains product IDs, which can be in most cases safely ignored.</li>
155 </ul>
156 <p>After you have these lists, you can set all active audio devices for SkypeKit with just one command: <a class="el" href="class_skype.html#a494bec4b1496140065202c946802b32c">Skype::SelectSoundDevices</a>-</p>
157 <p>In code, this would look approximately like this: </p>
158 <div class="fragment"><pre class="fragment"><a name="_a15"></a><a class="code" href="class_s_e_string_list.html" title="SEStringList represents a list of strings (SEString objects).">SEStringList</a> OutHandles, OutNames, OutProductIDs;
159 <a class="code" href="class_s_e_string_list.html" title="SEStringList represents a list of strings (SEString objects).">SEStringList</a> InHandles, InNames, InProductIDs;
160
161 printf(<span class="stringliteral">&quot;** Playback devices:\n&quot;</span>);
162 skype-&gt;GetAvailableOutputDevices (OutHandles, OutNames, OutProductIDs);
163 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; OutHandles.<a name="a16"></a><a class="code" href="class_s_e_string_list.html#a0f86fa4676e6bea28f9923955a503360">size</a>(); I++)
164 {
165     printf(<span class="stringliteral">&quot;\t%d. %s\n&quot;</span>, I, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)OutNames[I]);
166 };
167
168 printf(<span class="stringliteral">&quot;\n** Recording devices:\n&quot;</span>);
169 skype-&gt;GetAvailableRecordingDevices (InHandles, InNames, InProductIDs);
170 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; InHandles.<a class="code" href="class_s_e_string_list.html#a0f86fa4676e6bea28f9923955a503360">size</a>(); I++)
171 {
172     printf(<span class="stringliteral">&quot;\t%d. Name=%s\n&quot;</span>, I, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)InNames[I]);
173 };
174
175 <span class="comment">// Currently setting the sound devices to 1st item in both lists.</span>
176 <span class="comment">// If your microphone or speakers fail to work, you might want</span>
177 <span class="comment">// to change these values.</span>
178 skype-&gt;SelectSoundDevices(InHandles[0], OutHandles[0], OutHandles[0]);
179 </pre></div><h2><a class="anchor" id="Step5FullCode">
180 Full code of this example</a></h2>
181 <div class="fragment"><pre class="fragment"><span class="comment">/****************************************************************************</span>
182 <span class="comment"></span>
183 <span class="comment">Getting Started With SkypeKit. Tutorial Application, Step 5.</span>
184 <span class="comment"></span>
185 <span class="comment">In this step of the tutorial, we finally get around to voice calls. We&#39;ll write a small SkypeKit client that </span>
186 <span class="comment">  * waits for incoming calls</span>
187 <span class="comment">  * picks them up </span>
188 <span class="comment">  * if there&#39;s audio coming in from any of the remote parties, prints audio volume levels</span>
189 <span class="comment"></span>
190 <span class="comment">**/</span>
191
192 <span class="preprocessor">#ifdef _WIN32</span>
193 <span class="preprocessor"></span><span class="preprocessor">#include &quot;Windows.h&quot;</span>
194 <span class="preprocessor">#else</span>
195 <span class="preprocessor"></span><span class="preprocessor">#include &lt;unistd.h&gt;</span>
196 <span class="preprocessor">#endif</span>
197 <span class="preprocessor"></span>
198 <span class="preprocessor">#include &quot;<a class="code" href="skype-embedded__2_8h.html">skype-embedded_2.h</a>&quot;</span>
199 <span class="preprocessor">#include &quot;<a class="code" href="skype-tcp-transport_8h.html">skype-tcp-transport.h</a>&quot;</span>
200 <span class="preprocessor">#include &quot;app_token.h&quot;</span>
201
202 <span class="keyword">using namespace </span>Sid;
203
204 <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> inetAddr       = <span class="stringliteral">&quot;127.0.0.1&quot;</span>;
205 uint portNum            = 8963;
206
207 <span class="keywordtype">bool</span> LoggedIn           = <span class="keyword">false</span>;
208 <span class="keywordtype">bool</span> LoggedOut          = <span class="keyword">false</span>;
209 <span class="keywordtype">bool</span> IsLiveSessionUp    = <span class="keyword">false</span>;
210
211 <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> MyAccountName;
212 <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> MyAccountPsw;
213
214 <a name="_a17"></a><a class="code" href="class_s_e_t_c_p_transport.html" title="TCP transport to skypekit.">SETCPTransport</a>* transport   = 0;
215
216
217 <span class="keywordtype">void</span> debugOut(<span class="keyword">const</span> <span class="keywordtype">char</span>* out)
218 {
219     <span class="comment">//printf(&quot;%s&quot;, out);</span>
220 }
221
222 <span class="keywordtype">void</span> Delay(<span class="keywordtype">int</span> Ms)
223 {
224 <span class="preprocessor">    #ifdef _WIN32</span>
225 <span class="preprocessor"></span>        Sleep(Ms);
226 <span class="preprocessor">    #else</span>
227 <span class="preprocessor"></span>        sleep(Ms);
228 <span class="preprocessor">    #endif</span>
229 <span class="preprocessor"></span>};
230
231
232 <span class="comment">//---------------------------------------------------------------------------------------</span>
233 <span class="comment">// Subclassing Account</span>
234
235 <span class="keyword">class </span>MyAccount : <span class="keyword">public</span> <a name="_a18"></a><a class="code" href="class_account.html" title="Represents a local account. Encapsulates methods for Skype account creation, login...">Account</a>
236 {
237 <span class="keyword">public</span>:
238     <span class="keyword">typedef</span> <a class="code" href="struct_d_ref.html" title="Used for downcast the skypekit references to references to you own derived classes...">DRef&lt;MyAccount, Account&gt;</a> Ref;
239     MyAccount(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root);
240     ~MyAccount() {};
241
242     <span class="keywordtype">void</span> <a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">OnChange</a>(<span class="keywordtype">int</span> prop);
243 };
244
245 MyAccount::MyAccount(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root) : <a class="code" href="class_account.html" title="Represents a local account. Encapsulates methods for Skype account creation, login...">Account</a>(oid, root) {};
246
247 <span class="keywordtype">void</span> <a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">MyAccount::OnChange</a>(<span class="keywordtype">int</span> prop)
248 {
249     <span class="keywordflow">if</span> (prop == <a name="a19"></a><a class="code" href="class_account.html#a0e7af48c2ba1d22690d83f5adbc071c5a61a8b512c81fd58cbcd6ea8f9e8d54af">Account::P_STATUS</a>)
250     {
251         <a class="code" href="class_account.html#ac2cd2fd3f85a302363a51db3ba97c90d">Account::STATUS</a> LoginStatus;
252         GetPropStatus(LoginStatus);
253         <span class="keywordflow">if</span> (LoginStatus == <a name="a20"></a><a class="code" href="class_account.html#ac2cd2fd3f85a302363a51db3ba97c90dac2c5c7998621e577285e6c4517a897bd">Account::LOGGED_IN</a>)        { LoggedIn  = <span class="keyword">true</span>; };
254         <span class="keywordflow">if</span> (LoginStatus == <a name="a21"></a><a class="code" href="class_account.html#ac2cd2fd3f85a302363a51db3ba97c90dac506fb36d2c2004e4f9abe5c64941c3d">Account::LOGGED_OUT</a>)       { LoggedOut = <span class="keyword">true</span>; };
255     };
256 };
257
258
259 <span class="comment">//---------------------------------------------------------------------------------------</span>
260 <span class="comment">// Subclassing Participant</span>
261
262 <span class="keyword">class </span>MyParticipant : <span class="keyword">public</span> <a class="code" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a>
263 {
264 <span class="keyword">public</span>:
265     <span class="keyword">typedef</span> <a class="code" href="struct_d_ref.html" title="Used for downcast the skypekit references to references to you own derived classes...">DRef&lt;MyParticipant, Participant&gt;</a> Ref;
266     MyParticipant(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root);
267     ~MyParticipant() {};
268
269     <span class="keywordtype">void</span> <a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">OnChange</a>(<span class="keywordtype">int</span> prop);
270 };
271
272 MyParticipant::MyParticipant(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> oid, <a class="code" href="class_s_e_root_object.html" title="SERootObject is the root module and entry point for API.">SERootObject</a>* root) : <a class="code" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a>(oid, root) {};
273
274 <span class="keywordtype">void</span> <a class="code" href="class_s_e_object.html#a9bbdb15b8b15ac9c3471da3855f67227">MyParticipant::OnChange</a>(<span class="keywordtype">int</span> prop)
275 {
276     <span class="keywordflow">if</span> (prop == <a class="code" href="class_participant.html#a0789ec8e8c2faea38a444800004be26dae09cf97d97304778a53f913955d6bd4d">Participant::P_SOUND_LEVEL</a>)
277     {
278         <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> Name;
279         uint SoundLevel;
280         GetPropIdentity(Name);
281         GetPropSoundLevel(SoundLevel);
282         printf(<span class="stringliteral">&quot;%s sound level = %d\n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)Name, SoundLevel);
283     }
284 };
285
286
287 <span class="comment">//---------------------------------------------------------------------------------------</span>
288 <span class="comment">// Subclassing Skype</span>
289
290 <span class="keyword">class </span>MySkype : <span class="keyword">public</span> <a name="_a22"></a><a class="code" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a>
291 {
292 <span class="keyword">public</span>:
293     MySkype(<a name="_a23"></a><a class="code" href="class_s_e_transport.html" title="Abstract interface for transport layer.">SETransport</a>* transport) : <a class="code" href="class_skype.html" title="The main class that exposes Skype-related functionality to your application.">Skype</a>(transport) {}
294     ~MySkype() {}
295     <a class="code" href="class_account.html" title="Represents a local account. Encapsulates methods for Skype account creation, login...">Account</a>* <a name="a24"></a><a class="code" href="class_skype.html#a3f609b824744b88ec82b47e460116b92">newAccount</a>(<span class="keywordtype">int</span> oid) {<span class="keywordflow">return</span> <span class="keyword">new</span> MyAccount(oid, <span class="keyword">this</span>);}
296     <a class="code" href="class_participant.html" title="Conversation participant class. Instances of this class represent contacts in context...">Participant</a>* <a name="a25"></a><a class="code" href="class_skype.html#a60cbc623c29f1faf2326b804ea94a4d0">newParticipant</a>(<span class="keywordtype">int</span> oid) {<span class="keywordflow">return</span> <span class="keyword">new</span> MyParticipant(oid, <span class="keyword">this</span>);}
297
298     <span class="keywordtype">void</span> <a class="code" href="class_skype.html#aa598df73a5ea412c30441e597fcbdb11">OnConversationListChange</a>(
299         <span class="keyword">const</span> <a class="code" href="class_conversation_ref.html" title="Reference to an Conversation class instance, equivalent to Conversation::Ref.">ConversationRef</a> &amp;conversation,
300         <span class="keyword">const</span> <a class="code" href="class_conversation.html#a0eb196dd7006e1e37ba1c246c30d6183">Conversation::LIST_TYPE</a> &amp;type,
301         <span class="keyword">const</span> <span class="keywordtype">bool</span> &amp;added);
302 };
303
304
305 <span class="keywordtype">void</span> <a class="code" href="class_skype.html#aa598df73a5ea412c30441e597fcbdb11">MySkype::OnConversationListChange</a>(
306         <span class="keyword">const</span> <a class="code" href="class_conversation_ref.html" title="Reference to an Conversation class instance, equivalent to Conversation::Ref.">ConversationRef</a> &amp;conversation,
307         <span class="keyword">const</span> <a class="code" href="class_conversation.html#a0eb196dd7006e1e37ba1c246c30d6183">Conversation::LIST_TYPE</a> &amp;type,
308         <span class="keyword">const</span> <span class="keywordtype">bool</span> &amp;added)
309 {
310     <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> DisplayName;
311     <a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8f">Conversation::LOCAL_LIVESTATUS</a> LiveStatus;
312     conversation-&gt;GetPropDisplayname(DisplayName);
313     conversation-&gt;GetPropLocalLivestatus(LiveStatus);
314
315     printf(<span class="stringliteral">&quot;ConversationListChange fired on: %s\n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)DisplayName);
316     
317     <span class="keywordflow">if</span> (type == <a name="a26"></a><a class="code" href="class_conversation.html#a0eb196dd7006e1e37ba1c246c30d6183a0b24b475845c969751f905f569a3b63c">Conversation::LIVE_CONVERSATIONS</a>)
318     {
319         printf(<span class="stringliteral">&quot;Live status changed to %d\n&quot;</span>, LiveStatus);
320
321         <span class="keywordflow">if</span> (LiveStatus == <a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa123514d0921715cb2882899c32dd44fe">Conversation::RINGING_FOR_ME</a>)
322         {
323             <a class="code" href="class_participant_refs.html" title="list of references to Participant class instances, equivalent to Participant::Refs...">ParticipantRefs</a> CallerList;
324             conversation-&gt;GetParticipants(CallerList, <a class="code" href="class_conversation.html#a3b9a94385c62856673e211120ea2ca7badaf9ba258a630895b4eb1055ad619adf">Conversation::OTHER_CONSUMERS</a>);
325             <a class="code" href="class_s_e_string.html" title="SEString is basic char* based string class.">SEString</a> PartList = <span class="stringliteral">&quot;&quot;</span>;
326             <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; CallerList.<a class="code" href="class_s_e_ref_list.html#a6abe33cebf6e934cb268c4e667d3e601">size</a>(); I++)
327             {
328                 PartList = PartList + <span class="stringliteral">&quot; &quot;</span> + (<span class="keyword">const</span> <span class="keywordtype">char</span>*)CallerList[I]-&gt;GetProp(<a class="code" href="class_participant.html#a0789ec8e8c2faea38a444800004be26dae6efd49f53150606b810cd7caf6ba9a4">Participant::P_IDENTITY</a>);
329             };
330
331             <span class="keywordflow">if</span> (!IsLiveSessionUp)
332             {
333                 printf(<span class="stringliteral">&quot;Incoming call from: %s \n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)PartList);
334                 conversation-&gt;JoinLiveSession();
335             }
336             <span class="keywordflow">else</span>
337             {
338                 printf(<span class="stringliteral">&quot;Another call is coming in from : %s \n&quot;</span>, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)PartList);
339                 printf(<span class="stringliteral">&quot;As we already have a live session up, we will reject it. \n&quot;</span>);
340                 conversation-&gt;LeaveLiveSession(<span class="keyword">true</span>);
341             };
342         };
343
344         <span class="keywordflow">if</span> (LiveStatus == <a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8fa32af02c79b904609c269e86f28a86bd8">Conversation::IM_LIVE</a>)
345         {
346             printf(<span class="stringliteral">&quot;Live session is up.\n&quot;</span>);
347             IsLiveSessionUp = <span class="keyword">true</span>;
348         };
349
350         <span class="keywordflow">if</span> (LiveStatus == <a class="code" href="class_conversation.html#a65f54d9d78c06e3164b73cbba8df0f8facd6e7d0bed121f4a6e47aae2f9fcfb13">Conversation::RECENTLY_LIVE</a>)
351         {
352             printf(<span class="stringliteral">&quot;Call finished.\n&quot;</span>);
353             IsLiveSessionUp = <span class="keyword">false</span>;
354         };
355     };
356 };
357
358 <span class="comment">//---------------------------------------------------------------------------------------</span>
359 <span class="comment">// Main</span>
360
361 MySkype* skype = 0;
362
363 <span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])
364 {
365     printf(<span class="stringliteral">&quot;*****************************************************************\n&quot;</span>);
366     printf(<span class="stringliteral">&quot; SkypeKit Tutorial, Step 5. - Answering incoming audio calls.\n&quot;</span>);
367     printf(<span class="stringliteral">&quot;*****************************************************************\n&quot;</span>);
368
369     <span class="keywordflow">if</span> (argc &lt; 3)
370     {
371         printf(<span class="stringliteral">&quot;usage: tutorial_5 &lt;skypename&gt; &lt;password&gt;\n&quot;</span>);
372         <span class="keywordflow">return</span> 0;
373     };
374
375     MyAccountName = argv[1];
376     MyAccountPsw = argv[2];
377
378     printf(<span class="stringliteral">&quot;Creating transport ..\n&quot;</span>);
379     transport = <span class="keyword">new</span> <a class="code" href="class_s_e_t_c_p_transport.html" title="TCP transport to skypekit.">SETCPTransport</a>(inetAddr, portNum);
380     printf(<span class="stringliteral">&quot;Creating skype ..\n&quot;</span>);
381     skype = <span class="keyword">new</span> MySkype(transport);
382     skype-&gt;log = &amp;(debugOut);
383
384     skype-&gt;init();
385     skype-&gt;start();
386
387     printf(<span class="stringliteral">&quot;Submitting application token..\n&quot;</span>);
388     skype-&gt;SetApplicationToken(AppToken);
389
390     printf(<span class="stringliteral">&quot;Retrieving account ..\n&quot;</span>);
391     MyAccount::Ref A;
392
393     <span class="keywordflow">if</span> (skype-&gt;GetAccount(MyAccountName, A))
394     {
395         printf(<span class="stringliteral">&quot;Logging in..\n&quot;</span>);
396         A-&gt;LoginWithPassword(MyAccountPsw, <span class="keyword">false</span>, <span class="keyword">true</span>);
397         <span class="keywordflow">while</span> (!LoggedIn) {Delay(1);};
398         printf(<span class="stringliteral">&quot;Loggin complete.\n&quot;</span>);
399         
400         <span class="comment">// Getting a list of audio devices. There are two separate commands:</span>
401         <span class="comment">// Skype::GetAvailableOutputDevices and Skype-&gt;GetAvailableRecordingDevices</span>
402         <span class="comment">// Both retrurn three SEStringLists. </span>
403         <span class="comment">// 1. First of them is list of device handles. These can be used as arguments</span>
404         <span class="comment">// to other audio related commands, such as Skype::SelectSoundDevices</span>
405         <span class="comment">// 2. Second list will contain descriptive device name.</span>
406         <span class="comment">// 3. Third list contains product IDs, which can be in most cases safely ignored.</span>
407
408         <a class="code" href="class_s_e_string_list.html" title="SEStringList represents a list of strings (SEString objects).">SEStringList</a> OutHandles, OutNames, OutProductIDs;
409         <a class="code" href="class_s_e_string_list.html" title="SEStringList represents a list of strings (SEString objects).">SEStringList</a> InHandles, InNames, InProductIDs;
410
411         printf(<span class="stringliteral">&quot;** Playback devices:\n&quot;</span>);
412         skype-&gt;GetAvailableOutputDevices (OutHandles, OutNames, OutProductIDs);
413         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; OutHandles.<a class="code" href="class_s_e_string_list.html#a0f86fa4676e6bea28f9923955a503360">size</a>(); I++)
414         {
415             printf(<span class="stringliteral">&quot;\t%d. %s\n&quot;</span>, I, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)OutNames[I]);
416         };
417
418         <span class="comment">// Getting a list of audio input devices.</span>
419         printf(<span class="stringliteral">&quot;\n** Recording devices:\n&quot;</span>);
420         skype-&gt;GetAvailableRecordingDevices (InHandles, InNames, InProductIDs);
421         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> I = 0; I &lt; InHandles.<a class="code" href="class_s_e_string_list.html#a0f86fa4676e6bea28f9923955a503360">size</a>(); I++)
422         {
423             printf(<span class="stringliteral">&quot;\t%d. Name=%s\n&quot;</span>, I, (<span class="keyword">const</span> <span class="keywordtype">char</span>*)InNames[I]);
424         };
425
426         <span class="comment">// Currently setting the sound devices to 1st item in both lists.</span>
427         <span class="comment">// If your microphone or speakers fail to work, you might want</span>
428         <span class="comment">// to change these values.</span>
429         skype-&gt;SelectSoundDevices(InHandles[0], OutHandles[0], OutHandles[0]);
430         skype-&gt;SetSpeakerVolume(100);
431
432         <span class="keywordtype">char</span> Ch;
433         printf(<span class="stringliteral">&quot;Now accepting incoming calls..\n&quot;</span>);
434         printf(<span class="stringliteral">&quot;Press ENTER to quit.\n&quot;</span>);
435         Ch = getchar();
436
437         printf(<span class="stringliteral">&quot;Logging out..\n&quot;</span>);
438         A-&gt;Logout(<span class="keyword">false</span>);
439
440         <span class="keywordflow">while</span> (!LoggedOut) {Delay(1);};
441         printf(<span class="stringliteral">&quot;Logout complete.\n&quot;</span>);
442     }
443     <span class="keywordflow">else</span>
444     {
445         printf(<span class="stringliteral">&quot;Account does not exist\n&quot;</span>);
446     };
447
448     printf(<span class="stringliteral">&quot;Cleaning up.\n&quot;</span>);
449     skype-&gt;stop();
450     skype-&gt;cleanup();
451     <span class="keyword">delete</span> skype;
452     <span class="keyword">delete</span> transport;
453     printf(<span class="stringliteral">&quot;Done.\n&quot;</span>);
454     <span class="keywordflow">return</span> 0;
455 };
456 </pre></div> </div>
457
458 <hr/>   
459                 <p><b>(c) Skype Technologies S.A. Confidential/Proprietary</b></p>              
460                 <p>Last updated: 18 Jun 2010</p>                
461                 </BODY>
462 </HTML>