Ignore:
Timestamp:
Nov 27, 2013 9:37:32 AM (10 years ago)
Author:
nanang
Message:

Re #1519: Added presence API in pjsua2.

Location:
pjproject/branches/projects/pjsua2
Files:
3 added
21 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/account.py

    r4648 r4657  
    4646                self.cfg =  pj.AccountConfig() 
    4747                self.cfgChanged = False 
     48                self.buddyList = [] 
    4849 
    4950        def statusText(self): 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/accountsetting.py

    r4640 r4657  
    4141                self.transient(parent) 
    4242                self.parent = parent 
     43                self.geometry("+100+100") 
    4344                self.title('Account settings') 
    4445                 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/pygui/application.py

    r4648 r4657  
    3333import accountsetting 
    3434import account 
     35import buddy 
    3536import endpoint 
    3637 
     
    6364                self.pack(expand='yes', fill='both') 
    6465                self.master.title('pjsua2 Demo') 
     66                self.master.geometry('500x500+100+100') 
    6567                 
    6668                # Logger 
     
    7274                # GUI variables 
    7375                self.showLogWindow = tk.IntVar() 
    74                 self.showLogWindow.set(1) 
     76                self.showLogWindow.set(0) 
    7577                self.quitting = False  
    7678                 
     
    100102                t.cfg.port = 0 
    101103                self.transportCfgs.append(t) 
     104                t = SipTransportConfig() 
     105                t.type = pj.PJSIP_TRANSPORT_TCP 
     106                t.cfg.port = 0 
     107                self.transportCfgs.append(t) 
    102108                 
    103109         
     
    116122                node = json.writeNewArray("accounts") 
    117123                for acc in self.accList: 
    118                         node.writeObject(acc.cfg); 
     124                        acc_node = node.writeNewContainer("Account") 
     125                        acc_node.writeObject(acc.cfg); 
     126 
     127                        # Write buddy configs 
     128                        buddy_node = acc_node.writeNewArray("buddies") 
     129                        for bud in acc.buddyList: 
     130                                buddy_node.writeObject(bud.cfg) 
     131                                 
    119132                json.saveFile(filename) 
    120133         
     
    141154                        node = json.readArray("accounts") 
    142155                        while node.hasUnread(): 
    143                                 cfg = pj.AccountConfig() 
    144                                 cfg.readObject(node) 
    145                                 acc_cfgs.append(cfg) 
    146                  
     156                                acc_node = node.readContainer("Account") 
     157                                acc_cfg = pj.AccountConfig() 
     158                                acc_cfg.readObject(acc_node) 
     159                 
     160                                # Load buddy configs 
     161                                buddy_cfgs = [] 
     162                                buddy_node = acc_node.readArray("buddies") 
     163                                while buddy_node.hasUnread(): 
     164                                        buddy_cfg = pj.BuddyConfig() 
     165                                        buddy_cfg.readObject(buddy_node) 
     166                                        buddy_cfgs.append(buddy_cfg) 
     167 
     168                                acc_cfgs.append((acc_cfg, buddy_cfgs)) 
     169                                 
     170                                 
    147171                # Initialize library 
    148172                self.epCfg.uaConfig.userAgent = "pygui-" + self.ep.libVersion().full; 
     
    155179                         
    156180                # Add accounts 
    157                 for cfg in acc_cfgs: 
     181                for cfg, buddy_cfgs in acc_cfgs: 
    158182                        self._createAcc(cfg) 
    159                  
     183                        acc = self.accList[-1] 
     184                        for buddy_cfg in buddy_cfgs: 
     185                                self._createBuddy(acc, buddy_cfg) 
     186                                 
    160187                # Start library 
    161188                self.ep.libStart() 
     
    173200                        self.tv.item(iid, text=text, values=values) 
    174201                else: 
    175                         self.tv.insert('', 0,  iid, open=True, text=text, values=values) 
    176                         self.tv.insert(iid, 0, '', open=True, text='Buddy 1', values=('Online',)) 
    177                         self.tv.insert(iid, 1, '', open=True, text='Buddy 2', values=('Online',)) 
     202                        self.tv.insert('', 'end',  iid, open=True, text=text, values=values) 
     203                 
     204        def updateBuddy(self, bud): 
     205                iid = 'buddy' + str(bud.randId) 
     206                text = bud.cfg.uri 
     207                status = bud.statusText() 
     208                 
     209                values = (status,) 
     210                if self.tv.exists(iid): 
     211                        self.tv.item(iid, text=text, values=values) 
     212                else: 
     213                        self.tv.insert(str(bud.account.randId), 'end',  iid, open=True, text=text, values=values) 
    178214                 
    179215        def _createAcc(self, acc_cfg): 
     
    186222                self.updateAccount(acc) 
    187223                                 
     224        def _createBuddy(self, acc, buddy_cfg): 
     225                bud = buddy.Buddy(self) 
     226                bud.cfg = buddy_cfg 
     227                bud.account = acc 
     228                bud.create(acc, bud.cfg) 
     229                self.updateBuddy(bud) 
     230                acc.buddyList.append(bud) 
     231 
    188232        def _createWidgets(self): 
    189233                self._createAppMenu() 
     
    222266        def _createContextMenu(self): 
    223267                top = self.winfo_toplevel() 
     268 
     269                # Create Account context menu 
    224270                self.accMenu = tk.Menu(top, tearoff=False) 
    225271                # Labels, must match with _onAccContextMenu() 
    226                 labels = ['Unregister', 'Reregister', '-', 'Online', 'Invisible', 'Away', 'Busy', '-', 'Settings...', '-', 'Delete...'] 
     272                labels = ['Unregister', 'Reregister', 'Add buddy...', '-', 
     273                          'Online', 'Invisible', 'Away', 'Busy', '-', 
     274                          'Settings...', '-', 
     275                          'Delete...'] 
    227276                for label in labels: 
    228277                        if label=='-': 
     
    232281                                self.accMenu.add_command(label=label, command=cmd) 
    233282                 
     283                # Create Buddy context menu 
     284                # Labels, must match with _onAccContextMenu() 
     285                self.buddyMenu = tk.Menu(top, tearoff=False) 
     286                labels = ['Video call', 'Audio call', 'Send instant message', '-', 
     287                          'Settings...', '-', 
     288                          'Delete...'] 
     289                 
     290                for label in labels: 
     291                        if label=='-': 
     292                                self.buddyMenu.add_separator() 
     293                        else: 
     294                                cmd = lambda arg=label: self._onBuddyContextMenu(arg) 
     295                                self.buddyMenu.add_command(label=label, command=cmd) 
     296                 
    234297                if (top.tk.call('tk', 'windowingsystem')=='aqua'): 
    235298                        self.tv.bind('<2>', self._onTvRightClick) 
     
    251314                return accs[0] 
    252315         
     316        def _getSelectedBuddy(self): 
     317                items = self.tv.selection() 
     318                if not items: 
     319                        return None 
     320                try: 
     321                        iid = int(items[0][5:]) 
     322                        iid_parent = int(self.tv.parent(items[0])) 
     323                except: 
     324                        return None 
     325                         
     326                accs = [acc for acc in self.accList if acc.randId==iid_parent] 
     327                if not accs: 
     328                        return None 
     329                         
     330                buds = [b for b in accs[0].buddyList if b.randId==iid] 
     331                if not buds: 
     332                        return None 
     333                         
     334                return buds[0] 
     335         
    253336        def _onTvRightClick(self, event): 
    254                 iid = self.tv.identify('item', event.x, event.y) 
     337                iid = self.tv.identify_row(event.y) 
     338                #iid = self.tv.identify('item', event.x, event.y) 
    255339                if iid: 
    256                         self.tv.selection_add( (iid,) ) 
     340                        self.tv.selection_set( (iid,) ) 
    257341                        acc = self._getSelectedAccount() 
    258342                        if acc: 
     
    260344                        else: 
    261345                                # A buddy is selected 
    262                                 pass 
     346                                self.buddyMenu.post(event.x_root, event.y_root) 
    263347         
    264348        def _onAccContextMenu(self, label): 
     
    272356                        acc.setRegistration(True) 
    273357                elif label=='Online': 
    274                         ps = pj.AccountPresenceStatus() 
     358                        ps = pj.PresenceStatus() 
    275359                        ps.isOnline = True 
    276360                        acc.setOnlineStatus(ps) 
    277361                elif label=='Invisible': 
    278                         ps = pj.AccountPresenceStatus() 
     362                        ps = pj.PresenceStatus() 
    279363                        ps.isOnline = False 
    280364                        acc.setOnlineStatus(ps) 
    281365                elif label=='Away': 
    282                         ps = pj.AccountPresenceStatus() 
     366                        ps = pj.PresenceStatus() 
    283367                        ps.isOnline = True 
    284368                        ps.activity = pj.PJRPID_ACTIVITY_AWAY 
     
    286370                        acc.setOnlineStatus(ps) 
    287371                elif label=='Busy': 
    288                         ps = pj.AccountPresenceStatus() 
     372                        ps = pj.PresenceStatus() 
    289373                        ps.isOnline = True 
    290374                        ps.activity = pj.PJRPID_ACTIVITY_BUSY 
     
    305389                        del acc 
    306390                        self.tv.delete( (iid,) ) 
     391                elif label=='Add buddy...': 
     392                        cfg = pj.BuddyConfig() 
     393                        dlg = buddy.SettingDialog(self.master, cfg) 
     394                        if dlg.doModal(): 
     395                                self._createBuddy(acc, cfg) 
    307396                else: 
    308397                        assert not ("Unknown menu " + label) 
    309398         
     399        def _onBuddyContextMenu(self, label): 
     400                bud = self._getSelectedBuddy() 
     401                if not bud: 
     402                        return 
     403                acc = bud.account 
     404                         
     405                if label=='Video call': 
     406                        pass 
     407                elif label=='Audio call': 
     408                        pass 
     409                elif label=='Send instant message': 
     410                        pass 
     411                elif label=='Settings...': 
     412                        subs = bud.cfg.subscribe 
     413                        uri  = bud.cfg.uri 
     414                        dlg = buddy.SettingDialog(self.master, bud.cfg) 
     415                        if dlg.doModal(): 
     416                                self.updateBuddy(bud) 
     417                                # URI updated? 
     418                                if uri != bud.cfg.uri: 
     419                                        cfg = bud.cfg 
     420                                        # del old 
     421                                        iid = 'buddy' + str(bud.randId) 
     422                                        acc.buddyList.remove(bud) 
     423                                        del bud 
     424                                        self.tv.delete( (iid,) ) 
     425                                        # add new 
     426                                        self._createBuddy(acc, cfg) 
     427                                # presence subscribe setting updated 
     428                                elif subs != bud.cfg.subscribe: 
     429                                        bud.subscribePresence(bud.cfg.subscribe) 
     430                elif label=='Delete...': 
     431                        msg = "Do you really want to delete buddy '%s'?" % bud.cfg.uri 
     432                        if msgbox.askquestion('Delete buddy?', msg, default=msgbox.NO) != u'yes': 
     433                                return 
     434                        iid = 'buddy' + str(bud.randId) 
     435                        acc.buddyList.remove(bud) 
     436                        del bud 
     437                        self.tv.delete( (iid,) ) 
     438                else: 
     439                        assert not ("Unknown menu " + label) 
     440                         
    310441        def _onTimer(self): 
    311442                if not self.quitting: 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/importsym.py

    r4639 r4657  
    3030                return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 
    3131         
     32        if sys.platform == 'win32' and not program.endswith(".exe"): 
     33                program += ".exe" 
     34 
    3235        fpath, fname = os.path.split(program) 
    3336        if fpath: 
     
    6669C_HEADING_SECTION = """ 
    6770#define PJ_AUTOCONF             1 
    68 #define CC_DUMMY 
    6971#define jmp_buf                 int 
    7072#define __attribute__(x) 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i

    r4646 r4657  
    3737%feature("director") Endpoint;  
    3838%feature("director") Account; 
     39%feature("director") Buddy; 
     40%feature("director") FindBuddyMatch; 
    3941 
    4042 
     
    6062%include "pjsua2/types.hpp" 
    6163 
     64%ignore pj::ContainerNode::op; 
     65%ignore pj::ContainerNode::data; 
    6266%ignore container_node_op; 
     67%ignore container_node_internal_data; 
    6368%include "pjsua2/persistent.hpp" 
    6469 
     70%ignore pj::TransportInfo::TransportInfo(const pjsua_transport_info &info); 
    6571%include "pjsua2/siptypes.hpp" 
    6672 
     
    6874%template(AuthCredInfoVector)           std::vector<pj::AuthCredInfo>; 
    6975%template(SipMultipartPartVector)       std::vector<pj::SipMultipartPart>; 
     76%template(BuddyVector)                  std::vector<pj::Buddy*>; 
    7077 
    7178%include "pjsua2/endpoint.hpp" 
     79%include "pjsua2/presence.hpp" 
    7280%include "pjsua2/account.hpp" 
    7381 
    74 %ignore JsonDocument::allocElement(); 
    75 %ignore JsonDocument::getPool(); 
     82%ignore pj::JsonDocument::allocElement; 
     83%ignore pj::JsonDocument::getPool; 
    7684%include "pjsua2/json.hpp" 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/symbols.i

    r4639 r4657  
    5555typedef enum pjrpid_activity {PJRPID_ACTIVITY_UNKNOWN, PJRPID_ACTIVITY_AWAY, PJRPID_ACTIVITY_BUSY} pjrpid_activity; 
    5656 
     57typedef enum pjsip_evsub_state {PJSIP_EVSUB_STATE_NULL, PJSIP_EVSUB_STATE_SENT, PJSIP_EVSUB_STATE_ACCEPTED, PJSIP_EVSUB_STATE_PENDING, PJSIP_EVSUB_STATE_ACTIVE, PJSIP_EVSUB_STATE_TERMINATED, PJSIP_EVSUB_STATE_UNKNOWN} pjsip_evsub_state; 
     58 
    5759enum pjsua_invalid_id_const_ {PJSUA_INVALID_ID = -1}; 
    5860 
     
    7375typedef enum pjsua_ipv6_use {PJSUA_IPV6_DISABLED, PJSUA_IPV6_ENABLED} pjsua_ipv6_use; 
    7476 
     77typedef enum pjsua_buddy_status {PJSUA_BUDDY_STATUS_UNKNOWN, PJSUA_BUDDY_STATUS_ONLINE, PJSUA_BUDDY_STATUS_OFFLINE} pjsua_buddy_status; 
     78 
  • pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/symbols.lst

    r4639 r4657  
    1818 
    1919pjsip-simple/rpid.h             pjrpid_activity 
     20pjsip-simple/evsub.h            pjsip_evsub_state 
    2021 
    21 pjsua-lib/pjsua.h               pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use 
     22pjsua-lib/pjsua.h               pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status 
  • pjproject/branches/projects/pjsua2/pjsip/build/Makefile

    r4644 r4657  
    9191export PJSUA2_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 
    9292                           account.o endpoint.o json.o persistent.o types.o \ 
    93                            siptypes.o 
     93                           siptypes.o presence.o 
    9494export PJSUA2_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS) 
    9595export PJSUA2_LIB_CXXFLAGS = $(PJSUA2_LIB_CFLAGS)  
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsip-simple/evsub.h

    r3553 r4657  
    5959 * in state_str member of the susbcription structure. 
    6060 */ 
    61 enum pjsip_evsub_state 
     61typedef enum pjsip_evsub_state 
    6262{ 
    6363    PJSIP_EVSUB_STATE_NULL,      /**< State is NULL.                        */ 
     
    7171                                      Application can query the state by  
    7272                                      calling #pjsip_evsub_get_state_name().*/ 
    73 }; 
    74  
    75 /** 
    76  * @see pjsip_evsub_state 
    77  */ 
    78 typedef enum pjsip_evsub_state pjsip_evsub_state; 
     73} pjsip_evsub_state; 
    7974 
    8075 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2.hpp

    r4644 r4657  
    2222#include <pjsua2/endpoint.hpp> 
    2323#include <pjsua2/account.hpp> 
     24#include <pjsua2/presence.hpp> 
    2425#include <pjsua2/json.hpp> 
    2526 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp

    r4644 r4657  
    2626#include <pjsua-lib/pjsua.h> 
    2727#include <pjsua2/persistent.hpp> 
     28#include <pjsua2/presence.hpp> 
    2829#include <pjsua2/siptypes.hpp> 
    2930 
     
    913914}; 
    914915 
    915 /** 
    916  * This describes account presence status. 
    917  */ 
    918 struct AccountPresenceStatus 
    919 { 
    920     /** Basic status. */ 
    921     bool                isOnline; 
    922  
    923     /** Activity type. */ 
    924     pjrpid_activity     activity; 
    925  
    926     /** Optional text describing the person/element. */ 
    927     string              note; 
    928  
    929     /** Optional RPID ID string. */ 
    930     string              rpidId; 
    931  
    932 public: 
    933     AccountPresenceStatus(); 
    934 }; 
    935  
    936916 
    937917/** 
     
    10711051{ 
    10721052    /** 
     1053     * Server presence subscription instance. If application delays 
     1054     * the acceptance of the request, it will need to specify this object 
     1055     * when calling Account::presNotify(). 
     1056     */ 
     1057    void               *srvPres; 
     1058 
     1059    /** 
    10731060     *  Sender URI. 
    10741061     */ 
     
    12201207}; 
    12211208 
     1209/** 
     1210 * Parameters for presNotify() account method. 
     1211 */ 
     1212struct PresNotifyParam 
     1213{ 
     1214    /** 
     1215     * Server presence subscription instance. 
     1216     */ 
     1217    void               *srvPres; 
     1218 
     1219    /** 
     1220     * Server presence subscription state to set. 
     1221     */ 
     1222    pjsip_evsub_state   state; 
     1223     
     1224    /** 
     1225     * Optionally specify the state string name, if state is not "active", 
     1226     * "pending", or "terminated". 
     1227     */ 
     1228    string              stateStr; 
     1229 
     1230    /** 
     1231     * If the new state is PJSIP_EVSUB_STATE_TERMINATED, optionally specify 
     1232     * the termination reason. 
     1233     */ 
     1234    string              reason; 
     1235 
     1236    /** 
     1237     * If the new state is PJSIP_EVSUB_STATE_TERMINATED, this specifies 
     1238     * whether the NOTIFY request should contain message body containing 
     1239     * account's presence information. 
     1240     */ 
     1241    bool                withBody; 
     1242 
     1243    /** 
     1244     * Optional list of headers to be sent with the NOTIFY request. 
     1245     */ 
     1246    SipTxOption         txOption; 
     1247}; 
     1248 
     1249 
     1250/** 
     1251 * Wrapper class for Buddy matching algo. 
     1252 * 
     1253 * Default algo is a simple substring lookup of search-token in the 
     1254 * Buddy URIs, with case sensitive. Application can implement its own 
     1255 * matching algo by overriding this class and specifying its instance 
     1256 * in Account::findBuddy(). 
     1257 */ 
     1258class FindBuddyMatch 
     1259{ 
     1260public: 
     1261    /** 
     1262     * Default algo implementation. 
     1263     */ 
     1264    virtual bool match(const string &token, const Buddy &buddy) 
     1265    { 
     1266        BuddyInfo bi = buddy.getInfo(); 
     1267        return bi.uri.find(token) != string::npos; 
     1268    } 
     1269 
     1270    /** 
     1271     * Destructor. 
     1272     */ 
     1273    virtual ~FindBuddyMatch() {} 
     1274}; 
    12221275 
    12231276/** 
     
    13321385     * @param pres_st           Presence online status. 
    13331386     */ 
    1334     void setOnlineStatus(const AccountPresenceStatus &pres_st) throw(Error); 
     1387    void setOnlineStatus(const PresenceStatus &pres_st) throw(Error); 
    13351388 
    13361389    /** 
     
    13501403    void setTransport(TransportId tp_id) throw(Error); 
    13511404 
     1405    /** 
     1406     * Send NOTIFY to inform account presence status or to terminate server 
     1407     * side presence subscription. If application wants to reject the incoming 
     1408     * request, it should set the param \a PresNotifyParam.state to 
     1409     * PJSIP_EVSUB_STATE_TERMINATED. 
     1410     * 
     1411     * @param prm               The sending NOTIFY parameter. 
     1412     */ 
     1413    void presNotify(const PresNotifyParam &prm) throw(Error); 
     1414     
     1415    /** 
     1416     * Enumerate all buddies of the account. 
     1417     * 
     1418     * @return                  The buddy list. 
     1419     */ 
     1420    const BuddyVector& enumBuddies() const throw(Error); 
     1421 
     1422    /** 
     1423     * Find a buddy in the buddy list with the specified URI.  
     1424     * 
     1425     * Exception: if buddy is not found, PJ_ENOTFOUND will be thrown. 
     1426     * 
     1427     * @param uri               The buddy URI. 
     1428     * @param buddy_match       The buddy match algo. 
     1429     * 
     1430     * @return                  The pointer to buddy. 
     1431     */ 
     1432    Buddy* findBuddy(string uri, FindBuddyMatch *buddy_match = NULL) const 
     1433                    throw(Error); 
     1434 
     1435    /** 
     1436     * An internal function to add a Buddy to Account buddy list. 
     1437     * This function must never be used by application. 
     1438     */ 
     1439    void addBuddy(Buddy *buddy); 
     1440 
     1441    /** 
     1442     * An internal function to remove a Buddy from Account buddy list. 
     1443     * This function must never be used by application. 
     1444     */ 
     1445    void removeBuddy(Buddy *buddy); 
     1446 
    13521447public: 
    13531448    /* 
     
    13601455     */ 
    13611456    virtual void onIncomingCall(OnIncomingCallParam &prm) 
    1362     {} 
     1457    { PJ_UNUSED_ARG(prm); } 
    13631458 
    13641459    /** 
     
    13711466     */ 
    13721467    virtual void onRegStarted(OnRegStartedParam &prm) 
    1373     {} 
     1468    { PJ_UNUSED_ARG(prm); } 
    13741469 
    13751470    /** 
     
    13811476     */ 
    13821477    virtual void onRegState(OnRegStateParam &prm) 
    1383     {} 
     1478    { PJ_UNUSED_ARG(prm); } 
    13841479 
    13851480    /** 
     
    14031498     *    user permission whether to accept or reject the request. In this 
    14041499     *    case, the application MUST set the IncomingSubscribeParam.code 
    1405      *    argument to 202, then IMMEDIATELY calls #pjsua_pres_notify() with 
    1406      *    state PJSIP_EVSUB_STATE_PENDING and later calls #pjsua_pres_notify() 
     1500     *    argument to 202, then IMMEDIATELY calls presNotify() with 
     1501     *    state PJSIP_EVSUB_STATE_PENDING and later calls presNotify() 
    14071502     *    again to accept or reject the subscription request. 
    14081503     * 
     
    14161511     */ 
    14171512    virtual void onIncomingSubscribe(OnIncomingSubscribeParam &prm) 
    1418     {} 
     1513    { PJ_UNUSED_ARG(prm); } 
    14191514 
    14201515    /** 
     
    14251520     */ 
    14261521    virtual void onInstantMessage(OnInstantMessageParam &prm) 
    1427     {} 
     1522    { PJ_UNUSED_ARG(prm); } 
    14281523 
    14291524    /** 
     
    14341529     */ 
    14351530    virtual void onInstantMessageStatus(OnInstantMessageStatusParam &prm) 
    1436     {} 
     1531    { PJ_UNUSED_ARG(prm); } 
    14371532 
    14381533    /** 
     
    14421537     */ 
    14431538    virtual void onTypingIndication(OnTypingIndicationParam &prm) 
    1444     {} 
     1539    { PJ_UNUSED_ARG(prm); } 
    14451540 
    14461541    /** 
     
    14531548     */ 
    14541549    virtual void onMwiInfo(OnMwiInfoParam &prm) 
    1455     {} 
     1550    { PJ_UNUSED_ARG(prm); } 
    14561551 
    14571552protected: 
     
    14611556    pjsua_acc_id         id; 
    14621557    string               tmpReason;     // for saving response's reason 
     1558    BuddyVector          buddyList; 
    14631559}; 
    14641560 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp

    r4644 r4657  
    960960    virtual void onNatDetectionComplete( 
    961961                        const OnNatDetectionCompleteParam &prm) 
    962     {} 
     962    { PJ_UNUSED_ARG(prm); } 
    963963 
    964964    /** 
     
    970970    virtual void onNatCheckStunServersComplete( 
    971971                        const OnNatCheckStunServersCompleteParam &prm) 
    972     {} 
     972    { PJ_UNUSED_ARG(prm); } 
    973973 
    974974    /** 
     
    979979    virtual void onTransportState( 
    980980                        const OnTransportStateParam &prm) 
    981     {} 
     981    { PJ_UNUSED_ARG(prm); } 
    982982 
    983983    /** 
     
    988988     */ 
    989989    virtual void onTimer(const OnTimerParam &prm) 
    990     {} 
     990    { PJ_UNUSED_ARG(prm); } 
    991991 
    992992    /** 
     
    10061006     */ 
    10071007    virtual void onSelectAccount(OnSelectAccountParam &prm) 
    1008     {} 
     1008    { PJ_UNUSED_ARG(prm); } 
    10091009 
    10101010 
     
    10711071    static void on_mwi_info(pjsua_acc_id acc_id, 
    10721072                            pjsua_mwi_info *mwi_info); 
     1073    static void on_buddy_state(pjsua_buddy_id buddy_id); 
     1074 
    10731075}; 
    10741076 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/persistent.hpp

    r4644 r4657  
    334334                                      throw(Error); 
    335335}; 
     336 
     337 
     338/** 
     339 * Forward declaration of container_node_op. 
     340 */ 
     341struct container_node_op; 
     342 
     343 
     344/** 
     345 * Internal data for ContainerNode. See ContainerNode implementation notes 
     346 * for more info. 
     347 */ 
     348struct container_node_internal_data 
     349{ 
     350    void        *doc; 
     351    void        *data1; 
     352    void        *data2; 
     353}; 
     354 
     355/** 
     356 * A container node is a placeholder for storing other data elements, which 
     357 * could be boolean, number, string, array of strings, or another container. 
     358 * Each data in the container is basically a name/value pair, with a type 
     359 * internally associated with it so that written data can be read in the 
     360 * correct type. Data is read and written serially, hence the order of 
     361 * reading must be the same as the order of writing. 
     362 * 
     363 * Application can read data from it by using the various read methods, and 
     364 * write data to it using the various write methods. Alternatively, it 
     365 * may be more convenient to use the provided macros below to read and write 
     366 * the data, because these macros set the name automatically: 
     367 *      - NODE_READ_BOOL(node,item) 
     368 *      - NODE_READ_UNSIGNED(node,item) 
     369 *      - NODE_READ_INT(node,item) 
     370 *      - NODE_READ_FLOAT(node,item) 
     371 *      - NODE_READ_NUM_T(node,type,item) 
     372 *      - NODE_READ_STRING(node,item) 
     373 *      - NODE_READ_STRINGV(node,item) 
     374 *      - NODE_READ_OBJ(node,item) 
     375 *      - NODE_WRITE_BOOL(node,item) 
     376 *      - NODE_WRITE_UNSIGNED(node,item) 
     377 *      - NODE_WRITE_INT(node,item) 
     378 *      - NODE_WRITE_FLOAT(node,item) 
     379 *      - NODE_WRITE_NUM_T(node,type,item) 
     380 *      - NODE_WRITE_STRING(node,item) 
     381 *      - NODE_WRITE_STRINGV(node,item) 
     382 *      - NODE_WRITE_OBJ(node,item) 
     383 * 
     384 * Implementation notes: 
     385 * 
     386 * The ContainerNode class is subclass-able, but not in the usual C++ way. 
     387 * With the usual C++ inheritance, some methods will be made pure virtual 
     388 * and must be implemented by the actual class. However, doing so will 
     389 * require dynamic instantiation of the ContainerNode class, which means 
     390 * we will need to pass around the class as pointer, for example as the 
     391 * return value of readContainer() and writeNewContainer() methods. Then 
     392 * we will need to establish who needs or how to delete these objects, or 
     393 * use shared pointer mechanism, each of which is considered too inconvenient 
     394 * or complicated for the purpose. 
     395 * 
     396 * So hence we use C style "inheritance", where the methods are declared in 
     397 * container_node_op and the data in container_node_internal_data structures. 
     398 * An implementation of ContainerNode class will need to set up these members 
     399 * with values that makes sense to itself. The methods in container_node_op 
     400 * contains the pointer to the actual implementation of the operation, which 
     401 * would be specific according to the format of the document. The methods in 
     402 * this ContainerNode class are just thin wrappers which call the 
     403 * implementation in the container_node_op structure. 
     404 * 
     405 */ 
     406class ContainerNode 
     407{ 
     408public: 
     409    /** 
     410     * Determine if there is unread element. If yes, then app can use one of 
     411     * the readXxx() functions to read it. 
     412     */ 
     413    bool                hasUnread() const; 
     414 
     415    /** 
     416     * Get the name of the next unread element. 
     417     */ 
     418    string              unreadName() const throw(Error); 
     419 
     420    /** 
     421     * Read an integer value from the document and return the value. 
     422     * This will throw Error if the current element is not a number. 
     423     * The read position will be advanced to the next element. 
     424     * 
     425     * @param name      If specified, then the function will check if the 
     426     *                  name of the next element matches the specified 
     427     *                  name and throw Error if it doesn't match. 
     428     * 
     429     * @return          The value. 
     430     */ 
     431    int                 readInt(const string &name="") const throw(Error); 
     432 
     433    /** 
     434     * Read a number value from the document and return the value. 
     435     * This will throw Error if the current element is not a number. 
     436     * The read position will be advanced to the next element. 
     437     * 
     438     * @param name      If specified, then the function will check if the 
     439     *                  name of the next element matches the specified 
     440     *                  name and throw Error if it doesn't match. 
     441     * 
     442     * @return          The value. 
     443     */ 
     444    float               readNumber(const string &name="") const throw(Error); 
     445 
     446    /** 
     447     * Read a boolean value from the container and return the value. 
     448     * This will throw Error if the current element is not a boolean. 
     449     * The read position will be advanced to the next element. 
     450     * 
     451     * @param name      If specified, then the function will check if the 
     452     *                  name of the next element matches the specified 
     453     *                  name and throw Error if it doesn't match. 
     454     * 
     455     * @return          The value. 
     456     */ 
     457    bool                readBool(const string &name="") const throw(Error); 
     458 
     459    /** 
     460     * Read a string value from the container and return the value. 
     461     * This will throw Error if the current element is not a string. 
     462     * The read position will be advanced to the next element. 
     463     * 
     464     * @param name      If specified, then the function will check if the 
     465     *                  name of the next element matches the specified 
     466     *                  name and throw Error if it doesn't match. 
     467     * 
     468     * @return          The value. 
     469     */ 
     470    string              readString(const string &name="") const throw(Error); 
     471 
     472    /** 
     473     * Read a string array from the container. This will throw Error 
     474     * if the current element is not a string array. The read position 
     475     * will be advanced to the next element. 
     476     * 
     477     * @param name      If specified, then the function will check if the 
     478     *                  name of the next element matches the specified 
     479     *                  name and throw Error if it doesn't match. 
     480     * 
     481     * @return          The value. 
     482     */ 
     483    StringVector        readStringVector(const string &name="") const 
     484                                         throw(Error); 
     485 
     486    /** 
     487     * Read the specified object from the container. This is equal to 
     488     * calling PersistentObject.readObject(ContainerNode); 
     489     * 
     490     * @param obj       The object to read. 
     491     */ 
     492    void                readObject(PersistentObject &obj) const throw(Error); 
     493 
     494    /** 
     495     * Read a container from the container. This will throw Error if the 
     496     * current element is not a container. The read position will be advanced 
     497     * to the next element. 
     498     * 
     499     * @param name      If specified, then the function will check if the 
     500     *                  name of the next element matches the specified 
     501     *                  name and throw Error if it doesn't match. 
     502     * 
     503     * @return          Container object. 
     504     */ 
     505    ContainerNode       readContainer(const string &name="") const 
     506                                      throw(Error); 
     507 
     508    /** 
     509     * Read array container from the container. This will throw Error if the 
     510     * current element is not an array. The read position will be advanced 
     511     * to the next element. 
     512     * 
     513     * @param name      If specified, then the function will check if the 
     514     *                  name of the next element matches the specified 
     515     *                  name and throw Error if it doesn't match. 
     516     * 
     517     * @return          Container object. 
     518     */ 
     519    ContainerNode       readArray(const string &name="") const 
     520                                  throw(Error); 
     521 
     522    /** 
     523     * Write a number value to the container. 
     524     * 
     525     * @param name      The name for the value in the container. 
     526     * @param value     The value to be written. 
     527     */ 
     528    void                writeNumber(const string &name, 
     529                                    float num) throw(Error); 
     530 
     531    /** 
     532     * Write a number value to the container. 
     533     * 
     534     * @param name      The name for the value in the container. 
     535     * @param value     The value to be written. 
     536     */ 
     537    void                writeInt(const string &name, 
     538                                 int num) throw(Error); 
     539 
     540    /** 
     541     * Write a boolean value to the container. 
     542     * 
     543     * @param name      The name for the value in the container. 
     544     * @param value     The value to be written. 
     545     */ 
     546    void                writeBool(const string &name, 
     547                                  bool value) throw(Error); 
     548 
     549    /** 
     550     * Write a string value to the container. 
     551     * 
     552     * @param name      The name for the value in the container. 
     553     * @param value     The value to be written. 
     554     */ 
     555    void                writeString(const string &name, 
     556                                    const string &value) throw(Error); 
     557 
     558    /** 
     559     * Write string vector to the container. 
     560     * 
     561     * @param name      The name for the value in the container. 
     562     * @param array     The vector to be written. 
     563     */ 
     564    void                writeStringVector(const string &name, 
     565                                          const StringVector &value) 
     566                                          throw(Error); 
     567 
     568    /** 
     569     * Write an object to the container. This is equal to calling 
     570     * PersistentObject.writeObject(ContainerNode); 
     571     * 
     572     * @param obj       The object to be written 
     573     */ 
     574    void                writeObject(const PersistentObject &obj) throw(Error); 
     575 
     576    /** 
     577     * Create and write an empty Object node that can be used as parent 
     578     * for subsequent write operations. 
     579     * 
     580     * @param name      The name for the new container in the container. 
     581     * 
     582     * @return          A sub-container. 
     583     */ 
     584    ContainerNode       writeNewContainer(const string &name) 
     585                                          throw(Error); 
     586 
     587    /** 
     588     * Create and write an empty array node that can be used as parent 
     589     * for subsequent write operations. 
     590     * 
     591     * @param name      The name for the array. 
     592     * 
     593     * @return          A sub-container. 
     594     */ 
     595    ContainerNode       writeNewArray(const string &name) 
     596                                      throw(Error); 
     597 
     598public: 
     599    /* internal data */ 
     600    container_node_op *op; 
     601    container_node_internal_data data; 
     602}; 
     603 
    336604 
    337605/** 
     
    387655}; 
    388656 
    389 /** 
    390  * Internal data for ContainerNode. See ContainerNode implementation notes 
    391  * for more info. 
    392  */ 
    393 struct container_node_internal_data 
    394 { 
    395     void        *doc; 
    396     void        *data1; 
    397     void        *data2; 
    398 }; 
    399  
    400 /** 
    401  * A container node is a placeholder for storing other data elements, which 
    402  * could be boolean, number, string, array of strings, or another container. 
    403  * Each data in the container is basically a name/value pair, with a type 
    404  * internally associated with it so that written data can be read in the 
    405  * correct type. Data is read and written serially, hence the order of 
    406  * reading must be the same as the order of writing. 
    407  * 
    408  * Application can read data from it by using the various read methods, and 
    409  * write data to it using the various write methods. Alternatively, it 
    410  * may be more convenient to use the provided macros below to read and write 
    411  * the data, because these macros set the name automatically: 
    412  *      - NODE_READ_BOOL(node,item) 
    413  *      - NODE_READ_UNSIGNED(node,item) 
    414  *      - NODE_READ_INT(node,item) 
    415  *      - NODE_READ_FLOAT(node,item) 
    416  *      - NODE_READ_NUM_T(node,type,item) 
    417  *      - NODE_READ_STRING(node,item) 
    418  *      - NODE_READ_STRINGV(node,item) 
    419  *      - NODE_READ_OBJ(node,item) 
    420  *      - NODE_WRITE_BOOL(node,item) 
    421  *      - NODE_WRITE_UNSIGNED(node,item) 
    422  *      - NODE_WRITE_INT(node,item) 
    423  *      - NODE_WRITE_FLOAT(node,item) 
    424  *      - NODE_WRITE_NUM_T(node,type,item) 
    425  *      - NODE_WRITE_STRING(node,item) 
    426  *      - NODE_WRITE_STRINGV(node,item) 
    427  *      - NODE_WRITE_OBJ(node,item) 
    428  * 
    429  * Implementation notes: 
    430  * 
    431  * The ContainerNode class is subclass-able, but not in the usual C++ way. 
    432  * With the usual C++ inheritance, some methods will be made pure virtual 
    433  * and must be implemented by the actual class. However, doing so will 
    434  * require dynamic instantiation of the ContainerNode class, which means 
    435  * we will need to pass around the class as pointer, for example as the 
    436  * return value of readContainer() and writeNewContainer() methods. Then 
    437  * we will need to establish who needs or how to delete these objects, or 
    438  * use shared pointer mechanism, each of which is considered too inconvenient 
    439  * or complicated for the purpose. 
    440  * 
    441  * So hence we use C style "inheritance", where the methods are declared in 
    442  * container_node_op and the data in container_node_internal_data structures. 
    443  * An implementation of ContainerNode class will need to set up these members 
    444  * with values that makes sense to itself. The methods in container_node_op 
    445  * contains the pointer to the actual implementation of the operation, which 
    446  * would be specific according to the format of the document. The methods in 
    447  * this ContainerNode class are just thin wrappers which call the 
    448  * implementation in the container_node_op structure. 
    449  * 
    450  */ 
    451 class ContainerNode 
    452 { 
    453 public: 
    454     /** 
    455      * Determine if there is unread element. If yes, then app can use one of 
    456      * the readXxx() functions to read it. 
    457      */ 
    458     bool                hasUnread() const; 
    459  
    460     /** 
    461      * Get the name of the next unread element. 
    462      */ 
    463     string              unreadName() const throw(Error); 
    464  
    465     /** 
    466      * Read an integer value from the document and return the value. 
    467      * This will throw Error if the current element is not a number. 
    468      * The read position will be advanced to the next element. 
    469      * 
    470      * @param name      If specified, then the function will check if the 
    471      *                  name of the next element matches the specified 
    472      *                  name and throw Error if it doesn't match. 
    473      * 
    474      * @return          The value. 
    475      */ 
    476     int                 readInt(const string &name="") const throw(Error); 
    477  
    478     /** 
    479      * Read a number value from the document and return the value. 
    480      * This will throw Error if the current element is not a number. 
    481      * The read position will be advanced to the next element. 
    482      * 
    483      * @param name      If specified, then the function will check if the 
    484      *                  name of the next element matches the specified 
    485      *                  name and throw Error if it doesn't match. 
    486      * 
    487      * @return          The value. 
    488      */ 
    489     float               readNumber(const string &name="") const throw(Error); 
    490  
    491     /** 
    492      * Read a boolean value from the container and return the value. 
    493      * This will throw Error if the current element is not a boolean. 
    494      * The read position will be advanced to the next element. 
    495      * 
    496      * @param name      If specified, then the function will check if the 
    497      *                  name of the next element matches the specified 
    498      *                  name and throw Error if it doesn't match. 
    499      * 
    500      * @return          The value. 
    501      */ 
    502     bool                readBool(const string &name="") const throw(Error); 
    503  
    504     /** 
    505      * Read a string value from the container and return the value. 
    506      * This will throw Error if the current element is not a string. 
    507      * The read position will be advanced to the next element. 
    508      * 
    509      * @param name      If specified, then the function will check if the 
    510      *                  name of the next element matches the specified 
    511      *                  name and throw Error if it doesn't match. 
    512      * 
    513      * @return          The value. 
    514      */ 
    515     string              readString(const string &name="") const throw(Error); 
    516  
    517     /** 
    518      * Read a string array from the container. This will throw Error 
    519      * if the current element is not a string array. The read position 
    520      * will be advanced to the next element. 
    521      * 
    522      * @param name      If specified, then the function will check if the 
    523      *                  name of the next element matches the specified 
    524      *                  name and throw Error if it doesn't match. 
    525      * 
    526      * @return          The value. 
    527      */ 
    528     StringVector        readStringVector(const string &name="") const 
    529                                          throw(Error); 
    530  
    531     /** 
    532      * Read the specified object from the container. This is equal to 
    533      * calling PersistentObject.readObject(ContainerNode); 
    534      * 
    535      * @param obj       The object to read. 
    536      */ 
    537     void                readObject(PersistentObject &obj) const throw(Error); 
    538  
    539     /** 
    540      * Read a container from the container. This will throw Error if the 
    541      * current element is not a container. The read position will be advanced 
    542      * to the next element. 
    543      * 
    544      * @param name      If specified, then the function will check if the 
    545      *                  name of the next element matches the specified 
    546      *                  name and throw Error if it doesn't match. 
    547      * 
    548      * @return          Container object. 
    549      */ 
    550     ContainerNode       readContainer(const string &name="") const 
    551                                       throw(Error); 
    552  
    553     /** 
    554      * Read array container from the container. This will throw Error if the 
    555      * current element is not an array. The read position will be advanced 
    556      * to the next element. 
    557      * 
    558      * @param name      If specified, then the function will check if the 
    559      *                  name of the next element matches the specified 
    560      *                  name and throw Error if it doesn't match. 
    561      * 
    562      * @return          Container object. 
    563      */ 
    564     ContainerNode       readArray(const string &name="") const 
    565                                   throw(Error); 
    566  
    567     /** 
    568      * Write a number value to the container. 
    569      * 
    570      * @param name      The name for the value in the container. 
    571      * @param value     The value to be written. 
    572      */ 
    573     void                writeNumber(const string &name, 
    574                                     float num) throw(Error); 
    575  
    576     /** 
    577      * Write a number value to the container. 
    578      * 
    579      * @param name      The name for the value in the container. 
    580      * @param value     The value to be written. 
    581      */ 
    582     void                writeInt(const string &name, 
    583                                  int num) throw(Error); 
    584  
    585     /** 
    586      * Write a boolean value to the container. 
    587      * 
    588      * @param name      The name for the value in the container. 
    589      * @param value     The value to be written. 
    590      */ 
    591     void                writeBool(const string &name, 
    592                                   bool value) throw(Error); 
    593  
    594     /** 
    595      * Write a string value to the container. 
    596      * 
    597      * @param name      The name for the value in the container. 
    598      * @param value     The value to be written. 
    599      */ 
    600     void                writeString(const string &name, 
    601                                     const string &value) throw(Error); 
    602  
    603     /** 
    604      * Write string vector to the container. 
    605      * 
    606      * @param name      The name for the value in the container. 
    607      * @param array     The vector to be written. 
    608      */ 
    609     void                writeStringVector(const string &name, 
    610                                           const StringVector &value) 
    611                                           throw(Error); 
    612  
    613     /** 
    614      * Write an object to the container. This is equal to calling 
    615      * PersistentObject.writeObject(ContainerNode); 
    616      * 
    617      * @param obj       The object to be written 
    618      */ 
    619     void                writeObject(const PersistentObject &obj) throw(Error); 
    620  
    621     /** 
    622      * Create and write an empty Object node that can be used as parent 
    623      * for subsequent write operations. 
    624      * 
    625      * @param name      The name for the new container in the container. 
    626      * 
    627      * @return          A sub-container. 
    628      */ 
    629     ContainerNode       writeNewContainer(const string &name) 
    630                                           throw(Error); 
    631  
    632     /** 
    633      * Create and write an empty array node that can be used as parent 
    634      * for subsequent write operations. 
    635      * 
    636      * @param name      The name for the array. 
    637      * 
    638      * @return          A sub-container. 
    639      */ 
    640     ContainerNode       writeNewArray(const string &name) 
    641                                       throw(Error); 
    642  
    643 public: 
    644     /* internal data */ 
    645     container_node_op *op; 
    646     container_node_internal_data data; 
    647 }; 
    648657 
    649658/* 
     
    660669 
    661670#define NODE_WRITE_BOOL(node,item)      node.writeBool(#item, item) 
    662 #define NODE_WRITE_UNSIGNED(node,item)  node.writeNumber(#item, item) 
    663 #define NODE_WRITE_INT(node,item)       node.writeNumber(#item, item) 
    664 #define NODE_WRITE_NUM_T(node,T,item)   node.writeNumber(#item, (int)item) 
     671#define NODE_WRITE_UNSIGNED(node,item)  node.writeNumber(#item, (float)item) 
     672#define NODE_WRITE_INT(node,item)       node.writeNumber(#item, (float)item) 
     673#define NODE_WRITE_NUM_T(node,T,item)   node.writeNumber(#item, (float)item) 
    665674#define NODE_WRITE_FLOAT(node,item)     node.writeNumber(#item, item) 
    666675#define NODE_WRITE_STRING(node,item)    node.writeString(#item, item) 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/siptypes.hpp

    r4655 r4657  
    589589     */ 
    590590    void toPj(pjsua_msg_data &msg_data) const; 
     591}; 
     592 
     593 
     594/** 
     595 * This structure contains parameters for sending instance message methods, 
     596 * e.g: Buddy::sendInstantMessage(), Call:sendInstantMessage(). 
     597 */ 
     598struct SendInstantMessageParam 
     599{ 
     600    /** 
     601     * MIME type. Default is "text/plain". 
     602     */ 
     603    string contentType; 
     604     
     605    /** 
     606     * The message content. 
     607     */ 
     608    string content; 
     609     
     610    /** 
     611     * List of headers etc to be included in outgoing request. 
     612     */ 
     613    SipTxOption txOption; 
     614 
     615    /** 
     616     * User data, which will be given back when the IM callback is called. 
     617     */ 
     618    Token userData; 
     619}; 
     620 
     621 
     622/** 
     623 * This structure contains parameters for sending typing indication methods, 
     624 * e.g: Buddy::sendTypingIndication(), Call:sendTypingIndication(). 
     625 */ 
     626struct SendTypingIndicationParam 
     627{ 
     628    /** 
     629     * True to indicate to remote that local person is currently typing an IM. 
     630     */ 
     631    bool isTyping; 
     632     
     633    /** 
     634     * List of headers etc to be included in outgoing request. 
     635     */ 
     636    SipTxOption txOption; 
    591637}; 
    592638 
  • pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp

    r4644 r4657  
    2020#define __PJSUA2_TYPES_HPP__ 
    2121 
     22#ifdef _MSC_VER 
     23#   pragma warning( disable : 4290 ) // exception spec ignored 
     24#endif 
     25 
    2226/** 
    2327 * @file pjsua2/types.hpp 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/account.cpp

    r4644 r4657  
    1919#include <pjsua2/account.hpp> 
    2020#include <pjsua2/endpoint.hpp> 
     21#include <pjsua2/presence.hpp> 
    2122#include <pj/ctype.h> 
    2223#include "util.hpp" 
     
    446447    regConfig.firstRetryIntervalSec = prm.reg_first_retry_interval; 
    447448    regConfig.delayBeforeRefreshSec = prm.reg_delay_before_refresh; 
    448     regConfig.dropCallsOnFail   = prm.drop_calls_on_reg_fail; 
     449    regConfig.dropCallsOnFail   = PJ2BOOL(prm.drop_calls_on_reg_fail); 
    449450    regConfig.unregWaitSec      = prm.unreg_timeout; 
    450451    regConfig.proxyUse          = prm.reg_use_proxy; 
     
    484485    sipConfig.contactParams     = pj2Str(prm.contact_params); 
    485486    sipConfig.contactUriParams  = pj2Str(prm.contact_uri_params); 
    486     sipConfig.authInitialEmpty  = prm.auth_pref.initial_auth; 
     487    sipConfig.authInitialEmpty  = PJ2BOOL(prm.auth_pref.initial_auth); 
    487488    sipConfig.authInitialAlgorithm = pj2Str(prm.auth_pref.algorithm); 
    488489    sipConfig.transportId       = prm.transport_id; 
     
    504505        hdr = hdr->next; 
    505506    } 
    506     presConfig.publishEnabled   = prm.publish_enabled; 
    507     presConfig.publishQueue     = prm.publish_opt.queue_request; 
     507    presConfig.publishEnabled   = PJ2BOOL(prm.publish_enabled); 
     508    presConfig.publishQueue     = PJ2BOOL(prm.publish_opt.queue_request); 
    508509    presConfig.publishShutdownWaitMsec = prm.unpublish_max_wait_time_msec; 
    509510    presConfig.pidfTupleId      = pj2Str(prm.pidf_tuple_id); 
    510511 
    511512    // AccountMwiConfig 
    512     mwiConfig.enabled           = prm.mwi_enabled; 
     513    mwiConfig.enabled           = PJ2BOOL(prm.mwi_enabled); 
    513514    mwiConfig.expirationSec     = prm.mwi_expires; 
    514515 
     
    517518    natConfig.mediaStunUse      = prm.media_stun_use; 
    518519    if (prm.ice_cfg_use == PJSUA_ICE_CONFIG_USE_CUSTOM) { 
    519         natConfig.iceEnabled = prm.ice_cfg.enable_ice; 
     520        natConfig.iceEnabled = PJ2BOOL(prm.ice_cfg.enable_ice); 
    520521        natConfig.iceMaxHostCands = prm.ice_cfg.ice_max_host_cands; 
    521         natConfig.iceAggressiveNomination = prm.ice_cfg.ice_opt.aggressive; 
     522        natConfig.iceAggressiveNomination = PJ2BOOL(prm.ice_cfg.ice_opt.aggressive); 
    522523        natConfig.iceNominatedCheckDelayMsec = prm.ice_cfg.ice_opt.nominated_check_delay; 
    523524        natConfig.iceWaitNominationTimeoutMsec = prm.ice_cfg.ice_opt.controlled_agent_want_nom_timeout; 
    524         natConfig.iceNoRtcp     = prm.ice_cfg.ice_no_rtcp; 
    525         natConfig.iceAlwaysUpdate = prm.ice_cfg.ice_always_update; 
     525        natConfig.iceNoRtcp     = PJ2BOOL(prm.ice_cfg.ice_no_rtcp); 
     526        natConfig.iceAlwaysUpdate = PJ2BOOL(prm.ice_cfg.ice_always_update); 
    526527    } else { 
    527528        pjsua_media_config default_mcfg; 
     
    530531            mcfg = &default_mcfg; 
    531532        } 
    532         natConfig.iceEnabled    = mcfg->enable_ice; 
     533        natConfig.iceEnabled    = PJ2BOOL(mcfg->enable_ice); 
    533534        natConfig.iceMaxHostCands= mcfg->ice_max_host_cands; 
    534         natConfig.iceAggressiveNomination = mcfg->ice_opt.aggressive; 
     535        natConfig.iceAggressiveNomination = PJ2BOOL(mcfg->ice_opt.aggressive); 
    535536        natConfig.iceNominatedCheckDelayMsec = mcfg->ice_opt.nominated_check_delay; 
    536537        natConfig.iceWaitNominationTimeoutMsec = mcfg->ice_opt.controlled_agent_want_nom_timeout; 
    537         natConfig.iceNoRtcp     = mcfg->ice_no_rtcp; 
    538         natConfig.iceAlwaysUpdate = mcfg->ice_always_update; 
     538        natConfig.iceNoRtcp     = PJ2BOOL(mcfg->ice_no_rtcp); 
     539        natConfig.iceAlwaysUpdate = PJ2BOOL(mcfg->ice_always_update); 
    539540    } 
    540541 
    541542    if (prm.turn_cfg_use == PJSUA_TURN_CONFIG_USE_CUSTOM) { 
    542         natConfig.turnEnabled   = prm.turn_cfg.enable_turn; 
     543        natConfig.turnEnabled   = PJ2BOOL(prm.turn_cfg.enable_turn); 
    543544        natConfig.turnServer    = pj2Str(prm.turn_cfg.turn_server); 
    544545        natConfig.turnConnType  = prm.turn_cfg.turn_conn_type; 
     
    552553            mcfg = &default_mcfg; 
    553554        } 
    554         natConfig.turnEnabled   = mcfg->enable_turn; 
     555        natConfig.turnEnabled   = PJ2BOOL(mcfg->enable_turn); 
    555556        natConfig.turnServer    = pj2Str(mcfg->turn_server); 
    556557        natConfig.turnConnType  = mcfg->turn_conn_type; 
     
    571572    // AccountMediaConfig 
    572573    mediaConfig.transportConfig.fromPj(prm.rtp_cfg); 
    573     mediaConfig.lockCodecEnabled= prm.lock_codec; 
     574    mediaConfig.lockCodecEnabled= PJ2BOOL(prm.lock_codec); 
    574575#if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0) 
    575     mediaConfig.streamKaEnabled = prm.use_stream_ka; 
     576    mediaConfig.streamKaEnabled = PJ2BOOL(prm.use_stream_ka); 
    576577#else 
    577578    mediaConfig.streamKaEnabled = false; 
     
    582583 
    583584    // AccountVideoConfig 
    584     videoConfig.autoShowIncoming        = prm.vid_in_auto_show; 
    585     videoConfig.autoTransmitOutgoing    = prm.vid_out_auto_transmit; 
     585    videoConfig.autoShowIncoming        = PJ2BOOL(prm.vid_in_auto_show); 
     586    videoConfig.autoTransmitOutgoing    = PJ2BOOL(prm.vid_out_auto_transmit); 
    586587    videoConfig.windowFlags             = prm.vid_wnd_flags; 
    587588    videoConfig.defaultCaptureDevice    = prm.vid_cap_dev; 
     
    623624} 
    624625 
    625  
    626 /////////////////////////////////////////////////////////////////////////////// 
    627  
    628 AccountPresenceStatus::AccountPresenceStatus() 
    629 : isOnline(false), activity(PJRPID_ACTIVITY_UNKNOWN) 
    630 { 
    631 } 
    632626 
    633627/////////////////////////////////////////////////////////////////////////////// 
     
    662656     */ 
    663657    if (isValid() && pjsua_get_state() < PJSUA_STATE_CLOSING) { 
     658        // Cleanup buddies in the buddy list 
     659        while(buddyList.size() > 0) { 
     660            Buddy *b = buddyList[0]; 
     661            delete b; 
     662        } 
     663 
    664664        PJSUA2_CHECK_EXPR( pjsua_acc_set_user_data(id, NULL) ); 
    665665        PJSUA2_CHECK_EXPR( pjsua_acc_del(id) ); 
     
    724724 
    725725void 
    726 Account::setOnlineStatus(const AccountPresenceStatus &pres_st) throw(Error) 
     726Account::setOnlineStatus(const PresenceStatus &pres_st) throw(Error) 
    727727{ 
    728728    pjrpid_element pj_rpid; 
     
    734734    pj_rpid.note        = str2Pj(pres_st.note); 
    735735 
    736     PJSUA2_CHECK_EXPR( pjsua_acc_set_online_status2(id, pres_st.isOnline, 
    737                                                     &pj_rpid) ); 
     736    PJSUA2_CHECK_EXPR( pjsua_acc_set_online_status2( 
     737                            id, pres_st.status == PJSUA_BUDDY_STATUS_ONLINE, 
     738                            &pj_rpid) ); 
    738739} 
    739740 
     
    743744} 
    744745 
     746void Account::presNotify(const PresNotifyParam &prm) throw(Error) 
     747{ 
     748    pj_str_t pj_state_str   = str2Pj(prm.stateStr); 
     749    pj_str_t pj_reason      = str2Pj(prm.reason); 
     750    pjsua_msg_data msg_data; 
     751    prm.txOption.toPj(msg_data); 
     752 
     753    PJSUA2_CHECK_EXPR( pjsua_pres_notify(id, (pjsua_srv_pres*)prm.srvPres, 
     754                                         prm.state, &pj_state_str, 
     755                                         &pj_reason, prm.withBody, 
     756                                         &msg_data) ); 
     757} 
     758 
     759const BuddyVector& Account::enumBuddies() const throw(Error) 
     760{ 
     761    return buddyList; 
     762} 
     763 
     764Buddy* Account::findBuddy(string uri, FindBuddyMatch *buddy_match) const 
     765                throw(Error) 
     766{ 
     767    if (!buddy_match) { 
     768        static FindBuddyMatch def_bm; 
     769        buddy_match = &def_bm; 
     770    } 
     771 
     772    for (unsigned i = 0; i < buddyList.size(); i++) { 
     773        if (buddy_match->match(uri, *buddyList[i])) 
     774            return buddyList[i]; 
     775    } 
     776    PJSUA2_RAISE_ERROR(PJ_ENOTFOUND); 
     777} 
     778 
     779void Account::addBuddy(Buddy *buddy) 
     780{ 
     781    pj_assert(buddy); 
     782 
     783    buddyList.push_back(buddy); 
     784} 
     785 
     786void Account::removeBuddy(Buddy *buddy) 
     787{ 
     788    pj_assert(buddy); 
     789 
     790    BuddyVector::iterator it; 
     791    for (it = buddyList.begin(); it != buddyList.end(); it++) { 
     792        if (*it == buddy) { 
     793            buddyList.erase(it); 
     794            return; 
     795        } 
     796    } 
     797 
     798    pj_assert(!"Bug! Buddy to be removed is not in the buddy list!"); 
     799} 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp

    r4644 r4657  
    1919#include <pjsua2/endpoint.hpp> 
    2020#include <pjsua2/account.hpp> 
     21#include <pjsua2/presence.hpp> 
    2122#include "util.hpp" 
    2223 
     
    6364    } 
    6465 
    65     this->stunIgnoreFailure = ua_cfg.stun_ignore_failure; 
     66    this->stunIgnoreFailure = PJ2BOOL(ua_cfg.stun_ignore_failure); 
    6667    this->natTypeInSdp = ua_cfg.nat_type_in_sdp; 
    67     this->mwiUnsolicitedEnabled = ua_cfg.enable_unsolicited_mwi; 
     68    this->mwiUnsolicitedEnabled = PJ2BOOL(ua_cfg.enable_unsolicited_mwi); 
    6869} 
    6970 
     
    205206    this->audioFramePtime = mc.audio_frame_ptime; 
    206207    this->maxMediaPorts = mc.max_media_ports; 
    207     this->hasIoqueue = mc.has_ioqueue; 
     208    this->hasIoqueue = PJ2BOOL(mc.has_ioqueue); 
    208209    this->threadCnt = mc.thread_cnt; 
    209210    this->quality = mc.quality; 
    210211    this->ptime = mc.ptime; 
    211     this->noVad = mc.no_vad; 
     212    this->noVad = PJ2BOOL(mc.no_vad); 
    212213    this->ilbcMode = mc.ilbc_mode; 
    213214    this->txDropPct = mc.tx_drop_pct; 
     
    222223    this->jbMax = mc.jb_max; 
    223224    this->sndAutoCloseTime = mc.snd_auto_close_time; 
    224     this->vidPreviewEnableNative = mc.vid_preview_enable_native; 
     225    this->vidPreviewEnableNative = PJ2BOOL(mc.vid_preview_enable_native); 
    225226} 
    226227 
     
    362363    } catch (Error &err) { 
    363364        // Ignore 
     365        PJ_UNUSED_ARG(err); 
    364366    } 
    365367    delete writer; 
     
    412414                        pj_timer_entry *entry) 
    413415{ 
     416    PJ_UNUSED_ARG(timer_heap); 
     417 
    414418    Endpoint &ep = Endpoint::instance(); 
    415419    UserTimer *ut = (UserTimer*) entry->user_data; 
     
    505509 
    506510    OnRegStartedParam prm; 
    507     prm.renew = renew; 
     511    prm.renew = PJ2BOOL(renew); 
    508512    acc->onRegStarted(prm); 
    509513} 
     
    536540                                     pjsua_msg_data *msg_data) 
    537541{ 
     542    PJ_UNUSED_ARG(buddy_id); 
     543    PJ_UNUSED_ARG(srv_pres); 
     544 
    538545    Account *acc = lookupAcc(acc_id, "on_incoming_subscribe()"); 
    539546    if (!acc) { 
     
    543550 
    544551    OnIncomingSubscribeParam prm; 
     552    prm.srvPres         = srv_pres; 
    545553    prm.fromUri         = pj2Str(*from); 
    546554    prm.rdata.fromPj(*rdata); 
    547555    prm.code            = *code; 
    548556    prm.reason          = pj2Str(*reason); 
     557    prm.txOption.fromPj(*msg_data); 
    549558 
    550559    acc->onIncomingSubscribe(prm); 
     
    553562    acc->tmpReason = prm.reason; 
    554563    *reason = str2Pj(acc->tmpReason); 
    555     // TODO: 
    556     //  apply msg_data 
     564    prm.txOption.toPj(*msg_data); 
    557565} 
    558566 
     
    599607                                 pjsua_acc_id acc_id) 
    600608{ 
     609    PJ_UNUSED_ARG(tdata); 
     610 
    601611    OnInstantMessageStatusParam prm; 
    602612    prm.userData        = user_data; 
     
    667677} 
    668678 
     679void Endpoint::on_buddy_state(pjsua_buddy_id buddy_id) 
     680{ 
     681    Buddy *buddy = (Buddy*)pjsua_buddy_get_user_data(buddy_id); 
     682    if (!buddy || !buddy->isValid()) { 
     683        /* Ignored */ 
     684        return; 
     685    } 
     686 
     687    buddy->onBuddyState(); 
     688} 
     689 
    669690 
    670691/////////////////////////////////////////////////////////////////////////////// 
     
    723744    ua_cfg.cb.on_typing2        = &Endpoint::on_typing2; 
    724745    ua_cfg.cb.on_mwi_info       = &Endpoint::on_mwi_info; 
     746    ua_cfg.cb.on_buddy_state    = &Endpoint::on_buddy_state; 
    725747 
    726748    /* Init! */ 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/json.cpp

    r4644 r4657  
    124124        PJSUA2_RAISE_ERROR(PJ_ENOTFOUND); 
    125125 
    126     pj_ssize_t size = pj_file_size(filename.c_str()); 
     126    pj_ssize_t size = (pj_ssize_t)pj_file_size(filename.c_str()); 
    127127    pj_status_t status; 
    128128 
     
    359359    json_verify(jdat, "readBool()", name, PJ_JSON_VAL_BOOL); 
    360360    jdat->childPtr = jdat->childPtr->next; 
    361     return jdat->childPtr->prev->value.is_true; 
     361    return PJ2BOOL(jdat->childPtr->prev->value.is_true); 
    362362} 
    363363 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/persistent.cpp

    r4644 r4657  
    8585                                  int num) throw(Error) 
    8686{ 
    87     getRootContainer().writeNumber(name, num); 
     87    getRootContainer().writeNumber(name, (float)num); 
    8888} 
    8989 
     
    188188                             int num) throw(Error) 
    189189{ 
    190     return op->writeNumber(this, name, num); 
     190    return op->writeNumber(this, name, (float)num); 
    191191} 
    192192 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/siptypes.cpp

    r4655 r4657  
    4646    ContainerNode array_node = node.writeNewArray(array_name); 
    4747    for (unsigned i=0; i<v.size(); ++i) { 
    48         array_node.writeNumber("", v[i]); 
     48        array_node.writeNumber("", (float)v[i]); 
    4949    } 
    5050} 
     
    190190    pj_assert(sizeof(prm.ciphers[0]) == sizeof(int)); 
    191191    this->ciphers       = IntVector(prm.ciphers, prm.ciphers+prm.ciphers_num); 
    192     this->verifyServer  = prm.verify_server; 
    193     this->verifyClient  = prm.verify_client; 
    194     this->requireClientCert = prm.require_client_cert; 
     192    this->verifyServer  = PJ2BOOL(prm.verify_server); 
     193    this->verifyClient  = PJ2BOOL(prm.verify_client); 
     194    this->requireClientCert = PJ2BOOL(prm.require_client_cert); 
    195195    this->msecTimeout   = PJ_TIME_VAL_MSEC(prm.timeout); 
    196196    this->qosType       = prm.qos_type; 
    197197    this->qosParams     = prm.qos_params; 
    198     this->qosIgnoreError = prm.qos_ignore_error; 
     198    this->qosIgnoreError = PJ2BOOL(prm.qos_ignore_error); 
    199199} 
    200200 
  • pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/util.hpp

    r4644 r4657  
    2121#include <string> 
    2222 
     23#define PJ2BOOL(var) ((var) != PJ_FALSE) 
     24 
    2325namespace pj 
    2426{ 
Note: See TracChangeset for help on using the changeset viewer.