#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "iniparser/iniparser.h"

#define Boolean     int
#define TRUE        1
#define FALSE       0
#define ALSA_DEF    "alsa,default"
#define ALSA_PLUGHW "alsa,plug:mixmic"
#define SPK_CONF    "/oem/etc/speaker.conf"
#define ACC_CONF    "/tmp/accounts"
#define SPHONE_MODULE_CONF  "/tmp/config"

struct sip_account
{
    char enable[8];
    char username[64];
    char authuser[64];
    char domain[128];
    char passwd[64];
    char server[128];
    char port[8];
    char reg_expires[8];
    char transport[8];
    char autoanswer[8];
    char sip_autoanswer[8];
    char ringfile[64];
    char nat_mode[16];
    char stun_server[64];
    char stun_port[8];
    char nat_username[64];
    char nat_password[64];
    char keepalive[8];
    char ka_interval[8];
};

struct sip_p2p
{
    char enable[8];
    char username[64];
    char auth[8];
    char transport[8];
    char autoanswer[8];
    char sip_autoanswer[8];
    char ringfile[64];
};

struct SPEAKER_CONF
{
    char hw_version[16];
    char dev_type[32];
    char version[16];
    char mac[16];
    char localport[8];
    char startport[8];
    char endport[8];
    char rtptimeout[8];
    char jbufftype[16];
    struct sip_account acc1;
    struct sip_account acc2;
    struct sip_account acc3;
    struct sip_p2p p2p;
    char g722[8];
    char alaw[8];
    char ulaw[8];
    char opus[8];
    char g729[8];
    char aec[8];
    char anr[8];
    char agc[8];
    char cng[8];
    char agc_max_gain[4];
    char agc_gate_threshold[4];
    char volume[4];
    char end_beep[4];
    char second_call[16];
};

/*
*   @cmd 执行命令
*   @value 命令结果指针
*   @lenth 存储结果长度
*/
int GetCmdValue(char *cmd, char *value, int lenth)
{
    bzero(value, lenth);
    FILE *fp = popen(cmd,"r");
    if(fp){
        fread(value, 1, lenth, fp);
        pclose(fp);
    } else {
        printf("Handle \"%s\" failed.\n", cmd);
        return FALSE;
    }
    return TRUE;
}

struct SPEAKER_CONF confParse()
{
    struct SPEAKER_CONF conf;
	dictionary * ini ;
	ini = iniparser_load(SPK_CONF);
	
