terça-feira, 7 de outubro de 2025

1

  # --- Configurações ---

$ussd = "*#100#"     # altera para o código que quiseres (p.ex. *#99#, *#134#, etc.)

$baud = 115200       # 9600–921600: deixa 115200 a não ser que saibas outro valor


# --- Helper: abrir porta e enviar AT ---

function Send-AT {

    param(

        [string]$PortName,

        [string]$Cmd,

        [int]$WaitMs = 500

    )

    $sp = New-Object System.IO.Ports.SerialPort $PortName,$baud,'None',8,'one'

    $sp.ReadTimeout = 1500

    $sp.WriteTimeout = 1500

    try {

        $sp.Open()

        # limpa buffers

        $sp.DiscardInBuffer(); $sp.DiscardOutBuffer()

        $sp.Write($Cmd + "`r")

        Start-Sleep -Milliseconds $WaitMs

        $out = $sp.ReadExisting()

        return $out

    } finally {

        if ($sp.IsOpen) { $sp.Close() }

        $sp.Dispose()

    }

}


# --- Descobrir portas COM que pareçam do modem (AT / Application / Modem / WWAN) ---

$comCandidates =

  Get-WmiObject Win32_PnPEntity |

  Where-Object { $_.Name -match 'COM\d+' -and $_.Name -match 'Modem|WWAN|AT|Application|Mobile|Broadband|LTE|5G|MBIM|USB' } |

  ForEach-Object {

      if ($_.Name -match '\(COM(\d+)\)') { "COM$($Matches[1])" }

  } | Select-Object -Unique


if (-not $comCandidates -or $comCandidates.Count -eq 0) {

    # fallback: tenta todas as portas COM que existam

    $comCandidates = [System.IO.Ports.SerialPort]::GetPortNames()

}


Write-Host "Portas candidatas: $($comCandidates -join ', ')" -ForegroundColor Cyan


# --- Tenta cada COM até obter OK em 'AT' ---

$okPort = $null

foreach ($p in $comCandidates) {

    try {

        $resp = Send-AT -PortName $p -Cmd "AT"

        if ($resp -match 'OK') { $okPort = $p; break }

    } catch {}

}

if (-not $okPort) {

    Write-Warning "Não consegui encontrar uma porta AT válida. Abre o Gestor de Dispositivos e vê qual é a porta 'AT' do modem."

    return

}

Write-Host "Porta AT: $okPort" -ForegroundColor Green


# --- Ativar indicação USSD e tentar em GSM 7-bit (DCS=1) ---

$null = Send-AT -PortName $okPort -Cmd 'AT+CUSD=1' -WaitMs 300

Write-Host "A enviar USSD (GSM 7-bit): $ussd" -ForegroundColor Yellow

$resp1 = Send-AT -PortName $okPort -Cmd ("AT+CUSD=1,""{0}"",1" -f $ussd) -WaitMs 1200


# Se não veio +CUSD, tenta UCS2 (DCS=15)

function To-UCS2 {

    param([string]$s)

    $bytes = @()

    $s.ToCharArray() | ForEach-Object {

        $c = [int][char]$_

        $bytes += [byte]($c -shr 8)

        $bytes += [byte]($c -band 0xFF)

    }

    ($bytes | ForEach-Object { $_.ToString("X2") }) -join ''

}


$finalResp = $resp1

if ($resp1 -notmatch '\+CUSD:') {

    $ussdUcs2 = To-UCS2 $ussd

    Write-Host "Sem resposta útil. A enviar USSD em UCS2: $ussd" -ForegroundColor Yellow

    $finalResp = Send-AT -PortName $okPort -Cmd ("AT+CUSD=1,""{0}"",15" -f $ussdUcs2) -WaitMs 1500

}


# --- Mostrar resposta formatada ---

if ($finalResp -match '\+CUSD:(.*)') {

    Write-Host "`nResposta do modem:" -ForegroundColor Cyan

    $finalResp.Trim() | Write-Output

    Write-Host "`nDica: se aparece +CUSD com '1' no primeiro campo, a rede espera nova entrada (menu USSD)." -ForegroundColor DarkGray

} else {

    Write-Warning "Não recebi resposta USSD legível. Possíveis causas: USSD bloqueado pela operadora, SIM sem registo na rede, modem/driver não suporta CUSD, ou é preciso app do fabricante."

}


Sem comentários:

Enviar um comentário