PJSip在iPhone中发出通话问题

时间:2016-07-04 11:10:35

标签: voip pjsip

当我尝试使用以下代码拨打电话时。

-(int)make_callWithURI:(char *) destURI{
/* Make call! : */
pj_str_t tmp;
pj_status_t status;

int regid = app_config.account_id;

int callNo = -1;

tmp = pj_str(destURI);

status = pjsua_call_make_call( regid, &tmp, 0, NULL, NULL, &callNo);

if (status != PJ_SUCCESS){
    error_exit("Error making call", status);
    return -1;
}

return callNo;

}

但是在pjsua_call_make_call()行获取信号SIGABRT

错误日志::

  1. 16:18:04.376 pjsua_call.c!拨打acc#0来拨打:mobile_number @ sip_ip:port
  2. 16:18:04.376 pjsua_aud.c。设置声音设备:capture = -1,playback = -2
  3. 16:18:04.376 pjsua_aud.c ..打开音响设备(扬声器+麦克风)PCM @ 16000/1 / 20ms
  4. 16:18:04.376 coreaudio_dev。 ...使用VoiceProcessingIO音频单元
  5. 16:18:04.378 tsx0x14e0cc8a8!超时计时器事件
  6. 16:18:04.379 tsx0x14e0cc8a8。State已从Completed更改为Terminated,event = TIMER
  7. 16:18:04.379 tsx0x14e0cd0a8超时计时器事件
  8. 16:18:04.379 tsx0x14e0cd0a8。State已从Completed更改为Terminated,event = TIMER
  9. 16:18:04.858 coreaudio_dev。 !...核心音频流开始
  10. 16:18:04.862 dlg0x14d8000a8。创建了UAC对话框
  11. 16:18:04.862 dlg0x14d8000a8 .. mod-pjsua的会议数量为2

  12. 列出项目

  13. ** 16:18:04.862 pjsua_call.c。错误初始化媒体频道:对象正忙(PJ_EBUSY)[status = 70011]

    16:18:04.862 dlg0x14d8000a8 ..会议计数由mod-pjsua决定为1

    16:18:04.862 dlg0x14d8000a8 .Dialog被摧毁

    16:18:04.863 pjsua_media.c。电话0:取消媒体宣传..

    断言失败:(entry-> cb!=((void *)0)),函数schedule_w_grp_lock,file ../src/pj/timer.c,第501行。**

    请告诉我为什么会出现这个问题。我已使用默认配置初始化媒体:

    //initialize media config with default configuration
    pjsua_media_config_default(&cfg->pjsua_media_cfg);
    

1 个答案:

答案 0 :(得分:0)

