You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGAPPDU WarningMessageContents编码异常求助(Wireshark解码报错)

CBS消息编码问题排查

问题描述

我尝试将字符串“Severe Earthquake expected immediately”编码为字节流,封装到NGAP PDU的WarningMessageContents中。根据ETSI TS 138 413 V17.11.0 (2025-01)规范,WarningMessageContents定义为WarningMessageContents ::= OCTET STRING (SIZE(1..9600)),但目前遇到问题:Wireshark显示解码内容错误,且页码计算已确认正确。请帮忙排查以下代码可能存在的问题,编码方案的其他规范可参考ETSI TS 123 038 V17.0.0 (2022-04)第5节。

待排查代码

const (
  MaxCBSPageSize  = 82   // Bytes per page (after GSM 7-bit encoding)
  MaxPages        = 15   // 3GPP TS 23.041 limit
  MaxMessageBytes = 9600 // Total CBS message size limit
)

type WarningMessageContents struct {
  Value aper.OctetString `aper:"sizeLB:1,sizeUB:9600"`
}
type OctetString []byte

// Function to encode CBS message according to ETSI TS 123 041
func EncodeCBSWarningMessage(message string) (*ngapType.WarningMessageContents, error) {
  // Calculate number of pages
  messageLen := len(message)
  numPages := (messageLen + MaxCBSPageSize - 1) / MaxCBSPageSize // Ceiling division

  // Strict validation for maximum pages
  if numPages > 15 {
    return nil, fmt.Errorf("too many CBS pages (must be <= 15), found: %d", numPages)
  }

  // Validate total size
  if messageLen < 1 || messageLen > 9600 {
    return nil, errors.New("warning message size out of range (must be between 1 and 9600 bytes)")
  }

  // Build CBS formatted message
  cbsMessage := make([]byte, 0, messageLen+numPages*5) // Pre-allocate with some extra space

  // First byte is Total Number of Pages
  cbsMessage = append(cbsMessage, byte(numPages))

  // Split message into pages
  for i := 0; i < numPages; i++ {
    start := i * MaxCBSPageSize
    end := start + MaxCBSPageSize
    if end > messageLen {
      end = messageLen
    }

    // Precise page header according to CBS specifications
    pageHeader := []byte{
      byte(i + 1), // Page Number (1-based)
      0x01,        // Data Coding Scheme (GSM 7-bit)
      0x00,        // Language Group (English)
    }

    // Append page header
    cbsMessage = append(cbsMessage, pageHeader...)

    // Append page content
    cbsMessage = append(cbsMessage, []byte(message[start:end])...)
  }

  // Create WarningMessageContents
  return &ngapType.WarningMessageContents{
    Value: aper.OctetString(cbsMessage),
  }, nil
}

代码问题分析

  • GSM 7-bit编码未实现
    代码直接将原始字符串转为字节数组,但MaxCBSPageSize = 82是GSM 7-bit编码后的每页字节数。GSM 7-bit编码是把8个字符打包成7字节,因此每页能容纳的原始字符数约为82 * 8 /7 ≈93个,而非82个。当前分页逻辑用原始字符数除以82,混淆了原始字符数和编码后字节数,导致分页完全错误。必须先对字符串做GSM 7-bit编码,再按编码后的字节数分页。

  • CBS消息结构不符合规范
    根据ETSI TS 123 038第5节,多页CBS的每页头部应包含总页数+当前页号,而非仅在消息开头放一个总页数。正确的每页头部格式应为:[总页数(1字节)] + [当前页号(1字节)] + [DCS(1字节)] + [语言组(1字节)],当前结构会导致Wireshark无法识别分页信息。

  • 字符集与编码转换缺失
    Go中[]byte(message)默认输出UTF-8编码,但GSM 7-bit编码依赖GSM 03.38字符集,若字符串包含该字符集外的字符,直接转换会导致解码失败。需要先将UTF-8字符串转换为GSM 03.38字符集的字节,再执行7-bit打包。

  • DCS与编码的匹配问题
    设置的DCS值0x01对应GSM 7-bit编码,但未处理7-bit编码的填充位(最后一个字节若不足7位需补0),这会导致Wireshark解码时出现字节对齐错误。

  • 长度验证逻辑错误
    当前验证的是原始字符串长度是否在1-9600之间,但WarningMessageContents的大小限制是编码完成后的整个CBS消息(含所有头部和内容)的字节数,而非原始字符串长度。应在编码完成后检查最终cbsMessage的长度是否符合要求。

内容的提问来源于stack exchange,提问作者van

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:23:18