Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
  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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
/** @file
 * @brief HL7800 modem public API header file.
 *
 * Allows an application to control the HL7800 modem.
 *
 * Copyright (c) 2020 Laird Connectivity
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_
#define ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <zephyr/types.h>

#ifdef CONFIG_NEWLIB_LIBC
#include <time.h>
#endif

/* The size includes the NUL character, the strlen doesn't */
#define MDM_HL7800_REVISION_MAX_SIZE 29
#define MDM_HL7800_REVISION_MAX_STRLEN (MDM_HL7800_REVISION_MAX_SIZE - 1)

#define MDM_HL7800_IMEI_SIZE 16
#define MDM_HL7800_IMEI_STRLEN (MDM_HL7800_IMEI_SIZE - 1)

#define MDM_HL7800_ICCID_SIZE 21
#define MDM_HL7800_ICCID_STRLEN (MDM_HL7800_ICCID_SIZE - 1)

#define MDM_HL7800_SERIAL_NUMBER_SIZE 15
#define MDM_HL7800_SERIAL_NUMBER_STRLEN (MDM_HL7800_SERIAL_NUMBER_SIZE - 1)

#define MDM_HL7800_APN_MAX_SIZE 64
#define MDM_HL7800_APN_USERNAME_MAX_SIZE 65
#define MDM_HL7800_APN_PASSWORD_MAX_SIZE 65

#define MDM_HL7800_APN_MAX_STRLEN (MDM_HL7800_APN_MAX_SIZE - 1)
#define MDM_HL7800_APN_USERNAME_MAX_STRLEN                                     \
	(MDM_HL7800_APN_USERNAME_MAX_SIZE - 1)
#define MDM_HL7800_APN_PASSWORD_MAX_STRLEN                                     \
	(MDM_HL7800_APN_PASSWORD_MAX_SIZE - 1)

#define MDM_HL7800_APN_CMD_MAX_SIZE                                            \
	(32 + MDM_HL7800_APN_USERNAME_MAX_STRLEN +                             \
	 MDM_HL7800_APN_PASSWORD_MAX_STRLEN)

#define MDM_HL7800_APN_CMD_MAX_STRLEN (MDM_HL7800_APN_CMD_MAX_SIZE - 1)

struct mdm_hl7800_apn {
	char value[MDM_HL7800_APN_MAX_SIZE];
	char username[MDM_HL7800_APN_USERNAME_MAX_SIZE];
	char password[MDM_HL7800_APN_PASSWORD_MAX_SIZE];
};

#define MDM_HL7800_LTE_BAND_STR_SIZE 21
#define MDM_HL7800_LTE_BAND_STRLEN (MDM_HL7800_LTE_BAND_STR_SIZE - 1)

#define MDM_HL7800_OPERATOR_INDEX_SIZE 3
#define MDM_HL7800_OPERATOR_INDEX_STRLEN (MDM_HL7800_OPERATOR_INDEX_SIZE - 1)

#define MDM_HL7800_IMSI_MIN_STR_SIZE 15
#define MDM_HL7800_IMSI_MAX_STR_SIZE 16
#define MDM_HL7800_IMSI_MAX_STRLEN (MDM_HL7800_IMSI_MAX_STR_SIZE - 1)

#define MDM_HL7800_MODEM_FUNCTIONALITY_SIZE 2
#define MDM_HL7800_MODEM_FUNCTIONALITY_STRLEN                                  \
	(MDM_HL7800_MODEM_FUNCTIONALITY_SIZE - 1)

#define MDM_HL7800_MAX_GPS_STR_SIZE 33

#define MDM_HL7800_MAX_POLTE_USER_ID_SIZE 16
#define MDM_HL7800_MAX_POLTE_PASSWORD_SIZE 16
#define MDM_HL7800_MAX_POLTE_LOCATION_STR_SIZE 33

/* Assign the server error code (location response) to a value
 * that isn't used by locate response so that a single status
 * callback can be used.
 */
#define MDM_HL7800_POLTE_SERVER_ERROR 10

#define MDM_HL7800_SET_POLTE_USER_AND_PASSWORD_FMT_STR "AT%%POLTECMD=\"SERVERAUTH\",\"%s\",\"%s\""

struct mdm_hl7800_site_survey {
	uint32_t earfcn; /* EUTRA Absolute Radio Frequency Channel Number */
	uint32_t cell_id;
	int rsrp;
	int rsrq;
};