    if (ini==NULL) {
        fprintf(stderr, "cannot parse file: %s\n", SPK_CONF);
        exit(-1);
    }
	strcpy(conf.dev_type, iniparser_getstring(ini, "system:model", ""));
	strcpy(conf.hw_version, iniparser_getstring(ini, "system:hard_version", ""));
	strcpy(conf.version, iniparser_getstring(ini, "system:firmware", ""));
    GetCmdValue("ifconfig eth0 | grep HWaddr | awk '{print $5}' | tr -d ':' | tr -d '\n'",conf.mac, sizeof(conf.mac));
	strcpy(conf.localport, iniparser_getstring(ini, "sip_advance:localport", ""));
	strcpy(conf.startport, iniparser_getstring(ini, "sip_advance:rtpstartport", ""));
	strcpy(conf.endport, iniparser_getstring(ini, "sip_advance:rtpendport", ""));
	strcpy(conf.rtptimeout, iniparser_getstring(ini, "sip_advance:rtptimeout", ""));
	strcpy(conf.jbufftype, iniparser_getstring(ini, "sip_advance:jbufftype", "off"));
	strcpy(conf.acc1.enable, iniparser_getstring(ini, "account_info_1:enable", "no"));
    if(strcmp(conf.acc1.enable, "yes") == 0)
    {
        strcpy(conf.acc1.username, iniparser_getstring(ini, "account_info_1:username", ""));
        strcpy(conf.acc1.authuser, iniparser_getstring(ini, "account_info_1:authuser", ""));
        if(strlen(conf.acc1.authuser) == 0)
        {
            strcpy(conf.acc1.authuser, conf.acc1.username);
        }
        GetCmdValue("sysconf /etc/speaker.conf get account_info_1 passwd", conf.acc1.passwd, sizeof(conf.acc1.passwd));
        //strcpy(conf.acc1.passwd, iniparser_getstring(ini, "account_info_1:passwd", ""));
        strcpy(conf.acc1.server, iniparser_getstring(ini, "account_info_1:server", ""));
        strcpy(conf.acc1.port, iniparser_getstring(ini, "account_info_1:port", ""));
        strcpy(conf.acc1.domain, iniparser_getstring(ini, "account_info_1:domain", ""));
        if(strlen(conf.acc1.domain) == 0)
        {
            strcpy(conf.acc1.domain, conf.acc1.server);
        }
        strcpy(conf.acc1.reg_expires, iniparser_getstring(ini, "account_info_1:reg_expires", ""));
        strcpy(conf.acc1.transport, iniparser_getstring(ini, "account_info_1:transport", ""));
        strcpy(conf.acc1.autoanswer, iniparser_getstring(ini, "account_info_1:autoanswer", ""));
        strcpy(conf.acc1.sip_autoanswer, iniparser_getstring(ini, "account_info_1:sip_autoanswer", "yes"));
        strcpy(conf.acc1.ringfile, iniparser_getstring(ini, "account_info_1:ringfile", ""));
        strcpy(conf.acc1.nat_mode, iniparser_getstring(ini, "account_info_1:nat_mode", "disabled"));
        strcpy(conf.acc1.stun_server, iniparser_getstring(ini, "account_info_1:stun_server", ""));
        strcpy(conf.acc1.stun_port, iniparser_getstring(ini, "account_info_1:stun_port", "3478"));
        strcpy(conf.acc1.nat_username, iniparser_getstring(ini, "account_info_1:nat_username", ""));
        strcpy(conf.acc1.nat_password, iniparser_getstring(ini, "account_info_1:nat_password", ""));
        strcpy(conf.acc1.keepalive, iniparser_getstring(ini, "account_info_1:keepalive", "yes"));
        strcpy(conf.acc1.ka_interval, iniparser_getstring(ini, "account_info_1:keepalive_interval", "30"));
    }
	
