
/************************************************/
/*Title:        common_type.c                   */
/*Descr:        CAP Provide                     */
/*Author:       Liang Hanxi                     */
/*Create:       2002-5-7                        */
/************************************************/

#include "../../../public/src/include/pub_include.h"
#include "cap_head.h"
#include "cap_msg.h"

/*++++++++++++++++++++++++ */
//SubscriberState===========>
/*++++++++++++++++++++++++ */
int encSubscriberState(u_char sel, char *tagprefix, CapSubscriberState arg, ASN_BUF * asnbuf)
{                               //return length if success,or -1 is returned
     char tagseq[16];

     switch (sel)
     {
     case 0:                   //assumedIdle--->(NULL)
          sprintf(tagseq, "%s.0", tagprefix);
          return add_null(tagseq, 0x80, asnbuf);
     case 1:                   //camelBusy--->(NULL)
          sprintf(tagseq, "%s.1", tagprefix);
          return add_null(tagseq, 0x80, asnbuf);
     case 2:                   //netDetNotReachable
          sprintf(tagseq, "%s.10", tagprefix);
          return AddInteger(tagseq, arg.netDetNotReachable, 0, asnbuf);
     case 3:                   //notProvidedFromVLR--->(NULL)
          sprintf(tagseq, "%s.2", tagprefix);
          return add_null(tagseq, 0x80, asnbuf);
     }
     return -1;
}

int decSubscriberState(char *tagprefix, CapSubscriberState * parg, ASN_BUF * asnbuf)
//return choice indicator,-1 if none.
{
     char tagseq[16];
     int  len;

     //-------(0)assumedIdle--->(NULL)
     sprintf(tagseq, "%s.0", tagprefix);
     if((len = GetTLV(tagseq, 1, &parg->assumedIdle, 0x80, asnbuf)) >= 0)
          return 0;
     //-------(1)camelBusy--->(NULL)
     sprintf(tagseq, "%s.1", tagprefix);
     if((len = GetTLV(tagseq, 1, &parg->camelBusy, 0x80, asnbuf)) >= 0)
          return 1;
     //-------(2)netDetNotReachable--->
     sprintf(tagseq, "%s.10", tagprefix);
     if((len = GetInteger(tagseq, (int *)&parg->netDetNotReachable, 0, asnbuf)) > 0)
          return 2;
     //-------(3)notProvidedFromVLR--->(NULL)
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, 1, &parg->notProvidedFromVLR, 0x80, asnbuf)) >= 0)
          return 3;
     return -1;
}

/*++++++++++++++++++++++++ */
//CellIdOrLAI==============>
/*++++++++++++++++++++++++ */
int encCellIdOrLAI(u_char sel, char *tagprefix, CapCellIdOrLAI arg, ASN_BUF * asnbuf)
{
     char tagseq[16];

     switch (sel)
     {
     case 0:                   //cellIdFixedLength
          sprintf(tagseq, "%s.0", tagprefix);
          return AddTLV(tagseq, arg.cellIdFixedLength[0], arg.cellIdFixedLength + 1, 0x80, asnbuf);
     case 1:                   //laiFixedLength
          sprintf(tagseq, "%s.1", tagprefix);
          return AddTLV(tagseq, arg.cellIdFixedLength[0], arg.laiFixedLength + 1, 0x80, asnbuf);
     }
     return -1;
}

int decCellIdOrLAI(char *tagprefix, CapCellIdOrLAI * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  len;

     //-------(0)cellIdFixedLength--->
     sprintf(tagseq, "%s.0", tagprefix);
     if((len = GetTLV(tagseq, 7, parg->cellIdFixedLength + 1, 0x80, asnbuf)) > 0)
     {
          parg->cellIdFixedLength[0] = len;
          return 0;
     }
     //-------(1)laiFixedLength--->
     sprintf(tagseq, "%s.1", tagprefix);
     if((len = GetTLV(tagseq, 5, parg->laiFixedLength + 1, 0x80, asnbuf)) > 0)
     {
          parg->laiFixedLength[0] = len;
          return 1;
     }
     return -1;
}