enum mdm_hl7800_radio_mode { MDM_RAT_CAT_M1 = 0, MDM_RAT_CAT_NB1 };

enum mdm_hl7800_event {
	HL7800_EVENT_RESERVED = 0,
	HL7800_EVENT_NETWORK_STATE_CHANGE,
	HL7800_EVENT_APN_UPDATE,
	HL7800_EVENT_RSSI,
	HL7800_EVENT_SINR,
	HL7800_EVENT_STARTUP_STATE_CHANGE,
	HL7800_EVENT_SLEEP_STATE_CHANGE,
	HL7800_EVENT_RAT,
	HL7800_EVENT_BANDS,
	HL7800_EVENT_ACTIVE_BANDS,
	HL7800_EVENT_FOTA_STATE,
	HL7800_EVENT_FOTA_COUNT,
	HL7800_EVENT_REVISION,
	HL7800_EVENT_GPS,
	HL7800_EVENT_GPS_POSITION_STATUS,
	HL7800_EVENT_POLTE_REGISTRATION,
	HL7800_EVENT_POLTE_LOCATE_STATUS,
	HL7800_EVENT_POLTE,
	HL7800_EVENT_SITE_SURVEY,
};

enum mdm_hl7800_startup_state {
	HL7800_STARTUP_STATE_READY = 0,
	HL7800_STARTUP_STATE_WAITING_FOR_ACCESS_CODE,
	HL7800_STARTUP_STATE_SIM_NOT_PRESENT,
	HL7800_STARTUP_STATE_SIMLOCK,
	HL7800_STARTUP_STATE_UNRECOVERABLE_ERROR,
	HL7800_STARTUP_STATE_UNKNOWN,
	HL7800_STARTUP_STATE_INACTIVE_SIM
};

enum mdm_hl7800_network_state {
	HL7800_NOT_REGISTERED = 0,
	HL7800_HOME_NETWORK,
	HL7800_SEARCHING,
	HL7800_REGISTRATION_DENIED,
	HL7800_OUT_OF_COVERAGE,
	HL7800_ROAMING,
	HL7800_EMERGENCY = 8,
	/* Laird defined states */
	HL7800_UNABLE_TO_CONFIGURE = 0xf0
};

enum mdm_hl7800_sleep_state {
	HL7800_SLEEP_STATE_UNINITIALIZED = 0,
	HL7800_SLEEP_STATE_ASLEEP,
	HL7800_SLEEP_STATE_AWAKE
};

enum mdm_hl7800_fota_state {
	HL7800_FOTA_IDLE,
	HL7800_FOTA_START,
	HL7800_FOTA_WIP,
	HL7800_FOTA_PAD,
	HL7800_FOTA_SEND_EOT,
	HL7800_FOTA_FILE_ERROR,
	HL7800_FOTA_INSTALL,
	HL7800_FOTA_REBOOT_AND_RECONFIGURE,
	HL7800_FOTA_COMPLETE,
};

enum mdm_hl7800_functionality {
	HL7800_FUNCTIONALITY_MINIMUM = 0,
	HL7800_FUNCTIONALITY_FULL = 1,
	HL7800_FUNCTIONALITY_AIRPLANE = 4
};

/* The modem reports state values as an enumeration and a string.
 * GPS values are reported with a type of value and string.
 */
struct mdm_hl7800_compound_event {
	uint8_t code;
	char *string;
};

enum mdm_hl7800_gnss_event {
	HL7800_GNSS_EVENT_INVALID = -1,
	HL7800_GNSS_EVENT_INIT,
	HL7800_GNSS_EVENT_START,
	HL7800_GNSS_EVENT_STOP,
	HL7800_GNSS_EVENT_POSITION,
};

enum mdm_hl7800_gnss_status {
	HL7800_GNSS_STATUS_INVALID = -1,
	HL7800_GNSS_STATUS_FAILURE,
	HL7800_GNSS_STATUS_SUCCESS,
};

enum mdm_hl7800_gnss_position_event {
	HL7800_GNSS_POSITION_EVENT_INVALID = -1,
	HL7800_GNSS_POSITION_EVENT_LOST_OR_NOT_AVAILABLE_YET,
	HL7800_GNSS_POSITION_EVENT_PREDICTION_AVAILABLE,
	HL7800_GNSS_POSITION_EVENT_2D_AVAILABLE,
	HL7800_GNSS_POSITION_EVENT_3D_AVAILABLE,
	HL7800_GNSS_POSITION_EVENT_FIXED_TO_INVALID,
};

