# camel.cnf # camel conformation file # Anders Broman 2007 #.IMPORT ../gsm_map/gsm_map-exp.cnf #.IMPORT ../inap/inap-exp.cnf #.MODULE CS1-DataTypes inap CS2-datatypes inap #.ASSIGNED_OBJECT_IDENTIFIER classes #.ASSIGNED_OBJECT_IDENTIFIER ros-InformationObjects #.ASSIGNED_OBJECT_IDENTIFIER tc-Messages #.ASSIGNED_OBJECT_IDENTIFIER tc-NotationExtensions #.ASSIGNED_OBJECT_IDENTIFIER gprsSSF-gsmSCF-Operations #.ASSIGNED_OBJECT_IDENTIFIER gsmSCF-gsmSRF-Operations #.ASSIGNED_OBJECT_IDENTIFIER gsmSSF-gsmSCF-Operations #.ASSIGNED_OBJECT_IDENTIFIER sms-Operations #.ASSIGNED_OBJECT_IDENTIFIER gsmSSF-gsmSCF-Protocol #.ASSIGNED_OBJECT_IDENTIFIER gsmSCF-gsmSRF-Protocol #.ASSIGNED_OBJECT_IDENTIFIER operationcodes #.ASSIGNED_OBJECT_IDENTIFIER datatypes #.ASSIGNED_OBJECT_IDENTIFIER errortypes #.OMIT_ASSIGNMENT Remote-Operations-Information-Objects Bind Unbind #.END #.OMIT_ASSIGNMENT # Removed as they are giving 'defined but not used' warnings currently. RejectProblem TariffSwitchInterval Priority #.END #.PDU ERROR.&ParameterType OPERATION.&ArgumentType OPERATION.&ResultType #.END #.REGISTER CAP-GPRS-ReferenceNumber B "0.4.0.0.1.1.5.2" "id-CAP-GPRS-ReferenceNumber" CAP-U-ABORT-REASON B "0.4.0.0.1.1.2.2" "id-CAP-U-ABORT-Reason" #.NO_EMIT ONLY_VALS CAMEL-AChBillingChargingCharacteristicsV2 ROS #.TYPE_RENAME ReturnResult/result/result ResultArgument #.FIELD_RENAME Invoke/linkedId/present linkedIdPresent Reject/problem/invoke invokeProblem Reject/problem/returnError returnErrorProblem ReturnResult/result/result resultArgument Reject/problem/returnResult problemReturnResult PAR-cancelFailed/problem par-cancelFailedProblem CAMEL-FCIBillingChargingCharacteristics/fCIBCCCAMELsequence1 fci-fCIBCCCAMELsequence1 CAMEL-FCIGPRSBillingChargingCharacteristics/fCIBCCCAMELsequence1 fciGPRS-fCIBCCCAMELsequence1 CAMEL-FCISMSBillingChargingCharacteristics/fCIBCCCAMELsequence1 fciSMS-fCIBCCCAMELsequence1 EventSpecificInformationBCSM/oMidCallSpecificInfo/midCallEvents omidCallEvents EventSpecificInformationBCSM/tMidCallSpecificInfo/midCallEvents tmidCallEvents AudibleIndicator/tone audibleIndicatorTone GapIndicators/duration gapIndicatorsDuration InbandInfo/duration inbandInfoDuration Tone/duration toneDuration Burst/toneDuration burstToneDuration EventSpecificInformationSMS/o-smsFailureSpecificInfo/failureCause mo-smsfailureCause EventSpecificInformationBCSM/routeSelectFailureSpecificInfo/failureCause routeSelectfailureCause EventSpecificInformationSMS/t-smsFailureSpecificInfo/failureCause t-smsfailureCause CAMEL-FCIBillingChargingCharacteristics/fCIBCCCAMELsequence1/partyToCharge fCIBCCCAMELsequence1partyToCharge CAMEL-CallResult/timeDurationChargingResult/partyToCharge timeDurationChargingResultpartyToCharge AOCSubsequent/tariffSwitchInterval aocSubsequent-tariffSwitchInterval CAMEL-AChBillingChargingCharacteristics/timeDurationCharging/tariffSwitchInterval timeDurationCharging-tariffSwitchInterval ApplyChargingGPRSArg/tariffSwitchInterval applyChargingGPRS-tariffSwitchInterval TimeIfTariffSwitch/tariffSwitchInterval timeIfTariffSwitch-tariffSwitchInterval # This table creates the value_string to name Camel operation codes and errors # in file packet-camel-table.c which is included in the template file # #.TABLE_HDR /* CAMEL OPERATIONS */ const value_string camel_opr_code_strings[] = { #.TABLE_BODY OPERATION { %(&operationCode)s, "%(_ident)s" }, #.TABLE_FTR { 0, NULL } }; #.END #.TABLE_HDR /* CAMEL ERRORS */ static const value_string camel_err_code_string_vals[] = { #.TABLE_BODY ERROR { %(&errorCode)s, "%(_ident)s" }, #.TABLE_FTR { 0, NULL } }; #.END # This table creates the switch() to branch on Camel operation codes and errors # in file packet-camel-table2.c which is included in the template file # #.TABLE2_HDR static int dissect_invokeData(proto_tree *tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx) { switch(opcode){ #.TABLE2_BODY OPERATION.&ArgumentType case %(&operationCode)s: /* %(_ident)s */ offset= %(_argument_pdu)s(tvb, actx->pinfo , tree , NULL); break; #.TABLE2_FTR default: proto_tree_add_expert_format(tree, actx->pinfo, &ei_camel_unknown_invokeData, tvb, offset, -1, "Unknown invokeData %d", opcode); /* todo call the asn.1 dissector */ break; } return offset; } #.END #.TABLE2_HDR static int dissect_returnResultData(proto_tree *tree, tvbuff_t *tvb, int offset,asn1_ctx_t *actx) { switch(opcode){ #.TABLE2_BODY OPERATION.&ResultType case %(&operationCode)s: /* %(_ident)s */ offset= %(_result_pdu)s(tvb, actx->pinfo , tree , NULL); break; #.TABLE2_FTR default: proto_tree_add_expert_format(tree, actx->pinfo, &ei_camel_unknown_returnResultData, tvb, offset, -1, "Unknown returnResultData %d",opcode); } return offset; } #.END #.TABLE2_HDR static int dissect_returnErrorData(proto_tree *tree, tvbuff_t *tvb, int offset,asn1_ctx_t *actx) { switch(errorCode) { #.TABLE2_BODY ERROR.&ParameterType case %(&errorCode)s: /* %(_ident)s */ %(_parameter_pdu)s(tvb, actx->pinfo , tree , NULL); break; #.TABLE2_FTR default: proto_tree_add_expert_format(tree, actx->pinfo, &ei_camel_unknown_returnErrorData, tvb, offset, -1, "Unknown returnErrorData %d",errorCode); } return offset; } #.END # ROS stuff here XXX change when TCAP is redone. #.FN_BODY Code/local VAL_PTR = &opcode if (is_ExtensionField){ hf_index = hf_camel_extension_code_local; }else if (camel_opcode_type == CAMEL_OPCODE_RETURN_ERROR){ hf_index = hf_camel_error_code_local; } %(DEFAULT_BODY)s if (is_ExtensionField == false){ if (camel_opcode_type == CAMEL_OPCODE_RETURN_ERROR){ errorCode = opcode; col_append_str(actx->pinfo->cinfo, COL_INFO, val_to_str(errorCode, camel_err_code_string_vals, "Unknown CAMEL error (%%u)")); col_append_str(actx->pinfo->cinfo, COL_INFO, " "); col_set_fence(actx->pinfo->cinfo, COL_INFO); }else{ col_append_str(actx->pinfo->cinfo, COL_INFO, val_to_str(opcode, camel_opr_code_strings, "Unknown CAMEL (%%u)")); col_append_str(actx->pinfo->cinfo, COL_INFO, " "); col_set_fence(actx->pinfo->cinfo, COL_INFO); } gp_camelsrt_info->opcode=opcode; } #.FN_HDR Invoke camel_opcode_type=CAMEL_OPCODE_INVOKE; #.FN_HDR ReturnResult camel_opcode_type=CAMEL_OPCODE_RETURN_RESULT; #.FN_HDR ReturnError camel_opcode_type=CAMEL_OPCODE_RETURN_ERROR; #.FN_HDR Reject camel_opcode_type=CAMEL_OPCODE_REJECT; #.FN_BODY Invoke/argument offset = dissect_invokeData(tree, tvb, offset, actx); #.FN_BODY ReturnResult/result/result offset = dissect_returnResultData(tree, tvb, offset, actx); #.FN_BODY ReturnError/parameter offset = dissect_returnErrorData(tree, tvb, offset, actx); # END ROS #.FN_BODY InitialDPArgExtension if((camel_ver == 2)||(camel_ver == 1)){ return dissect_camel_InitialDPArgExtensionV2(implicit_tag, tvb, offset, actx, tree, hf_index); } %(DEFAULT_BODY)s #.FN_HDR ExtensionField camel_obj_id = NULL; is_ExtensionField =true; #.FN_PARS Code/global FN_VARIANT = _str VAL_PTR = &camel_obj_id #.FN_BODY ExtensionField/value /*XXX handle local form here */ if(camel_obj_id){ offset=call_ber_oid_callback(camel_obj_id, tvb, offset, actx->pinfo, tree, NULL); } is_ExtensionField = false; #---------------------------------------------------------------------------------------- #.FN_BODY CallingPartyNumber VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_callingpartynumber); dissect_isup_calling_party_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_BODY CalledPartyNumber VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_calledpartybcdnumber); dissect_isup_called_party_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_BODY LocationNumber VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_locationnumber); dissect_isup_location_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_BODY GenericNumber VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; dissect_isup_generic_number_parameter(parameter_tvb, actx->pinfo, tree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_BODY Cause VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; uint8_t Cause_value; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_cause); dissect_q931_cause_ie(parameter_tvb, 0, tvb_reported_length_remaining(parameter_tvb,0), subtree, hf_camel_cause_indicator, &Cause_value, isup_parameter_type_value); #.END #---------------------------------------------------------------------------------------- #.FN_BODY RPCause VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; uint8_t Cause_value; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_RPcause); dissect_RP_cause_ie(parameter_tvb, 0, tvb_reported_length_remaining(parameter_tvb,0), subtree, hf_camel_RP_Cause, &Cause_value); #.END #---------------------------------------------------------------------------------------- #.FN_BODY DateAndTime /* * date_option = 1 european dd:mm:yyyy * date_option = 2 american mm:dd:yyyy */ /* * Output should be HH:MM:SS;dd/mm/yyyy * if european is selected, and HH:MM:SS;mm/dd/yyyy * otherwise. */ uint8_t digit_pair; uint8_t i = 0, curr_offset; char camel_time[CAMEL_DATE_AND_TIME_LEN]; char c[CAMEL_DATE_AND_TIME_LEN]; /*temporary container*/ /* 2 digits per octet, 7 octets total + 5 delimiters */ for (curr_offset = 0; curr_offset < 7 ; curr_offset++) /*Loop to extract date*/ { digit_pair = tvb_get_uint8(tvb, curr_offset); proto_tree_add_uint(tree, hf_digit, tvb, curr_offset, 1, digit_pair & 0x0F); proto_tree_add_uint(tree, hf_digit, tvb, curr_offset, 1, digit_pair >>4); c[i] = camel_number_to_char( digit_pair & 0x0F); i++; c[i] = camel_number_to_char( digit_pair >>4); i++; } /* Pretty print date */ /* XXX - Should we use snprintf here instead of assembling the string by * hand? */ camel_time[0] = c[8]; camel_time[1] = c[9]; camel_time[2] = ':'; camel_time[3] = c[10]; camel_time[4] = c[11]; camel_time[5] = ':'; camel_time[6] = c[12]; camel_time[7] = c[13]; camel_time[8] = ';'; if ( EUROPEAN_DATE == date_format) /*european*/ { camel_time[9] = c[6]; /*day*/ camel_time[10] = c[7]; camel_time[11] = '/'; camel_time[12] = c[4]; /*month*/ camel_time[13] = c[5]; } else /*american*/ { camel_time[9] = c[4]; /*month*/ camel_time[10] = c[5]; camel_time[11] = '/'; camel_time[12] = c[6]; /*day*/ camel_time[13] = c[7]; } camel_time[14] = '/'; camel_time[15] = c[0]; camel_time[16] = c[1]; camel_time[17] = c[2]; camel_time[18] = c[3]; camel_time[CAMEL_DATE_AND_TIME_LEN - 1] = '\0'; /*start = 0, length = 7*/ proto_tree_add_string(tree, hf_index, tvb, 0, 7, camel_time); return 7; /* 7 octets eaten*/ #.END #---------------------------------------------------------------------------------------- #.FN_BODY BearerCapability/bearerCap VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; dissect_q931_bearer_capability_ie(parameter_tvb, 0, tvb_reported_length_remaining(parameter_tvb,0), tree); #.END #---------------------------------------------------------------------------------------- #.FN_BODY OriginalCalledPartyID VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_originalcalledpartyid); dissect_isup_original_called_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_PARS RedirectingPartyID VAL_PTR = ¶meter_tvb #.FN_BODY RedirectingPartyID tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_redirectingpartyid); dissect_isup_redirecting_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); #.END #---------------------------------------------------------------------------------------- #.FN_PARS AccessPointName VAL_PTR = ¶meter_tvb #.FN_BODY AccessPointName tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_AccessPointName); de_sm_apn(parameter_tvb, subtree, actx->pinfo, 0, tvb_reported_length(parameter_tvb), NULL, 0); #.END #---------------------------------------------------------------------------------------- #.FN_BODY EndUserAddress/pDPTypeOrganization VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; PDPTypeOrganization = (tvb_get_uint8(parameter_tvb,0) &0x0f); #.END #---------------------------------------------------------------------------------------- #.FN_BODY EndUserAddress/pDPTypeNumber VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; PDPTypeNumber = tvb_get_uint8(parameter_tvb,0); subtree = proto_item_add_subtree(actx->created_item, ett_camel_pdptypenumber); switch (PDPTypeOrganization){ case 0: /* ETSI */ proto_tree_add_item(subtree, hf_camel_PDPTypeNumber_etsi, parameter_tvb, 0, 1, ENC_BIG_ENDIAN); break; case 1: /* IETF */ proto_tree_add_item(subtree, hf_camel_PDPTypeNumber_ietf, parameter_tvb, 0, 1, ENC_BIG_ENDIAN); break; default: break; } #.END #.FN_BODY EndUserAddress/pDPAddress VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_pdptypenumber); switch (PDPTypeOrganization){ case 0: /* ETSI */ break; case 1: /* IETF */ switch(PDPTypeNumber){ case 0x21: /* IPv4 */ proto_tree_add_item(subtree, hf_camel_PDPAddress_IPv4, parameter_tvb, 0, tvb_reported_length(parameter_tvb), ENC_BIG_ENDIAN); break; case 0x57: /* IPv6 */ proto_tree_add_item(subtree, hf_camel_PDPAddress_IPv6, parameter_tvb, 0, tvb_reported_length(parameter_tvb), ENC_NA); break; default: break; } default: break; } #.END #---------------------------------------------------------------------------------------- #.FN_BODY LocationInformationGPRS/cellGlobalIdOrServiceAreaIdOrLAI proto_tree *subtree; int start_offset; start_offset = offset; %(DEFAULT_BODY)s subtree = proto_item_add_subtree(actx->created_item, ett_camel_pdptypenumber); if (tvb_reported_length_remaining(tvb,start_offset) == 7){ dissect_gsm_map_CellGlobalIdOrServiceAreaIdFixedLength(true, tvb, start_offset, actx, subtree, hf_camel_cellGlobalIdOrServiceAreaIdFixedLength); }else{ dissect_gsm_map_LAIFixedLength(true, tvb, start_offset, actx, subtree, hf_camel_locationAreaId); } #.END #---------------------------------------------------------------------------------------- #.FN_BODY AChBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_AChBillingChargingCharacteristics); if((camel_ver == 2)||(camel_ver == 1)){ return dissect_camel_CAMEL_AChBillingChargingCharacteristicsV2(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_AChBillingChargingCharacteristics); } dissect_camel_CAMEL_AChBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_AChBillingChargingCharacteristics); #.FN_BODY FCIBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_FCIBillingChargingCharacteristics); dissect_camel_CAMEL_FCIBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_FCIBillingChargingCharacteristics); #.FN_BODY FCIGPRSBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_FCIGPRSBillingChargingCharacteristics); dissect_camel_CAMEL_FCIGPRSBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_FCIGPRSBillingChargingCharacteristics); #.FN_BODY FCISMSBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_FCISMSBillingChargingCharacteristics); dissect_camel_CAMEL_FCISMSBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_FCISMSBillingChargingCharacteristics); #.FN_BODY SCIBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_SCIBillingChargingCharacteristics); dissect_camel_CAMEL_SCIBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_SCIBillingChargingCharacteristics); #.FN_BODY SCIGPRSBillingChargingCharacteristics VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_SCIGPRSBillingChargingCharacteristics); dissect_camel_CAMEL_SCIGPRSBillingChargingCharacteristics(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_SCIGPRSBillingChargingCharacteristics); #.FN_BODY CallResult VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_CAMEL_CallResult); dissect_camel_CAMEL_CallResult(false, parameter_tvb, 0, actx, subtree, hf_camel_CAMEL_CallResult); # V3 and V4 incompatibillity bug #1719 #.FN_BODY CAMEL-AChBillingChargingCharacteristics/timeDurationCharging/audibleIndicator if (tvb_reported_length_remaining(tvb,offset) < 2) offset = dissect_camel_BOOLEAN(true, tvb, offset, actx , tree, hf_camel_audibleIndicatorTone); else %(DEFAULT_BODY)s #.FN_BODY CalledPartyBCDNumber VAL_PTR = ¶meter_tvb /* See 3GPP TS 29.078 * and 3GPP TS 24.008, section 10.5.4.7 * Indicates the Called Party Number, including service selection information. * Refer to 3GPP TS 24.008 [9] for encoding. * This data type carries only the 'type of number', 'numbering plan * identification' and 'number digit' fields defined in 3GPP TS 24.008 [9]; * it does not carry the 'called party BCD number IEI' or 'length of called * party BCD number contents'. * In the context of the DestinationSubscriberNumber field in ConnectSMSArg or * InitialDPSMSArg, a CalledPartyBCDNumber may also contain an alphanumeric * character string. In this case, type-of-number '101'B is used, in accordance * with 3GPP TS 23.040 [6]. The address is coded in accordance with the * GSM 7-bit default alphabet definition and the SMS packing rules * as specified in 3GPP TS 23.038 [15] in this case. */ tvbuff_t *parameter_tvb; proto_tree *subtree; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_camel_calledpartybcdnumber); de_cld_party_bcd_num(parameter_tvb, subtree, actx->pinfo, 0, tvb_reported_length(parameter_tvb), NULL, 0); #.END #.FN_BODY Digits VAL_PTR = ¶meter_tvb /* * Digits {PARAMETERS-BOUND : bound} ::= OCTET STRING (SIZE( * bound.&minDigitsLength .. bound.&maxDigitsLength)) *-- Indicates the address signalling digits. *-- Refer to ETSI EN 300 356 1 [23] Generic Number & Generic Digits parameters for encoding. *-- The coding of the subfields 'NumberQualifier' in Generic Number and 'TypeOfDigits' in *-- Generic Digits are irrelevant to the CAP; *-- the ASN.1 tags are sufficient to identify the parameter. *-- The ISUP format does not allow to exclude these subfields, *-- therefore the value is network operator specific. *-- *-- The following parameters shall use Generic Number: *-- - AdditionalCallingPartyNumber for InitialDP *-- - AssistingSSPIPRoutingAddress for EstablishTemporaryConnection *-- - CorrelationID for AssistRequestInstructions *-- - CalledAddressValue for all occurrences, CallingAddressValue for all occurrences. *-- *-- The following parameters shall use Generic Digits: *-- - CorrelationID in EstablishTemporaryConnection *-- - number in VariablePart *-- - digitsResponse in ReceivedInformationArg *-- - midCallEvents in oMidCallSpecificInfo and tMidCallSpecificInfo *-- *-- In the digitsResponse and midCallevents, the digits may also include the '*', '#', *-- a, b, c and d digits by using the IA5 character encoding scheme. If the BCD even or *-- BCD odd encoding scheme is used, then the following encoding shall be applied for the *-- non-decimal characters: 1011 (*), 1100 (#). *-- *-- AssistingSSPIPRoutingAddress in EstablishTemporaryConnection and CorrelationID in *-- AssistRequestInstructions may contain a Hex B digit as address signal. Refer to *-- Annex A.6 for the usage of the Hex B digit. *-- *-- Note that when CorrelationID is transported in Generic Digits, then the digits shall *-- always be BCD encoded. */ tvbuff_t *parameter_tvb; proto_tree *subtree; int ett = -1; bool digits = false; offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, ¶meter_tvb); if (!parameter_tvb) return offset; if (hf_index == hf_camel_calledAddressValue) { ett = ett_camel_calledAddressValue; } else if (hf_index == hf_camel_callingAddressValue) { ett = ett_camel_callingAddressValue; } else if (hf_index == hf_camel_additionalCallingPartyNumber) { ett = ett_camel_additionalcallingpartynumber; } else if (hf_index == hf_camel_assistingSSPIPRoutingAddress) { ett = ett_camel_assistingSSPIPRoutingAddress; } else if (hf_index == hf_camel_correlationID) { ett = ett_camel_correlationID; digits = (opcode == opcode_establishTemporaryConnection) ? true : false; } else if (hf_index == hf_camel_dTMFDigitsCompleted) { ett = ett_camel_dTMFDigitsCompleted; digits = true; } else if (hf_index == hf_camel_dTMFDigitsTimeOut) { ett = ett_camel_dTMFDigitsTimeOut; digits = true; } else if (hf_index == hf_camel_number) { ett = ett_camel_number; digits = true; } else if (hf_index == hf_camel_digitsResponse) { ett = ett_camel_digitsResponse; digits = true; } subtree = proto_item_add_subtree(actx->created_item, ett); if (digits) { dissect_isup_generic_digits_parameter(parameter_tvb, subtree, NULL); } else { dissect_isup_generic_number_parameter(parameter_tvb, actx->pinfo, subtree, NULL); } # I don't know how to "access" the EstablishTemporaryConnectionArg-PDU which would have been cleaner. #.FN_BODY EstablishTemporaryConnectionArg if(camel_ver==2){ return dissect_camel_EstablishTemporaryConnectionArgV2(implicit_tag, tvb, offset, actx, tree, hf_index); } %(DEFAULT_BODY)s #.FN_BODY SpecializedResourceReportArg if (camel_ver < 4) { return dissect_camel_SpecializedResourceReportArgV23(implicit_tag, tvb, offset, actx, tree, hf_camel_allAnnouncementsComplete); } %(DEFAULT_BODY)s #.FN_BODY TimeAndTimezone VAL_PTR = ¶meter_tvb tvbuff_t *parameter_tvb; proto_tree *subtree; proto_item *item; char *digit_str; unsigned length; char year[5]; char month[3]; char day[3]; char hour[3]; char minute[3]; char second[3]; uint8_t oct; int8_t tz; %(DEFAULT_BODY)s if (!parameter_tvb) return offset; length = tvb_reported_length(parameter_tvb); if (length < 8 /*cAPSpecificBoundSetminTimeAndTimezoneLength*/){ expert_add_info(actx->pinfo, actx->created_item, &ei_camel_par_wrong_length); return offset; } subtree = proto_item_add_subtree(actx->created_item, ett_camel_timeandtimezone); item = proto_tree_add_item_ret_display_string(subtree, hf_camel_timeandtimezone_time, parameter_tvb, 0, 7, ENC_BCD_DIGITS_0_9|ENC_LITTLE_ENDIAN, actx->pinfo->pool, &digit_str); /* The Time Zone indicates the difference, expressed in quarters of an hour, between the local time and GMT. In the first of the two semi octets, the first bit (bit 3 of the seventh octet of the TP Service Centre Time Stamp field) represents the algebraic sign of this difference (0: positive, 1: negative). */ oct = tvb_get_uint8(parameter_tvb,7); /* packet-gsm_sms.c time dis_field_scts_aux() */ tz = (oct >> 4) + (oct & 0x07) * 10; tz = (oct & 0x08) ? -tz : tz; proto_tree_add_int_format_value(subtree, hf_camel_timeandtimezone_tz, parameter_tvb, 7, 1, tz, "GMT %%+d hours %%d minutes", tz / 4, tz %% 4 * 15); /* ENC_BCD_DIGITS_0_9 truncates if the nibble is 0xf. */ if (strlen(digit_str) < 14 || strchr(digit_str, '?')) { expert_add_info(actx->pinfo, item, &ei_camel_bcd_not_digit); return offset; } (void) g_strlcpy(year, digit_str, 5); (void) g_strlcpy(month, digit_str+4, 3); (void) g_strlcpy(day, digit_str+6, 3); (void) g_strlcpy(hour, digit_str+8, 3); (void) g_strlcpy(minute, digit_str+10, 3); (void) g_strlcpy(second, digit_str+12, 3); proto_item_append_text(item, " (%%s-%%s-%%s %%s:%%s:%%s)",year,month,day,hour,minute,second); #.TYPE_ATTR PDPTypeOrganization TYPE = FT_UINT8 DISPLAY = BASE_DEC BITMASK = 0x0f STRINGS = VALS(gsm_map_PDP_Type_Organisation_vals) DateAndTime TYPE = FT_STRING DISPLAY = BASE_NONE Code/local TYPE = FT_INT32 DISPLAY = BASE_DEC STRINGS = VALS(camel_opr_code_strings) ServiceInteractionIndicatorsTwo/holdTreatmentIndicator TYPE = FT_INT32 DISPLAY = BASE_DEC STRINGS = VALS(camel_holdTreatmentIndicator_values) ServiceInteractionIndicatorsTwo/cwTreatmentIndicator TYPE = FT_INT32 DISPLAY = BASE_DEC STRINGS = VALS(camel_cwTreatmentIndicator_values) ServiceInteractionIndicatorsTwo/ectTreatmentIndicator TYPE = FT_INT32 DISPLAY = BASE_DEC STRINGS = VALS(camel_ectTreatmentIndicator_values) #.FIELD_ATTR EventSpecificInformationSMS/o-smsFailureSpecificInfo/failureCause ABBREV=mo-smsfailureCause EventSpecificInformationBCSM/routeSelectFailureSpecificInfo/failureCause ABBREV=routeSelectfailureCause EventSpecificInformationSMS/t-smsFailureSpecificInfo/failureCause ABBREV=t-smsfailureCause Tone/duration ABBREV=toneDuration GapIndicators/duration ABBREV=gapIndicatorsDuration InbandInfo/duration ABBREV=inbandInfoDuration #.END