60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package onboarding
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
)
|
||
|
|
|
||
|
|
type VoiceRuntimeInput struct {
|
||
|
|
BootID string `json:"boot_id"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// VoiceRuntime is independent of the short-lived provisioning screen. It
|
||
|
|
// exposes only this authenticated device's current, bound activation command.
|
||
|
|
// Registration is owned by the server; the device only acknowledges SDK initialization.
|
||
|
|
func (s *Service) VoiceRuntime(ctx context.Context, d Device, in VoiceRuntimeInput) (map[string]any, error) {
|
||
|
|
if !uuidV4(in.BootID) {
|
||
|
|
return nil, fail(400, "VALIDATION_FAILED", "启动编号不正确")
|
||
|
|
}
|
||
|
|
tx, e := s.pool.Begin(ctx)
|
||
|
|
if e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
defer tx.Rollback(ctx)
|
||
|
|
current, e := readDevice(ctx, tx, d.ID, true)
|
||
|
|
if e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
if !deviceAllowed(current) || current.BootID != in.BootID {
|
||
|
|
return nil, errState
|
||
|
|
}
|
||
|
|
var bound bool
|
||
|
|
if e = tx.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM device_binding WHERE device_id=$1::uuid AND generation=$2 AND unbound_at IS NULL) OR EXISTS(SELECT 1 FROM device_account_binding WHERE device_id=$1::uuid AND generation=$2 AND released_at IS NULL)`, d.ID, current.Generation).Scan(&bound); e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
if !bound {
|
||
|
|
return nil, fail(409, "DEVICE_UNBOUND", "请先绑定设备")
|
||
|
|
}
|
||
|
|
command, e := s.activationCommand(ctx, tx, current)
|
||
|
|
if e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
st, e := s.state(ctx, tx, current)
|
||
|
|
if e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
out := map[string]any{"state": st, "command": command, "call_contract": "CALL-MEMORY-1.1"}
|
||
|
|
if !s.options.LegacyDeviceRegistration {
|
||
|
|
fields, err := s.voiceFields(ctx, tx, current)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
for k, v := range fields {
|
||
|
|
out[k] = v
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if e = tx.Commit(ctx); e != nil {
|
||
|
|
return nil, e
|
||
|
|
}
|
||
|
|
return out, nil
|
||
|
|
}
|