+ pj_uint8_t c, hook_status;
+ pj_status_t status = PJ_SUCCESS;
+ IFX_TAPI_DEV_START_CFG_t tapistart;
+ IFX_TAPI_MAP_DATA_t datamap;
+ IFX_TAPI_ENC_CFG_t enc_cfg;
+ IFX_TAPI_LINE_VOLUME_t line_vol;
+ IFX_TAPI_CID_CFG_t cid_cnf;
+
+ /* Open device */
+ f->dev_ctx.dev_fd = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, 0);
+
+ if (f->dev_ctx.dev_fd < 0) {
+ TRACE_((THIS_FILE, "ERROR - TAPI device open failed!"));
+ return PJ_EUNKNOWN;
+ }
+
+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) {
+ ch_fd[c] = f->dev_ctx.ch_fd[c] = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, TAPI_AUDIO_PORT_NUM - c);
+
+ if (f->dev_ctx.dev_fd < 0) {
+ TRACE_((THIS_FILE, "ERROR - TAPI channel%d open failed!", c));
+ return PJ_EUNKNOWN;
+ }
+ f->dev_ctx.data2phone_map[c] = c & 0x1 ? 0 : 1;
+ }
+
+ status = tapi_dev_firmware_download(f->dev_ctx.dev_fd, TAPI_LL_DEV_FIRMWARE_NAME);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - Voice Firmware Download failed!"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* Download coefficients */
+ /*
+ status = tapi_dev_bbd_download(f->dev_ctx.dev_fd, TAPI_LL_BBD_NAME);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - Voice Coefficients Download failed!"));
+ return PJ_EUNKNOWN;
+ }
+ */
+
+ memset(&tapistart, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t));
+ tapistart.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER;
+
+ /* Start TAPI */
+ status = ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_START, &tapistart);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_START ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+
+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) {
+ /* Perform mapping */
+ memset(&datamap, 0x0, sizeof(IFX_TAPI_MAP_DATA_t));
+ datamap.nDstCh = f->dev_ctx.data2phone_map[c];
+ datamap.nChType = IFX_TAPI_MAP_TYPE_PHONE;
+
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &datamap);
+
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_MAP_DATA_ADD ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* Set Line feed */
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY);
+
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* Configure encoder for linear stream */
+ memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t));
+
+ enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20;
+ enc_cfg.nEncType = IFX_TAPI_COD_TYPE_LIN16_8;
+
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_CFG_SET ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* Suppress TAPI volume, otherwise PJSIP starts autogeneration!!! */
+ line_vol.nGainRx = -8;
+ line_vol.nGainTx = -8;
+
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &line_vol);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_PHONE_VOLUME_SET ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* Configure Caller ID type */
+ /* One can choose from following (for now at compile time):
+ IFX_TAPI_CID_STD_TELCORDIA
+ IFX_TAPI_CID_STD_ETSI_FSK
+ IFX_TAPI_CID_STD_ETSI_DTMF
+ IFX_TAPI_CID_STD_SIN
+ IFX_TAPI_CID_STD_NTT
+ IFX_TAPI_CID_STD_KPN_DTMF
+ IFX_TAPI_CID_STD_KPN_DTMF_FSK
+ */
+ memset(&cid_cnf, 0, sizeof(cid_cnf));
+ cid_cnf.nStandard = IFX_TAPI_CID_STD_ETSI_FSK;
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_CID_CFG_SET, &cid_cnf);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_CID_CFG_SET ioctl failed"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* check hook status */
+ hook_status = 0;
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_HOOK_STATUS_GET, &hook_status);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed!"));
+ return PJ_EUNKNOWN;
+ }
+
+ /* if off hook do initialization */
+ if (hook_status) {
+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_ACTIVE);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!"));
+ return PJ_EUNKNOWN;
+ }
+ status = ioctl(c, IFX_TAPI_ENC_START, 0);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_START ioctl failed!"));
+ return PJ_EUNKNOWN;
+ }
+
+ status = ioctl(c, IFX_TAPI_DEC_START, 0);
+ if (status != PJ_SUCCESS) {
+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_START ioctl failed!"));
+ return PJ_EUNKNOWN;
+ }
+ }
+ }
+
+ return status;