enum mdm_hl7800_gps_string_types {
	HL7800_GPS_STR_LATITUDE,
	HL7800_GPS_STR_LONGITUDE,
	HL7800_GPS_STR_GPS_TIME,
	HL7800_GPS_STR_FIX_TYPE,
	HL7800_GPS_STR_HEPE,
	HL7800_GPS_STR_ALTITUDE,
	HL7800_GPS_STR_ALT_UNC,
	HL7800_GPS_STR_DIRECTION,
	HL7800_GPS_STR_HOR_SPEED,
	HL7800_GPS_STR_VER_SPEED
};

/* status: negative errno, 0 on success
 * user and password aren't valid if status is non-zero.
 */
struct mdm_hl7800_polte_registration_event_data {
	int status;
	char *user;
	char *password;
};

/* status: negative errno, 0 on success, non-zero error code
 * Data is not valid if status is non-zero.
 */
struct mdm_hl7800_polte_location_data {
	uint32_t timestamp;
	int status;
	char latitude[MDM_HL7800_MAX_POLTE_LOCATION_STR_SIZE];
	char longitude[MDM_HL7800_MAX_POLTE_LOCATION_STR_SIZE];
	char confidence_in_meters[MDM_HL7800_MAX_POLTE_LOCATION_STR_SIZE];
};

/**
 * event - The type of event
 * event_data - Pointer to event specific data structure
 * HL7800_EVENT_NETWORK_STATE_CHANGE - compound event
 * HL7800_EVENT_APN_UPDATE - struct mdm_hl7800_apn
 * HL7800_EVENT_RSSI - int
 * HL7800_EVENT_SINR - int
 * HL7800_EVENT_STARTUP_STATE_CHANGE - compound event
 * HL7800_EVENT_SLEEP_STATE_CHANGE - compound event
 * HL7800_EVENT_RAT - int
 * HL7800_EVENT_BANDS - string
 * HL7800_EVENT_ACTIVE_BANDS - string
 * HL7800_EVENT_FOTA_STATE - compound event
 * HL7800_EVENT_FOTA_COUNT - uint32_t
 * HL7800_EVENT_REVISION - string
 * HL7800_EVENT_GPS - compound event
 * HL7800_EVENT_GPS_POSITION_STATUS int
 * HL7800_EVENT_POLTE_REGISTRATION mdm_hl7800_polte_registration_event_data
 * HL7800_EVENT_POLTE mdm_hl7800_polte_location_data
 * HL7800_EVENT_POLTE_LOCATE_STATUS int
 * HL7800_EVENT_SITE_SURVEY mdm_hl7800_site_survey
 */
typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event,
					    void *event_data);

/**
 * @brief Power off the HL7800
 *
 * @return int32_t 0 for success
 */
int32_t mdm_hl7800_power_off(void);

/**
 * @brief Reset the HL7800 (and allow it to reconfigure).
 *
 * @return int32_t 0 for success
 */
int32_t mdm_hl7800_reset(void);

/**
 * @brief Control the wake signals to the HL7800.
 * @note this API should only be used for debug purposes.
 *
 * @param awake True to keep the HL7800 awake, False to allow sleep
 */
void mdm_hl7800_wakeup(bool awake);

/**
 * @brief Send an AT command to the HL7800.
 * @note this API should only be used for debug purposes.
 *
 * @param data AT command string
 * @return int32_t 0 for success
 */
int32_t mdm_hl7800_send_at_cmd(const uint8_t *data);

/**
 * @brief Get the signal quality of the HL7800
 *
 * @param rsrp Reference Signals Received Power (dBm)
 *             Range = -140 dBm to -44 dBm
 * @param sinr Signal to Interference plus Noise Ratio (dBm)
 *             Range = -128 dBm to 40dBm
 */
void mdm_hl7800_get_signal_quality(int *rsrp, int *sinr);

/**
 * @brief Get the SIM card ICCID
 *
 */
char *mdm_hl7800_get_iccid(void);

/**
 * @brief Get the HL7800 serial number
 *
 */
char *mdm_hl7800_get_sn(void);

/**
 * @brief Get the HL7800 IMEI
 *
 */
char *mdm_hl7800_get_imei(void);

/**
 * @brief Get the HL7800 firmware version
 *
 */
