-
Notifications
You must be signed in to change notification settings - Fork 21
/
ModemFirmware.go
executable file
·241 lines (214 loc) · 9.23 KB
/
ModemFirmware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package modemmanager
import (
"encoding/json"
"errors"
"fmt"
"github.com/godbus/dbus/v5"
)
// Paths of methods and properties
const (
ModemFirmwareInterface = ModemInterface + ".Firmware"
/* Methods */
ModemFirmwareList = ModemFirmwareInterface + ".List"
ModemFirmwareSelect = ModemFirmwareInterface + ".Select"
/* Property */
ModemFirmwarePropertyUpdateSettings = ModemFirmwareInterface + ".UpdateSettings" // readable (ua{sv})
)
// ModemFirmware provides access to perform different firmware-related operations in the modem,
// including listing the available firmware images in the module and selecting which of them to use.
// This interface does not provide direct access to perform firmware updates in the device. Instead, it
// exposes information about the expected firmware update method as well as method-specific details required for the
// upgrade to happen. The actual firmware upgrade may be performed via the Linux Vendor Firmware Service and the fwupd daemon.
// This interface will always be available as long a the modem is considered valid.
type ModemFirmware interface {
/* METHODS */
// Returns object path
GetObjectPath() dbus.ObjectPath
// List installed firmware images.
// Firmware slots and firmware images are identified by arbitrary opaque strings.
// List (OUT s selected, OUT aa{sv} installed);
List() ([]FirmwareProperty, error)
// Selects a different firmware image to use, and immediately resets the modem so that it begins using the new firmware image.
// The method will fail if the identifier does not match any of the names returned by List(), or if the image could not be selected for some reason.
// Installed images can be selected non-destructively.
// IN s uniqueid: The unique ID of the firmware image to select.
Select(string) error
MarshalJSON() ([]byte, error)
/* PROPERTIES */
// Detailed settings that provide information about how the module should be updated.
GetUpdateSettings() (UpdateSettingsProperty, error)
}
// NewModemFirmware returns new ModemFirmware Interface
func NewModemFirmware(objectPath dbus.ObjectPath) (ModemFirmware, error) {
var fi modemFirmware
return &fi, fi.init(ModemManagerInterface, objectPath)
}
type modemFirmware struct {
dbusBase
}
// FirmwareProperty represents all properties of a firmware
type FirmwareProperty struct {
ImageType MMFirmwareImageType `json:"image-type"` // (Required) Type of the firmware image, given as a MMFirmwareImageType value (signature "u"). Firmware images of type MM_FIRMWARE_IMAGE_TYPE_GENERIC will only expose only the mandatory properties.
UniqueId string `json:"unique-id"` // (Required) A user-readable unique ID for the firmware image, given as a string value (signature "s").
GobiPriVersion string `json:"gobi-pri-version"` // (Optional) The version of the PRI firmware image, in images of type MM_FIRMWARE_IMAGE_TYPE_GOBI, given as a string value (signature "s").
GobiPriInfo string `json:"gobi-pri-info"` // (Optional) Additional information of the PRI image, in images of type MM_FIRMWARE_IMAGE_TYPE_GOBI, given as a string value (signature "s").
GobiBootVersion string `json:"gobi-boot-version"` // (Optional) The boot version of the PRI firmware image, in images of type MM_FIRMWARE_IMAGE_TYPE_GOBI, given as a string value (signature "s").
GobiPriUniqueId string `json:"gobi-pri-unique-id"` // (Optional) The unique ID of the PRI firmware image, in images of type MM_FIRMWARE_IMAGE_TYPE_GOBI, given as a string value (signature "s").
GobiModemUniqueId string `json:"gobi-modem-unique-id"` // (Optional) The unique ID of the Modem firmware image, in images of type MM_FIRMWARE_IMAGE_TYPE_GOBI, given as a string value (signature "s").
Selected bool `json:"selected"` // Shows if certain firmware is selected
}
// MarshalJSON returns a byte array
func (fp FirmwareProperty) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"ImageType": fmt.Sprint(fp.ImageType),
"UniqueId": fp.UniqueId,
"GobiPriVersion": fp.GobiPriVersion,
"GobiPriInfo": fp.GobiPriInfo,
"GobiBootVersion": fp.GobiBootVersion,
"GobiPriUniqueId": fp.GobiPriUniqueId,
"GobiModemUniqueId": fp.GobiModemUniqueId,
"Selected": fp.Selected,
})
}
func (fp FirmwareProperty) String() string {
return "ImageType: " + fmt.Sprint(fp.ImageType) +
", UniqueId: " + fp.UniqueId +
", GobiPriVersion: " + fp.GobiPriVersion +
", GobiPriInfo: " + fp.GobiPriInfo +
", GobiBootVersion: " + fp.GobiBootVersion +
", GobiPriUniqueId: " + fp.GobiPriUniqueId +
", GobiModemUniqueId: " + fp.GobiModemUniqueId +
", Selected: " + fmt.Sprint(fp.Selected)
}
// UpdateSettingsProperty represents all available update settings
type UpdateSettingsProperty struct {
UpdateMethods []MMModemFirmwareUpdateMethod `json:"update-methods"` // The settings are given as a bitmask of MMModemFirmwareUpdateMethod values specifying the type of firmware update procedures
DeviceIds []string `json:"device-ids"` // (Required) This property exposes the list of device IDs associated to a given device, from most specific to least specific. (signature 'as'). E.g. a list containing: "USB\VID_413C&PID_81D7&REV_0001", "USB\VID_413C&PID_81D7" and "USB\VID_413C"
Version string `json:"version"` // (Required) This property exposes the current firmware version string of the module. If the module uses separate version numbers for firmware version and carrier configuration, this version string will be a combination of both, and so it may be different to the version string showed in the "Revision" property. (signature 's')
FastbootAt string `json:"fastboot-at"` // only if update method fastboot: (Required) This property exposes the AT command that should be sent to the module to trigger a reset into fastboot mode (signature 's')
}
// MarshalJSON returns a byte array
func (us UpdateSettingsProperty) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"UpdateMethods": fmt.Sprint(us.UpdateMethods),
"DeviceIds": us.DeviceIds,
"Version": us.Version,
"FastbootAt": us.FastbootAt,
})
}
func (us UpdateSettingsProperty) String() string {
return "UpdateMethods: " + fmt.Sprint(us.UpdateMethods) +
", DeviceIds: " + fmt.Sprint(us.DeviceIds) +
", Version: " + us.Version +
", FastbootAt: " + us.FastbootAt
}
func (fi modemFirmware) GetObjectPath() dbus.ObjectPath {
return fi.obj.Path()
}
func (fi modemFirmware) Select(uid string) error {
return fi.call(ModemFirmwareSelect, uid)
}
func (fi modemFirmware) List() (properties []FirmwareProperty, err error) {
var resMap []map[string]dbus.Variant
var tmpString string
err = fi.callWithReturn2(&tmpString, &resMap, ModemFirmwareList)
if err != nil {
return
}
for _, el := range resMap {
var property FirmwareProperty
for key, element := range el {
switch key {
case "image-type":
tmpValue, ok := element.Value().(uint32)
if ok {
property.ImageType = MMFirmwareImageType(tmpValue)
}
case "unique-id":
tmpValue, ok := element.Value().(string)
if ok {
property.UniqueId = tmpValue
if tmpValue == tmpString {
property.Selected = true
}
}
case "gobi-pri-version":
tmpValue, ok := element.Value().(string)
if ok {
property.GobiPriVersion = tmpValue
}
case "gobi-pri-info":
tmpValue, ok := element.Value().(string)
if ok {
property.GobiPriInfo = tmpValue
}
case "gobi-boot-version":
tmpValue, ok := element.Value().(string)
if ok {
property.GobiBootVersion = tmpValue
}
case "gobi-pri-unique-id":
tmpValue, ok := element.Value().(string)
if ok {
property.GobiPriUniqueId = tmpValue
}
case "gobi-modem-unique-id":
tmpValue, ok := element.Value().(string)
if ok {
property.GobiModemUniqueId = tmpValue
}
}
}
properties = append(properties, property)
}
return
}
func (fi modemFirmware) GetUpdateSettings() (property UpdateSettingsProperty, err error) {
res, err := fi.getPairProperty(ModemFirmwarePropertyUpdateSettings)
if err != nil {
return
}
var tmp MMModemFirmwareUpdateMethod
bitmask, ok := res.GetLeft().(uint32)
if !ok {
return property, errors.New("wrong type")
}
property.UpdateMethods = tmp.BitmaskToSlice(bitmask)
resMap, ok := res.GetRight().(map[string]dbus.Variant)
if !ok {
return property, errors.New("wrong type")
}
for key, element := range resMap {
switch key {
case "device-ids":
tmpValue, ok := element.Value().([]string)
if ok {
property.DeviceIds = tmpValue
}
case "version":
tmpValue, ok := element.Value().(string)
if ok {
property.Version = tmpValue
}
case "fastboot-at":
tmpValue, ok := element.Value().(string)
if ok {
property.FastbootAt = tmpValue
}
}
}
return
}
func (fi modemFirmware) MarshalJSON() ([]byte, error) {
updateSettings, err := fi.GetUpdateSettings()
if err != nil {
return nil, err
}
updateSettingsJson, err := updateSettings.MarshalJSON()
if err != nil {
return nil, err
}
return json.Marshal(map[string]interface{}{
"UpdateSettings": updateSettingsJson,
})
}