**> Please check this registration  scenarios**

    pj_status_t sip_startup(app_config_t *app_config)
    {
      pj_status_t status;
      long val;
      char tmp[80];
      pjsua_transport_id transport_id = -1;
      const char *srv;
          const char *ip_addr;

      NSArray * array;
      NSString *dns;

      SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];

      /* Create pjsua first! */
      status = pjsua_create();
      if (status != PJ_SUCCESS)
        return status;

      /* Create pool for application */
      app_config->pool = pjsua_pool_create("pjsua", 1000, 1000);

      /* Initialize default config */
      pjsua_config_default(&(app_config->cfg));
      pj_ansi_snprintf(tmp, 80, "Siphon PjSip v%s/%s", pj_get_version(), PJ_OS_NAME);
      pj_strdup2_with_null(app_config->pool, &(app_config->cfg.user_agent), tmp);

      pjsua_logging_config_default(&(app_config->log_cfg));

      val = [[NSUserDefaults standardUserDefaults] integerForKey: 
             @"logLevel"];
    #ifdef RELEASE_VERSION
      app_config->log_cfg.msg_logging = PJ_FALSE;
      app_config->log_cfg.console_level = 0;
      app_config->log_cfg.level = 0;
    #else  
      app_config->log_cfg.msg_logging = (val!=0 ? PJ_TRUE : PJ_FALSE);
      app_config->log_cfg.console_level = val;
      app_config->log_cfg.level = val;
      if (val != 0)
      {
    #if defined(CYDIA) && (CYDIA == 1)
        NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
        NSString *path = [NSString stringWithFormat:@"%@/Siphon", [filePaths objectAtIndex:0]];
    #else
        NSArray *filePaths =    NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, 
                                                                   NSUserDomainMask,
                                                                   YES); 
            NSString *path = [filePaths objectAtIndex: 0];
    #endif
        //NSString *path = NSTemporaryDirectory();
        path = [path stringByAppendingString: @"/log.txt"];

        app_config->log_cfg.log_filename = pj_strdup3(app_config->pool, 
                                                      [path UTF8String]);
      }
    #endif

      pjsua_media_config_default(&(app_config->media_cfg));

      // TODO select clock rate with enabled codec (8000 if nb codec only, or 16000 and more if wb codec)
      //app_config->media_cfg.clock_rate = 8000;
      //app_config->media_cfg.snd_clock_rate = 8000;
      app_config->media_cfg.clock_rate = 16000;
      app_config->media_cfg.snd_clock_rate = 16000;
      //app_config->media_cfg.ec_options = 0;//0=default,1=speex, 2=suppressor

      if (![[NSUserDefaults standardUserDefaults] boolForKey:@"enableEC"])
        app_config->media_cfg.ec_tail_len = 0;

      // Enable/Disable VAD/silence detector
      app_config->media_cfg.no_vad = [[NSUserDefaults standardUserDefaults] 
                                      boolForKey:@"disableVad"];

      app_config->media_cfg.snd_auto_close_time = 0;
      //app_config->media_cfg.quality = 2;
      //app_config->media_cfg.channel_count = 2;

      app_config->media_cfg.enable_ice = [[NSUserDefaults standardUserDefaults] 
                                          boolForKey:@"enableICE"];

      pjsua_transport_config_default(&(app_config->udp_cfg));
      val = [[NSUserDefaults standardUserDefaults] integerForKey: @"localPort"];
      if (val < 0 || val > 65535)
      {
        PJ_LOG(1,(THIS_FILE, 
          "Error: local-port argument value (expecting 0-65535"));
        [app displayParameterError:
         @"Invalid value for Local Port (expecting 1-65535)."];

        status = PJ_EINVAL;
        goto error;
      }
      app_config->udp_cfg.port = val;

      pjsua_transport_config_default(&(app_config->rtp_cfg));
      app_config->rtp_cfg.port = [[NSUserDefaults standardUserDefaults] 
        integerForKey: @"rtpPort"];  
      if (app_config->rtp_cfg.port == 0) 
      {
        enum { START_PORT=4000 };
        unsigned range;

        range = (65535-START_PORT-PJSUA_MAX_CALLS*4);
        app_config->rtp_cfg.port = START_PORT + 
                ((pj_rand() % range) & 0xFFFE);
      }

      if (app_config->rtp_cfg.port < 1 || app_config->rtp_cfg.port > 65535) 
      {
        PJ_LOG(1,(THIS_FILE,
            "Error: rtp-port argument value (expecting 1-65535)"));
        [app displayParameterError:
         @"Invalid value for RTP port (expecting 1-65535)."];
        status = PJ_EINVAL;
        goto error;
      }

    #if 1 // TEST pour le vpn
      ip_addr = [[[NSUserDefaults standardUserDefaults] stringForKey: 
                  @"boundAddr"] UTF8String];
      if (ip_addr && strlen(ip_addr))
      {
        pj_strdup2_with_null(app_config->pool, 
                             &(app_config->udp_cfg.bound_addr), 
                             ip_addr);
        pj_strdup2_with_null(app_config->pool, 
                             &(app_config->rtp_cfg.bound_addr), 
                             ip_addr);
      }

      ip_addr = [[[NSUserDefaults standardUserDefaults] stringForKey: 
                  @"publicAddr"] UTF8String];
      if (ip_addr && strlen(ip_addr))
      {
        pj_strdup2_with_null(app_config->pool, 
                             &(app_config->udp_cfg.public_addr), 
                             ip_addr);
        pj_strdup2_with_null(app_config->pool, 
                             &(app_config->rtp_cfg.public_addr), 
                             ip_addr);
      }
    #endif

      /* Initialize application callbacks */
      app_config->cfg.cb.on_call_state = &on_call_state;
      app_config->cfg.cb.on_call_media_state = &on_call_media_state;
      app_config->cfg.cb.on_incoming_call = &on_incoming_call;
      app_config->cfg.cb.on_reg_state = &on_reg_state;
    #if defined(MWI) && MWI==1
      app_config->cfg.cb.on_mwi_info = &on_mwi_info;
      app_config->cfg.enable_unsolicited_mwi = PJ_TRUE;
    #endif

      srv = [[[NSUserDefaults standardUserDefaults] stringForKey: 
                  @"stunServer"] UTF8String];
      if (srv && strlen(srv))
      {
        if (app_config->cfg.stun_srv_cnt==PJ_ARRAY_SIZE(app_config->cfg.stun_srv)) 
        {
          PJ_LOG(1,(THIS_FILE, "Error: too many STUN servers"));
          return PJ_ETOOMANY;
        }
        pj_strdup2_with_null(app_config->pool, 
                             &(app_config->cfg.stun_srv[app_config->cfg.stun_srv_cnt++]), 
                             srv);
      }

     // app_config->cfg.outbound_proxy[0] = pj_str(outbound_proxy);
     // app_config->cfg.outbound_proxy_cnt = 1;

      dns = [[NSUserDefaults standardUserDefaults] stringForKey: @"dnsServer"];
      array = [dns componentsSeparatedByString:@","];
      NSEnumerator *enumerator = [array objectEnumerator];
      NSString *anObject;
      while (anObject = [enumerator nextObject])
      {
        NSMutableString *mutableStr = [anObject mutableCopy];
        CFStringTrimWhitespace((CFMutableStringRef)mutableStr);
        srv = [mutableStr UTF8String];
        if (srv && strlen(srv))
        {
          if (app_config->cfg.nameserver_count==PJ_ARRAY_SIZE(app_config->cfg.nameserver)) 
          {
            PJ_LOG(1,(THIS_FILE, "Error: too many DNS servers"));
            [mutableStr release];
            break;
          }
          pj_strdup2_with_null(app_config->pool, 
                               &(app_config->cfg.nameserver[app_config->cfg.nameserver_count++]), 
                               srv);
        }
          [mutableStr release];
      }
      //[enumerator release];
      //[array release];

      /* Initialize pjsua */
      status = pjsua_init(&app_config->cfg, &app_config->log_cfg, 
        &app_config->media_cfg);
      if (status != PJ_SUCCESS)
        goto error;

      /* Initialize Ring and Ringback */
      sip_ring_init(app_config);

      /* Add UDP transport. */
      status = pjsua_transport_create(PJSIP_TRANSPORT_UDP,
              &app_config->udp_cfg, &transport_id);
      if (status != PJ_SUCCESS)
        goto error;

      /* Add RTP transports */
     // status = pjsua_media_transports_create(&app_config->rtp_cfg);
     // if (status != PJ_SUCCESS)
      //  goto error;

    #if LOCAL_ACCOUNT
      {
        if (status == PJ_SUCCESS  && transport_id != -1)
        {
          /* Add local account */
          pjsua_acc_add_local(transport_id, PJ_TRUE, &aid);
        }
      }
    #endif

      /* */
      sip_manage_codec();

      /* Initialization is done, now start pjsua */
      status = pjsua_start();
      if (status != PJ_SUCCESS)
        goto error;

      return status;
    error:
      sip_cleanup(app_config);
      return status;
    }



