implemented extension config for phone connector
Stefan Schuermans

Stefan Schuermans commited on 2011-12-22 15:00:51
Showing 5 changed files, with 206 additions and 1 deletions.

... ...
@@ -6,11 +6,13 @@
6 6
 #ifndef BLINKER_PHONE_H
7 7
 #define BLINKER_PHONE_H
8 8
 
9
+#include <map>
9 10
 #include <string>
10 11
 
11 12
 #include "Directory.h"
12 13
 #include "File.h"
13 14
 #include "IoCallee.h"
15
+#include "ListTracker.h"
14 16
 #include "Mgrs.h"
15 17
 #include "Module.h"
16 18
 #include "SettingFile.h"
... ...
@@ -27,6 +29,15 @@ protected:
27 29
   /// type for address setting file
28 30
   typedef SettingFile<ADDR> AddrFile;
29 31
 
32
+  /// extension to be called
33
+  class Extension;
34
+
35
+  /// extension list tracker
36
+  typedef ListTracker<Phone, Extension, Directory> ExtListTracker;
37
+
38
+  /// map of extensions to call (extension name  -> module name)
39
+  typedef std::map<std::string, std::string> ExtMap;
40
+
30 41
 public:
31 42
   /**
32 43
    * @brief constructor
... ...
@@ -89,6 +100,12 @@ protected:
89 100
   /// receive data from socket
90 101
   void receiveFromSock();
91 102
 
103
+  /**
104
+   * @brief process message from server
105
+   * @param[in] msg message from server
106
+   */
107
+  void serverMsg(const std::string &msg);
108
+
92 109
   /// update time callback
93 110
   void updateTimeCallback();
94 111
 
... ...
@@ -99,9 +116,11 @@ protected:
99 116
 protected:
100 117
   AddrFile       m_fileBind;       ///< bind address file
101 118
   AddrFile       m_fileServer;     ///< server address file
119
+  ExtListTracker m_extListTracker; ///< extension tracker
102 120
   SOCK           *m_pSock;         ///< socket to use for sending messages
103 121
   Time           m_timeRegister;   ///< time to re-register
104 122
   Time           m_timeHeartbeat;  ///< time to send next heartbeat
123
+  ExtMap         m_extMap;         ///< map of extensions to call
105 124
 }; // class Phone
106 125
 
107 126
 } // namespace Blinker
... ...
@@ -0,0 +1,58 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_PHONEEXTENSION_H
7
+#define BLINKER_PHONEEXTENSION_H
8
+
9
+#include <string>
10
+
11
+#include "Directory.h"
12
+#include "Module.h"
13
+#include "NameFile.h"
14
+#include "Phone.h"
15
+
16
+namespace Blinker {
17
+
18
+/// phone extension to call
19
+template<typename ADDR, typename SOCK>
20
+class Phone<ADDR, SOCK>::Extension
21
+{
22
+public:
23
+  /**
24
+   * @brief constructor
25
+   * @param[in] phone owning phone object
26
+   * @param[in] name extension name (i.e. phone number)
27
+   * @param[in] dirBase base directory
28
+   */
29
+  Extension(Phone &phone, const std::string &name, const Directory &dirBase);
30
+
31
+  /// destructor
32
+  ~Extension();
33
+
34
+private:
35
+  /// copy constructor disabled
36
+  Extension(const Extension &that);
37
+
38
+  /// assignment operator disabled
39
+  const Extension & operator=(const Extension &that);
40
+
41
+public:
42
+  /// check for update of configuration
43
+  void updateConfig();
44
+
45
+protected:
46
+  /// (re-)get module to connect to
47
+  void getModule();
48
+
49
+protected:
50
+  Phone       &m_phone;     ///< owning phone object
51
+  std::string m_name;       ///< extension name (i.e. phone number)
52
+  NameFile    m_fileModule; ///< file containing module to connect to
53
+}; // class Phone<ADDR, SOCK>::Extension
54
+
55
+} // namespace Blinker
56
+
57
+#endif // #ifndef BLINKER_PHONEEXTENSION_H
58
+
... ...
@@ -0,0 +1,72 @@
1
+/* Blinker
2
+   Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_PHONEEXTENSION_IMPL_H
7
+#define BLINKER_PHONEEXTENSION_IMPL_H
8
+
9
+#include <string>
10
+
11
+#include "Directory.h"
12
+#include "File.h"
13
+#include "Module.h"
14
+#include "NameFile.h"
15
+#include "Phone.h"
16
+#include "PhoneExtension.h"
17
+
18
+namespace Blinker {
19
+
20
+/**
21
+ * @brief constructor
22
+ * @param[in] phone owning phone object
23
+ * @param[in] name extension name (i.e. phone number)
24
+ * @param[in] dirBase base directory
25
+ */
26
+template<typename ADDR, typename SOCK>
27
+Phone<ADDR, SOCK>::Extension::Extension(Phone &phone, const std::string &name,
28
+                               const Directory &dirBase):
29
+  m_phone(phone),
30
+  m_name(name),
31
+  m_fileModule(dirBase.getFile("module"))
32
+{
33
+  // set up
34
+  getModule();
35
+}
36
+
37
+/// destructor
38
+template<typename ADDR, typename SOCK>
39
+Phone<ADDR, SOCK>::Extension::~Extension()
40
+{
41
+  // remove extension from extension map
42
+  m_phone.m_extMap.erase(m_name);
43
+}
44
+
45
+/// check for update of configuration
46
+template<typename ADDR, typename SOCK>
47
+void Phone<ADDR, SOCK>::Extension::updateConfig()
48
+{
49
+  // module file was modified -> re-get module to connect to
50
+  if (m_fileModule.checkModified())
51
+    getModule();
52
+}
53
+
54
+/// (re-)get module to connect to
55
+template<typename ADDR, typename SOCK>
56
+void Phone<ADDR, SOCK>::Extension::getModule()
57
+{
58
+  // remove old extension information from extension map
59
+  m_phone.m_extMap.erase(m_name);
60
+
61
+  // get new module name from file
62
+  m_fileModule.update();
63
+
64
+  // add new module name to extension map
65
+  if (m_fileModule.m_valid)
66
+    m_phone.m_extMap[m_name] = m_fileModule.m_obj.m_str;
67
+}
68
+
69
+} // namespace Blinker
70
+
71
+#endif // #ifndef BLINKER_PHONEEXTENSION_IMPL_H
72
+
... ...
@@ -11,10 +11,15 @@
11 11
 #include "Directory.h"