char *mdm_hl7800_get_fw_version(void);

/**
 * @brief Get the IMSI
 *
 */
char *mdm_hl7800_get_imsi(void);

/**
 * @brief Update the Access Point Name in the modem.
 *
 * @retval 0 on success, negative on failure.
 */
int32_t mdm_hl7800_update_apn(char *access_point_name);

/**
 * @brief Update the Radio Access Technology (mode).
 *
 * @retval 0 on success, negative on failure.
 */
int32_t mdm_hl7800_update_rat(enum mdm_hl7800_radio_mode value);

/**
 * @retval true if RAT value is valid
 */
bool mdm_hl7800_valid_rat(uint8_t value);

/**
 * @brief Register a function that is called when a modem event occurs.
 *
 * @param cb event callback
 */
void mdm_hl7800_register_event_callback(mdm_hl7800_event_callback_t cb);

/**
 * @brief Force modem module to generate status events.
 *
 * @note This can be used to get the current state when a module initializes
 * later than the modem.
 */
void mdm_hl7800_generate_status_events(void);

#ifdef CONFIG_NEWLIB_LIBC
/**
 * @brief Get the local time from the modem's real time clock.
 *
 * @param tm time structure
 * @param offset The amount the local time is offset from GMT/UTC in seconds.
 *
 * @param 0 if successful
 */
int32_t mdm_hl7800_get_local_time(struct tm *tm, int32_t *offset);
#endif

#ifdef CONFIG_MODEM_HL7800_FW_UPDATE
/**
 * @brief Update the HL7800 via XMODEM protocol.  During the firmware update
 * no other modem fuctions will be available.
 *
 * @param file_path Absolute path of the update file
 *
 * @param 0 if successful
 */
int32_t mdm_hl7800_update_fw(char *file_path);
#endif

/**
 * @brief Read the operator index from the modem.
 *
 * @retval negative error code, 0 on success
 */
int32_t mdm_hl7800_get_operator_index(void);

/**
 * @brief Get modem functionality
 *
 * @return int32_t negative errno on failure, else mdm_hl7800_functionality
 */
int32_t mdm_hl7800_get_functionality(void);

/**
 * @brief Set airplane, normal, or reduced functionality mode.
 * Airplane mode persists when reset.
 *
 * @note Boot functionality is also controlled by Kconfig
 * MODEM_HL7800_BOOT_IN_AIRPLANE_MODE.
 *
 * @param mode
 * @return int32_t negative errno, 0 on success
 */
int32_t mdm_hl7800_set_functionality(enum mdm_hl7800_functionality mode);

/**
 * @brief When rate is non-zero: Put modem into Airplane mode. Enable GPS and
 * generate HL7800_EVENT_GPS events.
 * When zero: Disable GPS and put modem into normal mode.
 *
 * @note Airplane mode isn't cleared when the modem is reset.
 *
 * @param rate in seconds to query location
 * @return int32_t negative errno, 0 on success
 */
int32_t mdm_hl7800_set_gps_rate(uint32_t rate);

/**
 * @brief Register modem/SIM with polte.io
 *
 * @note It takes around 30 seconds for HL7800_EVENT_POLTE_REGISTRATION to
 * be generated.  If the applications saves the user and password
 * information into non-volatile memory, then this command
 * only needs to be run once.
 *
 * @return int32_t negative errno, 0 on success
 */
int32_t mdm_hl7800_polte_register(void);

/**
 * @brief Enable PoLTE.
 *
 * @param user from polte.io or register command callback
 * @param password from polte.io register command callback
 * @return int32_t negative errno, 0 on success
 */
int32_t mdm_hl7800_polte_enable(char *user, char *password);

/**
 * @brief Locate device using PoLTE.
 *
 * @note The first HL7800_EVENT_POLTE_LOCATE_STATUS event indicates
 * the status of issuing the locate command. The second event
 * requires 20-120 seconds to be generated and it contains the
 * location information (or indicates server failure).
 *
 * @return int32_t negative errno, 0 on success
 */
int32_t mdm_hl7800_polte_locate(void);

/**
 * @brief Perform a site survey.  This command may return different values
 * each time it is run (depending on what is in range).
 *
 * HL7800_EVENT_SITE_SURVEY is generated for each response received from modem.
 *
 * @retval negative error code, 0 on success
 */
int32_t mdm_hl7800_perform_site_survey(void);

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_ */