	strcpy(conf.acc2.enable, iniparser_getstring(ini, "account_info_2:enable", "no"));
    if(strcmp(conf.acc2.enable, "yes") == 0)
    {
        strcpy(conf.acc2.username, iniparser_getstring(ini, "account_info_2:username", ""));
        strcpy(conf.acc2.authuser, iniparser_getstring(ini, "account_info_2:authuser", ""));
        if(strlen(conf.acc2.authuser) == 0)
        {
            strcpy(conf.acc2.authuser, conf.acc2.username);
        }
        GetCmdValue("sysconf /etc/speaker.conf get account_info_2 passwd", conf.acc2.passwd, sizeof(conf.acc2.passwd));
        //strcpy(conf.acc2.passwd, iniparser_getstring(ini, "account_info_2:passwd", ""));
        strcpy(conf.acc2.server, iniparser_getstring(ini, "account_info_2:server", ""));
        strcpy(conf.acc2.port, iniparser_getstring(ini, "account_info_2:port", ""));
        strcpy(conf.acc2.domain, iniparser_getstring(ini, "account_info_2:domain", ""));
        if(strlen(conf.acc2.domain) == 0)
        {
            strcpy(conf.acc2.domain, conf.acc2.server);
        }
        strcpy(conf.acc2.reg_expires, iniparser_getstring(ini, "account_info_2:reg_expires", ""));
        strcpy(conf.acc2.transport, iniparser_getstring(ini, "account_info_2:transport", ""));
        strcpy(conf.acc2.autoanswer, iniparser_getstring(ini, "account_info_2:autoanswer", ""));
        strcpy(conf.acc2.sip_autoanswer, iniparser_getstring(ini, "account_info_2:sip_autoanswer", "yes"));
        strcpy(conf.acc2.ringfile, iniparser_getstring(ini, "account_info_2:ringfile", ""));
        strcpy(conf.acc2.nat_mode, iniparser_getstring(ini, "account_info_2:nat_mode", "disabled"));
        strcpy(conf.acc2.stun_server, iniparser_getstring(ini, "account_info_2:stun_server", ""));
        strcpy(conf.acc2.stun_port, iniparser_getstring(ini, "account_info_2:stun_port", "3478"));
        strcpy(conf.acc2.nat_username, iniparser_getstring(ini, "account_info_2:nat_username", ""));
        strcpy(conf.acc2.nat_password, iniparser_getstring(ini, "account_info_2:nat_password", ""));
        strcpy(conf.acc2.keepalive, iniparser_getstring(ini, "account_info_2:keepalive", "yes"));
        strcpy(conf.acc2.ka_interval, iniparser_getstring(ini, "account_info_2:keepalive_interval", "30"));
    }
	strcpy(conf.acc3.enable, iniparser_getstring(ini, "account_info_3:enable", "no"));
    if(strcmp(conf.acc3.enable, "yes") == 0)
    {
        strcpy(conf.acc3.username, iniparser_getstring(ini, "account_info_3:username", ""));
        strcpy(conf.acc3.authuser, iniparser_getstring(ini, "account_info_3:authuser", ""));
        if(strlen(conf.acc3.authuser) == 0)
        {
            strcpy(conf.acc3.authuser, conf.acc3.username);
        }
        GetCmdValue("sysconf /etc/speaker.conf get account_info_3 passwd", conf.acc3.passwd, sizeof(conf.acc3.passwd));
        //strcpy(conf.acc3.passwd, iniparser_getstring(ini, "account_info_3:passwd", ""));
        strcpy(conf.acc3.server, iniparser_getstring(ini, "account_info_3:server", ""));
        strcpy(conf.acc3.port, iniparser_getstring(ini, "account_info_3:port", ""));
        strcpy(conf.acc3.domain, iniparser_getstring(ini, "account_info_3:domain", ""));
        if(strlen(conf.acc3.domain) == 0)
        {
            strcpy(conf.acc3.domain, conf.acc3.server);
        }
        strcpy(conf.acc3.reg_expires, iniparser_getstring(ini, "account_info_3:reg_expires", ""));
        strcpy(conf.acc3.transport, iniparser_getstring(ini, "account_info_3:transport", ""));
        strcpy(conf.acc3.autoanswer, iniparser_getstring(ini, "account_info_3:autoanswer", ""));
        strcpy(conf.acc3.sip_autoanswer, iniparser_getstring(ini, "account_info_3:sip_autoanswer", "yes"));
        strcpy(conf.acc3.ringfile, iniparser_getstring(ini, "account_info_3:ringfile", ""));
        strcpy(conf.acc3.nat_mode, iniparser_getstring(ini, "account_info_3:nat_mode", "disabled"));
        strcpy(conf.acc3.stun_server, iniparser_getstring(ini, "account_info_3:stun_server", ""));
        strcpy(conf.acc3.stun_port, iniparser_getstring(ini, "account_info_3:stun_port", "3478"));
        strcpy(conf.acc3.nat_username, iniparser_getstring(ini, "account_info_3:nat_username", ""));
        strcpy(conf.acc3.nat_password, iniparser_getstring(ini, "account_info_3:nat_password", ""));
        strcpy(conf.acc3.keepalive, iniparser_getstring(ini, "account_info_3:keepalive", "yes"));
        strcpy(conf.acc3.ka_interval, iniparser_getstring(ini, "account_info_3:keepalive_interval", "30"));
    }
	strcpy(conf.p2p.enable, iniparser_getstring(ini, "account_info_p2p:enable", "no"));
	strcpy(conf.p2p.username, iniparser_getstring(ini, "account_info_p2p:username", ""));
	strcpy(conf.p2p.auth, iniparser_getstring(ini, "account_info_p2p:auth", "no"));
	strcpy(conf.p2p.transport, iniparser_getstring(ini, "account_info_p2p:transport", ""));
	strcpy(conf.p2p.autoanswer, iniparser_getstring(ini, "account_info_p2p:autoanswer", ""));
	strcpy(conf.p2p.sip_autoanswer, iniparser_getstring(ini, "account_info_p2p:sip_autoanswer", "yes"));
	strcpy(conf.p2p.ringfile, iniparser_getstring(ini, "account_info_p2p:ringfile", ""));
	strcpy(conf.g722, iniparser_getstring(ini, "codec:g722", "yes"));
	strcpy(conf.alaw, iniparser_getstring(ini, "codec:alaw", "yes"));
	strcpy(conf.ulaw, iniparser_getstring(ini, "codec:ulaw", "yes"));
	strcpy(conf.opus, iniparser_getstring(ini, "codec:opus", "no"));
	strcpy(conf.g729, iniparser_getstring(ini, "codec:g729", "no"));
	strcpy(conf.aec, iniparser_getstring(ini, "sip_advance:echocancel", "yes"));
	strcpy(conf.anr, iniparser_getstring(ini, "sip_advance:anr", "yes"));
	strcpy(conf.agc, iniparser_getstring(ini, "sip_advance:agc", "no"));
	strcpy(conf.agc_max_gain, iniparser_getstring(ini, "sip_advance:agc_max_gain", "30"));
	strcpy(conf.agc_gate_threshold, iniparser_getstring(ini, "sip_advance:agc_gate_threshold", "-65"));
	strcpy(conf.cng, iniparser_getstring(ini, "sip_advance:cng", "no"));
	strcpy(conf.end_beep, iniparser_getstring(ini, "sip_function:hangup_beep", "no"));
	strcpy(conf.second_call, iniparser_getstring(ini, "sip_function:second_call", "hangup"));
    GetCmdValue("sysconf /oem/etc/volctrl.conf get volume sip_volume",conf.volume, sizeof(conf.volume));
    if(strlen(conf.volume) == 0)
    {
        strcpy(conf.volume, "90");
    }
    