/* */
pj_status_t sip_cleanup(app_config_t *app_config)
{
  pj_status_t status;

  /* Cleanup Ring and Ringback */
  sip_ring_deinit(app_config);

  if (app_config->pool) 
  {
    pj_pool_release(app_config->pool);
    app_config->pool = NULL;
  }

  /* Destroy pjsua */
  status = pjsua_destroy();

  pj_bzero(app_config, sizeof(app_config_t));

  return status;

}

/* */
pj_status_t sip_connect(pj_pool_t *pool, pjsua_acc_id *acc_id)
{
  pj_status_t status;
  pjsua_acc_config acc_cfg;
  const char *uname;
  const char *authname;
  const char *contactname;
  const char *passwd;
  const char *server;

  SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];

  // TODO Verify if wifi is connected, if not verify if user wants edge connection 

  uname  = [[[NSUserDefaults standardUserDefaults] stringForKey: 
             @"username"] UTF8String];
  authname  = [[[NSUserDefaults standardUserDefaults] stringForKey: 
                @"authname"] UTF8String];
  contactname  = [[[NSUserDefaults standardUserDefaults] stringForKey: 
                @"contact"] UTF8String];
  passwd = [[[NSUserDefaults standardUserDefaults] stringForKey: 
             @"password"] UTF8String];
  server = [[[NSUserDefaults standardUserDefaults] stringForKey: 
             @"server"] UTF8String];

  pjsua_acc_config_default(&acc_cfg);

  // ID
  acc_cfg.id.ptr = (char*) pj_pool_alloc(/*app_config.*/pool, PJSIP_MAX_URL_SIZE);
  if (contactname && strlen(contactname))
    acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE, 
                                       "\"%s\"<sip:%s@%s>", contactname, uname, server);
  else
    acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE, 
                                       "sip:%s@%s", uname, server);
  if ((status = pjsua_verify_sip_url(acc_cfg.id.ptr)) != 0) 
  {
    PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in local id argument", 
      acc_cfg.id));
    [app displayParameterError: @"Invalid value for username or server."];
    return status;
  }

  // Registrar
  acc_cfg.reg_uri.ptr = (char*) pj_pool_alloc(/*app_config.*/pool, 
    PJSIP_MAX_URL_SIZE);
  acc_cfg.reg_uri.slen = pj_ansi_snprintf(acc_cfg.reg_uri.ptr, 
    PJSIP_MAX_URL_SIZE, "sip:%s", server);
  if ((status = pjsua_verify_sip_url(acc_cfg.reg_uri.ptr)) != 0) 
  {
    PJ_LOG(1,(THIS_FILE,  "Error: invalid SIP URL '%s' in registrar argument",
      acc_cfg.reg_uri));
    [app displayParameterError: @"Invalid value for server parameter."];
    return status;
  }

  //acc_cfg.id = pj_str(id);
  //acc_cfg.reg_uri = pj_str(registrar);
  acc_cfg.cred_count = 1;
  acc_cfg.cred_info[0].scheme = pj_str("Digest");
  acc_cfg.cred_info[0].realm = pj_str("*");//pj_str(realm);
  if (authname && strlen(authname))
    acc_cfg.cred_info[0].username = pj_str((char *)authname);
  else
    acc_cfg.cred_info[0].username = pj_str((char *)uname);
  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableMJ"])
    acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_DIGEST;
  else
    acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
  acc_cfg.cred_info[0].data = pj_str((char *)passwd);

  acc_cfg.publish_enabled = PJ_TRUE;
