Created
May 28, 2025 17:15
-
-
Save hlord2000/d473e5b549a9d79989d6dc74a6e10eab to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- /opt/ncs/ncs-v3.0/nrf/applications/serial_lte_modem/src/slm_at_socket.c 2025-04-15 11:53:22.452023051 -0400 | |
+++ src/slm_at_socket.c 2025-05-28 13:00:00.173393697 -0400 | |
@@ -1656,6 +1656,224 @@ | |
return err; | |
} | |
+/* Begin app specific commands */ | |
+ | |
+SLM_AT_CMD_CUSTOM(qiopen, "AT+QIOPEN", handle_qiopen_socket); | |
+static int handle_qiopen_socket(enum at_parser_cmd_type cmd_type, struct at_parser *parser, | |
+ uint32_t param_count) | |
+{ | |
+ int err = -EINVAL; | |
+ uint16_t context_id; | |
+ | |
+ char service_type[16] = {0}; | |
+ int service_type_size = 16; | |
+ | |
+ char url[SLM_MAX_URL] = {0}; | |
+ int url_size = SLM_MAX_URL; | |
+ uint16_t port; | |
+ | |
+ switch (cmd_type) { | |
+ case AT_PARSER_CMD_TYPE_SET: | |
+ err = at_parser_num_get(parser, 1, &context_id); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ err = util_string_get(parser, 3, service_type, &service_type_size); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ if (find_avail_socket() < 0) { | |
+ LOG_ERR("Max socket count reached"); | |
+ return -EINVAL; | |
+ } | |
+ INIT_SOCKET(sock); | |
+ | |
+ err = at_parser_num_get(parser, 2, &sock.cid); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ if (sock.cid > 10) { | |
+ return -EINVAL; | |
+ } | |
+ | |
+ sock.family = AF_INET; | |
+ | |
+ if (slm_util_casecmp(service_type, "TCP")) { | |
+ sock.type = SOCK_STREAM; | |
+ sock.role = 0; // Client | |
+ } else if (slm_util_casecmp(service_type, "UDP")) { | |
+ sock.type = SOCK_DGRAM; | |
+ sock.role = 0; // Client | |
+ } else if (slm_util_casecmp(service_type, "TCP LISTENER")) { | |
+ sock.type = SOCK_STREAM; | |
+ sock.role = 1; // Server | |
+ } else if (slm_util_casecmp(service_type, "UDP SERVICE")) { | |
+ sock.type = SOCK_DGRAM; | |
+ sock.role = 1; // Server | |
+ } else { | |
+ LOG_ERR("Invalid service type"); | |
+ return -EINVAL; | |
+ } | |
+ | |
+ err = do_socket_open(); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ err = util_string_get(parser, 4, url, &url_size); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ err = at_parser_num_get(parser, 5, &port); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ if (!slm_util_casecmp(url, "127.0.0.1")) { | |
+ err = do_connect(url, port); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ } else if (sock.type == SOCK_STREAM && sock.role == 1) { | |
+ err = do_listen(); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ } else if (sock.type == SOCK_DGRAM && sock.role == 1) { | |
+ err = slm_bind_to_local_addr(sock.fd, sock.family, port); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ } | |
+ | |
+ break; | |
+ | |
+ case AT_PARSER_CMD_TYPE_READ: | |
+ if (sock.fd != INVALID_SOCKET) { | |
+ rsp_send("\r\n+QIOPEN: %d,%d,%d,%d,%d\r\n", sock.fd, | |
+ sock.family, sock.role, sock.type, sock.cid); | |
+ } | |
+ err = 0; | |
+ break; | |
+ | |
+ case AT_PARSER_CMD_TYPE_TEST: | |
+ rsp_send("\r\n+QIOPEN: (%d,%d,%d),(%d,%d,%d),(%d,%d),<cid>", | |
+ AT_SOCKET_CLOSE, AT_SOCKET_OPEN, AT_SOCKET_OPEN6, | |
+ SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, | |
+ AT_SOCKET_ROLE_CLIENT, AT_SOCKET_ROLE_SERVER); | |
+ err = 0; | |
+ break; | |
+ | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ return err; | |
+} | |
+ | |
+SLM_AT_CMD_CUSTOM(qiclose, "AT+QICLOSE", handle_qiclose_socket); | |
+static int handle_qiclose_socket(enum at_parser_cmd_type cmd_type, struct at_parser *parser, | |
+ uint32_t param_count) | |
+{ | |
+ int err = -EINVAL; | |
+ uint16_t cid; | |
+ | |
+ err = at_parser_num_get(parser, 1, &cid); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ if (cid > 10) { | |
+ return -EINVAL; | |
+ } | |
+ | |
+ for (int i = 0; i < SLM_MAX_SOCKET_COUNT; i++) { | |
+ if (socks[i].cid == cid) { | |
+ sock = socks[i]; | |
+ } | |
+ } | |
+ | |
+ switch (cmd_type) { | |
+ case AT_PARSER_CMD_TYPE_SET: | |
+ err = do_socket_close(); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ break; | |
+ | |
+ case AT_PARSER_CMD_TYPE_READ: | |
+ if (sock.fd != INVALID_SOCKET) { | |
+ rsp_send("\r\n+QICLOSE: %d,%d,%d,%d,%d\r\n", sock.fd, | |
+ sock.family, sock.role, sock.type, sock.cid); | |
+ } | |
+ err = 0; | |
+ break; | |
+ | |
+ case AT_PARSER_CMD_TYPE_TEST: | |
+ rsp_send("\r\n+QICLOSE: (%d,%d,%d),(%d,%d,%d),(%d,%d),<cid>", | |
+ AT_SOCKET_CLOSE, AT_SOCKET_OPEN, AT_SOCKET_OPEN6, | |
+ SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, | |
+ AT_SOCKET_ROLE_CLIENT, AT_SOCKET_ROLE_SERVER); | |
+ err = 0; | |
+ break; | |
+ | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ return err; | |
+} | |
+ | |
+SLM_AT_CMD_CUSTOM(qisend, "AT+QISEND", handle_at_qisend); | |
+static int handle_at_qisend(enum at_parser_cmd_type cmd_type, struct at_parser *parser, | |
+ uint32_t param_count) | |
+{ | |
+ | |
+ int err = -EINVAL; | |
+ int size; | |
+ uint16_t cid; | |
+ | |
+ err = at_parser_num_get(parser, 1, &cid); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ | |
+ /* | |
+ for (int i = 0; i < SLM_MAX_SOCKET_COUNT; i++) { | |
+ if (socks[i].cid == cid) { | |
+ sock = socks[i]; | |
+ } | |
+ } | |
+ */ | |
+ | |
+ switch (cmd_type) { | |
+ case AT_PARSER_CMD_TYPE_SET: | |
+ size = sizeof(udp_url); | |
+ err = util_string_get(parser, 3, udp_url, &size); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ err = at_parser_num_get(parser, 4, &udp_port); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ err = enter_datamode(socket_datamode_callback); | |
+ if (err) { | |
+ return err; | |
+ } | |
+ break; | |
+ | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ return err; | |
+} | |
+ | |
/**@brief API to initialize Socket AT commands handler | |
*/ | |
int slm_at_socket_init(void) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment