mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-20 22:58:44 +05:00
115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
//go:build ignore
|
|
|
|
// Parses Wireshark's packet-e212.c and generates utils/mccmnc_data.go.
|
|
// Run: go generate ./utils/...
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"go/format"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const wiresharkURL = "https://raw.githubusercontent.com/wireshark/wireshark/master/epan/dissectors/packet-e212.c"
|
|
|
|
// matches entries like { 123, "Some Name" } in C value_string arrays
|
|
var entryRe = regexp.MustCompile(`\{\s*(\d+),\s*"([^"]+)"\s*\}`)
|
|
|
|
func main() {
|
|
log.SetFlags(0)
|
|
|
|
src := fetchSource()
|
|
|
|
countries := parseTable(src, "E212_codes[]", func(code int) string {
|
|
return fmt.Sprintf("%03d", code)
|
|
})
|
|
networks := parseTable(src, "mcc_mnc_2digits_codes[]", func(code int) string {
|
|
return fmt.Sprintf("%03d-%02d", code/100, code%100)
|
|
})
|
|
// 3-digit MNC: only add if no 2-digit entry exists for the same key
|
|
for k, v := range parseTable(src, "mcc_mnc_3digits_codes[]", func(code int) string {
|
|
return fmt.Sprintf("%03d-%03d", code/1000, code%1000)
|
|
}) {
|
|
if _, ok := networks[k]; !ok {
|
|
networks[k] = v
|
|
}
|
|
}
|
|
|
|
var buf strings.Builder
|
|
buf.WriteString("// Code generated by gen_mccmnc from Wireshark's packet-e212.c; DO NOT EDIT.\n\npackage utils\n\n")
|
|
writeMap(&buf, "mccCountry", "MCC to country name (ITU-T E.212)", countries)
|
|
writeMap(&buf, "mccmncNetwork", "MCC-MNC to network/operator name (ITU-T E.212)", networks)
|
|
|
|
formatted, err := format.Source([]byte(buf.String()))
|
|
if err != nil {
|
|
log.Fatalf("gofmt: %v", err)
|
|
}
|
|
if err := os.WriteFile("mccmnc_data.go", formatted, 0644); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Printf("generated mccmnc_data.go: %d countries, %d networks\n", len(countries), len(networks))
|
|
}
|
|
|
|
func fetchSource() string {
|
|
resp, err := http.Get(wiresharkURL)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return string(body)
|
|
}
|
|
|
|
func parseTable(src, name string, formatKey func(int) string) map[string]string {
|
|
block := extractBlock(src, name)
|
|
if block == "" {
|
|
log.Fatalf("table %s not found", name)
|
|
}
|
|
result := make(map[string]string)
|
|
for _, m := range entryRe.FindAllStringSubmatch(block, -1) {
|
|
if m[2] == "Unassigned" || m[2] == "Unset" {
|
|
continue
|
|
}
|
|
code, _ := strconv.Atoi(m[1])
|
|
result[formatKey(code)] = m[2]
|
|
}
|
|
return result
|
|
}
|
|
|
|
// extractBlock returns the body of a C value_string array, up to its { 0, NULL } terminator.
|
|
func extractBlock(src, name string) string {
|
|
marker := "value_string " + name + " = {"
|
|
start := strings.Index(src, marker)
|
|
if start < 0 {
|
|
return ""
|
|
}
|
|
end := strings.Index(src[start:], "{ 0, NULL }")
|
|
if end < 0 {
|
|
return ""
|
|
}
|
|
return src[start : start+end]
|
|
}
|
|
|
|
func writeMap(buf *strings.Builder, varName, comment string, m map[string]string) {
|
|
keys := make([]string, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
fmt.Fprintf(buf, "// %s maps %s.\nvar %s = map[string]string{\n", varName, comment, varName)
|
|
for _, k := range keys {
|
|
fmt.Fprintf(buf, "\t%q: %q,\n", k, m[k])
|
|
}
|
|
buf.WriteString("}\n\n")
|
|
}
|