36 #include <px4_platform_common/tasks.h> 50 static constexpr
const char *
satcom_state_string[4] = {
"STANDBY",
"SIGNAL CHECK",
"SBD SESSION",
"TEST"};
52 #define VERBOSE_INFO(...) if (_verbose) { PX4_INFO(__VA_ARGS__); } 54 #define IRIDIUMSBD_DEVICE_PATH "/dev/iridium" 72 if (IridiumSBD::instance !=
nullptr) {
73 PX4_WARN(
"already started");
109 if (IridiumSBD::instance ==
nullptr) {
110 PX4_WARN(
"not started");
115 PX4_WARN(
"device is used. Stop all users (MavLink)");
119 PX4_WARN(
"stopping...");
133 PX4_WARN(
"killing task forcefully");
139 IridiumSBD::instance =
nullptr;
147 if (IridiumSBD::instance ==
nullptr) {
148 PX4_WARN(
"not started");
167 PX4_WARN(
"not started");
172 PX4_WARN(
"MODEM BUSY!");
207 return CDev::ioctl(filp, cmd, arg);
219 IridiumSBD::instance->
main_loop(argc, argv);
225 IridiumSBD::instance =
nullptr;
238 int arg_uart_name = 0;
240 while (arg_i < argc) {
241 if (!strcmp(argv[arg_i],
"-d")) {
243 arg_uart_name = arg_i;
245 }
else if (!strcmp(argv[arg_i],
"-v")) {
246 PX4_WARN(
"verbose mode ON");
253 if (arg_uart_name == 0) {
254 PX4_ERR(
"no Iridium SBD modem UART port provided!");
260 bool command_executed =
false;
264 command_executed =
true;
271 if (!command_executed) {
272 PX4_ERR(
"failed to open UART port!");
278 command_executed =
false;
287 command_executed =
true;
291 if (!command_executed) {
292 PX4_ERR(
"modem not responding");
298 command_executed =
false;
307 command_executed =
true;
311 if (!command_executed) {
312 PX4_ERR(
"modem not responding");
322 param_pointer =
param_find(
"ISBD_SBD_TIMEOUT");
329 param_pointer =
param_find(
"ISBD_STACK_TIME");
381 write(0,
"kreczmer", 8);
480 PX4_WARN(
"SBD SESSION: TIMEOUT!");
500 VERBOSE_INFO(
"SBD SESSION: WRONG ANSWER: %s", _rx_command_buf);
508 int mo_status, mt_status, mt_len, mt_queued;
509 const char *p = (
const char *)_rx_command_buf + 7;
510 char **rx_buf_parse = (
char **)&p;
512 mo_status = strtol(*rx_buf_parse, rx_buf_parse, 10);
514 strtol(*rx_buf_parse, rx_buf_parse, 10);
516 mt_status = strtol(*rx_buf_parse, rx_buf_parse, 10);
518 strtol(*rx_buf_parse, rx_buf_parse, 10);
520 mt_len = strtol(*rx_buf_parse, rx_buf_parse, 10);
522 mt_queued = strtol(*rx_buf_parse, rx_buf_parse, 10);
524 VERBOSE_INFO(
"MO ST: %d, MT ST: %d, MT LEN: %d, MT QUEUED: %d", mo_status, mt_status, mt_len, mt_queued);
613 VERBOSE_INFO(
"UPDATE SIGNAL QUALITY: MODEM NOT READY!");
653 PX4_INFO(
"CANNOT ENTER TEST STATE");
660 PX4_WARN(
"SOMETHING WAS IN BUFFER");
671 PX4_WARN(
"MODEM NOT READY!");
682 PX4_WARN(
"The test command does not include AT or at: %s, ignoring it.",
_test_command);
687 PX4_INFO(
"TEST DONE");
705 }
else if ((
unsigned char)buffer[0] == 253 && (buflen == 10)) {
706 const uint8_t payload_len = buffer[1];
707 const uint8_t incompat_flags = buffer[2];
711 if (incompat_flags & 0x1) {
715 }
else if ((
unsigned char)buffer[0] == 254 && (buflen == 6)) {
716 const uint8_t payload_len = buffer[1];
759 if (bytes_to_copy > buflen) {
760 bytes_to_copy = buflen;
763 memcpy(buffer, &
_rx_msg_buf[_rx_msg_read_idx], bytes_to_copy);
765 _rx_msg_read_idx += bytes_to_copy;
768 return bytes_to_copy;
807 uint8_t checksum[2] = {(uint8_t)(sum / 256), (uint8_t)(sum & 255)};
811 VERBOSE_INFO(
"SEND SBD: CHECKSUM %d %d", checksum[0], checksum[1]);
814 VERBOSE_INFO(
"WRITE SBD: ERROR WHILE WRITING DATA TO MODEM!");
860 PX4_ERR(
"READ SBD: WRONG DATA LENGTH");
868 for (
int i = 2; i < data_len + 2; i++) {
873 PX4_ERR(
"READ SBD: WRONG DATA CHECKSUM");
907 struct pollfd fds[1];
909 fds[0].events = POLLIN;
917 if (::
poll(&fds[0], 1, timeout) > 0) {
919 if (rx_buf_pos == 0 && (buf ==
'\r' || buf ==
'\n')) {
924 rx_buf[rx_buf_pos++] = buf;
926 if (rx_buf[rx_buf_pos - 1] ==
'\n' && rx_buf[rx_buf_pos - 2] ==
'\r') {
928 if (rx_buf_pos == last_rn_idx + 2) {
932 }
else if (!strncmp((
const char *)&rx_buf[last_rn_idx],
"OK\r\n", 4)) {
936 }
else if (!strncmp((
const char *)&rx_buf[last_rn_idx],
"ERROR\r\n", 7)) {
939 }
else if (!strncmp((
const char *)&rx_buf[last_rn_idx],
"SBDRING\r\n", 9)) {
947 }
else if (!strncmp((
const char *)&rx_buf[last_rn_idx],
"READY\r\n", 7)) {
950 }
else if (!strncmp((
const char *)&rx_buf[last_rn_idx],
"HARDWARE FAILURE", 16)) {
951 PX4_WARN(
"HARDWARE FAILURE!");
955 *rx_len = rx_buf_pos;
958 last_rn_idx = rx_buf_pos;
989 VERBOSE_INFO(
"opening Iridium SBD modem UART: %s", uart_name);
999 struct termios uart_config;
1000 tcgetattr(
uart_fd, &uart_config);
1001 cfsetspeed(&uart_config, 115200);
1002 tcsetattr(
uart_fd, TCSANOW, &uart_config);
1023 pollevent_t pollstate = 0;
1026 pollstate |= POLLIN;
1030 pollstate |= POLLOUT;
1038 bool need_to_publish =
false;
1041 need_to_publish =
true;
1046 need_to_publish =
true;
1051 need_to_publish =
true;
1056 need_to_publish =
true;
1061 need_to_publish =
true;
1066 need_to_publish =
true;
1071 need_to_publish =
true;
1076 need_to_publish =
true;
1081 need_to_publish =
true;
1086 need_to_publish =
true;
1091 need_to_publish =
true;
1096 need_to_publish =
true;
1101 need_to_publish =
true;
1106 need_to_publish =
true;
1113 if (need_to_publish) {
1120 const bool present =
true;
1121 const bool enabled =
true;
1139 return CDev::open_first(filep);
1145 return CDev::close_last(filep);
1154 if (!strcmp(argv[1],
"start")) {
1157 }
else if (!strcmp(argv[1],
"stop")) {
1160 }
else if (!strcmp(argv[1],
"status")) {
1164 }
else if (!strcmp(argv[1],
"test")) {
1170 PX4_INFO(
"usage: iridiumsbd {start|stop|status|test} [-d uart_device]");
virtual int open_first(struct file *filep) override
Notification of the first open of CDev.
pollevent_t poll_state(struct file *filp)
void sbdsession_loop(void)
static void test(int argc, char *argv[])
virtual int open(file_t *filep)
Handle an open of the device.
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
hrt_abstime _session_start_time
bool _tx_buf_write_pending
hrt_abstime _last_write_time
hrt_abstime _last_heartbeat
bool publish(const T &data)
Publish the struct.
int iridiumsbd_main(int argc, char *argv[])
uint16_t failed_sbd_sessions
#define SATCOM_MAX_MESSAGE_LENGTH
void publish_iridium_status(void)
virtual int close_last(struct file *filep) override
Notification of the last close of CDev.
static constexpr const char * satcom_state_string[4]
satcom_result_code read_at_command(int16_t timeout=100)
uORB::Publication< iridiumsbd_status_s > _iridiumsbd_status_pub
bool _writing_mavlink_packet
virtual int close(file_t *filep)
Handle a close of the device.
#define VERBOSE_INFO(...)
uint8_t _tx_buf[SATCOM_TX_BUF_LEN]
Global flash based parameter store.
uint16_t rx_buf_read_index
void main_loop(int argc, char *argv[])
uint16_t _failed_sbd_sessions
ssize_t write(struct file *filp, const char *buffer, size_t buflen)
bool publish(const T &data)
Publish the struct.
The driver for the Rockblock 9602 and 9603 RockBlock module for satellite communication over the Irid...
void init()
Activates/configures the hardware registers.
uint16_t successful_sbd_sessions
uint16_t rx_buf_end_index
#define SATCOM_SIGNAL_REFRESH_DELAY
hrt_abstime _last_signal_check
uint16_t _num_tx_buf_reset
ssize_t read(struct file *filp, char *buffer, size_t buflen)
satcom_uart_status open_uart(char *uart_name)
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
satcom_result_code read_at(uint8_t *rx_buf, int *rx_len, int16_t timeout=100)
int32_t _param_stacking_time_ms
bool tx_buf_write_pending
bool is_modem_ready(void)
#define IRIDIUMSBD_DEVICE_PATH
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
uint16_t _successful_sbd_sessions
pthread_mutex_t _rx_buf_mutex
satcom_result_code read_at_msg(int16_t timeout=100)
struct @83::@85::@87 file
#define SATCOM_TX_BUF_LEN
static IridiumSBD * instance
static int start(int argc, char *argv[])
int32_t _param_read_interval_s
uint16_t num_tx_buf_reset
void start_sbd_session(void)
void write_at(const char *command)
iridiumsbd_status_s _status
uint8_t _rx_msg_buf[SATCOM_RX_MSG_BUF_LEN]
static void main_loop_helper(int argc, char *argv[])
uORB::PublicationQueued< subsystem_info_s > _subsystem_pub
uint16_t tx_buf_write_index
uint8_t _rx_command_buf[SATCOM_RX_COMMAND_BUF_LEN]
int32_t _param_session_timeout_s
void publish_subsystem_status()
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
uint32_t param_t
Parameter handle.
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.
pthread_mutex_t _tx_buf_mutex
hrt_abstime _last_read_time
int ioctl(struct file *filp, int cmd, unsigned long arg)