Changeset 4566


Ignore:
Timestamp:
Jul 17, 2013 8:20:50 PM (11 years ago)
Author:
nanang
Message:

JNI projects:

  • More work on callbacks wrapper, i.e: pj_timer_heap_callback for pjsua_schedule_timer() and pjsua_logging_config::cb.
  • Map pjsua_call_dump() output buffer.
Location:
pjproject/branches/projects/jni/pjsip-apps/src/jni
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/callbacks.c.template

    r4549 r4566  
    33#include "callbacks.h" 
    44 
     5/* 
     6 * Wrapper of pjsua_logging_config callback 
     7 */ 
     8static PjsuaLoggingConfigCallback *pjsua_logging_config_cb = NULL; 
     9 
     10void pjsua_logging_config_callback_proxy(int level, const char *data, int len) 
     11{ 
     12  PJ_UNUSED_ARG(len); 
     13  pjsua_logging_config_cb->on_log(level, data); 
     14} 
     15 
     16void setPjsuaLoggingConfigCallback(PjsuaLoggingConfigCallback *callback) 
     17{ 
     18  pjsua_logging_config_cb = callback; 
     19} 
     20 
     21 
     22/* 
     23 * Wrapper of pj_timer_heap_callback 
     24 */ 
     25void pj_timer_heap_callback_proxy(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry) 
     26{ 
     27  PjTimerHeapCallback *cb = (PjTimerHeapCallback*)entry->user_data; 
     28  pj_assert(cb); 
     29  cb->on_timer(timer_heap, entry); 
     30} 
     31 
     32void setPjTimerHeapCallback(pj_timer_entry *entry, PjTimerHeapCallback *callback) 
     33{ 
     34  entry->user_data = callback; 
     35} 
     36 
     37 
     38/* 
     39 * Wrapper of pjsua_callback 
     40 */ 
    541static PjsuaCallback* cb = NULL; 
    642 
     
    1551}; 
    1652 
    17 pjsua_callback* PJSUA_CALLBACK_PROXY = &my_cb_proxy; 
     53pjsua_callback* pjsua_callback_proxy = &my_cb_proxy; 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/callbacks.h.template

    r4549 r4566  
    33#include <pjsua-lib/pjsua.h> 
    44 
     5/* 
     6 * Wrapper of pjsua_logging_config callback 
     7 */ 
     8class PjsuaLoggingConfigCallback { 
     9public: 
     10  virtual void on_log(int level, const char *data) {} 
     11  virtual ~PjsuaLoggingConfigCallback() {} 
     12}; 
     13 
    514#ifndef SWIG /* SWIG should ignore these */ 
    6 class PjsuaCallback; 
    7 extern void setPjsuaCallback(PjsuaCallback* callback); 
    8 extern pjsua_callback* PJSUA_CALLBACK_PROXY; 
     15extern void pjsua_logging_config_callback_proxy(int level, const char *data, int len); 
     16extern void setPjsuaLoggingConfigCallback(PjsuaLoggingConfigCallback *callback); 
    917#endif 
    1018 
     19 
     20/* 
     21 * Wrapper of pj_timer_heap_callback 
     22 */ 
     23class PjTimerHeapCallback { 
     24public: 
     25  virtual void on_timer(pj_timer_heap_t *timer_heap, pj_timer_entry *entry) {} 
     26  virtual ~PjTimerHeapCallback() {} 
     27}; 
     28 
     29#ifndef SWIG /* SWIG should ignore these */ 
     30extern void pj_timer_heap_callback_proxy(pj_timer_heap_t *timer_heap, pj_timer_entry *entry); 
     31extern void setPjTimerHeapCallback(pj_timer_entry *entry, PjTimerHeapCallback *callback); 
     32#endif 
     33 
     34 
     35/* 
     36 * Wrapper of pjsua_callback 
     37 */ 
    1138class PjsuaCallback { 
    1239public: 
     
    1441  virtual ~PjsuaCallback() {} 
    1542}; 
     43 
     44#ifndef SWIG /* SWIG should ignore these */ 
     45extern void setPjsuaCallback(PjsuaCallback* callback); 
     46extern pjsua_callback* pjsua_callback_proxy; 
     47#endif 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/callbacks.i

    r4557 r4566  
    55%} 
    66 
     7/* 
     8 * Wrap pjsua_logging_config callback 
     9 */ 
     10%feature("director") PjsuaLoggingConfigCallback; 
     11%ignore pjsua_logging_config::cb; 
     12%extend pjsua_logging_config { 
     13    void setCb(PjsuaLoggingConfigCallback* callback) { 
     14        setPjsuaLoggingConfigCallback(callback); 
     15        $self->cb = callback? &pjsua_logging_config_callback_proxy : NULL; 
     16    } 
     17} 
     18 
     19 
     20/* 
     21 * Wrap pj_timer_heap_callback in pj_timer_entry 
     22 */ 
     23%feature("director") PjTimerHeapCallback; 
     24%ignore pj_timer_entry::cb; 
     25/* Suppress user_data, app can put user data in PjTimerHeapCallback inherited class */ 
     26%ignore pj_timer_entry::user_data; 
     27%extend pj_timer_entry { 
     28    void setCb(PjTimerHeapCallback* callback) { 
     29        setPjTimerHeapCallback($self, callback); 
     30        $self->cb = callback? &pj_timer_heap_callback_proxy : NULL; 
     31    } 
     32} 
     33 
     34 
     35/* 
     36 * Wrap pjsua_callback 
     37 */ 
    738%feature("director") PjsuaCallback; 
    839%ignore pjsua_callback; 
    940%ignore pjsua_config::cb; 
    1041%extend pjsua_config { 
    11     void setCb(PjsuaCallback *pjsuaCb) { 
    12         $self->cb = *PJSUA_CALLBACK_PROXY; 
    13         setPjsuaCallback(pjsuaCb); 
     42    void setCb(PjsuaCallback *callback) { 
     43        setPjsuaCallback(callback); 
     44        if (callback) 
     45            $self->cb = *pjsua_callback_proxy; 
     46        else 
     47            pj_bzero(&$self->cb, sizeof($self->cb)); 
    1448    } 
    1549} 
    1650 
     51 
    1752%include <callbacks.h> 
     53 
     54/* Ignore these callbacks */ 
     55%ignore pjsip_msg_body::print_body; 
     56%ignore pjsip_msg_body::clone_data; 
     57%ignore pjsip_tx_data::cb; 
     58%ignore pjsip_transaction::state_handler; 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/header.i

    r4558 r4566  
    11/* $Id$ */ 
     2 
     3/* TODO: 
     4 * - fix memory leaks in pj_str_t - java String typemaps 
     5 * - typemap for pj_str_t as output param for callback/director, 
     6 *   e.g: "st_text" param in pjsua_callback::on_call_replace_request() 
     7 * - workaround for nested struct/union, i.e: moving out inner classes to global scope 
     8 */ 
    29 
    310%module (directors="1") pjsua 
     
    1522%rename("%(strip:[pjsua_])s", %$isfunction) ""; 
    1623 
     24/* Suppress pjsua_schedule_timer2(), app can still use pjsua_schedule_timer() */ 
     25%ignore pjsua_schedule_timer2; 
     26 
     27/* Suppress aux function pjsua_resolve_stun_servers(), usually app won't need this 
     28 * as app can just simply configure STUN server to use STUN. 
     29 */ 
     30%ignore pjsua_resolve_stun_servers; 
     31 
    1732/* Map 'void *' simply as long, app can use this "long" as index of its real user data */ 
    1833%apply long long { void * }; 
     
    2641%apply bool { pj_bool_t }; 
    2742 
     43/* Map pjsua_call_dump() output buffer */ 
     44%apply (char *STRING, size_t LENGTH) { (char *buffer, unsigned maxlen) }; 
     45 
    2846/* Map "int*" & "unsigned*" as input & output */ 
    2947%apply unsigned *INOUT  { unsigned * }; 
     
    3351%apply int      *INOUT  { pj_stun_nat_type * }; 
    3452%apply int      *INOUT  { pjsip_status_code * }; 
     53%apply pj_str_t *INOUT  { pj_str_t *p_contact }; 
     54 
     55/* Apply array of integer on array of enum */ 
    3556%apply int[ANY]         { pjmedia_format_id dec_fmt_id[ANY] }; 
    36 %apply pj_str_t *INOUT  { pj_str_t *p_contact }; 
    3757 
    3858/* Handle members typed array of pj_str_t */ 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/hello.java

    r4558 r4566  
    55import java.io.IOException; 
    66 
    7 import org.pjsip.pjsua.pj_pool_t; 
    8 import org.pjsip.pjsua.pjsip_rx_data; 
    9 import org.pjsip.pjsua.pjsip_transport_type_e; 
    10  
    11 import org.pjsip.pjsua.pjsua; 
    12 import org.pjsip.pjsua.pjsua_acc_config; 
    13 import org.pjsip.pjsua.pjsua_call_info; 
    14 import org.pjsip.pjsua.pjsua_call_media_status; 
    15 import org.pjsip.pjsua.pjsua_config; 
    16 import org.pjsip.pjsua.pjsua_logging_config; 
    17 import org.pjsip.pjsua.pjsua_transport_config; 
    18 import org.pjsip.pjsua.PjsuaCallback; 
     7import org.pjsip.pjsua.*; 
     8 
     9class app_config { 
     10        public static int cur_call_id = -1; 
     11} 
    1912 
    2013class MyPjsuaCallback extends PjsuaCallback { 
     
    3023                } 
    3124        } 
     25         
     26        /* Testing pj_str_t-String map with director */ 
    3227        @Override 
    3328        public void on_pager(int call_id, String from, String to, String contact, String mime_type, String body) 
     
    4439                /* Auto answer */ 
    4540                pjsua.call_answer(call_id, 200, null, null); 
    46         } 
    47 } 
     41                app_config.cur_call_id = call_id; 
     42        } 
     43} 
     44 
     45class MyLogger extends PjsuaLoggingConfigCallback { 
     46        @Override 
     47        public void on_log(int level, String data) 
     48        { 
     49                System.out.print("LOG: " + data); 
     50        } 
     51} 
     52 
     53class MyTimerCallback extends PjTimerHeapCallback { 
     54        private int _user_data; 
     55         
     56        /* Use this class itself to store app user data */ 
     57        MyTimerCallback(int user_data) { _user_data = user_data; } 
     58         
     59        @Override 
     60        public void on_timer(pj_timer_heap_t timer_heap, pj_timer_entry entry) 
     61        { 
     62                System.out.println("======== Timer fired (user data = " + _user_data + ")"); 
     63        } 
     64} 
     65 
    4866 
    4967public class hello { 
     
    8098                        pjsua_config cfg = new pjsua_config(); 
    8199                        pjsua.config_default(cfg); 
    82                         /* Setup callback */ 
    83100                        cfg.setCb(new MyPjsuaCallback()); 
    84                         status = pjsua.init(cfg, null, null); 
     101 
     102                        pjsua_logging_config log_cfg = new pjsua_logging_config(); 
     103                        pjsua.logging_config_default(log_cfg); 
     104                        log_cfg.setLevel(4); 
     105                        log_cfg.setCb(new MyLogger()); 
     106 
     107                        status = pjsua.init(cfg, log_cfg, null); 
    85108                        if (status != pjsua.PJ_SUCCESS) { 
    86109                                pj_error_exit("Error inintializing pjsua", status); 
     
    117140                /* Make call to the URL. */ 
    118141                if (false) { 
    119                         status = pjsua.call_make_call(acc_id[0], "sip:localhost", null, 0, null, call_id); 
     142                        status = pjsua.call_make_call(acc_id[0], "sip:localhost:6000", null, 0, null, call_id); 
    120143                        if (status != pjsua.PJ_SUCCESS) { 
    121144                                pj_error_exit("Error making call", status); 
    122145                        } 
     146                        app_config.cur_call_id = call_id[0]; 
     147                } 
     148                 
     149                /* Test timer */ 
     150                { 
     151                        pj_timer_entry timer = new pj_timer_entry(); 
     152                        timer.setCb(new MyTimerCallback(1234567890)); 
     153 
     154                        pj_time_val tv = new pj_time_val(); 
     155                        tv.setSec(0); 
     156                        tv.setMsec(1000); 
     157 
     158                        pjsua.schedule_timer(timer, tv); 
    123159                } 
    124160                 
     
    141177                        } else if (userInput.equals("h")) { 
    142178                                pjsua.call_hangup_all(); 
     179                                app_config.cur_call_id = -1; 
    143180                        } else if (userInput.equals("c")) { 
    144181                                /* Test string as output param, it is wrapped as string array */ 
     
    154191                        } else if (userInput.equals("dd")) { 
    155192                                pjsua.dump(true); 
     193                        } else if (userInput.equals("dq")) { 
     194                                if (app_config.cur_call_id == -1) { 
     195                                        System.out.println("No active call"); 
     196                                        continue; 
     197                                } 
     198                                 
     199                                byte[] buf = new byte[1024*2]; 
     200                                pjsua.call_dump(app_config.cur_call_id, true, buf, ""); 
     201 
     202                                /* Build string from byte array, find null terminator first */ 
     203                                int len = 0; 
     204                                while (len < buf.length && buf[len] != 0) ++len; 
     205                                String call_dump = new String(buf, 0, len); 
     206 
     207                                System.out.println("Statistics of call " + app_config.cur_call_id); 
     208                                System.out.println(call_dump); 
    156209                        } 
    157210                } 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/my_typemaps.i

    r4558 r4566  
    214214      $1->slen = str_len; 
    215215    } 
     216    jenv->ReleaseStringUTFChars($input, str_ptr); 
    216217  } 
    217218} 
  • pjproject/branches/projects/jni/pjsip-apps/src/jni/swig_gen.py

    r4563 r4566  
    1313#SOURCE_PATH  = PJ_ROOT_PATH + "pjlib-util/include/pjlib-util/scanner.h" 
    1414#SOURCE_PATH  = PJ_ROOT_PATH + "pjlib/include/pj/types.h" 
     15OUTDIR = "output" if len(sys.argv)<=1 else sys.argv[1] 
     16 
    1517 
    1618# CPP is needed by pycparser. 
     
    6264        'pjsip_rx_data_op_key', 
    6365        'pjsip_module', 
     66        'pjsip_uri', 
     67        'pjsip_uri_vptr', 
    6468        'pjmedia_port', 
    6569        'pjmedia_transport', 
     
    7276 
    7377class MyGen(c_generator.CGenerator): 
    74          
     78 
    7579        def __init__(self, ast): 
    7680                super(MyGen, self).__init__() 
     
    8690                        if name and not name.startswith(BASE_PREFIX): 
    8791                                continue 
    88                  
     92 
    8993                        if name in self.nodes: 
    9094                                self.nodes[name].append(ext) 
     
    9498                        else: 
    9599                                self.nodes[name] = [ext] 
    96                                  
     100 
    97101                # Generate dependencies, they are all APIs to be exported 
    98102                for name in self.nodes.keys(): 
     
    102106                                self._add_dep(name) 
    103107                self.deps_frozen = True 
    104          
     108 
    105109        # Override visit_IdentifierType() to collect "node name" and generate dependencies 
    106110        # from this node's children 
     
    114118                        return False 
    115119                return True 
    116          
     120 
    117121        def _get_node_name(self, node): 
    118122                s = getattr(node, 'name', None) 
     
    135139                        name in self.deps or name in self.deps_pending: 
    136140                        return 
    137                          
     141 
    138142                if name in FORCE_STRUCT_AS_OPAQUE: 
    139143                        self.deps.append(name) 
    140144                        return 
    141                          
     145 
    142146                self.deps_pending.append(name) 
    143147                for node in self.nodes[name]: 
     
    147151                        sys.exit(1) 
    148152                self.deps.append(name) 
    149                  
     153 
    150154        # Opaque struct is identified by empty struct member declaration. 
    151155        def _is_struct_opaque(self, node): 
     
    177181                        code = code.replace('typedef enum '+name+' '+name+';\n', '', 1) 
    178182                return code 
    179          
    180         def _gen_pjsua_callback(self): 
     183 
     184        def _gen_pjsua_callback(self, code): 
    181185                # init 
    182186                cbclass  = '' 
     
    184188                cbdef = [] 
    185189 
    186                 n = self.nodes['pjsua_callback'][0] 
    187                 raw_lines = self._print_node(n).splitlines() 
     190                raw_lines = code.splitlines() 
    188191                for idx, line in enumerate(raw_lines): 
    189192                        if idx in [0, 1, len(raw_lines)-1]: continue 
     
    208211                                fstrs[0] = m.group(1).strip() 
    209212                                fstrs[2] = m.group(3) 
    210                  
     213 
    211214                        cbclass += '  virtual ' + ' '.join(fstrs) 
    212215                        if fstrs[0] == 'void': 
     
    227230 
    228231                        cbdef.append('  &' + fstrs[1]) 
    229                                  
    230                 # trail  
    231                  
     232 
    232233                return [cbclass, cbproxy, ',\n'.join(cbdef)+'\n'] 
    233          
     234 
     235        def _process_pjsua_callback(self, name, code): 
     236                if name != 'pjsua_callback': 
     237                        return code 
     238 
     239                cb = self._gen_pjsua_callback(code) 
     240 
     241                fout = open(OUTDIR+'/callbacks.h', 'w+') 
     242                fin  = open('callbacks.h.template', 'r') 
     243                for line in fin: 
     244                        if line.find(r'$PJSUA_CALLBACK_CLASS$') >= 0: 
     245                                fout.write(cb[0]) 
     246                        else: 
     247                                fout.write(line) 
     248                fin.close() 
     249                fout.close() 
     250 
     251                fout = open(OUTDIR+'/callbacks.c', 'w+') 
     252                fin  = open('callbacks.c.template', 'r') 
     253                for line in fin: 
     254                        if line.find(r'$PJSUA_CALLBACK_PROXY$') >= 0: 
     255                                fout.write(cb[1]) 
     256                        elif line.find(r'$PJSUA_CALLBACK_DEF$') >= 0: 
     257                                fout.write(cb[2]) 
     258                        else: 
     259                                fout.write(line) 
     260                fin.close() 
     261                fout.close() 
     262                return '' 
     263 
    234264        # Generate code from the specified node. 
    235265        def _print_node(self, node): 
     
    248278                        for node in self.nodes[name]: 
    249279                                ss += self._print_node(node) 
    250                         s += self._process_opaque_struct(name, ss) 
     280 
     281                        ss = self._process_opaque_struct(name, ss) 
     282                        ss = self._process_pjsua_callback(name, ss) 
     283                        s += ss 
    251284                return s 
    252          
    253         def write_pjsua_callback(self, outdir): 
    254                 cb = self._gen_pjsua_callback() 
    255                  
    256                 fout = open(outdir+'/callbacks.h', 'w+') 
    257                 fin  = open('callbacks.h.template', 'r') 
    258                 for line in fin: 
    259                         if line.find(r'$PJSUA_CALLBACK_CLASS$') >= 0: 
    260                                 fout.write(cb[0]) 
    261                         else: 
    262                                 fout.write(line) 
    263                 fin.close() 
    264                 fout.close() 
    265  
    266                 fout = open(outdir+'/callbacks.c', 'w+') 
    267                 fin  = open('callbacks.c.template', 'r') 
    268                 for line in fin: 
    269                         if line.find(r'$PJSUA_CALLBACK_PROXY$') >= 0: 
    270                                 fout.write(cb[1]) 
    271                         elif line.find(r'$PJSUA_CALLBACK_DEF$') >= 0: 
    272                                 fout.write(cb[2]) 
    273                         else: 
    274                                 fout.write(line) 
    275                 fin.close() 
    276                 fout.close() 
     285 
    277286 
    278287# MAIN                   
     
    291300#   print d 
    292301 
    293 sys.argv.pop(0) 
    294 outdir = sys.argv.pop() if len(sys.argv) else 'output' 
    295 mygen.write_pjsua_callback(outdir) 
    296  
    297302s = mygen.go() 
    298303print s 
Note: See TracChangeset for help on using the changeset viewer.