#if defined(MWI) && MWI==1
  acc_cfg.mwi_enabled = PJ_TRUE;
#endif

  acc_cfg.allow_contact_rewrite = [[NSUserDefaults standardUserDefaults] 
                                   boolForKey:@"enableNat"];

  // FIXME: gestion du message 423 dans pjsip
  acc_cfg.reg_timeout = [[NSUserDefaults standardUserDefaults] integerForKey: 
    @"regTimeout"];

  if (acc_cfg.reg_timeout < 1 || acc_cfg.reg_timeout > 3600) 
  {
    PJ_LOG(1,(THIS_FILE, 
      "Error: invalid value for timeout (expecting 1-3600)"));
    [app displayParameterError: 
          @"Invalid value for timeout (expecting 1-3600)."];
    return PJ_EINVAL;
  }

  // Keep alive interval
  acc_cfg.ka_interval = [[NSUserDefaults standardUserDefaults] integerForKey: 
                    @"kaInterval"];

  // proxies server
  NSString *proxies = [[NSUserDefaults standardUserDefaults] stringForKey: @"proxyServer"];
  NSArray *array = [proxies componentsSeparatedByString:@","];
  NSEnumerator *enumerator = [array objectEnumerator];
  NSString *anObject;
  while (anObject = [enumerator nextObject])
  {
    NSMutableString *mutableStr = [anObject mutableCopy];
    CFStringTrimWhitespace((CFMutableStringRef)mutableStr);
    const char *proxy = [mutableStr UTF8String];
    if (proxy && strlen(proxy))
    {
      if (acc_cfg.proxy_cnt==PJ_ARRAY_SIZE(acc_cfg.proxy)) 
      {
        PJ_LOG(1,(THIS_FILE, "Error: too many proxy servers"));
        [mutableStr release];
        break;
      }
      pj_str_t pj_proxy;
      pj_proxy.slen = strlen(proxy) + 8;
      pj_proxy.ptr = (char*) pj_pool_alloc(pool, pj_proxy.slen);
      pj_proxy.slen = pj_ansi_snprintf(pj_proxy.ptr, pj_proxy.slen, "sip:%s;lr", proxy);
      if ((status = pjsua_verify_sip_url(pj_proxy.ptr)) != 0) 
      {
        PJ_LOG(1,(THIS_FILE,  "Error: invalid SIP URL '%*.s' in proxy argument (%d)",
                  pj_proxy.slen, pj_proxy.ptr, status));
        [mutableStr release];
        [app displayParameterError: @"Invalid value for proxy parameter."];
        continue;
      }
      acc_cfg.proxy[acc_cfg.proxy_cnt++] = pj_proxy;
    }
    [mutableStr release];
  }

