Changeset 28963


Ignore:
Timestamp:
2011-11-11T23:23:26+01:00 (4 years ago)
Author:
blogic
Message:

pjsip: bump to 1.10 and improve ltq_tapi backend

Location:
trunk/package/pjsip
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/pjsip/Makefile

    r27498 r28963  
    99 
    1010PKG_NAME:=pjsip 
    11 PKG_VERSION:=1.8.5 
    12 PKG_RELEASE:=2 
     11PKG_VERSION:=1.10 
     12PKG_RELEASE:=3 
    1313 
    1414PKG_SOURCE:=pjproject-$(PKG_VERSION).tar.bz2 
    1515PKG_SOURCE_URL:=http://www.pjsip.org/release/$(PKG_VERSION)/ 
    16 PKG_MD5SUM:=f9aa9e58b4d697245eb4bfa7d81a54a3 
     16PKG_MD5SUM:=e215d0637d3422d49a63c2cde6673951 
     17 
    1718PKG_INSTALL:=1 
     19PKG_BUILD_PARALLEL:=1 
    1820 
    1921PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/pjproject-$(PKG_VERSION) 
     
    3739ifeq ($(BUILD_VARIANT),oss) 
    3840CONFIGURE_ARGS += \ 
     41        --disable-floating-point \ 
    3942        --enable-g711-codec \ 
    4043        --disable-l16-codec \ 
     
    5255ifeq ($(BUILD_VARIANT),ltq-tapi) 
    5356CONFIGURE_ARGS += \ 
     57        --disable-floating-point \ 
    5458        --enable-g711-codec \ 
    5559        --disable-l16-codec \ 
     
    8185 
    8286define Build/Compile 
    83         CFLAGS="$(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ 
    84         LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS) $(LIBGCC_S)" \ 
    85                 $(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) 
     87        CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ 
     88        CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ 
     89        LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS) $(LIBGCC_S) -lm" \ 
     90                $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) 
    8691endef 
    8792 
    8893define Build/InstallDev 
    89         $(INSTALL_DIR) $(1)/usr/ 
    90         $(CP) $(PKG_INSTALL_DIR)/usr/pjsip-$(BUILD_VARIANT) \ 
    91                 $(1)/usr/ 
     94        $(INSTALL_DIR) $(1)/usr 
     95        $(CP) $(PKG_INSTALL_DIR)/usr/pjsip-$(BUILD_VARIANT) $(1)/usr 
    9296endef 
    9397 
  • trunk/package/pjsip/patches/000-aconf.patch

    r25298 r28963  
    11--- a/aconfigure.ac 
    22+++ b/aconfigure.ac 
    3 @@ -48,7 +48,7 @@ 
     3@@ -48,9 +48,9 @@ if test -z "$CROSS_COMPILE"; then 
    44     CROSS_COMPILE=`echo ${CC} | sed 's/gcc//'` 
    55 fi 
     
    88+AR="${CROSS_COMPILE}ar rv" 
    99 AC_SUBST(AR) 
    10  if test "$LD" = ""; then LD="$CC"; fi 
     10-if test "$LD" = ""; then LD="$CC"; fi 
     11+LD="${CROSS_COMPILE}gcc" 
    1112 AC_SUBST(LD) 
    12 @@ -590,6 +590,15 @@ 
     13 if test "$LDOUT" = ""; then LDOUT="-o"; fi 
     14 AC_SUBST(LDOUT) 
     15@@ -597,6 +597,15 @@ AC_ARG_ENABLE(ext_sound, 
    1316                AC_MSG_RESULT([Checking if external sound is set... yes]) 
    1417               fi] 
     
    2831--- a/pjmedia/build/os-auto.mak.in 
    2932+++ b/pjmedia/build/os-auto.mak.in 
    30 @@ -118,4 +118,11 @@ 
     33@@ -118,4 +118,11 @@ ifeq ($(AC_PJMEDIA_SND),external) 
    3134 export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=0 -DPJMEDIA_AUDIO_DEV_HAS_WMME=0 
    3235 endif 
  • trunk/package/pjsip/patches/100-pjsua_acc__snprintf.patch

    r25298 r28963  
    11--- a/pjsip/src/pjsua-lib/pjsua_acc.c 
    22+++ b/pjsip/src/pjsua-lib/pjsua_acc.c 
    3 @@ -430,7 +430,7 @@ 
     3@@ -511,7 +511,7 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( 
    44                     "<sip:%s%.*s%s:%d%s>",  
    55                     beginquote, 
     
    1010                     t->local_name.port, 
    1111                     transport_param); 
    12 @@ -1158,18 +1158,18 @@ 
     12@@ -1327,19 +1327,19 @@ static pj_bool_t acc_check_nat_addr(pjsu 
    1313        len = pj_ansi_snprintf(tmp, PJSIP_MAX_URL_SIZE, 
    14                                "<sip:%.*s%s%s%.*s%s:%d;transport=%s%.*s>%.*s", 
     14                               "<sip:%.*s%s%s%.*s%s:%d;transport=%s%.*s%s>%.*s", 
    1515                               (int)acc->user_part.slen, 
    1616-                              acc->user_part.ptr, 
     
    2727-                              acc->cfg.contact_uri_params.ptr, 
    2828+                              acc->cfg.contact_uri_params.slen ? acc->cfg.contact_uri_params.ptr : "", 
     29                               ob, 
    2930                               (int)acc->cfg.contact_params.slen, 
    3031-                              acc->cfg.contact_params.ptr); 
     
    3334            PJ_LOG(1,(THIS_FILE, "URI too long")); 
    3435            pj_pool_release(pool); 
    35 @@ -2233,22 +2233,22 @@ 
     36@@ -2467,23 +2467,23 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac 
     37     contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE, 
     38                                     "%.*s%s<%s:%.*s%s%s%.*s%s:%d%s%.*s%s>%.*s", 
     39                                     (int)acc->display.slen, 
     40-                                    acc->display.ptr, 
     41+                                    acc->display.slen ? acc->display.ptr : "", 
     42                                     (acc->display.slen?" " : ""), 
     43                                     (secure ? PJSUA_SECURE_SCHEME : "sip"), 
     44                                     (int)acc->user_part.slen, 
     45-                                    acc->user_part.ptr, 
     46+                                    acc->user_part.slen ? acc->user_part.ptr : "", 
     47                                     (acc->user_part.slen?"@":""), 
     48                                     beginquote, 
     49                                     (int)local_addr.slen, 
     50-                                    local_addr.ptr, 
     51+                                    local_addr.slen ? local_addr.ptr : "", 
     52                                     endquote, 
     53                                     local_port, 
     54                                     transport_param, 
     55                                     (int)acc->cfg.contact_uri_params.slen, 
     56-                                    acc->cfg.contact_uri_params.ptr, 
     57+                                    acc->cfg.contact_uri_params.slen ? acc->cfg.contact_uri_params.ptr : "", 
     58                                     ob, 
     59                                     (int)acc->cfg.contact_params.slen, 
     60-                                    acc->cfg.contact_params.ptr); 
     61+                                    acc->cfg.contact_params.slen ? acc->cfg.contact_params.ptr : ""); 
     62  
     63     return PJ_SUCCESS; 
     64 } 
     65@@ -2625,22 +2625,22 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas 
    3666     contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE, 
    3767                                     "%.*s%s<%s:%.*s%s%s%.*s%s:%d%s%.*s>%.*s", 
     
    6191     return PJ_SUCCESS; 
    6292 } 
    63 @@ -2390,22 +2390,22 @@ 
    64      contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE, 
    65                                      "%.*s%s<%s:%.*s%s%s%.*s%s:%d%s%.*s>%.*s", 
    66                                      (int)acc->display.slen, 
    67 -                                    acc->display.ptr, 
    68 +                                    acc->display.slen ? acc->display.ptr : "", 
    69                                      (acc->display.slen?" " : ""), 
    70                                      (secure ? PJSUA_SECURE_SCHEME : "sip"), 
    71                                      (int)acc->user_part.slen, 
    72 -                                    acc->user_part.ptr, 
    73 +                                    acc->user_part.slen ? acc->user_part.ptr : "", 
    74                                      (acc->user_part.slen?"@":""), 
    75                                      beginquote, 
    76                                      (int)local_addr.slen, 
    77 -                                    local_addr.ptr, 
    78 +                                    local_addr.slen ? local_addr.ptr : "", 
    79                                      endquote, 
    80                                      local_port, 
    81                                      transport_param, 
    82                                      (int)acc->cfg.contact_uri_params.slen, 
    83 -                                    acc->cfg.contact_uri_params.ptr, 
    84 +                                    acc->cfg.contact_uri_params.slen ? acc->cfg.contact_uri_params.ptr : "", 
    85                                      (int)acc->cfg.contact_params.slen, 
    86 -                                    acc->cfg.contact_params.ptr); 
    87 +                                    acc->cfg.contact_params.slen ? acc->cfg.contact_params.ptr : ""); 
    88   
    89      return PJ_SUCCESS; 
    90  } 
  • trunk/package/pjsip/patches/210-pjmedia_audiodev.patch

    r25298 r28963  
    11--- a/pjmedia/src/pjmedia-audiodev/audiodev.c 
    22+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c 
    3 @@ -98,6 +98,10 @@ 
     3@@ -98,6 +98,10 @@ pjmedia_aud_dev_factory* pjmedia_symb_md 
    44 pjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf); 
    55 #endif 
     
    1212 #define MAX_DEVS       64 
    1313  
    14 @@ -404,6 +408,9 @@ 
     14@@ -409,6 +413,9 @@ PJ_DEF(pj_status_t) pjmedia_aud_subsys_i 
    1515 #if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO 
    1616     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory; 
  • trunk/package/pjsip/src/pjmedia/src/pjmedia-audiodev/tapi_dev.c

    r25412 r28963  
    1616#include <pj/os.h> 
    1717 
    18 /* Linux includes*/ 
     18/* Linux includes */ 
    1919#include <stdio.h> 
    2020#include <string.h> 
     
    2828#include <sys/time.h> 
    2929#include <unistd.h> 
     30#include <poll.h> 
    3031 
    3132#if PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE 
    32  
    33 /* TAPI includes*/ 
     33/* TAPI includes */ 
    3434#include "drv_tapi_io.h" 
    3535#include "vmmc_io.h" 
    3636 
    37 /* Maximum 2 devices*/ 
    38 #define TAPI_AUDIO_DEV_NUM          (1) 
    39 #define TAPI_AUDIO_MAX_DEV_NUM      (2) 
     37/* Maximum 2 devices */ 
     38#define TAPI_AUDIO_PORT_NUM          (2) 
    4039#define TAPI_BASE_NAME              "TAPI" 
    4140#define TAPI_LL_DEV_BASE_PATH       "/dev/vmmc" 
    42 #define TAPI_LL_DEV_FIRMWARE_NAME   "/lib/firmware/danube_firmware.bin"  
     41#define TAPI_LL_DEV_FIRMWARE_NAME   "/lib/firmware/danube_firmware.bin" 
     42#define TAPI_LL_BBD_NAME   "/lib/firmware/danube_bbd_fxs.bin" 
    4343 
    4444#define TAPI_LL_DEV_SELECT_TIMEOUT_MS      (2000) 
     
    5151#define TAPI_LL_DEV_ENC_BYTES_PER_FRAME    (TAPI_LL_DEV_ENC_SMPL_PER_FRAME * (TAPI_LL_DEV_ENC_BITS_PER_SMPLS / 8)) 
    5252 
    53  
    54 #define FD_WIDTH_SET(fd, maxfd)   (maxfd) < (fd) ? (fd) : maxfd  
    55  
    5653#define THIS_FILE     "tapi_dev.c" 
    5754 
     
    6259#endif 
    6360 
     61pj_int32_t ch_fd[TAPI_AUDIO_PORT_NUM]; 
     62 
    6463typedef struct 
    6564{ 
    66    pj_int32_t dev_fd; 
    67    pj_int32_t ch_fd[TAPI_AUDIO_DEV_NUM]; 
    68    pj_int8_t  data2phone_map[TAPI_AUDIO_DEV_NUM]; 
    69     
     65        pj_int32_t dev_fd; 
     66        pj_int32_t ch_fd[TAPI_AUDIO_PORT_NUM]; 
     67        pj_int8_t  data2phone_map[TAPI_AUDIO_PORT_NUM]; 
    7068} tapi_ctx; 
    7169 
    72  
    73 /* TAPI factory */ 
    7470struct tapi_aud_factory 
    7571{ 
    76    pjmedia_aud_dev_factory  base; 
    77    pj_pool_t         *pool; 
    78    pj_pool_factory   *pf; 
    79  
    80    pj_uint32_t             dev_count; 
    81    pjmedia_aud_dev_info   *dev_info; 
    82  
    83    tapi_ctx   dev_ctx; 
     72        pjmedia_aud_dev_factory base; 
     73        pj_pool_t               *pool; 
     74        pj_pool_factory         *pf; 
     75        pj_uint32_t             dev_count; 
     76        pjmedia_aud_dev_info    *dev_info; 
     77        tapi_ctx                dev_ctx; 
    8478}; 
    8579 
    8680typedef struct tapi_aud_factory tapi_aud_factory_t; 
    8781 
    88 /* 
    89    Sound stream descriptor. 
    90 **/ 
    9182struct tapi_aud_stream 
    9283{ 
    93    /* Base*/ 
    94    pjmedia_aud_stream   base;      /**< Base class.  */ 
    95    /* Pool*/ 
    96    pj_pool_t            *pool;     /**< Memory pool.       */ 
    97    /* Common settings.*/ 
    98    pjmedia_aud_param    param;     /**< Stream param.  */ 
    99    pjmedia_aud_rec_cb   rec_cb;    /**< Record callback.   */ 
    100    pjmedia_aud_play_cb  play_cb;   /**< Playback callback. */ 
    101    void                *user_data; /**< Application data.  */ 
    102  
    103    pj_thread_desc       thread_desc; 
    104    pj_thread_t         *thread; 
    105    tapi_ctx            *dev_ctx; 
    106    pj_uint8_t           run_flag; 
    107    pj_timestamp         timestamp; 
     84        pjmedia_aud_stream      base; 
     85        pj_pool_t               *pool; 
     86        pjmedia_aud_param       param; 
     87        pjmedia_aud_rec_cb      rec_cb; 
     88        pjmedia_aud_play_cb     play_cb; 
     89        void                    *user_data; 
     90 
     91        pj_thread_desc          thread_desc; 
     92        pj_thread_t             *thread; 
     93        tapi_ctx                *dev_ctx; 
     94        pj_uint8_t              run_flag; 
     95        pj_timestamp            timestamp; 
    10896}; 
    10997 
     
    141129 
    142130static pjmedia_aud_dev_factory_op tapi_fact_op = 
    143   { 
    144       &factory_init, 
    145       &factory_destroy, 
    146       &factory_get_dev_count, 
    147       &factory_get_dev_info, 
    148       &factory_default_param, 
    149       &factory_create_stream 
    150   }; 
     131{ 
     132        &factory_init, 
     133        &factory_destroy, 
     134        &factory_get_dev_count, 
     135        &factory_get_dev_info, 
     136        &factory_default_param, 
     137        &factory_create_stream 
     138}; 
    151139 
    152140static pjmedia_aud_stream_op tapi_strm_op = 
    153141{ 
    154     &stream_get_param, 
    155     &stream_get_cap, 
    156     &stream_set_cap, 
    157     &stream_start, 
    158     &stream_stop, 
    159     &stream_destroy 
     142        &stream_get_param, 
     143        &stream_get_cap, 
     144        &stream_set_cap, 
     145        &stream_start, 
     146        &stream_stop, 
     147        &stream_destroy 
    160148}; 
    161149 
    162 void (*tapi_digit_callback)(unsigned char digit) = NULL; 
    163 void (*tapi_hook_callback)(unsigned char event) = NULL; 
    164  
    165 static pj_int32_t tapi_dev_open(char* dev_path, const pj_int32_t ch_num) 
    166 { 
    167    char devname[128] = {0}; 
    168  
    169    pj_ansi_sprintf(devname,"%s%u%u", dev_path, 1, ch_num); 
    170  
    171    return open((const char*)devname, O_RDWR, 0644); 
    172 } 
    173  
    174 static pj_status_t tapi_dev_binary_buffer_create( 
    175                      const char *pPath, 
    176                      pj_uint8_t **ppBuf, 
    177                      pj_uint32_t *pBufSz) 
    178 { 
    179    pj_status_t status = PJ_SUCCESS; 
    180    FILE *fd; 
    181    struct stat file_stat; 
    182  
    183    /* Open binary file for reading*/ 
    184    fd = fopen(pPath, "rb"); 
    185    if (fd == NULL) { 
    186       TRACE_((THIS_FILE, "ERROR -  binary file %s open failed!\n", pPath)); 
    187       return PJ_EUNKNOWN; 
    188    } 
    189  
    190    /* Get file statistics*/ 
    191    if (stat(pPath, &file_stat) != 0) { 
    192       TRACE_((THIS_FILE, "ERROR -  file %s statistics get failed!\n", pPath)); 
    193       return PJ_EUNKNOWN; 
    194    } 
    195  
    196    *ppBuf = malloc(file_stat.st_size); 
    197    if (*ppBuf == NULL) { 
    198       TRACE_((THIS_FILE, "ERROR -  binary file %s memory allocation failed!\n", pPath)); 
    199       status = PJ_EUNKNOWN; 
    200  
    201       goto on_exit; 
    202    } 
    203  
    204    if (fread (*ppBuf, sizeof(pj_uint8_t), file_stat.st_size, fd) <= 0) { 
    205       TRACE_((THIS_FILE, "ERROR - file %s read failed!\n", pPath)); 
    206       status = PJ_EUNKNOWN; 
    207  
    208       goto on_exit; 
    209    } 
    210  
    211    *pBufSz = file_stat.st_size;  
     150void (*tapi_digit_callback)(unsigned int port, unsigned char digit) = NULL; 
     151void (*tapi_hook_callback)(unsigned int port, unsigned char event) = NULL; 
     152 
     153static pj_int32_t 
     154tapi_dev_open(char* dev_path, const pj_int32_t ch_num) 
     155{ 
     156        char devname[128] = {0}; 
     157        pj_ansi_sprintf(devname,"%s%u%u", dev_path, 1, ch_num); 
     158        return open((const char*)devname, O_RDWR, 0644); 
     159} 
     160 
     161static pj_status_t 
     162tapi_dev_binary_buffer_create(const char *pPath, pj_uint8_t **ppBuf, pj_uint32_t *pBufSz) 
     163{ 
     164        pj_status_t status = PJ_SUCCESS; 
     165        FILE *fd; 
     166        struct stat file_stat; 
     167 
     168        fd = fopen(pPath, "rb"); 
     169        if (fd == NULL) { 
     170                TRACE_((THIS_FILE, "ERROR -  binary file %s open failed!\n", pPath)); 
     171                return PJ_EUNKNOWN; 
     172        } 
     173 
     174        if (stat(pPath, &file_stat) != 0) { 
     175                TRACE_((THIS_FILE, "ERROR -  file %s statistics get failed!\n", pPath)); 
     176                return PJ_EUNKNOWN; 
     177        } 
     178 
     179        *ppBuf = malloc(file_stat.st_size); 
     180        if (*ppBuf == NULL) { 
     181                TRACE_((THIS_FILE, "ERROR -  binary file %s memory allocation failed!\n", pPath)); 
     182                status = PJ_EUNKNOWN; 
     183                goto on_exit; 
     184        } 
     185 
     186        if (fread (*ppBuf, sizeof(pj_uint8_t), file_stat.st_size, fd) <= 0) { 
     187                TRACE_((THIS_FILE, "ERROR - file %s read failed!\n", pPath)); 
     188                status = PJ_EUNKNOWN; 
     189                goto on_exit; 
     190        } 
     191 
     192        *pBufSz = file_stat.st_size; 
    212193 
    213194on_exit: 
    214    if (fd != NULL) { 
    215       fclose(fd); 
    216    } 
    217  
    218    if (*ppBuf != NULL && status != PJ_SUCCESS) { 
    219       free(*ppBuf); 
    220    } 
    221  
    222    return status; 
    223 } 
    224  
    225 static void tapi_dev_binary_buffer_delete(pj_uint8_t *pBuf) 
    226 { 
    227    if (pBuf != NULL) 
    228       free(pBuf); 
    229 } 
    230  
    231 static pj_status_t tapi_dev_firmware_download( 
    232                      pj_int32_t fd, 
    233                      const char *pPath) 
    234 { 
    235    pj_status_t status = PJ_SUCCESS; 
    236    pj_uint8_t *pFirmware = NULL; 
    237    pj_uint32_t binSz = 0; 
    238    VMMC_IO_INIT vmmc_io_init; 
    239  
    240    /* Create binary buffer*/ 
    241    status = tapi_dev_binary_buffer_create(pPath, &pFirmware, &binSz); 
    242    if (status != PJ_SUCCESS) { 
    243       TRACE_((THIS_FILE, "ERROR - binary buffer create failed!\n")); 
    244  
    245       return PJ_EUNKNOWN; 
    246    } 
    247  
    248    /* Download Voice Firmware*/ 
    249    memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT)); 
    250    vmmc_io_init.pPRAMfw   = pFirmware; 
    251    vmmc_io_init.pram_size = binSz; 
    252  
    253    status = ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init); 
    254    if (status != PJ_SUCCESS) { 
    255       TRACE_((THIS_FILE, "ERROR -  FIO_FW_DOWNLOAD ioctl failed!")); 
    256    } 
    257  
    258    /* Delete binary buffer*/ 
    259    tapi_dev_binary_buffer_delete(pFirmware); 
    260  
    261    return status; 
    262 } 
    263  
     195        if (fd != NULL) 
     196                fclose(fd); 
     197 
     198        if (*ppBuf != NULL && status != PJ_SUCCESS) 
     199                free(*ppBuf); 
     200 
     201        return status; 
     202} 
     203 
     204static void 
     205tapi_dev_binary_buffer_delete(pj_uint8_t *pBuf) 
     206{ 
     207        if (pBuf != NULL) 
     208                free(pBuf); 
     209} 
     210 
     211static pj_status_t 
     212tapi_dev_firmware_download(pj_int32_t fd, const char *pPath) 
     213{ 
     214        pj_status_t status = PJ_SUCCESS; 
     215        pj_uint8_t *pFirmware = NULL; 
     216        pj_uint32_t binSz = 0; 
     217        VMMC_IO_INIT vmmc_io_init; 
     218 
     219        status = tapi_dev_binary_buffer_create(pPath, &pFirmware, &binSz); 
     220        if (status != PJ_SUCCESS) { 
     221                TRACE_((THIS_FILE, "ERROR - binary buffer create failed!\n")); 
     222                return PJ_EUNKNOWN; 
     223        } 
     224 
     225        memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT)); 
     226        vmmc_io_init.pPRAMfw   = pFirmware; 
     227        vmmc_io_init.pram_size = binSz; 
     228 
     229        status = ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init); 
     230        if (status != PJ_SUCCESS) 
     231                TRACE_((THIS_FILE, "ERROR -  FIO_FW_DOWNLOAD ioctl failed!")); 
     232 
     233        tapi_dev_binary_buffer_delete(pFirmware); 
     234 
     235        return status; 
     236} 
     237 
     238static int 
     239tapi_dev_bbd_download(int fd, const char *pPath) 
     240{ 
     241        int status = PJ_SUCCESS; 
     242        unsigned char *pFirmware = NULL; 
     243        unsigned int binSz = 0; 
     244        VMMC_DWLD_t bbd_data; 
     245 
     246 
     247        /* Create binary buffer */ 
     248        status = tapi_dev_binary_buffer_create(pPath, &pFirmware, &binSz); 
     249        if (status != PJ_SUCCESS) { 
     250                TRACE_((THIS_FILE, "ERROR - binary buffer create failed!\n")); 
     251                return status; 
     252        } 
     253 
     254        /* Download Voice Firmware */ 
     255        memset(&bbd_data, 0, sizeof(VMMC_DWLD_t)); 
     256        bbd_data.buf = pFirmware; 
     257        bbd_data.size = binSz; 
     258 
     259        status = ioctl(fd, FIO_BBD_DOWNLOAD, &bbd_data); 
     260        if (status != PJ_SUCCESS) { 
     261                TRACE_((THIS_FILE, "ERROR - FIO_BBD_DOWNLOAD failed!\n")); 
     262        } 
     263 
     264        /* Delete binary buffer */ 
     265        tapi_dev_binary_buffer_delete(pFirmware); 
     266 
     267        return status; 
     268} 
    264269 
    265270static pj_status_t tapi_dev_start(tapi_aud_factory_t *f) 
    266271{ 
    267    pj_status_t status = PJ_SUCCESS; 
    268    pj_uint8_t c; 
    269    IFX_TAPI_DEV_START_CFG_t tapistart; 
    270    IFX_TAPI_MAP_DATA_t datamap; 
    271    IFX_TAPI_ENC_CFG_t enc_cfg; 
    272    IFX_TAPI_LINE_VOLUME_t vol; 
    273  
    274    /* Open device*/ 
    275    f->dev_ctx.dev_fd = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, 0); 
    276  
    277    if (f->dev_ctx.dev_fd < 0) { 
    278       TRACE_((THIS_FILE, "ERROR - TAPI device open failed!")); 
    279       return PJ_EUNKNOWN; 
    280    } 
    281  
    282    for (c = 0; c < TAPI_AUDIO_DEV_NUM; c++) { 
    283       f->dev_ctx.ch_fd[c] = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, TAPI_AUDIO_MAX_DEV_NUM - c); 
    284  
    285       if (f->dev_ctx.dev_fd < 0) { 
    286          TRACE_((THIS_FILE, "ERROR - TAPI channel%d open failed!", c)); 
    287          return PJ_EUNKNOWN; 
    288       } 
    289        
    290       f->dev_ctx.data2phone_map[c] = c & 0x1 ? 0 : 1; 
    291    } 
    292  
    293    status = tapi_dev_firmware_download(f->dev_ctx.dev_fd, TAPI_LL_DEV_FIRMWARE_NAME); 
    294    if (status != PJ_SUCCESS) { 
    295       TRACE_((THIS_FILE, "ERROR - Voice Firmware Download failed!")); 
    296       return PJ_EUNKNOWN; 
    297    } 
    298  
    299    memset(&tapistart, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t)); 
    300    tapistart.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER; 
    301  
    302    /* Start TAPI*/ 
    303    status = ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_START, &tapistart); 
    304    if (status != PJ_SUCCESS) { 
    305       TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_START ioctl failed")); 
    306       return PJ_EUNKNOWN; 
    307    } 
    308  
    309  
    310    for (c = 0; c < TAPI_AUDIO_DEV_NUM; c++) { 
    311       /* Perform mapping*/ 
    312       memset(&datamap, 0x0, sizeof(IFX_TAPI_MAP_DATA_t)); 
    313       datamap.nDstCh  = f->dev_ctx.data2phone_map[c]; 
    314       datamap.nChType = IFX_TAPI_MAP_TYPE_PHONE; 
    315  
    316       status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &datamap); 
    317  
    318       if (status != PJ_SUCCESS) { 
    319          TRACE_((THIS_FILE, "ERROR - IFX_TAPI_MAP_DATA_ADD ioctl failed")); 
    320          return PJ_EUNKNOWN; 
    321       } 
    322  
    323       /* Set Line feed*/ 
    324       status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY); 
    325  
    326       if (status != PJ_SUCCESS) { 
    327          TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed")); 
    328          return PJ_EUNKNOWN; 
    329       } 
    330  
    331       /* Config encoder for linear stream*/ 
    332       memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t)); 
    333  
    334       enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20; 
    335       enc_cfg.nEncType  = IFX_TAPI_COD_TYPE_LIN16_8; 
    336  
    337       status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg); 
    338       if (status != PJ_SUCCESS) { 
    339          TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_CFG_SET ioctl failed")); 
    340          return PJ_EUNKNOWN; 
    341       } 
    342  
    343  
    344       /* Suppress TAPI volume, otherwise PJSIP starts autogeneration!!!*/ 
    345       vol.nGainRx = -8; 
    346       vol.nGainTx = -8; 
    347  
    348       status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &vol); 
    349       if (status != PJ_SUCCESS) { 
    350          TRACE_((THIS_FILE, "ERROR - IFX_TAPI_PHONE_VOLUME_SET ioctl failed")); 
    351          return PJ_EUNKNOWN; 
    352       } 
    353    } 
    354  
    355  
    356    return status; 
    357 } 
    358  
    359 static pj_status_t tapi_dev_stop(tapi_aud_factory_t *f) 
    360 { 
    361    pj_status_t status = PJ_SUCCESS; 
    362    pj_uint8_t c; 
    363     
    364    /* Stop TAPI device*/ 
    365    if (ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0) != PJ_SUCCESS) { 
    366       TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_STOP ioctl failed")); 
    367       status = PJ_EUNKNOWN; 
    368    } 
    369  
    370    /* Close device FD*/ 
    371    close(f->dev_ctx.dev_fd); 
    372  
    373    /* Close channel FD*/ 
    374    for (c = TAPI_AUDIO_DEV_NUM; c > 0; c--) { 
    375       close(f->dev_ctx.ch_fd[TAPI_AUDIO_DEV_NUM-c]); 
    376    } 
    377  
    378  
    379    return status; 
    380 } 
    381  
    382 static pj_status_t tapi_dev_codec_control(pj_int32_t fd, pj_uint8_t start) 
    383 { 
    384    if (ioctl(fd, start ? IFX_TAPI_ENC_START : IFX_TAPI_ENC_STOP, 0) != PJ_SUCCESS) { 
    385       TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_%s ioctl failed!", 
    386          start ? "START" : "STOP")); 
    387  
    388       return PJ_EUNKNOWN; 
    389    } 
    390  
    391    if (ioctl(fd, start ? IFX_TAPI_DEC_START : IFX_TAPI_DEC_STOP, 0) != IFX_SUCCESS) { 
    392       TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_%s ioctl failed!", 
    393          start ? "START" : "STOP")); 
    394  
    395       return PJ_EUNKNOWN; 
    396    } 
    397  
    398    return PJ_SUCCESS; 
    399 } 
    400  
    401 static pj_status_t tapi_dev_event_ONHOOK(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
     272        pj_uint8_t c, hook_status; 
     273        pj_status_t status = PJ_SUCCESS; 
     274        IFX_TAPI_DEV_START_CFG_t tapistart; 
     275        IFX_TAPI_MAP_DATA_t datamap; 
     276        IFX_TAPI_ENC_CFG_t enc_cfg; 
     277        IFX_TAPI_LINE_VOLUME_t line_vol; 
     278        IFX_TAPI_CID_CFG_t cid_cnf; 
     279         
     280        /* Open device */ 
     281        f->dev_ctx.dev_fd = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, 0); 
     282         
     283        if (f->dev_ctx.dev_fd < 0) { 
     284                TRACE_((THIS_FILE, "ERROR - TAPI device open failed!")); 
     285                return PJ_EUNKNOWN; 
     286        } 
     287 
     288        for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { 
     289                ch_fd[c] = f->dev_ctx.ch_fd[c] = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, TAPI_AUDIO_PORT_NUM - c); 
     290 
     291                if (f->dev_ctx.dev_fd < 0) { 
     292                        TRACE_((THIS_FILE, "ERROR - TAPI channel%d open failed!", c)); 
     293                        return PJ_EUNKNOWN; 
     294                } 
     295                f->dev_ctx.data2phone_map[c] = c & 0x1 ? 0 : 1; 
     296        } 
     297 
     298        status = tapi_dev_firmware_download(f->dev_ctx.dev_fd, TAPI_LL_DEV_FIRMWARE_NAME); 
     299        if (status != PJ_SUCCESS) { 
     300                TRACE_((THIS_FILE, "ERROR - Voice Firmware Download failed!")); 
     301                return PJ_EUNKNOWN; 
     302        } 
     303 
     304        /* Download coefficients */ 
     305        /* 
     306        status = tapi_dev_bbd_download(f->dev_ctx.dev_fd, TAPI_LL_BBD_NAME); 
     307        if (status != PJ_SUCCESS) { 
     308                TRACE_((THIS_FILE, "ERROR - Voice Coefficients Download failed!")); 
     309                return PJ_EUNKNOWN; 
     310        } 
     311        */ 
     312 
     313        memset(&tapistart, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t)); 
     314        tapistart.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER; 
     315         
     316        /* Start TAPI */ 
     317        status = ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_START, &tapistart); 
     318        if (status != PJ_SUCCESS) { 
     319                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_START ioctl failed")); 
     320                return PJ_EUNKNOWN; 
     321        } 
     322 
     323 
     324        for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { 
     325                /* Perform mapping */ 
     326                memset(&datamap, 0x0, sizeof(IFX_TAPI_MAP_DATA_t)); 
     327                datamap.nDstCh  = f->dev_ctx.data2phone_map[c]; 
     328                datamap.nChType = IFX_TAPI_MAP_TYPE_PHONE; 
     329                 
     330                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &datamap); 
     331                 
     332                if (status != PJ_SUCCESS) { 
     333                        TRACE_((THIS_FILE, "ERROR - IFX_TAPI_MAP_DATA_ADD ioctl failed")); 
     334                        return PJ_EUNKNOWN; 
     335                } 
     336                 
     337                /* Set Line feed */ 
     338                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY); 
     339                 
     340                if (status != PJ_SUCCESS) { 
     341                        TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed")); 
     342                        return PJ_EUNKNOWN; 
     343                } 
     344                 
     345                /* Configure encoder for linear stream */ 
     346                memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t)); 
     347                 
     348                enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20; 
     349                enc_cfg.nEncType  = IFX_TAPI_COD_TYPE_LIN16_8; 
     350                 
     351                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg); 
     352                if (status != PJ_SUCCESS) { 
     353                        TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_CFG_SET ioctl failed")); 
     354                        return PJ_EUNKNOWN; 
     355                } 
     356                 
     357                /* Suppress TAPI volume, otherwise PJSIP starts autogeneration!!! */ 
     358                line_vol.nGainRx = -8; 
     359                line_vol.nGainTx = -8; 
     360                 
     361                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &line_vol); 
     362                if (status != PJ_SUCCESS) { 
     363                        TRACE_((THIS_FILE, "ERROR - IFX_TAPI_PHONE_VOLUME_SET ioctl failed")); 
     364                        return PJ_EUNKNOWN; 
     365                } 
     366                 
     367                /* Configure Caller ID type */ 
     368                /* One can choose from following (for now at compile time): 
     369                        IFX_TAPI_CID_STD_TELCORDIA 
     370                        IFX_TAPI_CID_STD_ETSI_FSK 
     371                        IFX_TAPI_CID_STD_ETSI_DTMF 
     372                        IFX_TAPI_CID_STD_SIN 
     373                        IFX_TAPI_CID_STD_NTT 
     374                        IFX_TAPI_CID_STD_KPN_DTMF 
     375                        IFX_TAPI_CID_STD_KPN_DTMF_FSK 
     376                */ 
     377                memset(&cid_cnf, 0, sizeof(cid_cnf)); 
     378                cid_cnf.nStandard = IFX_TAPI_CID_STD_ETSI_FSK; 
     379                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_CID_CFG_SET, &cid_cnf); 
     380                if (status != PJ_SUCCESS) { 
     381                        TRACE_((THIS_FILE, "ERROR - IFX_TAPI_CID_CFG_SET ioctl failed")); 
     382                        return PJ_EUNKNOWN; 
     383                } 
     384                 
     385                /* check hook status */ 
     386                hook_status = 0; 
     387                status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_HOOK_STATUS_GET, &hook_status); 
     388                if (status != PJ_SUCCESS) { 
     389                   TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed!")); 
     390                   return PJ_EUNKNOWN; 
     391                } 
     392                 
     393                /* if off hook do initialization */ 
     394                if (hook_status) { 
     395                        status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_ACTIVE); 
     396                        if (status != PJ_SUCCESS) { 
     397                                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); 
     398                                return PJ_EUNKNOWN; 
     399                        } 
     400                        status = ioctl(c, IFX_TAPI_ENC_START, 0); 
     401                        if (status != PJ_SUCCESS) { 
     402                                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_START ioctl failed!")); 
     403                                return PJ_EUNKNOWN; 
     404                        } 
     405 
     406                        status = ioctl(c, IFX_TAPI_DEC_START, 0); 
     407                        if (status != PJ_SUCCESS) { 
     408                                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_START ioctl failed!")); 
     409                                return PJ_EUNKNOWN; 
     410                        } 
     411                } 
     412        } 
     413 
     414        return status; 
     415} 
     416 
     417static pj_status_t 
     418tapi_dev_stop(tapi_aud_factory_t *f) 
     419{ 
     420        pj_status_t status = PJ_SUCCESS; 
     421        pj_uint8_t c; 
     422 
     423        if (ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0) != PJ_SUCCESS) { 
     424                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_STOP ioctl failed")); 
     425                status = PJ_EUNKNOWN; 
     426        } 
     427 
     428        close(f->dev_ctx.dev_fd); 
     429        for (c = TAPI_AUDIO_PORT_NUM; c > 0; c--) 
     430                close(f->dev_ctx.ch_fd[TAPI_AUDIO_PORT_NUM-c]); 
     431 
     432        return status; 
     433} 
     434 
     435static pj_status_t 
     436tapi_dev_codec_control(pj_int32_t fd, pj_uint8_t start) 
     437{ 
     438        if (ioctl(fd, start ? IFX_TAPI_ENC_START : IFX_TAPI_ENC_STOP, 0) != PJ_SUCCESS) { 
     439                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_%s ioctl failed!", 
     440                        start ? "START" : "STOP")); 
     441                return PJ_EUNKNOWN; 
     442        } 
     443 
     444        if (ioctl(fd, start ? IFX_TAPI_DEC_START : IFX_TAPI_DEC_STOP, 0) != IFX_SUCCESS) { 
     445                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_%s ioctl failed!", 
     446                        start ? "START" : "STOP")); 
     447                return PJ_EUNKNOWN; 
     448        } 
     449 
     450        return PJ_SUCCESS; 
     451} 
     452 
     453static pj_status_t tapi_dev_event_on_hook(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
    402454{ 
    403455   PJ_LOG(1,(THIS_FILE, "TAPI: ONHOOK")); 
     
    410462   } 
    411463 
    412    /* enc/dec stop*/ 
     464   /* enc/dec stop */ 
    413465   if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 0) != PJ_SUCCESS) { 
    414466      TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
     
    420472} 
    421473 
    422 static pj_status_t tapi_dev_event_OFFHOOK(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
     474static pj_status_t tapi_dev_event_off_hook(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
    423475{ 
    424476   PJ_LOG(1,(THIS_FILE, "TAPI: OFFHOOK")); 
     
    431483   } 
    432484 
    433    /* enc/dec stop*/ 
     485   /* enc/dec stop */ 
    434486   if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 1) != PJ_SUCCESS) { 
    435487      TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
     
    441493} 
    442494 
    443 static pj_status_t tapi_dev_event_digit(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
    444 { 
    445    PJ_LOG(1,(THIS_FILE, "TAPI: OFFHOOK")); 
    446  
    447    if (ioctl(dev_ctx->ch_fd[dev_idx], IFX_TAPI_LINE_FEED_SET, 
    448                IFX_TAPI_LINE_FEED_ACTIVE) != PJ_SUCCESS) { 
    449       TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); 
    450  
    451       return PJ_EUNKNOWN; 
    452    } 
    453  
    454    /* enc/dec stop*/ 
    455    if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 1) != PJ_SUCCESS) { 
    456       TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
    457  
    458       return PJ_EUNKNOWN; 
    459    } 
    460  
    461    return PJ_SUCCESS; 
    462 } 
    463  
    464 static pj_status_t tapi_dev_event_handler( 
    465                      tapi_aud_stream_t *stream) 
    466 { 
    467    tapi_ctx *dev_ctx = stream->dev_ctx; 
    468    pj_uint32_t dev_idx = stream->param.rec_id; 
    469    pj_status_t status = PJ_SUCCESS; 
    470    IFX_TAPI_EVENT_t tapiEvent; 
    471  
    472    memset (&tapiEvent, 0, sizeof(tapiEvent)); 
    473  
    474    tapiEvent.ch = dev_ctx->data2phone_map[dev_idx]; 
    475  
    476    /* Get event*/ 
    477    status = ioctl(dev_ctx->dev_fd, IFX_TAPI_EVENT_GET, &tapiEvent); 
    478  
    479    if ((status == PJ_SUCCESS) && (tapiEvent.id != IFX_TAPI_EVENT_NONE)) { 
    480       switch(tapiEvent.id) { 
    481          case IFX_TAPI_EVENT_FXS_ONHOOK: 
    482             status = tapi_dev_event_ONHOOK(dev_ctx, dev_idx); 
    483             if(tapi_hook_callback) 
    484                    tapi_hook_callback(0); 
    485              break; 
    486          case IFX_TAPI_EVENT_FXS_OFFHOOK: 
    487             status = tapi_dev_event_OFFHOOK(dev_ctx, dev_idx); 
    488             if(tapi_hook_callback) 
    489                    tapi_hook_callback(1); 
    490              break; 
    491          case IFX_TAPI_EVENT_DTMF_DIGIT: 
    492             if(tapi_digit_callback) 
    493                    tapi_digit_callback(tapiEvent.data.dtmf.ascii); 
    494             break; 
    495          default: 
    496             printf("%s:%s[%d]%04X\n", __FILE__, __func__, __LINE__, tapiEvent.id); 
    497             break; 
    498       } 
    499    } 
    500  
    501    return status; 
    502 } 
    503  
    504 static pj_status_t tapi_dev_data_handler( 
    505                      tapi_aud_stream_t *stream) 
    506 { 
     495static pj_status_t 
     496tapi_dev_event_digit(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) 
     497{ 
     498        PJ_LOG(1,(THIS_FILE, "TAPI: OFFHOOK")); 
     499 
     500        if (ioctl(dev_ctx->ch_fd[dev_idx], IFX_TAPI_LINE_FEED_SET, 
     501                        IFX_TAPI_LINE_FEED_ACTIVE) != PJ_SUCCESS) { 
     502                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); 
     503                return PJ_EUNKNOWN; 
     504        } 
     505 
     506        /* enc/dec stop */ 
     507        if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 1) != PJ_SUCCESS) { 
     508                TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
     509                return PJ_EUNKNOWN; 
     510        } 
     511 
     512        return PJ_SUCCESS; 
     513} 
     514 
     515static pj_status_t 
     516tapi_dev_event_handler(tapi_aud_stream_t *stream) 
     517{ 
     518        IFX_TAPI_EVENT_t tapiEvent; 
     519        tapi_ctx *dev_ctx = stream->dev_ctx; 
     520        pj_status_t status = PJ_SUCCESS; 
     521        unsigned int i; 
     522 
     523        for (i = 0; i < TAPI_AUDIO_PORT_NUM; i++) { 
     524                memset (&tapiEvent, 0, sizeof(tapiEvent)); 
     525                tapiEvent.ch = dev_ctx->data2phone_map[i]; 
     526                status = ioctl(dev_ctx->dev_fd, IFX_TAPI_EVENT_GET, &tapiEvent); 
     527 
     528                if ((status == PJ_SUCCESS) && (tapiEvent.id != IFX_TAPI_EVENT_NONE)) { 
     529                        switch(tapiEvent.id) { 
     530                        case IFX_TAPI_EVENT_FXS_ONHOOK: 
     531                                status = tapi_dev_event_on_hook(dev_ctx, i); 
     532                                if(tapi_hook_callback) 
     533                                        tapi_hook_callback(i, 0); 
     534                                break; 
     535                        case IFX_TAPI_EVENT_FXS_OFFHOOK: 
     536                                status = tapi_dev_event_off_hook(dev_ctx, i); 
     537                                if(tapi_hook_callback) 
     538                                        tapi_hook_callback(i, 1); 
     539                                break; 
     540                        case IFX_TAPI_EVENT_DTMF_DIGIT: 
     541                                if(tapi_digit_callback) 
     542                                        tapi_digit_callback(i, tapiEvent.data.dtmf.ascii); 
     543                                break; 
     544                        case IFX_TAPI_EVENT_COD_DEC_CHG: 
     545                        case IFX_TAPI_EVENT_TONE_GEN_END: 
     546                        case IFX_TAPI_EVENT_CID_TX_SEQ_END: 
     547                                break; 
     548                        default: 
     549                                PJ_LOG(1,(THIS_FILE, "unknown tapi event %08X", tapiEvent.id)); 
     550                                break; 
     551                        } 
     552                } 
     553        } 
     554 
     555        return status; 
     556} 
     557 
     558static pj_status_t 
     559tapi_dev_data_handler(tapi_aud_stream_t *stream) { 
    507560   pj_status_t status = PJ_SUCCESS; 
    508561   tapi_ctx *dev_ctx = stream->dev_ctx; 
     
    513566   pj_int32_t ret; 
    514567 
    515    /* Get data from driver*/ 
     568   /* Get data from driver */ 
    516569   ret = read(dev_ctx->ch_fd[dev_idx], buf_rec, sizeof(buf_rec)); 
    517570   if (ret < 0) { 
     
    566619} 
    567620 
    568 /* TAPI capture and playback thread. */ 
    569 static int PJ_THREAD_FUNC tapi_dev_thread(void *arg) 
    570 { 
    571    tapi_aud_stream_t *strm = (struct tapi_aud_stream*)arg; 
    572    tapi_ctx *dev_ctx = strm->dev_ctx; 
    573    fd_set rfds, trfds; 
    574    pj_uint32_t width = 0; 
    575    struct timeval tv; 
    576    pj_uint32_t sretval; 
    577    pj_uint32_t dev_idx; 
    578  
    579    PJ_LOG(1,(THIS_FILE, "TAPI: thread starting...")); 
    580  
    581    if (strm->param.rec_id != strm->param.play_id) { 
    582       PJ_LOG(1,(THIS_FILE, "TAPI: thread exit - incorrect play/rec IDs")); 
    583       return 0; 
    584    } 
    585  
    586    dev_idx = strm->param.rec_id; 
    587  
    588    FD_ZERO(&rfds); 
    589  
    590    FD_SET(dev_ctx->dev_fd, &rfds); 
    591    width = FD_WIDTH_SET(dev_ctx->dev_fd, width); 
    592  
    593    FD_SET(dev_ctx->ch_fd[dev_idx], &rfds); 
    594    width = FD_WIDTH_SET(dev_ctx->ch_fd[dev_idx], width); 
    595  
    596    tv.tv_sec = TAPI_LL_DEV_SELECT_TIMEOUT_MS / 1000; 
    597    tv.tv_usec = (TAPI_LL_DEV_SELECT_TIMEOUT_MS % 1000) * 1000;  
    598  
    599    strm->run_flag = 1; 
    600  
    601    while(1) 
    602    { 
    603       /* Update the local file descriptor by the copy in the task parameter */ 
    604       memcpy((void *) &trfds, (void*) &rfds, sizeof(fd_set)); 
    605  
    606       sretval = select(width + 1, &trfds, NULL, NULL, &tv);  
    607  
    608       if (!strm->run_flag) { 
    609          break; 
    610       } 
    611  
    612       /* error or timeout on select */ 
    613       if (sretval <= 0) { 
    614          continue; 
    615       } 
    616  
    617       /* Check device control channel*/ 
    618       if (FD_ISSET(dev_ctx->dev_fd, &trfds)) { 
    619          if (tapi_dev_event_handler(strm) != PJ_SUCCESS) { 
    620             PJ_LOG(1,(THIS_FILE, "TAPI: event hanldler failed!")); 
    621             break; 
    622          } 
    623       } 
    624  
    625       /* Check device data channel*/ 
    626       if (FD_ISSET(dev_ctx->ch_fd[dev_idx], &trfds)) { 
    627          if (tapi_dev_data_handler(strm) != PJ_SUCCESS) { 
    628             PJ_LOG(1,(THIS_FILE, "TAPI: data hanldler failed!")); 
    629             break; 
    630          } 
    631       } 
    632    } 
    633  
    634    PJ_LOG(1,(THIS_FILE, "TAPI: thread stopping...")); 
    635  
    636    return 0; 
     621static int 
     622PJ_THREAD_FUNC tapi_dev_thread(void *arg) { 
     623        tapi_aud_stream_t *strm = (struct tapi_aud_stream*)arg; 
     624        tapi_ctx *dev_ctx = strm->dev_ctx; 
     625        pj_uint32_t sretval; 
     626        pj_uint32_t dev_idx; 
     627        struct pollfd fds[3]; 
     628 
     629        PJ_LOG(1,(THIS_FILE, "TAPI: thread starting...")); 
     630 
     631        if (strm->param.rec_id != strm->param.play_id) { 
     632                PJ_LOG(1,(THIS_FILE, "TAPI: thread exit - incorrect play/rec IDs")); 
     633                return 0; 
     634        } 
     635 
     636        dev_idx = strm->param.rec_id; 
     637        strm->run_flag = 1; 
     638 
     639        fds[0].fd = dev_ctx->dev_fd; 
     640        fds[0].events = POLLIN; 
     641        fds[1].fd = dev_ctx->ch_fd[0]; 
     642        fds[1].events = POLLIN; 
     643        fds[2].fd = dev_ctx->ch_fd[1]; 
     644        fds[2].events = POLLIN; 
     645 
     646        while(1) 
     647        { 
     648                sretval = poll(fds, TAPI_AUDIO_PORT_NUM + 1, TAPI_LL_DEV_SELECT_TIMEOUT_MS); 
     649 
     650                if (!strm->run_flag) 
     651                        break; 
     652                if (sretval <= 0) 
     653                        continue; 
     654 
     655                if (fds[0].revents == POLLIN) { 
     656                        if (tapi_dev_event_handler(strm) != PJ_SUCCESS) { 
     657                                PJ_LOG(1,(THIS_FILE, "TAPI: event hanldler failed!")); 
     658                                break; 
     659                        } 
     660                } 
     661 
     662                if (fds[1].revents == POLLIN) { 
     663                        if (tapi_dev_data_handler(strm) != PJ_SUCCESS) { 
     664                                PJ_LOG(1,(THIS_FILE, "TAPI: data hanldler failed!")); 
     665                                break; 
     666                        } 
     667                } 
     668 
     669                if (fds[2].revents == POLLIN) { 
     670                        if (tapi_dev_data_handler(strm) != PJ_SUCCESS) { 
     671                                PJ_LOG(1,(THIS_FILE, "TAPI: data hanldler failed!")); 
     672                                break; 
     673                        } 
     674                } 
     675        } 
     676        PJ_LOG(1,(THIS_FILE, "TAPI: thread stopping...")); 
     677 
     678        return 0; 
    637679} 
    638680 
     
    641683 ****************************************************************************/ 
    642684 
    643 /*  Init tapi audio driver. */ 
    644 pjmedia_aud_dev_factory* pjmedia_tapi_factory(pj_pool_factory *pf) 
    645 { 
    646     struct tapi_aud_factory *f; 
    647     pj_pool_t *pool; 
    648  
    649     TRACE_((THIS_FILE, "pjmedia_tapi_factory()")); 
    650  
    651     pool = pj_pool_create(pf, "tapi", 512, 512, NULL); 
    652     f = PJ_POOL_ZALLOC_T(pool, struct tapi_aud_factory); 
    653     f->pf = pf; 
    654     f->pool = pool; 
    655     f->base.op = &tapi_fact_op; 
    656  
    657     return &f->base; 
    658 } 
    659  
    660 /* API: init factory */ 
    661 static pj_status_t factory_init(pjmedia_aud_dev_factory *f) 
    662 { 
    663    struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
    664    pj_uint8_t c; 
    665  
    666    TRACE_((THIS_FILE, "factory_init()")); 
    667  
    668    /* Enumerate sound devices */ 
    669    af->dev_count = TAPI_AUDIO_DEV_NUM; 
    670  
    671    af->dev_info = (pjmedia_aud_dev_info*) 
    672          pj_pool_calloc(af->pool, af->dev_count, sizeof(pjmedia_aud_dev_info)); 
    673  
    674    for (c = 0; c < af->dev_count; c++) { 
    675       pj_ansi_sprintf(af->dev_info[c].name,"%s_%02d", TAPI_BASE_NAME, c); 
    676  
    677       af->dev_info[c].input_count = af->dev_info[c].output_count = 1; 
    678       af->dev_info[c].default_samples_per_sec = TAPI_LL_DEV_ENC_SMPL_PER_SEC; 
    679       pj_ansi_strcpy(af->dev_info[c].driver, "/dev/vmmc"); 
    680  
    681       af->dev_info[c].caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING | 
    682                              PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY | 
    683                              PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; 
    684  
    685       af->dev_info[c].routes = PJMEDIA_AUD_DEV_ROUTE_DEFAULT ; 
    686    } 
    687  
    688    /* Initialize TAPI device(s)*/ 
    689    if (tapi_dev_start(af) != PJ_SUCCESS) { 
    690       TRACE_((THIS_FILE, "ERROR - TAPI device init failed!")); 
    691       return PJ_EUNKNOWN; 
    692    } 
    693  
    694    return PJ_SUCCESS; 
    695 } 
    696  
    697 /* API: destroy factory */ 
    698 static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f) 
    699 { 
    700    struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
    701    pj_pool_t *pool; 
    702    pj_status_t status = PJ_SUCCESS; 
    703  
    704    TRACE_((THIS_FILE, "factory_destroy()")); 
    705  
    706    /* Stop TAPI device*/ 
    707    if (tapi_dev_stop(f) != PJ_SUCCESS) { 
    708       TRACE_((THIS_FILE, "ERROR - TAPI device stop failed!")); 
    709       status = PJ_EUNKNOWN; 
    710    } 
    711  
    712    pool = af->pool; 
    713    af->pool = NULL; 
    714    pj_pool_release(pool); 
    715  
    716    return status; 
    717 } 
    718  
    719 /* API: get number of devices */ 
    720 static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f) 
    721 { 
    722   struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
    723   TRACE_((THIS_FILE, "factory_get_dev_count()")); 
    724  
    725   return af->dev_count; 
    726 } 
    727  
    728 /* API: get device info */ 
    729 static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
    730           unsigned index, 
    731           pjmedia_aud_dev_info *info) 
    732 { 
    733   struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
    734  
    735   TRACE_((THIS_FILE, "factory_get_dev_info()")); 
    736   PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); 
    737  
    738   pj_memcpy(info, &af->dev_info[index], sizeof(*info)); 
    739  
    740   return PJ_SUCCESS; 
    741 } 
    742  
    743 /* API: create default device parameter */ 
    744 static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f, 
    745            unsigned index, 
    746            pjmedia_aud_param *param) 
    747 { 
    748   struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
    749   struct pjmedia_aud_dev_info *di = &af->dev_info[index]; 
    750  
    751   TRACE_((THIS_FILE, "factory_default_param.")); 
    752   PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); 
    753  
    754   pj_bzero(param, sizeof(*param)); 
    755   if (di->input_count && di->output_count) { 
    756     param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 
    757     param->rec_id = index; 
    758     param->play_id = index; 
    759   } else if (di->input_count) { 
    760     param->dir = PJMEDIA_DIR_CAPTURE; 
    761     param->rec_id = index; 
    762     param->play_id = PJMEDIA_AUD_INVALID_DEV; 
    763   } else if (di->output_count) { 
    764     param->dir = PJMEDIA_DIR_PLAYBACK; 
    765     param->play_id = index; 
    766     param->rec_id = PJMEDIA_AUD_INVALID_DEV; 
    767   } else { 
    768     return PJMEDIA_EAUD_INVDEV; 
    769   } 
    770  
    771   param->clock_rate        = TAPI_LL_DEV_ENC_SMPL_PER_SEC; //di->default_samples_per_sec; 
    772   param->channel_count     = 1; 
    773   param->samples_per_frame = TAPI_LL_DEV_ENC_SMPL_PER_FRAME; 
    774   param->bits_per_sample   = TAPI_LL_DEV_ENC_BITS_PER_SMPLS; 
    775   param->flags             = PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE | di->caps; 
    776   param->output_route      = PJMEDIA_AUD_DEV_ROUTE_DEFAULT; 
    777  
    778   return PJ_SUCCESS; 
    779 } 
    780  
    781 /* API: create stream */ 
    782 static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f, 
    783            const pjmedia_aud_param *param, 
    784            pjmedia_aud_rec_cb rec_cb, 
    785            pjmedia_aud_play_cb play_cb, 
    786            void *user_data, 
    787            pjmedia_aud_stream **p_aud_strm) 
     685pjmedia_aud_dev_factory* 
     686pjmedia_tapi_factory(pj_pool_factory *pf) { 
     687        struct tapi_aud_factory *f; 
     688        pj_pool_t *pool; 
     689 
     690        TRACE_((THIS_FILE, "pjmedia_tapi_factory()")); 
     691 
     692        pool = pj_pool_create(pf, "tapi", 512, 512, NULL); 
     693        f = PJ_POOL_ZALLOC_T(pool, struct tapi_aud_factory); 
     694        f->pf = pf; 
     695        f->pool = pool; 
     696        f->base.op = &tapi_fact_op; 
     697 
     698        return &f->base; 
     699} 
     700 
     701static pj_status_t 
     702factory_init(pjmedia_aud_dev_factory *f) 
     703{ 
     704        struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     705        pj_uint8_t c; 
     706 
     707        TRACE_((THIS_FILE, "factory_init()")); 
     708 
     709        af->dev_count = 1; 
     710        af->dev_info = (pjmedia_aud_dev_info*) 
     711        pj_pool_calloc(af->pool, af->dev_count, sizeof(pjmedia_aud_dev_info)); 
     712        pj_ansi_sprintf(af->dev_info[0].name,"%s_%02d", TAPI_BASE_NAME, c); 
     713        af->dev_info[0].input_count = af->dev_info[0].output_count = TAPI_AUDIO_PORT_NUM; 
     714        af->dev_info[0].default_samples_per_sec = TAPI_LL_DEV_ENC_SMPL_PER_SEC; 
     715        pj_ansi_strcpy(af->dev_info[0].driver, "/dev/vmmc"); 
     716        af->dev_info[0].caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING | 
     717                PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY | 
     718                PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; 
     719        af->dev_info[0].routes = PJMEDIA_AUD_DEV_ROUTE_DEFAULT ; 
     720        if (tapi_dev_start(af) != PJ_SUCCESS) { 
     721                TRACE_((THIS_FILE, "ERROR - TAPI device init failed!")); 
     722                return PJ_EUNKNOWN; 
     723        } 
     724 
     725        return PJ_SUCCESS; 
     726} 
     727 
     728static pj_status_t 
     729factory_destroy(pjmedia_aud_dev_factory *f) 
     730{ 
     731        struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     732        pj_pool_t *pool; 
     733        pj_status_t status = PJ_SUCCESS; 
     734 
     735        TRACE_((THIS_FILE, "factory_destroy()")); 
     736 
     737        if (tapi_dev_stop(f) != PJ_SUCCESS) { 
     738                TRACE_((THIS_FILE, "ERROR - TAPI device stop failed!")); 
     739                status = PJ_EUNKNOWN; 
     740        } 
     741        pool = af->pool; 
     742        af->pool = NULL; 
     743        pj_pool_release(pool); 
     744 
     745        return status; 
     746} 
     747 
     748static unsigned 
     749factory_get_dev_count(pjmedia_aud_dev_factory *f) 
     750{ 
     751        struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     752        TRACE_((THIS_FILE, "factory_get_dev_count()")); 
     753 
     754        return af->dev_count; 
     755} 
     756 
     757static pj_status_t 
     758factory_get_dev_info(pjmedia_aud_dev_factory *f, unsigned index, pjmedia_aud_dev_info *info) 
     759{ 
     760        struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     761 
     762        TRACE_((THIS_FILE, "factory_get_dev_info()")); 
     763        PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); 
     764 
     765        pj_memcpy(info, &af->dev_info[index], sizeof(*info)); 
     766 
     767        return PJ_SUCCESS; 
     768} 
     769 
     770static pj_status_t 
     771factory_default_param(pjmedia_aud_dev_factory *f, unsigned index, pjmedia_aud_param *param) 
     772{ 
     773        struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     774        struct pjmedia_aud_dev_info *di = &af->dev_info[index]; 
     775 
     776        TRACE_((THIS_FILE, "factory_default_param.")); 
     777        PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); 
     778 
     779        pj_bzero(param, sizeof(*param)); 
     780        if (di->input_count && di->output_count) { 
     781                param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 
     782                param->rec_id = index; 
     783                param->play_id = index; 
     784        } else if (di->input_count) { 
     785                param->dir = PJMEDIA_DIR_CAPTURE; 
     786                param->rec_id = index; 
     787                param->play_id = PJMEDIA_AUD_INVALID_DEV; 
     788        } else if (di->output_count) { 
     789                param->dir = PJMEDIA_DIR_PLAYBACK; 
     790                param->play_id = index; 
     791                param->rec_id = PJMEDIA_AUD_INVALID_DEV; 
     792        } else { 
     793                return PJMEDIA_EAUD_INVDEV; 
     794        } 
     795 
     796        param->clock_rate = TAPI_LL_DEV_ENC_SMPL_PER_SEC; //di->default_samples_per_sec; 
     797        param->channel_count = 1; 
     798        param->samples_per_frame = TAPI_LL_DEV_ENC_SMPL_PER_FRAME; 
     799        param->bits_per_sample = TAPI_LL_DEV_ENC_BITS_PER_SMPLS; 
     800        param->flags = PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE | di->caps; 
     801        param->output_route = PJMEDIA_AUD_DEV_ROUTE_DEFAULT; 
     802 
     803        return PJ_SUCCESS; 
     804} 
     805 
     806static pj_status_t 
     807factory_create_stream(pjmedia_aud_dev_factory *f, const pjmedia_aud_param *param, 
     808        pjmedia_aud_rec_cb rec_cb, pjmedia_aud_play_cb play_cb, 
     809        void *user_data, pjmedia_aud_stream **p_aud_strm) 
    788810{ 
    789811   struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; 
     
    837859} 
    838860 
    839 /**************************************************************************** 
    840  * Stream operations 
    841  */ 
    842 /* API: Get stream info. */ 
    843 static pj_status_t stream_get_param(pjmedia_aud_stream *s, 
    844                                     pjmedia_aud_param *pi) 
    845 { 
    846   struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
    847  
    848   PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL); 
    849  
    850   pj_memcpy(pi, &strm->param, sizeof(*pi)); 
    851   /* Update the volume setting */ 
    852   if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
    853         &pi->output_vol) == PJ_SUCCESS) 
    854   { 
    855     pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; 
    856   } 
    857  
    858   if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY, 
    859         &pi->output_latency_ms) == PJ_SUCCESS) 
    860   { 
    861     pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY; 
    862   } 
    863  
    864   if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY, 
    865         &pi->input_latency_ms) == PJ_SUCCESS) 
    866   { 
    867     pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; 
    868   } 
    869  
    870   return PJ_SUCCESS; 
    871 } 
    872  
    873 /* API: get capability */ 
    874 static pj_status_t stream_get_cap(pjmedia_aud_stream *s, 
    875           pjmedia_aud_dev_cap cap, 
    876           void *pval) 
    877 { 
    878   struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
    879 #ifdef OLD_IMPL 
    880   OSStatus status = 0; 
    881   PJ_ASSERT_RETURN(strm && pval, PJ_EINVAL); 
    882  
    883   if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && strm->play_strm->queue) 
    884   { 
    885     Float32 vol; 
    886     status = AudioQueueGetParameter(strm->play_strm->queue, 
    887                                     kAudioQueueParam_Volume, &vol); 
    888     if (!status) 
    889     { 
    890       *(unsigned*)pval = (vol * 100); 
    891       return PJ_SUCCESS; 
    892     } 
    893   } 
    894   else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY && strm->play_strm->queue) 
    895   { 
    896     Float32 lat; 
    897     UInt32 size = sizeof(lat); 
    898     status = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputLatency, 
    899                                      &size, &lat); 
    900     if (!status) 
    901     { 
    902       *(unsigned*)pval = lat * 1000; 
    903       return PJ_SUCCESS; 
    904     } 
    905   } 
    906   else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE && strm->play_strm->queue) 
    907   { 
    908     *(pjmedia_aud_dev_route*)pval = strm->param.output_route; 
    909     return PJ_SUCCESS; 
    910   } 
    911   else if (cap==PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY && strm->rec_strm->queue) 
    912   { 
    913     Float32 lat; 
    914     UInt32 size = sizeof(lat); 
    915     status = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputLatency, 
    916                                      &size, &lat); 
    917     if (!status) 
    918     { 
    919       *(unsigned*)pval = lat * 1000; 
    920       return PJ_SUCCESS; 
    921     } 
    922   } 
    923  
    924   if (status) 
    925     PJ_LOG(1, (THIS_FILE, "AudioQueueGetParameter/AudioSessionGetProperty err %d", status)); 
    926   return PJMEDIA_EAUD_INVCAP; 
    927 #else 
    928   return PJ_SUCCESS; 
     861static pj_status_t 
     862stream_get_param(pjmedia_aud_stream *s, pjmedia_aud_param *pi) 
     863{ 
     864        struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
     865 
     866        PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL); 
     867        pj_memcpy(pi, &strm->param, sizeof(*pi)); 
     868 
     869        if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
     870                        &pi->output_vol) == PJ_SUCCESS) 
     871                pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; 
     872 
     873        if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY, 
     874                        &pi->output_latency_ms) == PJ_SUCCESS) 
     875                pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY; 
     876 
     877        if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY, 
     878                        &pi->input_latency_ms) == PJ_SUCCESS) 
     879                pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; 
     880 
     881        return PJ_SUCCESS; 
     882} 
     883 
     884static pj_status_t 
     885stream_get_cap(pjmedia_aud_stream *s, pjmedia_aud_dev_cap cap, void *pval) 
     886{ 
     887        // struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
     888        return PJ_SUCCESS; 
     889} 
     890 
     891static pj_status_t 
     892stream_set_cap(pjmedia_aud_stream *s, pjmedia_aud_dev_cap cap, const void *pval) 
     893{ 
     894        // struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
     895        return PJ_SUCCESS; 
     896} 
     897 
     898static pj_status_t 
     899stream_start(pjmedia_aud_stream *s) 
     900{ 
     901        struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
     902        tapi_ctx *dev_ctx = strm->dev_ctx; 
     903        pj_uint32_t dev_idx; 
     904 
     905        TRACE_((THIS_FILE, "stream_start()")); 
     906 
     907        dev_idx = strm->param.rec_id; 
     908 
     909        return PJ_SUCCESS; 
     910} 
     911 
     912static pj_status_t 
     913stream_stop(pjmedia_aud_stream *s) 
     914{ 
     915        struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
     916        tapi_ctx *dev_ctx = strm->dev_ctx; 
     917        pj_uint32_t dev_idx; 
     918 
     919        TRACE_((THIS_FILE, "stream_stop()")); 
     920        dev_idx = strm->param.rec_id; 
     921 
     922        if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 0) != PJ_SUCCESS) { 
     923                TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
     924                return PJ_EUNKNOWN; 
     925        } 
     926 
     927        return PJ_SUCCESS; 
     928} 
     929 
     930static pj_status_t 
     931stream_destroy(pjmedia_aud_stream *s) 
     932{ 
     933        pj_status_t state = PJ_SUCCESS; 
     934        struct tapi_aud_stream *stream = (struct tapi_aud_stream*)s; 
     935        pj_pool_t *pool; 
     936 
     937        PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 
     938        TRACE_((THIS_FILE, "stream_destroy()")); 
     939 
     940        stream_stop(stream); 
     941        stream->run_flag = 0; 
     942 
     943        if (stream->thread) 
     944        { 
     945                pj_thread_join(stream->thread); 
     946                pj_thread_destroy(stream->thread); 
     947                stream->thread = NULL; 
     948        } 
     949 
     950        pool = stream->pool; 
     951        pj_bzero(stream, sizeof(stream)); 
     952        pj_pool_release(pool); 
     953 
     954        return state; 
     955} 
     956 
     957pj_status_t 
     958tapi_hook_status(pj_uint32_t port, pj_uint32_t *status) 
     959{ 
     960        if (ioctl(ch_fd[port], IFX_TAPI_LINE_HOOK_STATUS_GET, status) 
     961                        != PJ_SUCCESS) { 
     962                TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed!")); 
     963                return PJ_EUNKNOWN; 
     964        } 
     965                 
     966        return PJ_SUCCESS; 
     967} 
     968 
     969pj_status_t 
     970tapi_ring(pj_uint32_t port, pj_uint32_t state, char *caller_number) { 
     971        PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); 
     972 
     973        if (state) { 
     974                if (caller_number) { 
     975                        IFX_TAPI_CID_MSG_t cid_msg; 
     976                        IFX_TAPI_CID_MSG_ELEMENT_t cid_msg_el[1]; 
     977                        memset(&cid_msg, 0, sizeof(cid_msg)); 
     978                        memset(&cid_msg_el, 0, sizeof(cid_msg_el)); 
     979 
     980                        cid_msg_el[0].string.elementType = IFX_TAPI_CID_ST_CLI; 
     981                        cid_msg_el[0].string.len = strlen(caller_number); 
     982                        strncpy(cid_msg_el[0].string.element, caller_number, sizeof(cid_msg_el[0].string.element)); 
     983 
     984                        cid_msg.txMode = IFX_TAPI_CID_HM_ONHOOK; 
     985                        cid_msg.messageType = IFX_TAPI_CID_MT_CSUP; 
     986                        cid_msg.nMsgElements = 1; 
     987                        cid_msg.message = cid_msg_el; 
     988                        ioctl(ch_fd[port], IFX_TAPI_CID_TX_SEQ_START, &cid_msg); 
     989                } else { 
     990                        ioctl(ch_fd[port], IFX_TAPI_RING_START, 0); 
     991                } 
     992        } else { 
     993                ioctl(ch_fd[port], IFX_TAPI_RING_STOP, 0); 
     994        } 
     995 
     996        return PJ_SUCCESS; 
     997} 
     998 
     999pj_status_t 
     1000tapi_dial_tone(pj_uint32_t port) { 
     1001        PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); 
     1002 
     1003        ioctl(ch_fd[port], IFX_TAPI_TONE_DIALTONE_PLAY, 0); 
     1004 
     1005        return PJ_SUCCESS; 
     1006} 
     1007 
     1008pj_status_t 
     1009tapi_no_tone(pj_uint32_t port) { 
     1010        PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); 
     1011 
     1012        ioctl(ch_fd[port], IFX_TAPI_TONE_LOCAL_PLAY, 0); 
     1013 
     1014        return PJ_SUCCESS; 
     1015} 
     1016 
    9291017#endif 
    930 } 
    931  
    932 /* API: set capability */ 
    933 static pj_status_t stream_set_cap(pjmedia_aud_stream *s, 
    934           pjmedia_aud_dev_cap cap, 
    935           const void *pval) 
    936 { 
    937   struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
    938 #ifdef OLD_IMPL 
    939   OSStatus status = 0; 
    940   PJ_ASSERT_RETURN(strm && pval, PJ_EINVAL); 
    941  
    942   if (strm->play_strm->queue) 
    943     switch (cap) 
    944     { 
    945       case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING: 
    946       { 
    947         /* Output volume setting */ 
    948         unsigned vol = *(unsigned*)pval; 
    949         Float32 volume; 
    950  
    951         if (vol > 100) 
    952           vol = 100; 
    953         volume = vol / 100.; 
    954         status = AudioQueueSetParameter(strm->play_strm->queue, kAudioQueueParam_Volume, 
    955                                         volume); 
    956         if (!status) 
    957         { 
    958           PJ_LOG(1, (THIS_FILE, "AudioQueueSetParameter err %d", status)); 
    959           return PJMEDIA_EAUD_SYSERR; 
    960         } 
    961         strm->param.output_vol = *(unsigned*)pval; 
    962         return PJ_SUCCESS; 
    963       } 
    964       case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE: 
    965       { 
    966         pjmedia_aud_dev_route r = *(const pjmedia_aud_dev_route*)pval; 
    967         UInt32 route = (r == PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER ? 
    968             kAudioSessionOverrideAudioRoute_Speaker : 
    969             kAudioSessionOverrideAudioRoute_None); 
    970  
    971         status = AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, 
    972                                           sizeof(route), &route); 
    973         if (status) 
    974         { 
    975           PJ_LOG(1, (THIS_FILE, "AudioSessionSetProperty err %d", status)); 
    976           return PJMEDIA_EAUD_SYSERR; 
    977         } 
    978         strm->param.output_route = r; 
    979         return PJ_SUCCESS; 
    980       } 
    981       default: 
    982         return PJMEDIA_EAUD_INVCAP; 
    983     } 
    984  
    985  
    986   return PJMEDIA_EAUD_INVCAP; 
    987 #else 
    988   return PJ_SUCCESS; 
    989 #endif 
    990 } 
    991  
    992 /* API: Start stream. */ 
    993 static pj_status_t stream_start(pjmedia_aud_stream *s) 
    994 { 
    995    struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
    996    tapi_ctx *dev_ctx = strm->dev_ctx; 
    997    pj_uint32_t dev_idx; 
    998  
    999    TRACE_((THIS_FILE, "stream_start()")); 
    1000  
    1001    dev_idx = strm->param.rec_id; 
    1002  
    1003    return PJ_SUCCESS; 
    1004 } 
    1005  
    1006 /* API: Stop stream. */ 
    1007 static pj_status_t stream_stop(pjmedia_aud_stream *s) 
    1008 { 
    1009    struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; 
    1010    tapi_ctx *dev_ctx = strm->dev_ctx; 
    1011    pj_uint32_t dev_idx; 
    1012  
    1013    TRACE_((THIS_FILE, "stream_stop()")); 
    1014  
    1015    dev_idx = strm->param.rec_id; 
    1016  
    1017    /* enc/dec stop*/ 
    1018    if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 0) != PJ_SUCCESS) { 
    1019       TRACE_((THIS_FILE, "ERROR - codec start failed!")); 
    1020  
    1021       return PJ_EUNKNOWN; 
    1022    } 
    1023  
    1024    return PJ_SUCCESS; 
    1025 } 
    1026  
    1027 /* API: Destroy stream. */ 
    1028 static pj_status_t stream_destroy(pjmedia_aud_stream *s) 
    1029 { 
    1030    pj_status_t state = PJ_SUCCESS; 
    1031    struct tapi_aud_stream *stream = (struct tapi_aud_stream*)s; 
    1032    pj_pool_t *pool; 
    1033  
    1034    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 
    1035  
    1036    TRACE_((THIS_FILE, "stream_destroy()")); 
    1037  
    1038    stream_stop(stream); 
    1039  
    1040    stream->run_flag = 0; 
    1041  
    1042    /* Stop the stream thread */ 
    1043    if (stream->thread) 
    1044    { 
    1045       pj_thread_join(stream->thread); 
    1046       pj_thread_destroy(stream->thread); 
    1047       stream->thread = NULL; 
    1048    } 
    1049  
    1050    pool = stream->pool; 
    1051    pj_bzero(stream, sizeof(stream)); 
    1052    pj_pool_release(pool); 
    1053  
    1054    return state; 
    1055 } 
    1056  
    1057 #endif /* PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE */ 
Note: See TracChangeset for help on using the changeset viewer.