blob: 48f1bc0a01de192bdbf0beb1b51d042386063a5c [file] [log] [blame] [edit]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package network
import (
"context"
"chromiumos/tast/common/mmconst"
"chromiumos/tast/common/shillconst"
"chromiumos/tast/errors"
"chromiumos/tast/local/bundles/cros/network/cellular"
"chromiumos/tast/local/dbusutil"
"chromiumos/tast/local/modemmanager"
"chromiumos/tast/testing"
)
// This test is only run on the cellular_multisim group. All boards in that group
// provide the Modem.SimSlots property and have at least two provisioned SIM slots.
func init() {
testing.AddTest(&testing.Test{
Func: ShillCellularSimConnect,
Desc: "Verifies that Shill can connect to a service in a different slot",
Contacts: []string{"stevenjb@google.com", "cros-network-health@google.com"},
Attr: []string{"group:cellular", "cellular_sim_dual_active"},
})
}
func ShillCellularSimConnect(ctx context.Context, s *testing.State) {
simProps, primary, err := getModemSimSlots(ctx)
if err != nil {
s.Fatal("Failed to get Modem.SimSlots: ", err)
}
if simProps[primary] == nil {
s.Fatalf("No primary SimProperties at %d", primary)
}
var secondaryProps *dbusutil.Properties
var secondary uint32
for i := uint32(0); i < uint32(len(simProps)); i++ {
if i == primary {
continue
}
p := simProps[i]
if p != nil {
secondary = i
secondaryProps = p
break
}
}
if secondaryProps == nil {
s.Fatal("No secondary SimProperties")
}
s.Logf("Primary slot index=%d, Secondary slot index=%d", primary, secondary)
// Get the secondary slot ICCID and connect to it. This will change the primary slot.
// Cellular Multisim tests should not rely on a particular slot being active,
// so we do not defer a slot change if this fails.
secondaryICCID, err := secondaryProps.GetString(mmconst.SimPropertySimIdentifier)
if err != nil {
s.Fatal("Failed to get ICCID: ", err)
}
if secondaryICCID == "" {
s.Fatalf("Empty ICCID for secondary slot: %d", secondary)
}
helper, err := cellular.NewHelper(ctx)
if err != nil {
s.Fatal("Failed to create cellular.Helper")
}
serviceProps := map[string]interface{}{
shillconst.ServicePropertyCellularICCID: secondaryICCID,
shillconst.ServicePropertyType: shillconst.TypeCellular,
}
service, err := helper.Manager.WaitForServiceProperties(ctx, serviceProps, shillconst.DefaultTimeout)
if err != nil {
s.Fatalf("Cellular Service not found for ICCID: %s: %s", secondaryICCID, err)
}
s.Log("Connecting to secondary ICCID: ", secondaryICCID)
if err := helper.ConnectToService(ctx, service); err != nil {
s.Fatal("Failed to connect to secondary service: ", err)
}
// Connecting to the secondary service will change slots, causing the Modem object to be rebuilt.
// Request SimSlots properties from the new Modem.
newSimProps, newPrimary, err := getModemSimSlots(ctx)
if err != nil {
s.Fatal("Failed to get Modem.SimSlots: ", err)
}
if newPrimary != secondary {
s.Fatalf("Unexpected primary slot after connect, wanted: %d, got: %d: ", secondary, newPrimary)
}
primaryProps := newSimProps[primary]
if primaryProps == nil {
s.Fatal("Unexpected nil primary SimProperties")
}
// Get the original primary slot ICCID and connect to it.
primaryICCID, err := primaryProps.GetString(mmconst.SimPropertySimIdentifier)
if err != nil {
s.Fatal("Failed to get ICCID: ", err)
}
if primaryICCID == "" {
s.Fatalf("Empty ICCID for primary slot: %d", primary)
}
serviceProps[shillconst.ServicePropertyCellularICCID] = primaryICCID
service, err = helper.Manager.WaitForServiceProperties(ctx, serviceProps, shillconst.DefaultTimeout)
if err != nil {
s.Fatalf("Cellular Service not found for ICCID: %s: %s", primaryICCID, err)
}
s.Log("Connecting to original primary ICCID=", primaryICCID)
if err := helper.ConnectToService(ctx, service); err != nil {
s.Fatal("Failed to connect to primary service: ", err)
}
}
func getModemSimSlots(ctx context.Context) (simProps []*dbusutil.Properties, primary uint32, err error) {
modem, err := modemmanager.NewModem(ctx)
if err != nil {
return nil, 0, errors.Wrap(err, "failed to create Modem")
}
simProps, primary, err = modem.GetSimSlots(ctx)
if err != nil {
return nil, 0, errors.Wrap(err, "failed to get SimSlots")
}
numSlots := uint32(len(simProps))
if numSlots < 2 {
return nil, 0, errors.Errorf("expected at least 2 SIM slots, found: %d", numSlots)
}
if primary >= numSlots {
return nil, 0, errors.Errorf("invalid primary slot, want < %d, got: %d", numSlots, primary)
}
return simProps, primary, err
}