/*+++++++++++++++++++++++++ */
//Ext_BasicServiceCode======>
/*+++++++++++++++++++++++++ */
int encExt_BasicServiceCode(u_char sel, char *tagprefix, CapExt_BasicServiceCode arg, ASN_BUF * asnbuf)
{
     char tagseq[16];

     switch (sel)
     {
     case 0:                   //ext_BearerService
          sprintf(tagseq, "%s.2", tagprefix);
          return AddTLV(tagseq, arg.ext_BearerService[0], arg.ext_BearerService + 1, 0x80, asnbuf);
     case 1:                   //ext_Teleservice
          sprintf(tagseq, "%s.3", tagprefix);
          return AddTLV(tagseq, arg.ext_Teleservice[0], arg.ext_Teleservice + 1, 0x80, asnbuf);
     }
     return -1;
}

int decExt_BasicServiceCode(char *tagprefix, CapExt_BasicServiceCode * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  len;

     //-------(0)ext_BearerService--->
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, 5, parg->ext_BearerService + 1, 0x80, asnbuf)) > 0)
     {
          parg->ext_BearerService[0] = len;
          return 0;
     }
     //-------(1)ext_Teleservice--->
     sprintf(tagseq, "%s.3", tagprefix);
     if((len = GetTLV(tagseq, 5, parg->ext_Teleservice + 1, 0x80, asnbuf)) > 0)
     {
          parg->ext_Teleservice[0] = len;
          return 1;
     }
     return -1;
}