#if LOCAL_ACCOUNT 
 *acc_id = aid;
#else
  status = pjsua_acc_add(&acc_cfg, PJ_TRUE, acc_id);
  if (status != PJ_SUCCESS) 
  {
    pjsua_perror(THIS_FILE, "Error adding new account", status);
    [app displayParameterError: @"Error adding new account."];
  }
#endif  
  return status;
}

/* */
pj_status_t sip_disconnect(pjsua_acc_id *acc_id)
{
  pj_status_t status = PJ_SUCCESS;

  if (pjsua_acc_is_valid(*acc_id))
  {
    status = pjsua_acc_del(*acc_id);
    if (status == PJ_SUCCESS)
      *acc_id = PJSUA_INVALID_ID;
  }

  return status;
}

/* */
pj_status_t sip_dial_with_uri(pjsua_acc_id acc_id, const char *uri, 
                     pjsua_call_id *call_id)
{
  // FIXME: récupérer le domain à partir du compte (acc_id);
  // TODO be careful app already mustn't be in communication!
  // TODO if not SIP connected, use GSM ? NSURL with 'tel' protocol
  pj_status_t status = PJ_SUCCESS;
  pj_str_t pj_uri;

//  pjsua_msg_data msg_data;
//  pjsip_generic_string_hdr subject;
//  pj_str_t hvalue, hname;

  PJ_LOG(5,(THIS_FILE,  "Calling URI \"%s\".", uri));

  status = pjsua_verify_sip_url(uri);
  if (status != PJ_SUCCESS) 
  {
    PJ_LOG(1,(THIS_FILE,  "Invalid URL \"%s\".", uri));
    pjsua_perror(THIS_FILE, "Invalid URL", status);
    return status;
  }

  pj_uri = pj_str((char *)uri);
 //status = pjsua_set_null_snd_dev();

  status =  pjsua_snd_is_active();

//  hname = pj_str("Subject");
//  hvalue = pj_str("phone call");
//  
//  pjsua_msg_data_init(&msg_data);
//  pjsip_generic_string_hdr_init2(&subject, &hname, &hvalue);
//  pj_list_push_back(&msg_data.hdr_list, &subject);
//
//  status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, &msg_data, call_id);
  status = pjsua_call_make_call(acc_id, &pj_uri, 0, NULL, NULL, call_id);
  if (status != PJ_SUCCESS)
  {
    pjsua_perror(THIS_FILE, "Error making call", status);
  }

  return status;
}

pj_status_t sip_dial(pjsua_acc_id acc_id, const char *number, 
  pjsua_call_id *call_id)
{
  // FIXME: récupérer le domain à partir du compte (acc_id);f
  // TODO be careful app already mustn't be in communication!
  // TODO if not SIP connected, use GSM ? NSURL with 'tel' protocol
  char uri[256];
  const char *sip_domain;

  sip_domain = [[[NSUserDefaults standardUserDefaults] stringForKey: 
    @"server"] UTF8String];

  pj_ansi_snprintf(uri, 256, "sip:%s@%s", number, sip_domain);
  return sip_dial_with_uri(acc_id, uri, call_id);
}

/* */
pj_status_t sip_answer(pjsua_call_id *call_id)
{
  pj_status_t status;
    status = pjsua_set_null_snd_dev();

  status = pjsua_call_answer(*call_id, 200, NULL, NULL);
  if (status != PJ_SUCCESS)
  {
    *call_id = PJSUA_INVALID_ID;
  }

  return status;
}

/* */
pj_status_t sip_hangup(pjsua_call_id *call_id)
{
  pj_status_t status = PJ_SUCCESS;

  //pjsua_call_hangup_all();
  /* TODO Hangup current calls */
  if (*call_id != PJSUA_INVALID_ID)
    status = pjsua_call_hangup(*call_id, 0, NULL, NULL);
  *call_id = PJSUA_INVALID_ID;

  return status;
}

