
/************************************************/
/*Title:        capmsg.c                            */
/*Descr:        Encode/Decode Cap Message           */
/*Author:       Liang Hanxi                         */
/*Create:       2002-10-31                          */
/*Modify:   2002-12-4                           */

/************************************************/

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

/*++++++++++++++++++++++++++++++++++++++ */
/*Cancel-------------------------------> */
/*++++++++++++++++++++++++++++++++++++++ */
int eCancel(struct CapCancel caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     switch (caparg.ch)
     {
     case 0:
          return AddInteger("2", caparg.invokeID, 0, &asnbuf);
     case 1:
          return add_null("5", 0, &asnbuf);
     default:
          return -1;
     }
}

int dCancel(char *msgbuf, int msglen, PCapCancel pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if(GetInteger("2", (int *)&pcaparg->invokeID, 0, &asnbuf) >= 0)
     {
          pcaparg->ch = 0;
          return 1;
     }
     else if(GetTLV("5", 1, &pcaparg->allRequest, 0, &asnbuf) >= 0)
     {
          pcaparg->ch = 1;
          return 1;
     }
     return -1;
}

/*************************************/
/*InitialDP-------------------------> */

/*************************************/
int eInitialDP(struct CapInitialDP caparg, char *msgbuf, int maxlen,u8 version)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     retval = AddInteger("16.0", caparg.serviceKey, 0x80, &asnbuf);
     //optional part
     if(check_bit(caparg.optional_flag, 0))
     {
          if((retval = AddTLV("16.2", caparg.calledPartyNumber[0], caparg.calledPartyNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))
     {
          if((retval = AddTLV("16.3", caparg.callingPartyNumber[0], caparg.callingPartyNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 2))
     {
          if((retval = AddTLV("16.5", 1, &caparg.callingPartysCategory, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if( version > 1 )
     {
	     if(check_bit(caparg.optional_flag, 3))
	     {
	          if((retval = AddTLV("16.8", caparg.iPSSPCapabilities[0], caparg.iPSSPCapabilities + 1, 0x80, &asnbuf)) < 0)
	               return -1;
	     }
     }
     if(check_bit(caparg.optional_flag, 4))
     {
          if((retval = AddTLV("16.10", caparg.locationNumber[0], caparg.locationNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 5))
     {
          if((retval = AddTLV("16.12", caparg.originalCalledPartyID[0], caparg.originalCalledPartyID + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 7))
     {
          if((retval = AddTLV("16.23", caparg.highLayerCompatibility[0], caparg.highLayerCompatibility + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 8))
     {
          if((retval = AddTLV("16.25", caparg.additionalCallingPartyNumber[0], caparg.additionalCallingPartyNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 9))
     {
          if((retval = AddTLV("16.27.0", caparg.bearerCapability.bearerCap[0], caparg.bearerCapability.bearerCap + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 10))
     {
          if((retval = AddInteger("16.28", caparg.eventTypeBCSM, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 11))
     {
          if((retval = AddTLV("16.29", caparg.redirectingPartyID[0], caparg.redirectingPartyID + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 12))
     {
          if((retval = AddTLV("16.30", caparg.redirectionInformation[0], caparg.redirectionInformation + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 13))
     {
          if((retval = AddTLV("16.50", caparg.iMSI[0], caparg.iMSI + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 14))
     {
          if((retval = encSubscriberState(caparg.subscriberState_ch, "16.51", caparg.subscriberState, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 15))
     {
          if((retval = encLocationInformation("16.52", caparg.locationInformation, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 16))
     {
          if((retval = encExt_BasicServiceCode(caparg.ext_basicServiceCode_ch, "16.53", caparg.ext_basicServiceCode, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 17))
     {
          if((retval = AddTLV("16.54", caparg.callReferenceNumber[0], caparg.callReferenceNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if( version >1 )
     {
	     if(check_bit(caparg.optional_flag, 18))
	     {
	          if((retval = AddTLV("16.55", caparg.mscAddress[0], caparg.mscAddress + 1, 0x80, &asnbuf)) < 0)
	               return -1;
	     }
	     if(check_bit(caparg.optional_flag, 19))
	     {
	          if((retval = AddTLV("16.56", caparg.calledPartyBCDNumber[0], caparg.calledPartyBCDNumber + 1, 0x80, &asnbuf)) < 0)
	               return -1;
	     }
	     if(check_bit(caparg.optional_flag, 20))
	     {
	          if((retval = AddTLV("16.57", caparg.timeAndTimezone[0], caparg.timeAndTimezone + 1, 0x80, &asnbuf)) < 0)
	               return -1;
	     }
	     if(check_bit(caparg.optional_flag, 21))
	     {
	          if((retval = AddTLV("16.58", 0, &caparg.gsm_ForwardingPending, 0x80, &asnbuf)) < 0)
	               return -1;
	     }
     }
     return retval;
}

int dInitialDP(char *msgbuf, int msglen, PCapInitialDP pcaparg , u8 version )
{
     ASN_BUF asnbuf;
     int  temp, sel, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &temp, &asnbuf)) < 0)
     {
          return -1;
     }
     if(GetInteger("16.0", &pcaparg->serviceKey, 0x80, &asnbuf) < 0)    //serviceKey
          return -1;
     //optional part
     //called party number============>
     if((len = GetTLV("16.2", maxCalledPartyNumberLength, pcaparg->calledPartyNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
          pcaparg->calledPartyNumber[0] = len;
     }
     //calling party number============>
     if((len = GetTLV("16.3", maxCallingPartyNumberLength, pcaparg->callingPartyNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 1);
          pcaparg->callingPartyNumber[0] = len;
     }
     //calling party category============>
     if((len = GetTLV("16.5", 1, &pcaparg->callingPartysCategory, 0x80, &asnbuf)) > 0)
          set_bit(pcaparg->optional_flag, 2);
     if( version >1 )
     {
		     //IPSSPCapabilities============>
		     if((len = GetTLV("16.8", maxIPSSPCapabilitiesLength, pcaparg->iPSSPCapabilities + 1, 0x80, &asnbuf)) > 0)
		     {
		          set_bit(pcaparg->optional_flag, 3);
		          pcaparg->iPSSPCapabilities[0] = len;
		     }
     }
     //LocationNumber============>
     if((len = GetTLV("16.10", maxLocationNumberLength, pcaparg->locationNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 4);
          pcaparg->locationNumber[0] = len;
     }
     //OriginalCalledPartyID============>
     if((len = GetTLV("16.12", maxOriginalCalledPartyIDLength, pcaparg->originalCalledPartyID + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 5);
          pcaparg->originalCalledPartyID[0] = len;
     }
     //highLayerCompatibility============>
     if((len = GetTLV("16.23", 2, pcaparg->highLayerCompatibility + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 7);
          pcaparg->highLayerCompatibility[0] = len;
     }
     //additionalCallingPartyNumber============>
     if((len = GetTLV("16.25", maxDigitsLength, pcaparg->additionalCallingPartyNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 8);
          pcaparg->additionalCallingPartyNumber[0] = len;
     }
     //bearerCapability============>
     if((len = GetTLV("16.27.0", maxBearerCapabilityLength, pcaparg->bearerCapability.bearerCap + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 9);
          pcaparg->bearerCapability.bearerCap[0] = len;
     }
     //eventTypeBCSM============>
     if((len = GetInteger("16.28", (int *)&pcaparg->eventTypeBCSM, 0x80, &asnbuf)) > 0)
          set_bit(pcaparg->optional_flag, 10);
     //redirectingPartyID============>
     if((len = GetTLV("16.29", maxRedirectingPartyIDLength, pcaparg->redirectingPartyID + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 11);
          pcaparg->redirectingPartyID[0] = len;
     }
     //redirectingPartyID============>
     if((len = GetTLV("16.30", 2, pcaparg->redirectionInformation + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 12);
          pcaparg->redirectionInformation[0] = len;
     }
     //iMSI============>
     if((len = GetTLV("16.50", maxIMSILength, pcaparg->iMSI + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 13);
          pcaparg->iMSI[0] = len;
     }
     //subscriberState============>
     if((sel = decSubscriberState("16.51", &pcaparg->subscriberState, &asnbuf)) >= 0)
     {
          set_bit(pcaparg->optional_flag, 14);
          pcaparg->subscriberState_ch = sel;
     }
     //locationInformation============>
     if(decLocationInformation("16.52", &pcaparg->locationInformation, &asnbuf) >= 0)
          set_bit(pcaparg->optional_flag, 15);
     //ext_basicServiceCode============>
     if((sel = decExt_BasicServiceCode("16.53", &pcaparg->ext_basicServiceCode, &asnbuf)) >= 0)
     {
          set_bit(pcaparg->optional_flag, 16);
          pcaparg->ext_basicServiceCode_ch = sel;
     }
     //callReferenceNumber============>
     if((len = GetTLV("16.54", maxcallReferenceNumberLength, pcaparg->callReferenceNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 17);
          pcaparg->callReferenceNumber[0] = len;
     }
     if( version >1 )
     {
		     //mscAddress============>
		     if((len = GetTLV("16.55", maxISDNAddressLength, pcaparg->mscAddress + 1, 0x80, &asnbuf)) > 0)
		     {
		          set_bit(pcaparg->optional_flag, 18);
		          pcaparg->mscAddress[0] = len;
		     }
		     //calledPartyBCDNumber============>
		     if((len = GetTLV("16.56", maxCalledPartyBCDNumberLength, pcaparg->calledPartyBCDNumber + 1, 0x80, &asnbuf)) > 0)
		     {
		          set_bit(pcaparg->optional_flag, 19);
		          pcaparg->calledPartyBCDNumber[0] = len;
		     }
		     //timeAndTimezone============>
		     if((len = GetTLV("16.57", maxTimeAndTimezoneLength, pcaparg->timeAndTimezone + 1, 0x80, &asnbuf)) > 0)
		     {
		          set_bit(pcaparg->optional_flag, 20);
		          pcaparg->timeAndTimezone[0] = len;
		     }
		     //gsm_ForwardingPending============>
		     if((len = GetTLV("16.58", 1, &pcaparg->gsm_ForwardingPending, 0x80, &asnbuf)) >= 0)
		          set_bit(pcaparg->optional_flag, 21);
     }
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*ApplyCharging------------------------> */
/*++++++++++++++++++++++++++++++++++++++ */
int eApplyCharging(struct CapApplyCharging caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1, len;
     u_char bill_info[256];

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((len = encACBCC(caparg.ACBCC, bill_info, 256)) < 0)
          return -1;
     if((retval = AddTLV("16.0", len, bill_info, 0x80, &asnbuf)) < 0)
          return -1;
     if((retval = AddTLV("16.2.0", 1, &caparg.partyToCharge, 0x80, &asnbuf)) < 0)
          return -1;
     return retval;
}

int dApplyCharging(char *msgbuf, int msglen, PCapApplyCharging pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;
     u_char bill_info[256];

     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetTLV("16.0", 256, bill_info, 0x80, &asnbuf)) < 0)
          return -1;
     if(decACBCC(bill_info, len, &pcaparg->ACBCC) < 0)
          return -1;
     if((len = GetTLV("16.2.0", 1, &pcaparg->partyToCharge, 0x80, &asnbuf)) < 0)
          return -1;
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*RequestReportBCSMEvent--------------> */
/*++++++++++++++++++++++++++++++++++++++ */
int eRequestReportBCSMEvent(struct CapRequestReportBCSMEvent caparg, char *msgbuf, int maxlen, int version)
{
     ASN_BUF asnbuf;
     int  retval = -1, index = 0;
     char tagseq[32];

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     for(index = 0; index < caparg.bcsmEvents_num; index++)
     {
          sprintf(tagseq, "16.0.16-%d", index + 1);
          add_null(tagseq, 0x20, &asnbuf);
          sprintf(tagseq, "16.0.16-%d.0", index + 1);   //eventTypeBCSM
          if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].eventTypeBCSM, 0x80, &asnbuf)) < 0)
               return -1;
          sprintf(tagseq, "16.0.16-%d.1", index + 1);   //monitorMode
          if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].monitorMode, 0x80, &asnbuf)) < 0)
               return -1;
          sprintf(tagseq, "16.0.16-%d.2", index + 1);   //LegID
          if(check_bit(caparg.bcsmEvents[index].optional_flag, 0))      //LegID
          {
               if((retval = encLegID(caparg.bcsmEvents[index].legID_ch, tagseq, caparg.bcsmEvents[index].legID, &asnbuf)) < 0)
                    return -1;
          }
          if(version != 1)
          {
               sprintf(tagseq, "16.0.16-%d.30.1", index + 1);   //dPSpecificCriteria(applicationTimer)
               if(check_bit(caparg.bcsmEvents[index].optional_flag, 1)) //LegID
               {
                    if((retval = AddInteger(tagseq, caparg.bcsmEvents[index].dPSpecificCriteria.applicationTimer, 0x80, &asnbuf)) < 0)
                         return -1;
               }
          }
     }
     return retval;
}

int dRequestReportBCSMEvent(char *msgbuf, int msglen, PCapRequestReportBCSMEvent pcaparg, int version)
{
     ASN_BUF asnbuf;
     int  errpos, sel, len, index = 0;
     char tagseq[32];
     CapBCSMEvent *pevent;

     pcaparg->bcsmEvents_num = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     do
     {
          pevent = &pcaparg->bcsmEvents[index];
          pevent->optional_flag = 0;
          sprintf(tagseq, "16.0.16-%d.0", index + 1);   //eventTypeBCSM
          if((len = GetInteger(tagseq, (int *)&pevent->eventTypeBCSM, 0x80, &asnbuf)) < 0)
               break;
          sprintf(tagseq, "16.0.16-%d.1", index + 1);   //monitorMode
          if((len = GetInteger(tagseq, (int *)&pevent->monitorMode, 0x80, &asnbuf)) < 0)
               break;
          sprintf(tagseq, "16.0.16-%d.2", index + 1);   //LegID
          if((sel = decLegID(tagseq, &pevent->legID, &asnbuf)) >= 0)
          {
               set_bit(pevent->optional_flag, 0);
               pevent->legID_ch = sel;
          }
          if(version != 1)
          {
               sprintf(tagseq, "16.0.16-%d.30.1", index + 1);   //dPSpecificCriteria(applicationTimer)
               if((len = GetInteger(tagseq, (int *)&pevent->dPSpecificCriteria.applicationTimer, 0x80, &asnbuf)) > 0)
               {
                    set_bit(pevent->optional_flag, 1);
               }
          }
     }
     while(++index < numOfBCSMEvents);
     if((pcaparg->bcsmEvents_num = index) < 1)
          return -1;
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*EventReportBCSM-------------->        */
/*++++++++++++++++++++++++++++++++++++++ */
int eEventReportBCSM(struct CapEventReportBCSM caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((retval = AddInteger("16.0", caparg.eventTypeBCSM, 0x80, &asnbuf)) < 0)
          return -1;
     if(check_bit(caparg.optional_flag, 0))     //eventSpecificInformationBCSM
     {
          if((retval = encESIBCSM("16.2", caparg.eventSpecificInformationBCSM, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))     //legID
     {
          if((retval = AddTLV("16.3.1", 1, &caparg.legID, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 2))     //legID
     {
          if((retval = AddInteger("16.4.0", caparg.miscCallInfo.messageType, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dEventReportBCSM(char *msgbuf, int msglen, PCapEventReportBCSM pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetInteger("16.0", (int *)&pcaparg->eventTypeBCSM, 0x80, &asnbuf)) < 0)
          return -1;
     if((len = decESIBCSM("16.2", &pcaparg->eventSpecificInformationBCSM, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
          //pcaparg->eventSpecificInformationBCSM_ch = sel;
     }
     if((len = GetTLV("16.3.1", 1, &pcaparg->legID, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 1);

     if((len = GetInteger("16.4.0", (int *)&pcaparg->miscCallInfo.messageType, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 2);
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*Apply Charging Report------------->   */
/*++++++++++++++++++++++++++++++++++++++ */
int eApplyChargingReport(CapApplyChargingReport caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  len = -1;
     u_char callresult[256];

     //CAMEL-CallResult-timeDurationCharging
     AsnEncode(callresult, 256, &asnbuf);
     if((len = AddTLV("0.0.1", 1, &caparg.partyToCharge, 0x80, &asnbuf)) < 0)
          return -1;
     switch (caparg.timeInformation_ch)
     {
     case 0:
          if((len = AddInteger("0.1.0", caparg.timeInformation.timeIfNoTariffSwitch, 0x80, &asnbuf)) < 0)
               return -1;
          break;
     case 1:
          if((len = AddInteger("0.1.1.0", caparg.timeInformation.timeIfTariffSwitch.timeSinceTariffSwitch, 0x80, &asnbuf)) < 0)
               return -1;
          if((len = AddInteger("0.1.1.1", caparg.timeInformation.timeIfTariffSwitch.tariffSwitchInterval, 0x80, &asnbuf)) < 0)
               return -1;
          break;
     }
     if((len = AddTLV("0.2", 1, &caparg.callActive, 0x80, &asnbuf)) < 0)
          return -1;
     //ApplyChargingReportArg
     AsnEncode(msgbuf, maxlen, &asnbuf);
     if((len = AddTLV("4", len, callresult, 0, &asnbuf)) < 0)
          return -1;
     return len;
}

int dApplyChargingReport(char *msgbuf, int msglen, PCapApplyChargingReport pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;
     short tagcode;
     u_char callresult[256], temp[64];

     //ApplyChargingReportArg
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetTLV("4", 256, callresult, 0, &asnbuf)) < 0)
          return -1;
     //CAMEL-CallResult-timeDurationCharging
     if(AsnDecode(callresult, len, 1, &errpos, &asnbuf) < 0)
     {
          return -1;
     }
     if((len = GetTLV("0.0.1", 1, &pcaparg->partyToCharge, 0x80, &asnbuf)) < 0)
          return -1;

     if((len = GetAnyTLV("0.1.-1", 64, temp, NULL, &tagcode, &asnbuf)) < 0)
          return -1;

     switch (tagcode)
     {
     case 0:
          pcaparg->timeInformation_ch = 0;
          if((len = GetInteger("0.1.0", (int *)&pcaparg->timeInformation.timeIfNoTariffSwitch, 0x80, &asnbuf)) < 0)
               return -1;
          break;
     case 1:
          pcaparg->timeInformation_ch = 1;
          if((len = GetInteger("0.1.1.0", (int *)&pcaparg->timeInformation.timeIfTariffSwitch.timeSinceTariffSwitch, 0x80, &asnbuf)) < 0)
               return -1;
          if((len = GetInteger("0.1.1.1", (int *)&pcaparg->timeInformation.timeIfTariffSwitch.tariffSwitchInterval, 0x80, &asnbuf)) < 0)
               return -1;
          break;
     }
     if((len = GetTLV("0.2", 1, &pcaparg->callActive, 0x80, &asnbuf)) < 0)
          return -1;
     return 1;
}

int eReleaseCall(CapReleaseCall caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  reval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     reval = AddTLV("4", caparg.cause[0], caparg.cause + 1, 0, &asnbuf);
     return reval;
}

int dReleaseCall(char *msgbuf, int msglen, PCapReleaseCall pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     if(AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf) < 0)
     {
          return -1;
     }
     if((len = GetTLV("4", maxCauseLength, pcaparg->cause + 1, 0, &asnbuf)) > 0)
     {
          pcaparg->cause[0] = len;
          return 1;
     }
     else
          return -1;
}

/*************************************/
/*InitialDPSMS----------------------> */

/*************************************/
int eInitialDPSMS(struct CapInitialDPSMS caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     retval = AddInteger("16.0", caparg.serviceKey, 0x80, &asnbuf);
     //optional part
     if(check_bit(caparg.optional_flag, 0))
     {
          if((retval = AddTLV("16.1", caparg.destinationSubscriberNumber[0], caparg.destinationSubscriberNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))
     {
          if((retval = AddTLV("16.2", caparg.callingPartyNumber[0], caparg.callingPartyNumber + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 2))
     {
          if((retval = AddInteger("16.3", caparg.eventTypeSMS, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 3))
     {
          if((retval = AddTLV("16.4", caparg.iMSI[0], caparg.iMSI + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 4))
     {
          if((retval = encLocationInformation("16.5", caparg.locationInformation, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 5))
     {
          if((retval = encLocationInformationGPRS("16.6", caparg.locationInformationGPRS, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 6))
     {
          if((retval = AddTLV("16.7", caparg.sMSCAddress[0], caparg.sMSCAddress + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 7))
     {
          if((retval = AddTLV("16.8", caparg.timeAndTimezone[0], caparg.timeAndTimezone + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 8))
     {
          if((retval = AddTLV("16.9", 1, &caparg.tPShortMessageSubmissionInfo, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 9))
     {
          if((retval = AddTLV("16.10", 1, &caparg.tPProtocolIdentifier, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 10))
     {
          if((retval = AddTLV("16.11", 1, &caparg.tPDataCodingScheme + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 11))
     {
          if((retval = AddTLV("16.12", caparg.tPValidityPeriod[0], caparg.tPValidityPeriod + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dInitialDPSMS(char *msgbuf, int msglen, PCapInitialDPSMS pcaparg)
{
     ASN_BUF asnbuf;
     int  temp, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &temp, &asnbuf)) < 0)
          return -1;
     //serviceKey==============>
     if(GetInteger("16.0", &pcaparg->serviceKey, 0x80, &asnbuf) < 0)
          return -1;
     //optional part
     //destinationSubscriberNumber============>
     if((len = GetTLV("16.1", maxCalledPartyBCDNumberLength, pcaparg->destinationSubscriberNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
          pcaparg->destinationSubscriberNumber[0] = len;
     }
     //calling party number============>
     if((len = GetTLV("16.2", maxISDNAddressLength, pcaparg->callingPartyNumber + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 1);
          pcaparg->callingPartyNumber[0] = len;
     }
     //eventTypeSMS============>
     if((len = GetInteger("16.3", (int *)&pcaparg->eventTypeSMS, 0x80, &asnbuf)) > 0)
          set_bit(pcaparg->optional_flag, 2);
     //iMSI============>
     if((len = GetTLV("16.4", maxIMSILength, pcaparg->iMSI + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 3);
          pcaparg->iMSI[0] = len;
     }
     //locationInformation============>
     if(decLocationInformation("16.5", &pcaparg->locationInformation, &asnbuf) >= 0)
          set_bit(pcaparg->optional_flag, 4);
     //locationInformationGPRS============>
     if(decLocationInformationGPRS("16.6", &pcaparg->locationInformationGPRS, &asnbuf) >= 0)
          set_bit(pcaparg->optional_flag, 5);
     //sMSCAddress============>
     if((len = GetTLV("16.7", maxISDNAddressLength, pcaparg->sMSCAddress + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 6);
          pcaparg->sMSCAddress[0] = len;
     }
     //timeAndTimezone============>
     if((len = GetTLV("16.8", maxTimeAndTimezoneLength, pcaparg->timeAndTimezone + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 7);
          pcaparg->timeAndTimezone[0] = len;
     }
     //tPShortMessageSubmissionInfo============>
     if((len = GetTLV("16.9", 1, &pcaparg->tPShortMessageSubmissionInfo, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 8);
     //tPProtocolIdentifier============>
     if((len = GetTLV("16.10", 1, &pcaparg->tPProtocolIdentifier, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 9);
     //tPDataCodingScheme============>
     if((len = GetTLV("16.11", 1, &pcaparg->tPDataCodingScheme, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 10);
     //tPDataCodingScheme============>
     if((len = GetTLV("16.12", 7, pcaparg->tPValidityPeriod + 1, 0x80, &asnbuf)) >= 0)
     {
          set_bit(pcaparg->optional_flag, 11);
          pcaparg->tPValidityPeriod[0] = len;
     }
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*RequestReportSMSEvent--------------> */
/*++++++++++++++++++++++++++++++++++++++ */
int eRequestReportSMSEvent(struct CapRequestReportSMSEvent caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1, index = 0;
     char tagseq[32];

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     for(index = 0; index < caparg.sMSEvents_num; index++)
     {
          sprintf(tagseq, "16.0.16-%d", index + 1);
          add_null(tagseq, 0x20, &asnbuf);
          sprintf(tagseq, "16.0.16-%d.0", index + 1);   //eventTypeSMS
          if((retval = AddInteger(tagseq, caparg.sMSEvents[index].eventTypeSMS, 0x80, &asnbuf)) < 0)
               return -1;
          sprintf(tagseq, "16.0.16-%d.1", index + 1);   //monitorMode
          if((retval = AddInteger(tagseq, caparg.sMSEvents[index].monitorMode, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dRequestReportSMSEvent(char *msgbuf, int msglen, PCapRequestReportSMSEvent pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len, index = 0;
     char tagseq[32];
     CapSMSEvent *pevent;

     pcaparg->sMSEvents_num = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
          return -1;
     do
     {
          pevent = &pcaparg->sMSEvents[index];
          sprintf(tagseq, "16.0.16-%d.0", index + 1);   //eventTypeSMS
          if((len = GetInteger(tagseq, (int *)&pevent->eventTypeSMS, 0x80, &asnbuf)) < 0)
               break;
          sprintf(tagseq, "16.0.16-%d.1", index + 1);   //monitorMode
          if((len = GetInteger(tagseq, (int *)&pevent->monitorMode, 0x80, &asnbuf)) < 0)
               break;
     }
     while(++index < numOfSMSEvents);
     if((pcaparg->sMSEvents_num = index) < 1)
          return -1;
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*EventReportSMS-------------->        */
/*++++++++++++++++++++++++++++++++++++++ */
int eEventReportSMS(struct CapEventReportSMS caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((retval = AddInteger("16.0", caparg.eventTypeSMS, 0x80, &asnbuf)) < 0)
          return -1;
     if(check_bit(caparg.optional_flag, 0))     //eventSpecificInformationSMS
     {
          if((retval = encESISMS("16.1", caparg.eventSpecificInformationSMS, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))     //miscCallInfo
     {
          if((retval = AddInteger("16.2.0", caparg.miscCallInfo.messageType, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dEventReportSMS(char *msgbuf, int msglen, PCapEventReportSMS pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, sel, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
          return -1;
     if((len = GetInteger("16.0", (int *)&pcaparg->eventTypeSMS, 0x80, &asnbuf)) < 0)
          return -1;
     if((sel = decESISMS("16.1", &pcaparg->eventSpecificInformationSMS, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 0);
     if((len = GetInteger("16.2.0", (int *)&pcaparg->miscCallInfo.messageType, 0x80, &asnbuf)) >= 0)
          set_bit(pcaparg->optional_flag, 1);
     return 1;
}

/*++++++++++++++++++++++++++++++++++++++ */
/*ReleaseSMS------------->              */
/*++++++++++++++++++++++++++++++++++++++ */
int eReleaseSMS(CapReleaseSMS caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     return AddTLV("4", 1, &caparg.cause, 0, &asnbuf);
}

int dReleaseSMS(char *msgbuf, int msglen, PCapReleaseSMS pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     if(AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf) < 0)
          return -1;
     if((len = GetTLV("4", 1, &pcaparg->cause, 0, &asnbuf)) > 0)
          return 1;
     else
          return -1;
}

int dVPSRequst(char *msgbuf, int msglen, CapVPSRequest * vpsreq)
{
     ASN_BUF asn_buf;
     int  errpos, len;
     u8   temp_buf[1024];

     if(AsnDecode(msgbuf, msglen, 1, &errpos, &asn_buf) < 0)
          return -1;
     len = get_tlv("16.0", temp_buf, &asn_buf);
     if(len == maxVPSCallingLen)
          memcpy(vpsreq->calling_num, temp_buf, maxVPSCallingLen);
     else
          return -1;
     len = get_tlv("16.1", temp_buf, &asn_buf);
     if(len == maxVPSCalledLen)
          memcpy(vpsreq->called_num, temp_buf, maxVPSCalledLen);
     else
          return -1;
     return 1;
}

int eVPSPlayAnnounce(CapVPSPlayAnnounce * vps_ptr, char *msgbuf, int maxlen)
{
     int  temp_len;
     ASN_BUF asnbuf;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     temp_len = add_null("16", 0x20, &asnbuf);
     temp_len = add_tlv("16.0", vps_ptr->info_len, vps_ptr->send_info, 0x80, &asnbuf);
     return temp_len;
}

#ifdef _SRF_RELEVANT
int eAssistRequestInstructions(struct CapAssistRequestInstructions caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((retval = AddTLV("16.0", caparg.correlationID[0], caparg.correlationID + 1, 0x80, &asnbuf)) < 0)
          return -1;
     if((retval = AddTLV("16.2", caparg.iPSSPCapabilities[0], caparg.iPSSPCapabilities + 1, 0x80, &asnbuf)) < 0)
          return -1;
     return retval;
}

int dAssistRequestInstructions(char *msgbuf, int msglen, PCapAssistRequestInstructions pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetTLV("16.0", maxDigitsLength, pcaparg->correlationID + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->correlationID[0] = len;
     }
     if((len = GetTLV("16.2", maxIPSSPCapabilitiesLength, pcaparg->iPSSPCapabilities + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->iPSSPCapabilities[0] = len;
     }
     return 1;
}

int eEstablishTemporaryConnection(CapEstablishTemporaryConnection caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((retval = AddTLV("16.0", caparg.assistingSSPIPRoutingAddress[0], caparg.assistingSSPIPRoutingAddress + 1, 0x80, &asnbuf)) < 0)
          return -1;
     if(check_bit(caparg.optional_flag, 0))
     {
          if((retval = AddTLV("16.1", caparg.correlationID[0], caparg.correlationID + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))
     {
          if((retval = AddTLV("16.3", caparg.scfID[0], caparg.scfID + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 3))
     {
          if((retval = encServiceInteractionIndicatorsTwo("16.7", caparg.serviceInteractionIndicatorsTwo, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dEstablishTemporaryConnection(char *msgbuf, int msglen, PCapEstablishTemporaryConnection pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetTLV("16.0", maxDigitsLength, pcaparg->assistingSSPIPRoutingAddress + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->assistingSSPIPRoutingAddress[0] = len;
     }
     if((len = GetTLV("16.1", maxDigitsLength, pcaparg->correlationID + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
          pcaparg->correlationID[0] = len;
     }
     if((len = GetTLV("16.3", maxScfIDLength, pcaparg->scfID + 1, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 1);
          pcaparg->scfID[0] = len;
     }
     if(decServiceInteractionIndicatorsTwo("16.7", &pcaparg->serviceInteractionIndicatorsTwo, &asnbuf) >= 0)
     {
          set_bit(pcaparg->optional_flag, 3);
     }
     return 1;
}

int eConnectToResource(CapConnectToResource caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     switch (caparg.resourceAddress.choice_id)
     {
     case 0:
          if((retval = AddTLV("16.0", caparg.resourceAddress.ipRoutingAddress[0], caparg.resourceAddress.ipRoutingAddress + 1, 0x80, &asnbuf)) < 0)
               return -1;
          break;
     case 1:
          if((retval = add_bool("16.3", caparg.resourceAddress.none, 0x80, &asnbuf)) < 0)
               return -1;;
          break;
     }
     if(check_bit(caparg.optional_flag, 1))
     {
          if((retval = encServiceInteractionIndicatorsTwo("16.7", caparg.serviceInteractionIndicatorsTwo, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dConnectToResource(char *msgbuf, int msglen, PCapConnectToResource pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if((len = GetTLV("16.0", maxCalledPartyNumberLength, pcaparg->resourceAddress.ipRoutingAddress + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->resourceAddress.ipRoutingAddress[0] = len;
          pcaparg->resourceAddress.choice_id = 0;
     }
     else if((len = GetTLV("16.3", 1, &pcaparg->resourceAddress.none, 0x80, &asnbuf)) > 0)
     {
          pcaparg->resourceAddress.choice_id = 1;
     }
     if(decServiceInteractionIndicatorsTwo("16.7", &pcaparg->serviceInteractionIndicatorsTwo, &asnbuf) >= 0)
     {
          set_bit(pcaparg->optional_flag, 1);
     }
     return 1;
}

int eConnect(CapConnect caparg, char *msgbuf, int maxlen , u8 version)
{
     ASN_BUF asnbuf;
     int  retval = -1;
     int  index=0;
     char tagseq[16];

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     sprintf(tagseq, "16.0.4");
     if((retval = AddTLV(tagseq, caparg.destinationRoutingAddress[0], 		   caparg.destinationRoutingAddress + 1, 0x00, &asnbuf)) < 0)
          return -1;
      
     if( version >1 )
     {    
		     if(check_bit(caparg.optional_flag, 0))
		     {
		     	    sprintf(tagseq, "16.1");
		          if((retval = AddTLV("16.1", 3, caparg.alertingPattern, 0x80, &asnbuf)) < 0)
		               return -1;
		     }
     }
      
     if(check_bit(caparg.optional_flag, 1))
     {
     	    sprintf(tagseq, "16.6.4");
          if((retval = AddTLV(tagseq, caparg.originalCalledPartyID[0], caparg.originalCalledPartyID + 1, 0x00, &asnbuf)) < 0)
               return -1;
     }
     
     if( version == 1 )
     {
			     if(check_bit(caparg.optional_flag, 6))
			     {
			          for(index = 0; index < caparg.genericNumbers.num; index++)
			          {
			               sprintf(tagseq, "16.14");
			               if((retval = AddTLV(tagseq, caparg.genericNumbers.genericNumber[index][0], caparg.genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) < 0)
			                    return -1;
			          }
			     }
     
     
			     if(check_bit(caparg.optional_flag, 9))
			     {
			     	     sprintf(tagseq, "16.27.4");
			          if((retval = AddTLV("16.27.4", caparg.callingpartynum.callingpartyNmuber_len, caparg.callingpartynum.callingPartyNumber, 0x80, &asnbuf)) < 0)
			               return -1;
			     }
		 }
		 
     if(check_bit(caparg.optional_flag, 3))
     {
     	   sprintf(tagseq, "16.28-%d",index+1);
          if((retval = AddTLV("16.28", 1, &caparg.callingPartysCategory, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 4))
     {
     	    sprintf(tagseq, "16.29-%d",index+1);
          if((retval = AddTLV("16.29", caparg.redirectingPartyID[0], caparg.redirectingPartyID + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 5))
     {
     	
     	    sprintf(tagseq, "16.30-%d",index+1);
          if((retval = AddTLV("16.30", caparg.redirectionInformation[0], caparg.redirectionInformation + 1, 0x80, &asnbuf)) < 0)
               return -1;
     }
     
     if( version >1 )
     {
     	
     	    if(check_bit(caparg.optional_flag, 6))
     			{
		          for(index = 0; index < caparg.genericNumbers.num; index++)
		          {
		               sprintf(tagseq, "16.14-%d", index + 1);
		               if((retval = AddTLV(tagseq, caparg.genericNumbers.genericNumber[index][0], caparg.genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) < 0)
		                    return -1;
		          }
     			}
     }
     
     if(check_bit(caparg.optional_flag, 7))
     {
     	    sprintf(tagseq, "16.55-%d",index+1);
          if((retval = AddTLV("16.55", 1, &caparg.suppressionOfAnnouncement, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 8))
     {
     	    sprintf(tagseq, "16.56-%d",index+1);
          if((retval = AddTLV("16.56", 1, &caparg.oCSIApplicable, 0x80, &asnbuf)) < 0)
               return -1;
     }
     
     return retval;
}

int dConnect(char *msgbuf, int msglen, PCapConnect pcaparg , u8 version)
{
     ASN_BUF asnbuf;
     int  errpos, len;
     char tagseq[16];
     int  index;
     u8   temp_buf[256];

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     
     if((len = GetTLV("16.0.4", maxCalledPartyNumberLength, pcaparg->destinationRoutingAddress + 1, 0x00, &asnbuf)) > 0)
     {
          pcaparg->destinationRoutingAddress[0] = len;
     }
      if((len = GetTLV("16.1", 3, pcaparg->alertingPattern, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
     }
     if((len = GetTLV("16.6.4", maxOriginalCalledPartyIDLength, pcaparg->originalCalledPartyID + 1, 0x00, &asnbuf)) > 0)
     {
          pcaparg->originalCalledPartyID[0] = len;
          set_bit(pcaparg->optional_flag, 1);
     }
     
     
     pcaparg->genericNumbers.num = 0;
     for(index = 0; index < numOfGenericNumbers; index++)       //refer to decVariablePart(to be modified)
     {
          sprintf(tagseq, "16.14-%d", index + 1);
          if((len = GetTLV(tagseq, maxGenericNumberLength, pcaparg->genericNumbers.genericNumber[index] + 1, 0x80, &asnbuf)) > 0)
          {
               pcaparg->genericNumbers.genericNumber[index][0] = len;
               pcaparg->genericNumbers.num++;
          }
          else
          {
               if(pcaparg->genericNumbers.num > 0)
               {
                    set_bit(pcaparg->optional_flag, 6);
               }
               break;
          }
     }
     
     if((len = GetTLV("16.28", 1, &pcaparg->callingPartysCategory, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 3);
     }
     if((len = GetTLV("16.29", maxRedirectingPartyIDLength, pcaparg->redirectingPartyID + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->redirectingPartyID[0] = len;
          set_bit(pcaparg->optional_flag, 4);
     }
     if((len = GetTLV("16.30", 2, pcaparg->redirectionInformation + 1, 0x80, &asnbuf)) > 0)
     {
          pcaparg->redirectionInformation[0] = len;
          set_bit(pcaparg->optional_flag, 5);
     }

     if((len = GetTLV("16,55", 1, &pcaparg->suppressionOfAnnouncement, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 7);
     }
     if((len = GetTLV("16.56", 1, &pcaparg->oCSIApplicable, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 8);
     }
     
     if((len = get_tlv("16.27.4", temp_buf, &asnbuf)) != -1)
     {
          pcaparg->callingpartynum.callingpartyNmuber_len = len;
          memcpy(pcaparg->callingpartynum.callingPartyNumber, temp_buf, len);
          set_bit(pcaparg->optional_flag, 9);
     }
     return 1;
}

int ePlayAnnouncement(CapPlayAnnouncement caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);
     if((retval = encInformationToSend("16.0", caparg.informationToSend, &asnbuf)) < 0)
          return -1;
     if(check_bit(caparg.optional_flag, 0))
     {
          if((retval = AddTLV("16.1", 1, &caparg.disconnectFromIPForbidden, 0x80, &asnbuf)) < 0)
               return -1;
     }
     if(check_bit(caparg.optional_flag, 1))
     {
          if((retval = AddTLV("16.2", 1, &caparg.requestAnnouncementComplete, 0x80, &asnbuf)) < 0)
               return -1;
     }
     return retval;
}

int dPlayAnnouncement(char *msgbuf, int msglen, PCapPlayAnnouncement pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     pcaparg->optional_flag = 0;
     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if(decInformationToSend("16.0", &pcaparg->informationToSend, &asnbuf) < 0)
          return -1;
     if((len = GetTLV("16.1", 1, &pcaparg->disconnectFromIPForbidden, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 0);
     }
     if((len = GetTLV("16.2", 1, &pcaparg->requestAnnouncementComplete, 0x80, &asnbuf)) > 0)
     {
          set_bit(pcaparg->optional_flag, 1);
     }
     return 1;
}

int ePromptAndCollectUserInformation(u8 otype, CapPromptAndCollectUserInformation caparg, char *msgbuf, int maxlen)
{
     ASN_BUF asnbuf;
     int  retval = -1;

     AsnEncode(msgbuf, maxlen, &asnbuf);
     add_null("16", 0x20, &asnbuf);

     if(otype == CAP_REQUEST)   //invoke
     {
          if((retval = encCollectedInfo("16.0", caparg.collectedInfo, &asnbuf)) < 0)
               return -1;
          if(check_bit(caparg.optional_flag, 0))
          {
               if((retval = AddTLV("16.1", 1, &caparg.disconnectFromIPForbidden, 0x80, &asnbuf)) < 0)
                    return -1;
          }
          if(check_bit(caparg.optional_flag, 1))
          {
               if((retval = encInformationToSend("16.2", caparg.informationToSend, &asnbuf)) < 0)
                    return -1;
          }
     }
     else if(otype == CAP_RESPONSE)     //return result
     {
          if(caparg.choice_id == 0)
          {
               if((retval = AddTLV("16.0", caparg.digitsResponse[0], caparg.digitsResponse + 1, 0x80, &asnbuf)) < 0)
                    return -1;
          }
     }
     return retval;
}

int dPromptAndCollectUserInformation(u8 otype, char *msgbuf, int msglen, PCapPromptAndCollectUserInformation pcaparg)
{
     ASN_BUF asnbuf;
     int  errpos, len;

     if((len = AsnDecode(msgbuf, msglen, 1, &errpos, &asnbuf)) < 0)
     {
          return -1;
     }
     if(otype == CAP_INDICATE)
     {
          pcaparg->optional_flag = 0;
          if(decCollectedInfo("16.0", &pcaparg->collectedInfo, &asnbuf) < 0)
               return -1;
          if(GetTLV("16.1", 1, &pcaparg->disconnectFromIPForbidden, 0x80, &asnbuf) >= 0)
          {
               set_bit(pcaparg->optional_flag, 0);
          }
          if(decInformationToSend("16.2", &pcaparg->informationToSend, &asnbuf) >= 0)
          {
               set_bit(pcaparg->optional_flag, 1);
          }
     }
     else if(otype == CAP_CONFIRM)
     {
          if((len = GetTLV("16.0", maxDigitsLength, pcaparg->digitsResponse + 1, 0x80, &asnbuf)) > 0)
          {
               pcaparg->digitsResponse[0] = len;
               pcaparg->choice_id = 0;
          }
          else
          {
               return -1;
          }
     }
     return 1;
}
#endif

int encode_capmsg(struct CapArg caparg, u8 * msgbuf, u16 maxlen)
{                               //return the length of byte flow, if failed return -1
     int  retval = -1;

#ifdef	_SRF_RELEVANT
     u8   otype;
#endif

     switch (caparg.ocode)
     {
     case CAP_OC_ActivityTest:
          retval = 0;
          break;
     case CAP_OC_Cancel:
          retval = eCancel(caparg.msg_list.cancelArg, msgbuf, maxlen);
          break;
     case CAP_OC_Continue:
          retval = 0;
          break;
     case CAP_OC_EventReportBCSM:
          retval = eEventReportBCSM(caparg.msg_list.eventReportBCSMArg, msgbuf, maxlen);
          break;
     case CAP_OC_InitialDP:
          retval = eInitialDP(caparg.msg_list.initialDPArg, msgbuf, maxlen,caparg.version+1);
          break;
     case CAP_OC_ApplyCharging:
          retval = eApplyCharging(caparg.msg_list.applyChargingArg, msgbuf, maxlen);
          break;
     case CAP_OC_ApplyChargingReport:
          retval = eApplyChargingReport(caparg.msg_list.applyChargingReportArg, msgbuf, maxlen);
          break;
     case CAP_OC_RequestReportBCSMEvent:
          retval = eRequestReportBCSMEvent(caparg.msg_list.requestReportBCSMEventArg, msgbuf, maxlen, caparg.version+1);
          break;
     case CAP_OC_ReleaseCall:
          retval = eReleaseCall(caparg.msg_list.releaseCallArg, msgbuf, maxlen);
          break;
     case CAP_OC_ContinueSMS:
          retval = 0;
          break;
     case CAP_OC_EventReportSMS:
          retval = eEventReportSMS(caparg.msg_list.eventReportSMSArg, msgbuf, maxlen);
          break;
     case CAP_OC_InitialDPSMS:
          retval = eInitialDPSMS(caparg.msg_list.initialDPSMSArg, msgbuf, maxlen);
          break;
     case CAP_OC_RequestReportSMSEvent:
          retval = eRequestReportSMSEvent(caparg.msg_list.requestReportSMSEventArg, msgbuf, maxlen);
          break;
     case CAP_OC_ReleaseSMS:
          retval = eReleaseSMS(caparg.msg_list.releaseSMSArg, msgbuf, maxlen);
          break;
     case 0xb1:
          retval = eVPSPlayAnnounce(&caparg.msg_list.vpsPlayAnnounce, msgbuf, maxlen);
          break;
#ifdef _SRF_RELEVANT
     case CAP_OC_AssistRequestInstructions:
          retval = eAssistRequestInstructions(caparg.msg_list.assistRequestInstructionsArg, msgbuf, maxlen);
          break;
     case CAP_OC_EstablishTemporaryConnection:
          retval = eEstablishTemporaryConnection(caparg.msg_list.establishTemporaryConnectionArg, msgbuf, maxlen);
          break;
     case CAP_OC_DisconnectForwardConnection:
          retval = 0;
          break;
     case CAP_OC_ConnectToResource:
          retval = eConnectToResource(caparg.msg_list.connectToResourceArg, msgbuf, maxlen);
          break;
     case CAP_OC_Connect:
          retval = eConnect(caparg.msg_list.connectArg, msgbuf, maxlen, caparg.version+1);
          break;
     case CAP_OC_PlayAnnouncement:
          retval = ePlayAnnouncement(caparg.msg_list.playAnnouncementArg, msgbuf, maxlen);
          break;
     case CAP_OC_PromptAndCollectUserInformation:
          otype = caparg.message_flag;
          retval = ePromptAndCollectUserInformation(otype, caparg.msg_list.promptAndCollectUserInformationArg, msgbuf, maxlen);
          break;
     case CAP_OC_SpecializedResourceReport:
          retval = 0;
          break;
#endif
     default:
          break;
     }
     return retval;
}

#ifdef _SRF_RELEVANT
int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, u8 otype, struct CapArg *pcaparg)
#else
int decode_capmsg(char *msgbuf, u16 msglen, u8 ocode, struct CapArg *pcaparg)
#endif
{
     int  retval = 0;

     switch (ocode)
     {
     case CAP_OC_ActivityTest:
          break;
     case CAP_OC_Cancel:
          retval = dCancel(msgbuf, msglen, &pcaparg->msg_list.cancelArg);
          break;
     case CAP_OC_Continue:
          break;
     case CAP_OC_EventReportBCSM:
          retval = dEventReportBCSM(msgbuf, msglen, &pcaparg->msg_list.eventReportBCSMArg);
          break;
     case CAP_OC_InitialDP: 
          retval = dInitialDP(msgbuf, msglen, &pcaparg->msg_list.initialDPArg,pcaparg->version+1);
          break;
     case CAP_OC_ApplyCharging:
          retval = dApplyCharging(msgbuf, msglen, &pcaparg->msg_list.applyChargingArg);
          break;
     case CAP_OC_ApplyChargingReport:
          retval = dApplyChargingReport(msgbuf, msglen, &pcaparg->msg_list.applyChargingReportArg);
          break;
     case CAP_OC_RequestReportBCSMEvent:
          retval = dRequestReportBCSMEvent(msgbuf, msglen, &pcaparg->msg_list.requestReportBCSMEventArg, pcaparg->version+1);
          break;
     case CAP_OC_ReleaseCall:
          retval = dReleaseCall(msgbuf, msglen, &pcaparg->msg_list.releaseCallArg);
          break;
     case CAP_OC_ContinueSMS:
          break;
     case CAP_OC_EventReportSMS:
          retval = dEventReportSMS(msgbuf, msglen, &pcaparg->msg_list.eventReportSMSArg);
          break;
     case CAP_OC_InitialDPSMS:
          retval = dInitialDPSMS(msgbuf, msglen, &pcaparg->msg_list.initialDPSMSArg);
          break;
     case CAP_OC_RequestReportSMSEvent:
          retval = dRequestReportSMSEvent(msgbuf, msglen, &pcaparg->msg_list.requestReportSMSEventArg);
          break;
     case CAP_OC_ReleaseSMS:
          retval = dReleaseSMS(msgbuf, msglen, &pcaparg->msg_list.releaseSMSArg);
          break;
     case 0xb0:
          retval = dVPSRequst(msgbuf, msglen, &pcaparg->msg_list.vpsRequest);
          break;
#ifdef _SRF_RELEVANT
     case CAP_OC_AssistRequestInstructions:
          retval = dAssistRequestInstructions(msgbuf, msglen, &pcaparg->msg_list.assistRequestInstructionsArg);
          break;
     case CAP_OC_EstablishTemporaryConnection:
          retval = dEstablishTemporaryConnection(msgbuf, msglen, &pcaparg->msg_list.establishTemporaryConnectionArg);
          break;
     case CAP_OC_DisconnectForwardConnection:
          break;
     case CAP_OC_ConnectToResource:
          retval = dConnectToResource(msgbuf, msglen, &pcaparg->msg_list.connectToResourceArg);
          break;
     case CAP_OC_Connect:
          retval = dConnect(msgbuf, msglen, &pcaparg->msg_list.connectArg,pcaparg->version+1);
          break;
     case CAP_OC_PlayAnnouncement:
          retval = dPlayAnnouncement(msgbuf, msglen, &pcaparg->msg_list.playAnnouncementArg);
          break;
     case CAP_OC_PromptAndCollectUserInformation:
          retval = dPromptAndCollectUserInformation(otype, msgbuf, msglen, &pcaparg->msg_list.promptAndCollectUserInformationArg);
          break;
     case CAP_OC_SpecializedResourceReport:
          break;
#endif
     default:
          break;
     }
     pcaparg->ocode = ocode;
     return retval;
}