	iniparser_freedict(ini);

    return conf;
}

int main(int argc, char *argv[]){
    char audio_src[32], lport_line[32] = "", acc1_answermode[32], acc2_answermode[32], acc3_answermode[32], p2p_answermode[32],\
    acc1_natstring[256] = "", acc2_natstring[256] = "", acc3_natstring[256] = "", acc1_extrastring[64] = "", acc2_extrastring[64] = "",\
    acc3_extrastring[64] = "", nat_tmp[256], codecs[64], localip[32], sec_call[128] = "";
	struct SPEAKER_CONF conf;
	
    conf = confParse();

    FILE *phone_modules_fp = fopen(SPHONE_MODULE_CONF, "w+");
    if (phone_modules_fp == NULL){
        perror("Open phone module conf file Error: ");
        exit(1);
    }

//    if(strcmp(conf.echocancel,"yes") == 0)
//    {
//        strcpy(audio_src,ALSA_DEF);
//    }
//    else
//    {
        strcpy(audio_src,ALSA_PLUGHW);
//    }
    

    if(strlen(conf.localport) != 0 && strcmp(conf.localport,"0") != 0)
    {
        sprintf(lport_line,"sip_listen		0.0.0.0:%s", conf.localport);
    }
    if(strcmp(conf.second_call, "hangup") == 0)
    {
        sprintf(sec_call, "call_max_calls          1");
    }
    else if(strcmp(conf.second_call, "hold") == 0)
    {
        sprintf(sec_call, "call_max_calls          2");
    }
    else if(strcmp(conf.second_call, "merge") == 0)
    {
        sprintf(sec_call, "\
call_max_calls          2\n\
call_hold_other_calls   no");
    }
    else
    {
        sprintf(sec_call, "call_max_calls          1");
    }

    fprintf(phone_modules_fp, "\
poll_method             epoll\n\
%s\n\
sip_certificate         /etc/ssl/certs/cert.pem\n\
\n\
call_local_timeout      120\n\
%s\n\
\n\
# Audio\n\
audio_path              /usr/share/baresip\n\
audio_player            alsa,default\n\
audio_source            %s\n\
audio_alert             alsa,default\n\
auplay_channels         2\n\
audio_level             no\n\
ausrc_format            s16\n\
auplay_format           s16\n\
auenc_format            s16\n\
audec_format            s16\n\
audio_buffer            20-120\n\
audio_buffer_mode       adaptive\n\
\n\
# AVT - Audio/Video Transport\n\
rtp_tos                 184\n\
rtp_ports               %s-%s\n\
rtcp_mux                no\n\
audio_jitter_buffer_type      %s\n\
audio_jitter_buffer_delay     0-6\n\
rtp_stats               no\n\
rtp_timeout             %s\n\
\n\
#------------------------------------------------------------------------------\n\
# Speaker\n\
model                   %s\n\
version                 %s\n\
dev_mac                 %s\n\
au_en_aec               %s\n\
au_en_anr               %s\n\
au_en_anr_out           no\n\
au_en_agc               %s\n\
agc_max_gain            %s\n\
agc_gate_threshold      %s\n\
au_en_cng               %s\n\
volume                  %s\n\
end_beep                %s\n\
\n\
#------------------------------------------------------------------------------\n\
# Modules\n\
\n\
module_path             /usr/lib/baresip/modules\n\
\n\
# UI Modules\n\
module                  stdio.so\n\
module                  cons.so\n\
\n\
# Audio codec Modules (in order)\n\
module                  opus.so\n\
module                  g722.so\n\
module                  g711.so\n\
\n\
# Audio driver Modules\n\
module                  alsa.so\n\
\n\
# Audio filter Modules\n\
module                  aufile.so\n\
module                  mixausrc.so\n\
module                  auresamp.so\n\
\n\
# Media NAT modules\n\
module                  stun.so\n\
module                  turn.so\n\
module                  ice.so\n\
\n\
#------------------------------------------------------------------------------\n\
# Compatibility modules\n\
\n\
module                  uuid.so\n\
\n\
#------------------------------------------------------------------------------\n\
# Application Modules\n\
\n\
module_app              account.so\n\
module_app              auloop.so\n\
module_app              menu.so\n\
module_app              ctrl_tcp.so\n\
module_app              debug_cmd.so\n\
module_app		        kaoptions.so\n\
\n\
#------------------------------------------------------------------------------\n\
# Module parameters\n\
\n\
# UI Modules parameters\n\
ctrl_tcp_listen         127.0.0.1:4444\n\
cons_listen             127.0.0.1:5555\n\
\n\
# Opus codec parameters\n\
opus_bitrate            128000\n\
opus_stereo             no\n\
\n\
",\
lport_line,\
sec_call,\
audio_src,\
conf.startport,\
conf.endport,\
conf.jbufftype,\
conf.rtptimeout,\
conf.dev_type,\
conf.version,\
conf.mac,\
conf.aec,\
conf.anr,\
conf.agc,\
conf.agc_max_gain,\
conf.agc_gate_threshold,\
conf.cng,\
conf.volume,\
conf.end_beep
);
    FILE *acc_conf_fp = fopen(ACC_CONF, "w+");
    if (acc_conf_fp == NULL){
        perror("Open accounts conf file Error: ");
        exit(1);
    }

    if(strcmp(conf.acc1.enable, "yes") == 0)
    {
        if(strcmp(conf.acc1.autoanswer, "yes") == 0)
        {
            strcpy(acc1_answermode, "auto");
        }
        else if(strcmp(conf.acc1.autoanswer, "no") == 0)
        {
            strcpy(acc1_answermode, "manual");
        }
        else
        {
            sprintf(acc1_answermode, "manual;answerdelay=%d", (int) (atof(conf.acc1.autoanswer)*1000));
        }
        
        memset(codecs, 0, sizeof(codecs));
        if(strcmp(conf.g722, "yes") == 0)
        {
            strcpy(codecs,"g722/16000/1");
        }

        if(strcmp(conf.alaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcma");
            }
            else
            {
                strcpy(codecs,"pcma");
            }
        }

        if(strcmp(conf.ulaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcmu");
            }
            else
            {
                strcpy(codecs,"pcmu");
            }
        }

        if(strcmp(conf.opus, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",opus/48000/1");
            }
            else
            {
                strcpy(codecs,"opus/48000/1");
            }
        }

        if(strcmp(conf.g729, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",g729");
            }
            else
            {
                strcpy(codecs,"g729");
            }
        }

        if(strcmp(conf.acc1.nat_mode, "stun") == 0)
        {
            sprintf(acc1_natstring, ";medianat=stun;stunserver=\"stun:%s:%s\"", conf.acc1.stun_server, conf.acc1.stun_port);
        }
        else if(strcmp(conf.acc1.nat_mode, "turn") == 0)
        {
            sprintf(acc1_natstring, ";medianat=turn;stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc1.stun_server, conf.acc1.stun_port, conf.acc1.nat_username, conf.acc1.nat_password);
        }
        else if(strcmp(conf.acc1.nat_mode, "ice") == 0)
        {
            strcpy(acc1_natstring, ";medianat=ice");
            if(strlen(conf.acc1.stun_server) != 0)
            {
                if(strlen(conf.acc1.nat_username) != 0)
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc1.stun_server, conf.acc1.stun_port, conf.acc1.nat_username, conf.acc1.nat_password);
                    strcat(acc1_natstring, nat_tmp);
                }
                else
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"stun:%s:%s\"", conf.acc1.stun_server, conf.acc1.stun_port);
                    strcat(acc1_natstring, nat_tmp);
                }
            }
        }
        if(strcmp(conf.acc1.keepalive, "yes") == 0)
        {
            sprintf(acc1_extrastring,";extra=kaoptions=%s",conf.acc1.ka_interval);
        }
        if(strlen(conf.acc1.domain) == 0)
        {
            strcpy(conf.acc1.domain,conf.acc1.server);
        }
        
        fprintf(acc_conf_fp, "\
<sip:%s@%s>%s%s;auth_user=%s;auth_pass=%s;outbound=\"sip:%s:%s;transport=%s\";answermode=%s;sip_autoanswer=%s;audio_codecs=%s;regint=%s;rwait=50;ringfile=%s\n\
",\
conf.acc1.username,\
conf.acc1.domain,\
acc1_natstring,\
acc1_extrastring,\
conf.acc1.authuser,\
conf.acc1.passwd,\
conf.acc1.server,\
conf.acc1.port,\
conf.acc1.transport,\
acc1_answermode,\
conf.acc1.sip_autoanswer,\
codecs,\
conf.acc1.reg_expires,\
conf.acc1.ringfile\
);
    }

    if(strcmp(conf.acc2.enable, "yes") == 0)
    {
        if(strcmp(conf.acc2.autoanswer, "yes") == 0)
        {
            strcpy(acc2_answermode, "auto");
        }
        else if(strcmp(conf.acc2.autoanswer, "no") == 0)
        {
            strcpy(acc2_answermode, "manual");
        }
        else
        {
            sprintf(acc2_answermode, "manual;answerdelay=%d", (int) (atof(conf.acc2.autoanswer)*1000));
        }
        
        memset(codecs, 0, sizeof(codecs));
        if(strcmp(conf.g722, "yes") == 0)
        {
            strcpy(codecs,"g722/16000/1");
        }

        if(strcmp(conf.alaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcma");
            }
            else
            {
                strcpy(codecs,"pcma");
            }
        }

        if(strcmp(conf.ulaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcmu");
            }
            else
            {
                strcpy(codecs,"pcmu");
            }
        }

        if(strcmp(conf.opus, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",opus/48000/1");
            }
            else
            {
                strcpy(codecs,"opus/48000/1");
            }
        }

        if(strcmp(conf.g729, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",g729");
            }
            else
            {
                strcpy(codecs,"g729");
            }
        }

        if(strcmp(conf.acc2.nat_mode, "stun") == 0)
        {
            sprintf(acc2_natstring, ";medianat=stun;stunserver=\"stun:%s:%s\"", conf.acc2.stun_server, conf.acc2.stun_port);
        }
        else if(strcmp(conf.acc2.nat_mode, "turn") == 0)
        {
            sprintf(acc2_natstring, ";medianat=turn;stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc2.stun_server, conf.acc2.stun_port, conf.acc2.nat_username, conf.acc2.nat_password);
        }
        else if(strcmp(conf.acc2.nat_mode, "ice") == 0)
        {
            strcpy(acc2_natstring, ";medianat=ice");
            if(strlen(conf.acc2.stun_server) != 0)
            {
                if(strlen(conf.acc2.nat_username) != 0)
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc2.stun_server, conf.acc2.stun_port, conf.acc2.nat_username, conf.acc2.nat_password);
                    strcat(acc2_natstring, nat_tmp);
                }
                else
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"stun:%s:%s\"", conf.acc2.stun_server, conf.acc2.stun_port);
                    strcat(acc2_natstring, nat_tmp);
                }
            }
        }
        if(strcmp(conf.acc2.keepalive, "yes") == 0)
        {
            sprintf(acc2_extrastring,";extra=kaoptions=%s",conf.acc2.ka_interval);
        }
        if(strlen(conf.acc2.domain) == 0)
        {
            strcpy(conf.acc2.domain,conf.acc2.server);
        }
        
        fprintf(acc_conf_fp, "\
<sip:%s@%s>%s%s;auth_user=%s;auth_pass=%s;outbound=\"sip:%s:%s;transport=%s\";answermode=%s;sip_autoanswer=%s;audio_codecs=%s;regint=%s;rwait=50;ringfile=%s\n\
",\
conf.acc2.username,\
conf.acc2.domain,\
acc2_natstring,\
acc2_extrastring,\
conf.acc2.authuser,\
conf.acc2.passwd,\
conf.acc2.server,\
conf.acc2.port,\
conf.acc2.transport,\
acc2_answermode,\
conf.acc2.sip_autoanswer,\
codecs,\
conf.acc2.reg_expires,\
conf.acc2.ringfile\
);
    }

    if(strcmp(conf.acc3.enable, "yes") == 0)
    {
        if(strcmp(conf.acc3.autoanswer, "yes") == 0)
        {
            strcpy(acc3_answermode, "auto");
        }
        else if(strcmp(conf.acc3.autoanswer, "no") == 0)
        {
            strcpy(acc3_answermode, "manual");
        }
        else
        {
            sprintf(acc3_answermode, "manual;answerdelay=%d", (int) (atof(conf.acc3.autoanswer)*1000));
        }
        
        memset(codecs, 0, sizeof(codecs));
        if(strcmp(conf.g722, "yes") == 0)
        {
            strcpy(codecs,"g722/16000/1");
        }

        if(strcmp(conf.alaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcma");
            }
            else
            {
                strcpy(codecs,"pcma");
            }
            
        }

        if(strcmp(conf.ulaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcmu");
            }
            else
            {
                strcpy(codecs,"pcmu");
            }
            
        }

        if(strcmp(conf.opus, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",opus/48000/1");
            }
            else
            {
                strcpy(codecs,"opus/48000/1");
            }
        }

        if(strcmp(conf.g729, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",g729");
            }
            else
            {
                strcpy(codecs,"g729");
            }
        }

        if(strcmp(conf.acc3.nat_mode, "stun") == 0)
        {
            sprintf(acc3_natstring, ";medianat=stun;stunserver=\"stun:%s:%s\"", conf.acc3.stun_server, conf.acc3.stun_port);
        }
        else if(strcmp(conf.acc3.nat_mode, "turn") == 0)
        {
            sprintf(acc3_natstring, ";medianat=turn;stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc3.stun_server, conf.acc3.stun_port, conf.acc3.nat_username, conf.acc3.nat_password);
        }
        else if(strcmp(conf.acc3.nat_mode, "ice") == 0)
        {
            strcpy(acc3_natstring, ";medianat=ice");
            if(strlen(conf.acc3.stun_server) != 0)
            {
                if(strlen(conf.acc3.nat_username) != 0)
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"turn:%s:%s\";stunuser=%s;stunpass=%s", conf.acc3.stun_server, conf.acc3.stun_port, conf.acc3.nat_username, conf.acc3.nat_password);
                    strcat(acc3_natstring, nat_tmp);
                }
                else
                {
                    memset(nat_tmp,0,sizeof(nat_tmp));
                    sprintf(nat_tmp, ";stunserver=\"stun:%s:%s\"", conf.acc3.stun_server, conf.acc3.stun_port);
                    strcat(acc3_natstring, nat_tmp);
                }
                
            }
        }
        if(strcmp(conf.acc3.keepalive, "yes") == 0)
        {
            sprintf(acc3_extrastring,";extra=kaoptions=%s",conf.acc3.ka_interval);
        }
        if(strlen(conf.acc3.domain) == 0)
        {
            strcpy(conf.acc3.domain,conf.acc3.server);
        }
        
        fprintf(acc_conf_fp, "\
<sip:%s@%s>%s%s;auth_user=%s;auth_pass=%s;outbound=\"sip:%s:%s;transport=%s\";answermode=%s;sip_autoanswer=%s;audio_codecs=%s;regint=%s;rwait=50;ringfile=%s\n\
",\
conf.acc3.username,\
conf.acc3.domain,\
acc3_natstring,\
acc3_extrastring,\
conf.acc3.authuser,\
conf.acc3.passwd,\
conf.acc3.server,\
conf.acc3.port,\
conf.acc3.transport,\
acc3_answermode,\
conf.acc3.sip_autoanswer,\
codecs,\
conf.acc3.reg_expires,\
conf.acc3.ringfile\
);
    }

    if(strcmp(conf.p2p.enable, "yes") == 0)
    {
        if(strcmp(conf.p2p.autoanswer, "yes") == 0)
        {
            strcpy(p2p_answermode, "auto");
        }
        else if(strcmp(conf.p2p.autoanswer, "no") == 0)
        {
            strcpy(p2p_answermode, "manual");
        }
        else
        {
            sprintf(p2p_answermode, "manual;answerdelay=%d", (int) (atof(conf.p2p.autoanswer)*1000));
        }
        
        memset(codecs, 0, sizeof(codecs));
        if(strcmp(conf.g722, "yes") == 0)
        {
            strcpy(codecs,"g722/16000/1");
        }

        if(strcmp(conf.alaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcma");
            }
            else
            {
                strcpy(codecs,"pcma");
            }
            
        }

        if(strcmp(conf.ulaw, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",pcmu");
            }
            else
            {
                strcpy(codecs,"pcmu");
            }
            
        }

        if(strcmp(conf.opus, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",opus/48000/1");
            }
            else
            {
                strcpy(codecs,"opus/48000/1");
            }
            
        }

        if(strcmp(conf.g729, "yes") == 0)
        {
            if(strlen(codecs))
            {
                strcat(codecs,",g729");
            }
            else
            {
                strcpy(codecs,"g729");
            }
        }

        GetCmdValue("/sbin/ifconfig eth0 | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1", localip, sizeof(localip));
        
        if(strlen(localip) == 0)
        {
            memset(localip, 0, sizeof(localip));
            strcpy(localip,"127.0.0.1");
        }
        else
        {
            localip[strlen(localip) - 1] = '\0';
        }
        if(strcmp(conf.p2p.auth,"yes") == 0)
            fprintf(acc_conf_fp, "\
<sip:%s@%s:%s;transport=%s>;answermode=%s;sip_autoanswer=%s;audio_codecs=%s;regint=0;ringfile=%s\n\
",\
conf.p2p.username,\
localip,\
conf.localport,\
conf.p2p.transport,\
p2p_answermode,\
conf.p2p.sip_autoanswer,\
codecs,\
conf.p2p.ringfile\
);
        else
            fprintf(acc_conf_fp, "\
<sip:%s:%s;transport=%s>;answermode=%s;sip_autoanswer=%s;audio_codecs=%s;regint=0;ringfile=%s\n\
",\
localip,\
conf.localport,\
conf.p2p.transport,\
p2p_answermode,\
conf.p2p.sip_autoanswer,\
codecs,\
conf.p2p.ringfile\
);
    }

fclose(phone_modules_fp);
fclose(acc_conf_fp);
}