#if SETTINGS
/* */
pj_status_t sip_add_account(NSDictionary *account, pjsua_acc_id *acc_id)
{
  pj_status_t status;
  pjsua_acc_config acc_cfg;
  const char *uname;
  const char *passwd;
  const char *server;
  const char *proxy;

  SiphonApplication *app = (SiphonApplication *)[SiphonApplication sharedApplication];
  app_config_t *app_config = [app pjsipConfig];

  // TODO Verify if wifi is connected, if not verify if user wants edge connection 

  uname  = [[account objectForKey: @"username"] UTF8String];
  passwd = [[account objectForKey: @"password"] UTF8String];
  server = [[account objectForKey: @"server"] UTF8String];
  proxy  = [[account objectForKey: @"proxyServer"] UTF8String];

  pjsua_acc_config_default(&acc_cfg);

  // ID
  acc_cfg.id.ptr = (char*) pj_pool_alloc(app_config->pool, PJSIP_MAX_URL_SIZE);
  acc_cfg.id.slen = pj_ansi_snprintf(acc_cfg.id.ptr, PJSIP_MAX_URL_SIZE, 
                                     "sip:%s@%s", uname, server);
  // FIXME : verify in settings view
  if ((status = pjsua_verify_sip_url(acc_cfg.id.ptr)) != 0) 
  {
    PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' in local id argument", 
              acc_cfg.id));
    [app displayParameterError: @"Invalid value for username or server."];
    return status;
  }

  // Registrar
  acc_cfg.reg_uri.ptr = (char*) pj_pool_alloc(app_config->pool, 
                                              PJSIP_MAX_URL_SIZE);
  acc_cfg.reg_uri.slen = pj_ansi_snprintf(acc_cfg.reg_uri.ptr, 
                                          PJSIP_MAX_URL_SIZE, "sip:%s", server);
  // FIXME : verify in settings view
  if ((status = pjsua_verify_sip_url(acc_cfg.reg_uri.ptr)) != 0) 
  {
    PJ_LOG(1,(THIS_FILE,  "Error: invalid SIP URL '%s' in registrar argument",
              acc_cfg.reg_uri));
    [app displayParameterError: @"Invalid value for server parameter."];
    return status;
  }

  //acc_cfg.id = pj_str(id);
  //acc_cfg.reg_uri = pj_str(registrar);
  acc_cfg.cred_count = 1;
  acc_cfg.cred_info[0].scheme = pj_str("Digest");
  acc_cfg.cred_info[0].realm = pj_str("*");//pj_str(realm);
  acc_cfg.cred_info[0].username = pj_str((char *)uname);
  acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
  acc_cfg.cred_info[0].data = pj_str((char *)passwd);

  acc_cfg.publish_enabled = PJ_TRUE;

  acc_cfg.allow_contact_rewrite = [[account objectForKey:@"enableNat"] boolValue];

  // FIXME: gestion du message 423 dans pjsip
  acc_cfg.reg_timeout = [[account objectForKey: @"regTimeout"] intValue];
  // FIXME : verify in settings view
  if (acc_cfg.reg_timeout < 1 || acc_cfg.reg_timeout > 3600) 
  {
    PJ_LOG(1,(THIS_FILE, 
              "Error: invalid value for timeout (expecting 1-3600)"));
    [app displayParameterError: 
     @"Invalid value for timeout (expecting 1-3600)."];
    return PJ_EINVAL;
  }

  pj_str_t pj_proxy = pj_str((char *)proxy);
  if (pj_strlen(&pj_proxy) > 0)
  {
    acc_cfg.proxy[0].ptr = (char*) pj_pool_alloc(app_config->pool, 
                                                 PJSIP_MAX_URL_SIZE);
    acc_cfg.proxy[0].slen = pj_ansi_snprintf(acc_cfg.proxy[0].ptr, 
                                             PJSIP_MAX_URL_SIZE, "sip:%s;lr", proxy);
    // FIXME verify in settings view
    if ((status = pjsua_verify_sip_url(acc_cfg.proxy[0].ptr)) != 0) 
    {
      PJ_LOG(1,(THIS_FILE,  "Error: invalid SIP URL '%s' in proxy argument",
                acc_cfg.reg_uri));
      [app displayParameterError: @"Invalid value for proxy parameter."];
      return status;
    }
    acc_cfg.proxy_cnt = 1;
  }

  status = pjsua_acc_add(&acc_cfg, PJ_TRUE, acc_id);
  if (status != PJ_SUCCESS) 
  {
    pjsua_perror(THIS_FILE, "Error adding new account", status);
    [app displayParameterError: @"Error adding new account."];
  }

  return status;
}
#endif