/*++++++++++++++++++++++++ */
//LocationInformation======>
/*++++++++++++++++++++++++ */
int encLocationInformation(char *tagprefix, CapLocationInformation arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = -1;

     if(check_bit(arg.optional_flag, 0))        //ageOfLocationInformation---->
     {
          sprintf(tagseq, "%s.2-1", tagprefix);
          if((retval = AddInteger(tagseq, arg.ageOfLocationInformation, 0, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 1))        //geographicalInformation---->
     {
          sprintf(tagseq, "%s.0-2", tagprefix);
          if((retval = AddTLV(tagseq, arg.geographicalInformation[0], arg.geographicalInformation + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 2))        //vlr_number---->
     {
          sprintf(tagseq, "%s.1-3", tagprefix);
          if((retval = AddTLV(tagseq, arg.vlr_number[0], arg.vlr_number + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 3))        //locationNumber---->
     {
          sprintf(tagseq, "%s.2-4", tagprefix);
          if((retval = AddTLV(tagseq, arg.locationNumber[0], arg.locationNumber + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 4))        //cellIdOrLAI---->
     {
          sprintf(tagseq, "%s.3-5", tagprefix);
          if((retval = encCellIdOrLAI(arg.cellIdOrLAI_ch, tagseq, arg.cellIdOrLAI, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decLocationInformation(char *tagprefix, CapLocationInformation * parg, ASN_BUF * asnbuf)
{
     int  retval = -1, len, sel;
     char tagseq[16];

     parg->optional_flag = 0;

     //ageOfLocationInformation---->
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetInteger(tagseq, &parg->ageOfLocationInformation, 0, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 0);
          retval = 1;
     }
     //geographicalInformation---->
     sprintf(tagseq, "%s.0", tagprefix);
     if((len = GetTLV(tagseq, 8, parg->geographicalInformation + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 1);
          parg->geographicalInformation[0] = len;
          retval = 1;
     }
     //vlr_number---->
     sprintf(tagseq, "%s.1", tagprefix);
     if((len = GetTLV(tagseq, maxISDNAddressLength, parg->vlr_number + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 2);
          parg->vlr_number[0] = len;
          retval = 1;
     }
     //locationNumber---->
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, maxLocationNumberLength, parg->locationNumber + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 3);
          parg->locationNumber[0] = len;
          retval = 1;
     }
     //cellIdOrLAI---->
     sprintf(tagseq, "%s.3", tagprefix);
     if((sel = decCellIdOrLAI(tagseq, &parg->cellIdOrLAI, asnbuf)) >= 0)
     {
          set_bit(parg->optional_flag, 4);
          parg->cellIdOrLAI_ch = sel;
          retval = 1;
     }
     return retval;
}

/*++++++++++++++++++++++++++++ */
//LocationInformationGPRS======>
/*++++++++++++++++++++++++++++ */
int encLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = -1;

     if(check_bit(arg.optional_flag, 0))        //cellGlobalIdOrServiceAreaIdOrLAI ---->
     {
          sprintf(tagseq, "%s.0", tagprefix);
          if((retval = AddTLV(tagseq, arg.cellGlobalIdOrServiceAreaIdOrLAI[0], arg.cellGlobalIdOrServiceAreaIdOrLAI + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 1))        //routeingAreaIdentity ---->
     {
          sprintf(tagseq, "%s.1", tagprefix);
          if((retval = AddTLV(tagseq, arg.routeingAreaIdentity[0], arg.routeingAreaIdentity + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 2))        //geographicalInformation---->
     {
          sprintf(tagseq, "%s.2", tagprefix);
          if((retval = AddTLV(tagseq, arg.geographicalInformation[0], arg.geographicalInformation + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 3))        //sgsn_Number---->
     {
          sprintf(tagseq, "%s.3", tagprefix);
          if((retval = AddTLV(tagseq, arg.sgsn_Number[0], arg.sgsn_Number + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 4))        //cellIdOrLAI---->
     {
          sprintf(tagseq, "%s.4", tagprefix);
          if((retval = AddTLV(tagseq, arg.selectedLSAIdentity[0], arg.selectedLSAIdentity + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 6))        //cellIdOrLAI---->
     {
          sprintf(tagseq, "%s.6", tagprefix);
          if((retval = add_null(tagseq, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decLocationInformationGPRS(char *tagprefix, CapLocationInformationGPRS * parg, ASN_BUF * asnbuf)
{
     int  retval = -1, len;
     char tagseq[16];

     parg->optional_flag = 0;

     //cellGlobalIdOrServiceAreaIdOrLAI---->
     sprintf(tagseq, "%s.0", tagprefix);
     if((len = GetTLV(tagseq, 7, parg->cellGlobalIdOrServiceAreaIdOrLAI + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 0);
          parg->cellGlobalIdOrServiceAreaIdOrLAI[0] = len;
          retval = 1;
     }
     //routeingAreaIdentity---->
     sprintf(tagseq, "%s.1", tagprefix);
     if((len = GetTLV(tagseq, 7, parg->routeingAreaIdentity + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 1);
          parg->routeingAreaIdentity[0] = len;
          retval = 1;
     }
     //geographicalInformation---->
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, 8, parg->geographicalInformation + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 2);
          parg->geographicalInformation[0] = len;
          retval = 1;
     }
     //sgsn_Number---->
     sprintf(tagseq, "%s.3", tagprefix);
     if((len = GetTLV(tagseq, maxISDNAddressLength, parg->sgsn_Number + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 3);
          parg->sgsn_Number[0] = len;
          retval = 1;
     }
     //selectedLSAIdentity---->
     sprintf(tagseq, "%s.4", tagprefix);
     if((len = GetTLV(tagseq, 3, parg->selectedLSAIdentity + 1, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 4);
          parg->selectedLSAIdentity[0] = len;
          retval = 1;
     }
     //selectedLSAIdentity---->
     sprintf(tagseq, "%s.6", tagprefix);
     if((len = GetTLV(tagseq, 1, &parg->sai_Present, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 5);
          retval = 1;
     }
     return retval;
}

/*++++++++++++++++++++++++++++++++++++++++++++ */
//CAMEL-aChbillingChargingCharacteristics======>
/*++++++++++++++++++++++++++++++++++++++++++++ */
int encACBCC(struct CapACBCC arg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     if((retval = AddInteger("0.0", arg.maxCallPeriodDuration, 0x80, &asnbuf)) < 0)
          return -1;
     if(check_bit(arg.optional_flag, 0))
     {
          if((retval = AddTLV("0.1.1", 1, &arg.releaseIfdurationExceeded.tone, 0, &asnbuf)) < 0)
               /* no reason, why code as following lines */
               //      if((retval=AddTLV("0.1",1,&arg.releaseIfdurationExceeded.tone,0x80,&asnbuf))<0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 1))
     {
          if((retval = AddInteger("0.2", arg.tariffSwitchInterval, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decACBCC(char *msgbuf, int msglen, CapACBCC * parg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     parg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          printf("Decode error:%s", asnbuf.errmsg);
          return -1;
     }
     if(GetInteger("0.0", &parg->maxCallPeriodDuration, 0x80, &asnbuf) < 0)
          return -1;
     if((len = GetTLV("0.1.1", 1, &parg->releaseIfdurationExceeded.tone, 0, &asnbuf)) > 0)
          set_bit(parg->optional_flag, 0);
     if((len = GetInteger("0.2", &parg->tariffSwitchInterval, 0x80, &asnbuf)) > 0)
          set_bit(parg->optional_flag, 1);
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++++++++ */
//LegID======>
/*++++++++++++++++++++++++++++++++++++++++++++ */
int encLegID(u_char sel, char *tagprefix, CapLegID arg, ASN_BUF * asnbuf)
{
     char tagseq[16];

     switch (sel)
     {
     case 0:                   //sendingSideID
          sprintf(tagseq, "%s.0", tagprefix);
          return AddTLV(tagseq, 1, &arg.sendingSideID, 0x80, asnbuf);
     case 1:                   //receivingSideID
          sprintf(tagseq, "%s.1", tagprefix);
          return AddTLV(tagseq, 1, &arg.receivingSideID, 0x80, asnbuf);
     }
     return -1;
}

int decLegID(char *tagprefix, CapLegID * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  len;

     sprintf(tagseq, "%s.0", tagprefix);        //sendingSideID
     if((len = GetTLV(tagseq, 1, &parg->sendingSideID, 0x80, asnbuf)) >= 0)
          return 0;
     sprintf(tagseq, "%s.1", tagprefix);        //receivingSideID
     if((len = GetTLV(tagseq, 1, &parg->receivingSideID, 0x80, asnbuf)) >= 0)
          return 1;
     return -1;
}

/*++++++++++++++++++++++++++++++++++++++++++++ */
//EventSpecificInformationBCSM======>
/*++++++++++++++++++++++++++++++++++++++++++++ */
int encESIBCSM(char *tagprefix, CapESIBCSM arg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = -1;

     if(arg.infotype < 2 || arg.infotype > 12)
          return -1;
     sprintf(tagseq, "%s.%d", tagprefix, arg.infotype);
     if((retval = add_null(tagseq, 0xA0, asnbuf)) < 0)
          return -1;
     if(arg.cause[0] > 0)
     {
          sprintf(tagseq, "%s.%d.0", tagprefix, arg.infotype);
          if((retval = AddTLV(tagseq, arg.cause[0], arg.cause + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(arg.callForwarded)
     {
          sprintf(tagseq, "%s.%d.50", tagprefix, arg.infotype);
          if((retval = add_null(tagseq, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decESIBCSM(char *tagprefix, CapESIBCSM * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     u_char msgbuf[64];
     int  len;
     u_short tagcode;

     sprintf(tagseq, "%s.-1", tagprefix);       //get first tlv
     if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0)
          return -1;
     parg->infotype = tagcode;
     parg->callForwarded = 0;
     switch (tagcode)
     {
     case 2:
     case 3:
     case 7:
     case 12:
          sprintf(tagseq, "%s.-1.0", tagprefix);
          if((len = GetTLV(tagseq, maxCauseLength, parg->cause + 1, 0x80, asnbuf)) > 0)
               parg->cause[0] = len;
          else
               parg->cause[0] = 0;
          break;
     case 8:
          sprintf(tagseq, "%s.-1.0", tagprefix);
          if((len = GetTLV(tagseq, maxCauseLength, parg->cause + 1, 0x80, asnbuf)) > 0)
               parg->cause[0] = len;
          else
               parg->cause[0] = 0;
          sprintf(tagseq, "%s.-1.50", tagprefix);
          if((len = GetTLV(tagseq, 0, &parg->callForwarded, 0x80, asnbuf)) >= 0)
               parg->callForwarded = 1;
          break;
     case 9:
          sprintf(tagseq, "%s.-1.50", tagprefix);
          if(GetTLV(tagseq, 0, &parg->callForwarded, 0x80, asnbuf) >= 0)
               parg->callForwarded = 1;
          break;
     case 4:
     case 5:
     case 10:
          break;
     default:
          return -1;
     }
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++++++++ */
//EventSpecificInformationSMS======>
/*++++++++++++++++++++++++++++++++++++++++++++ */
int encESISMS(char *tagprefix, CapESISMS arg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = -1;

     if(arg.infotype > 1)
          return -1;
     sprintf(tagseq, "%s.%d", tagprefix, arg.infotype);
     if((retval = add_null(tagseq, 0xA0, asnbuf)) < 0)
          return -1;
     if(arg.infotype == 0 && arg.cause_flag)
     {
          sprintf(tagseq, "%s.%d.0", tagprefix, arg.infotype);
          if((retval = AddInteger(tagseq, arg.cause, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decESISMS(char *tagprefix, CapESISMS * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     u_char msgbuf[64];
     int  len;
     u_short tagcode;

     sprintf(tagseq, "%s.-1", tagprefix);       //get first tlv
     if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0)
          return -1;
     parg->infotype = tagcode;
     if(tagcode == 0)
     {
          sprintf(tagseq, "%s.-1.0", tagprefix);
          if((len = GetInteger(tagseq, (int *)&parg->cause, 0x80, asnbuf)) > 0)
               parg->cause_flag = 1;
          else
               parg->cause_flag = 0;
     }
     return 1;
}

#ifdef _SRF_RELEVANT
int encServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = 0;

     if(check_bit(arg.optional_flag, 0))
     {
          sprintf(tagseq, "%s.2", tagprefix);
          if((retval = add_bool(tagseq, arg.bothwayThroughConnectionInd, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decServiceInteractionIndicatorsTwo(char *tagprefix, CapServiceInteractionIndicatorsTwo * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = -1;
     int  len;

     parg->optional_flag = 0;
     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, 1, &parg->bothwayThroughConnectionInd, 0x80, asnbuf)) >= 0)
     {
          set_bit(parg->optional_flag, 0);
          retval = 1;
     }
     return retval;
}

int encVariablePart(char seq, char *tagprefix, CapVariablePart arg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = 0;

     switch (arg.choice_id)
     {
     case 0:
          sprintf(tagseq, "%s.0-%d", tagprefix, seq);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.integer, 0x80, asnbuf)) < 0)
               return -1;
          break;
     case 1:
          sprintf(tagseq, "%s.1-%d", tagprefix, seq);
          if((retval = AddTLV(tagseq, arg.number[0], arg.number + 1, 0x80, asnbuf)) < 0)
               return -1;
          break;
     case 2:
          sprintf(tagseq, "%s.2-%d", tagprefix, seq);
          if((retval = AddTLV(tagseq, 2, (u8 *) & arg.time, 0x80, asnbuf)) < 0)
               return -1;
          break;
     case 3:
          sprintf(tagseq, "%s.3-%d", tagprefix, seq);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.date, 0x80, asnbuf)) < 0)
               return -1;
          break;
     case 4:
          sprintf(tagseq, "%s.4-%d", tagprefix, seq);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.price, 0x80, asnbuf)) < 0)
               return -1;
          break;
     }
     return retval;
}

int decVariablePart(char *tagprefix, CapVariablePart * parg, ASN_BUF * asnbuf)
{
     //char          tagseq[32];
     int  len;
     char msgbuf[64];
     u_short tagcode;

     /*char          tagseq[16];
        u_char               msgbuf[64];
        int                  len;
        u_short              tagcode;

        sprintf(tagseq, "%s.-1", tagprefix); //get first tlv
        if(GetAnyTLV(tagseq, 64, msgbuf, NULL, &tagcode, asnbuf) < 0) */

     if((len = GetAnyTLV(tagprefix, 64, msgbuf, NULL, &tagcode, asnbuf)) > 0)
     {
          switch (tagcode)
          {
          case 0:
               memcpy(&parg->integer, msgbuf, len);
               parg->choice_id = 0;
               return 1;
          case 1:
               memcpy(parg->number + 1, msgbuf, len);
               parg->number[0] = len;
               parg->choice_id = 1;
               return 1;
          case 2:
               memcpy(parg->time, msgbuf, len);
               parg->choice_id = 2;
               return 1;
          case 3:
               memcpy(parg->date, msgbuf, len);
               parg->choice_id = 3;
               return 1;
          case 4:
               memcpy(parg->price, msgbuf, len);
               parg->choice_id = 4;
               return 1;
          }
     }
     return -1;
     /*sprintf(tagseq, "%s.0", tagprefix);
        if(GetTLV(tagseq,4,(u8 *)&parg->integer,0x80,asnbuf)>0)
        {
        parg->choice_id = 0;
        return 1;
        }
        sprintf(tagseq, "%s.1", tagprefix);
        if((len=GetTLV(tagseq,maxDigitsLength,parg->number+1,0x80,asnbuf))>0)
        {
        parg->number[0] = len;
        parg->choice_id = 1;
        return 1;
        }
        sprintf(tagseq, "%s.2", tagprefix);
        if(GetTLV(tagseq,2,(u8 *)&parg->time,0x80,asnbuf)>0)
        {
        parg->choice_id = 2;
        return 1;
        }
        sprintf(tagseq, "%s.3", tagprefix);
        if(GetTLV(tagseq,4,(u8 *)&parg->date,0x80,asnbuf)>0)
        {
        parg->choice_id = 3;
        return 1;
        }
        sprintf(tagseq, "%s.4", tagprefix);
        if(GetTLV(tagseq,4,(u8 *)&parg->price,0x80,asnbuf)>0)
        {
        parg->choice_id = 4;
        return 1;
        }
        return -1; */
}

int encMessageID(char *tagprefix, CapMessageID arg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = 0;
     int  index;

     switch (arg.choice_id)
     {
     case 0:
          sprintf(tagseq, "%s.0", tagprefix);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.elementaryMessageID, 0x80, asnbuf)) < 0)
               return -1;
          break;
     case 1:                   //text
          break;
     case 2:
          for(index = 0; index < arg.elementaryMessageIDs.num; index++)
          {
               sprintf(tagseq, "%s.29-%d", tagprefix, index + 1);
               if((retval = AddTLV(tagseq, 4, (u8 *) & arg.elementaryMessageIDs.elementaryMessageID[index], 0x80, asnbuf)) < 0)
                    return -1;
          }
          break;
     case 3:
          sprintf(tagseq, "%s.30.0", tagprefix);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.variableMessage.elementaryMessageID, 0x80, asnbuf)) < 0)
               return -1;
          for(index = 0; index < arg.variableMessage.variableParts.num; index++)
          {
               sprintf(tagseq, "%s.30.1", tagprefix);
               if((retval = encVariablePart(index + 1, tagseq, arg.variableMessage.variableParts.variablePart[index], asnbuf)) < 0)
                    return -1;
          }
          break;
     }
     return retval;
}

int decMessageID(char *tagprefix, CapMessageID * parg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  index , ret = 0 ;

     sprintf(tagseq, "%s.0", tagprefix);
     if(GetTLV(tagseq, 4, (u8 *) & parg->elementaryMessageID, 0x80, asnbuf) > 0)
     {
          parg->choice_id = 0;
          return 1;
     }

     parg->elementaryMessageIDs.num = 0;
     for(index = 0; index < numOfMessageIDs; index++)
     {
          sprintf(tagseq, "%s.29-%d", tagprefix, index + 1);
          if(GetTLV(tagseq, 4, (u8 *) & parg->elementaryMessageIDs.elementaryMessageID[index], 0x80, asnbuf) > 0)
          {
               parg->elementaryMessageIDs.num++;
               ret = 1;
          }
     }
     if( ret )
     {
         parg->choice_id = 2;
         return 1;
     }

     sprintf(tagseq, "%s.30.0", tagprefix);
     if(GetTLV(tagseq, 4, (u8 *) & parg->variableMessage.elementaryMessageID, 0x80, asnbuf) < 0)
          return -1;
     parg->variableMessage.variableParts.num = 0;
     for(index = 0; index < 5; index++)
     {
          sprintf(tagseq, "%s.30.1.-%d", tagprefix, index + 1);
          if(decVariablePart(tagseq, &parg->variableMessage.variableParts.variablePart[index], asnbuf) >= 0)
          {
               parg->variableMessage.variableParts.num++;
               ret = 1;
          }
     }
     if( ret )
     {
         parg->choice_id = 3;
         return 1;
     }
     return -1;
}

int encInbandInfo(char *tagprefix, CapInbandInfo arg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = 0;

     sprintf(tagseq, "%s.0", tagprefix);
     if((retval = encMessageID(tagseq, arg.messageID, asnbuf)) < 0)
          return -1;
     if(check_bit(arg.optional_flag, 0))
     {
          sprintf(tagseq, "%s.1", tagprefix);
          if((retval = AddInteger(tagseq, arg.numberOfRepetitions, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 1))
     {
          sprintf(tagseq, "%s.2", tagprefix);
          if((retval = AddInteger(tagseq, arg.duration, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 2))
     {
          sprintf(tagseq, "%s.3", tagprefix);
          if((retval = AddInteger(tagseq, arg.interval, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decInbandInfo(char *tagprefix, CapInbandInfo * parg, ASN_BUF * asnbuf)
{
     char tagseq[32];
     int  retval = -1;

     parg->optional_flag = 0;
     sprintf(tagseq, "%s.0", tagprefix);
     if(decMessageID(tagseq, &parg->messageID, asnbuf) >= 0)
     {
          retval = 1;
     }
     sprintf(tagseq, "%s.1", tagprefix);
     if((GetInteger(tagseq, &parg->numberOfRepetitions, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 0);
     }
     sprintf(tagseq, "%s.2", tagprefix);
     if((GetInteger(tagseq, &parg->duration, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 1);
     }
     sprintf(tagseq, "%s.3", tagprefix);
     if((GetInteger(tagseq, &parg->interval, 0x80, asnbuf)) > 0)
     {
          set_bit(parg->optional_flag, 2);
     }
     return retval;
}

int encTone(char *tagprefix, CapTone arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = 0;

     sprintf(tagseq, "%s.0", tagprefix);
     if((retval = AddTLV(tagseq, 4, (u8 *) & arg.toneID, 0x80, asnbuf)) < 0)
          return -1;
     if(check_bit(arg.optional_flag, 0))
     {
          sprintf(tagseq, "%s.1", tagprefix);
          if((retval = AddTLV(tagseq, 4, (u8 *) & arg.duration, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decTone(char *tagprefix, CapTone * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval = -1;

     parg->optional_flag = 0;
     sprintf(tagseq, "%s.0", tagprefix);
     if(GetTLV(tagseq, 4, (u8 *) & parg->toneID, 0x80, asnbuf) > 0)
     {
          retval = 1;
     }
     sprintf(tagseq, "%s.1", tagprefix);
     if(GetTLV(tagseq, 4, (u8 *) & parg->duration, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 0);
     }
     return retval;
}

int encInformationToSend(char *tagprefix, CapInformationToSend arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval;

     switch (arg.choice_id)
     {
     case 0:
          sprintf(tagseq, "%s.0", tagprefix);
          if((retval = encInbandInfo(tagseq, arg.inbandInfo, asnbuf)) < 0)
               return -1;
          break;
     case 1:
          sprintf(tagseq, "%s.1", tagprefix);
          if((retval = encTone(tagseq, arg.tone, asnbuf)) < 0)
               return -1;
          break;
     }
     return retval;
}

int decInformationToSend(char *tagprefix, CapInformationToSend * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];

     sprintf(tagseq, "%s.0", tagprefix);
     if(decInbandInfo(tagseq, &parg->inbandInfo, asnbuf) >= 0)
     {
          parg->choice_id = 0;
          return 1;
     }
     sprintf(tagseq, "%s.1", tagprefix);
     if(decTone(tagseq, &parg->tone, asnbuf) >= 0)
     {
          parg->choice_id = 1;
          return 1;
     }
     return -1;
}

int encCollectedDigits(char *tagprefix, CapCollectedDigits arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval;

     sprintf(tagseq, "%s.0", tagprefix);
     if((retval = AddTLV(tagseq, 1, &arg.minimumNbOfDigits, 0x80, asnbuf)) < 0)
          return -1;
     sprintf(tagseq, "%s.1", tagprefix);
     if((retval = AddTLV(tagseq, 1, &arg.maximumNbOfDigits, 0x80, asnbuf)) < 0)
          return -1;

     if(check_bit(arg.optional_flag, 0))
     {
          sprintf(tagseq, "%s.2", tagprefix);
          if((retval = AddTLV(tagseq, arg.endOfReplyDigit[0], arg.endOfReplyDigit + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 1))
     {
          sprintf(tagseq, "%s.3", tagprefix);
          if((retval = AddTLV(tagseq, arg.cancelDigit[0], arg.cancelDigit + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 2))
     {
          sprintf(tagseq, "%s.4", tagprefix);
          if((retval = AddTLV(tagseq, arg.startDigit[0], arg.startDigit + 1, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 3))
     {
          sprintf(tagseq, "%s.5", tagprefix);
          if((retval = AddTLV(tagseq, 1, &arg.firstDigitTimeOut, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 4))
     {
          sprintf(tagseq, "%s.6", tagprefix);
          if((retval = AddTLV(tagseq, 1, &arg.interDigitTimeOut, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 5))
     {
          sprintf(tagseq, "%s.7", tagprefix);
          if((retval = AddTLV(tagseq, 1, (u8 *) & arg.errorTreatment, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 6))
     {
          sprintf(tagseq, "%s.8", tagprefix);
          if((retval = AddTLV(tagseq, 1, &arg.interruptableAnnInd, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 7))
     {
          sprintf(tagseq, "%s.9", tagprefix);
          if((retval = AddTLV(tagseq, 1, &arg.voiceInformation, 0x80, asnbuf)) < 0)
               return -1;
     }
     if(check_bit(arg.optional_flag, 8))
     {
          sprintf(tagseq, "%s.10", tagprefix);
          if((retval = AddTLV(tagseq, 1, &arg.voiceBack, 0x80, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decCollectedDigits(char *tagprefix, CapCollectedDigits * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  len;

     parg->optional_flag = 0;
     sprintf(tagseq, "%s.0", tagprefix);
     if(GetTLV(tagseq, 1, &parg->minimumNbOfDigits, 0x80, asnbuf) < 0)
          ;                     //return -1;
     sprintf(tagseq, "%s.1", tagprefix);
     if(GetTLV(tagseq, 1, &parg->maximumNbOfDigits, 0x80, asnbuf) < 0)
          return -1;

     sprintf(tagseq, "%s.2", tagprefix);
     if((len = GetTLV(tagseq, 3, parg->endOfReplyDigit + 1, 0x80, asnbuf)) > 0)
     {
          parg->endOfReplyDigit[0] = len;
          set_bit(parg->optional_flag, 0);
     }
     sprintf(tagseq, "%s.3", tagprefix);
     if((len = GetTLV(tagseq, 3, parg->cancelDigit + 1, 0x80, asnbuf)) > 0)
     {
          parg->cancelDigit[0] = len;
          set_bit(parg->optional_flag, 1);
     }
     sprintf(tagseq, "%s.4", tagprefix);
     if((len = GetTLV(tagseq, 3, parg->startDigit + 1, 0x80, asnbuf)) > 0)
     {
          parg->startDigit[0] = len;
          set_bit(parg->optional_flag, 2);
     }
     sprintf(tagseq, "%s.5", tagprefix);
     if(GetTLV(tagseq, 1, &parg->firstDigitTimeOut, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 3);
     }
     sprintf(tagseq, "%s.6", tagprefix);
     if(GetTLV(tagseq, 1, &parg->interDigitTimeOut, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 4);
     }
     sprintf(tagseq, "%s.7", tagprefix);
     if(GetTLV(tagseq, 1, (u8 *) & parg->errorTreatment, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 5);
     }
     sprintf(tagseq, "%s.8", tagprefix);
     if(GetTLV(tagseq, 1, &parg->interruptableAnnInd, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 6);
     }
     sprintf(tagseq, "%s.9", tagprefix);
     if(GetTLV(tagseq, 1, &parg->voiceInformation, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 7);
     }
     sprintf(tagseq, "%s.10", tagprefix);
     if(GetTLV(tagseq, 1, &parg->voiceBack, 0x80, asnbuf) > 0)
     {
          set_bit(parg->optional_flag, 8);
     }
     return 1;
}

int encCollectedInfo(char *tagprefix, CapCollectedInfo arg, ASN_BUF * asnbuf)
{
     char tagseq[16];
     int  retval;

     if(arg.choice_id == 0)
     {
          sprintf(tagseq, "%s.0", tagprefix);
          if((retval = encCollectedDigits(tagseq, arg.collectedDigits, asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int decCollectedInfo(char *tagprefix, CapCollectedInfo * parg, ASN_BUF * asnbuf)
{
     char tagseq[16];

     sprintf(tagseq, "%s.0", tagprefix);
     if(decCollectedDigits(tagseq, &parg->collectedDigits, asnbuf) >= 0)
     {
          parg->choice_id = 0;
          return 1;
     }
     return -1;
}

#endif