12 12
 #include "File.h"
13 13
 #include "IoCallee.h"
14
+#include "ListTracker.h"
15
+#include "ListTracker_impl.h"
14 16
 #include "Mgrs.h"
15 17
 #include "Module.h"
16 18
 #include "Phone.h"
19
+#include "PhoneExtension.h"
20
+#include "PhoneExtension_impl.h"
17 21
 #include "SettingFile.h"
22
+#include "StringParser.h"
18 23
 #include "Time.h"
19 24
 #include "TimeCallee.h"
20 25
 
... ...
@@ -30,6 +35,7 @@ Phone<ADDR, SOCK>::Phone(Mgrs &mgrs, const Directory &dirBase):
30 35
   Module(mgrs, dirBase),
31 36
   m_fileBind(dirBase.getFile("bind")),
32 37
   m_fileServer(dirBase.getFile("server")),
38
+  m_extListTracker(*this, dirBase.getSubdir("extensions")),
33 39
   m_pSock(NULL)
34 40
 {
35 41
   // read server address
... ...
@@ -37,12 +43,18 @@ Phone<ADDR, SOCK>::Phone(Mgrs &mgrs, const Directory &dirBase):
37 43
 
38 44
   // create and bind socket
39 45
   createSock();
46
+
47
+  // load extensions
48
+  m_extListTracker.init();
40 49
 }
41 50
 
42 51
 /// virtual destructor
43 52
 template<typename ADDR, typename SOCK>
44 53
 Phone<ADDR, SOCK>::~Phone()
45 54
 {
55
+  // unload extensions
56
+  m_extListTracker.clear();
57
+
46 58
   // destroy socket
47 59
   destroySock();
48 60
 
... ...
@@ -63,6 +75,9 @@ void Phone<ADDR, SOCK>::updateConfig()
63 75
   // server address file was modified -> re-read server address
64 76
   if (m_fileServer.checkModified())
65 77
     readServer();
78
+
79
+  // extensions update
80
+  m_extListTracker.updateConfig();
66 81
 }
67 82
 
68 83
 /// callback when requested time reached
... ...
@@ -220,7 +235,47 @@ void Phone<ADDR, SOCK>::receiveFromSock()
220 235
   m_timeRegister = Time::now() + m_serverTimeout;
221 236
   updateTimeCallback();
222 237
 
223
-  // TODO
238
+  // process message
239
+  serverMsg(msg);
240
+}
241
+
242
+/**
243
+ * @brief process message from server
244
+ * @param[in] msg message from server
245
+ */
246
+template<typename ADDR, typename SOCK>
247
+void Phone<ADDR, SOCK>::serverMsg(const std::string &msg)
248
+{
249
+  StringParser parser(msg);
250
+
251
+  // get line number and command
252
+  unsigned int line;
253
+  std::string cmd;
254
+  if (!parser.uintNo(line) || !parser.fixChr(':') ||
255
+      !parser.untilDelim(":", false, cmd))
256
+    return;
257
+
258
+  // incoming call
259
+  if (cmd == "setup") {
260
+    std::string caller, extension;
261
+    if (!parser.fixChr(':') || !parser.untilDelim(":", true, caller) ||
262
+        !parser.fixChr(':') || !parser.untilDelim(":", false, extension))
263
+      return;
264
+    // TODO incomingCall(line, extension);
265
+  }
266
+
267
+  // hangup
268
+  else if (cmd == "onhook") {
269
+    // TODO hangup(line);
270
+  }
271
+
272
+  // DTMF symbol (i.e. key pressed)
273
+  else if (cmd == "dtmf") {
274
+    char key;
275
+    if (!parser.fixChr(':') || !parser.oneChrOf("0123456789*#", key))
276
+      return;
277
+    // TODO keyPressed(line, key);
278
+  }
224 279
 }
225 280
 
226 281
 /// update time callback
227 282