From 4a9b3a5881e7015c09e43f46eb934eb8d8d9d680 Mon Sep 17 00:00:00 2001 From: SPRESENSE <41312067+SPRESENSE@users.noreply.github.com> Date: Fri, 2 Jun 2023 18:31:14 +0900 Subject: [PATCH] lte: Add usrsock daemon for ALT1250 LTE modem Add usrsock daemon for ALT1250 LTE modem. --- include/lte/lapi.h | 81 + include/lte/lte_api.h | 1580 ++++++++++++ include/lte/lte_fw_def.h | 30 + include/lte/lte_fwupdate.h | 155 ++ include/lte/lte_log.h | 187 ++ include/lte/lte_lwm2m.h | 324 +++ lte/.gitignore | 2 + lte/Make.defs | 36 + lte/Makefile | 38 + lte/alt1250/Kconfig | 159 ++ lte/alt1250/Make.defs | 23 + lte/alt1250/Makefile | 87 + lte/alt1250/README.txt | 68 + lte/alt1250/alt1250_atcmd.c | 942 ++++++++ lte/alt1250/alt1250_atcmd.h | 215 ++ lte/alt1250/alt1250_container.c | 186 ++ lte/alt1250/alt1250_container.h | 74 + lte/alt1250/alt1250_daemon.h | 175 ++ lte/alt1250/alt1250_dbg.h | 44 + lte/alt1250/alt1250_devevent.c | 453 ++++ lte/alt1250/alt1250_devevent.h | 32 + lte/alt1250/alt1250_devif.c | 189 ++ lte/alt1250/alt1250_devif.h | 53 + lte/alt1250/alt1250_main.c | 490 ++++ lte/alt1250/alt1250_netdev.c | 100 + lte/alt1250/alt1250_netdev.h | 41 + lte/alt1250/alt1250_postproc.h | 49 + lte/alt1250/alt1250_reset_seq.c | 399 +++ lte/alt1250/alt1250_reset_seq.h | 41 + lte/alt1250/alt1250_select.c | 368 +++ lte/alt1250/alt1250_select.h | 40 + lte/alt1250/alt1250_socket.c | 195 ++ lte/alt1250/alt1250_socket.h | 249 ++ lte/alt1250/alt1250_usockevent.c | 148 ++ lte/alt1250/alt1250_usockevent.h | 74 + lte/alt1250/alt1250_usockif.c | 394 +++ lte/alt1250/alt1250_usockif.h | 129 + lte/alt1250/alt1250_util.c | 69 + lte/alt1250/alt1250_util.h | 45 + lte/alt1250/callback_handlers/alt1250_evt.c | 2148 +++++++++++++++++ lte/alt1250/callback_handlers/alt1250_evt.h | 74 + .../usock_handlers/alt1250_accepthdlr.c | 255 ++ lte/alt1250/usock_handlers/alt1250_bindhdlr.c | 184 ++ .../usock_handlers/alt1250_closehdlr.c | 199 ++ .../usock_handlers/alt1250_connecthdlr.c | 342 +++ lte/alt1250/usock_handlers/alt1250_fwupdate.h | 59 + .../usock_handlers/alt1250_getpeernamehdlr.c | 59 + .../usock_handlers/alt1250_getsocknamehdlr.c | 227 ++ .../usock_handlers/alt1250_getsockopthdlr.c | 233 ++ .../alt1250_ioctl_denyinetsock.c | 77 + .../usock_handlers/alt1250_ioctl_event.c | 169 ++ .../usock_handlers/alt1250_ioctl_fwupdate.c | 464 ++++ .../usock_handlers/alt1250_ioctl_ifreq.c | 409 ++++ .../usock_handlers/alt1250_ioctl_ltecmd.c | 122 + .../usock_handlers/alt1250_ioctl_lwm2m.c | 964 ++++++++ .../usock_handlers/alt1250_ioctl_normal.c | 577 +++++ .../usock_handlers/alt1250_ioctl_other.c | 249 ++ .../usock_handlers/alt1250_ioctl_power.c | 103 + .../usock_handlers/alt1250_ioctl_subhdlr.h | 99 + .../usock_handlers/alt1250_ioctlhdlr.c | 99 + .../usock_handlers/alt1250_listenhdlr.c | 169 ++ .../usock_handlers/alt1250_recvfromhdlr.c | 234 ++ .../usock_handlers/alt1250_sendtohdlr.c | 192 ++ .../usock_handlers/alt1250_setsockopthdlr.c | 191 ++ .../usock_handlers/alt1250_shutdownhdlr.c | 59 + lte/alt1250/usock_handlers/alt1250_sms.c | 1050 ++++++++ lte/alt1250/usock_handlers/alt1250_sms.h | 114 + .../usock_handlers/alt1250_sockethdlr.c | 471 ++++ .../usock_handlers/alt1250_usrsock_hdlr.h | 234 ++ lte/lapi/Kconfig | 49 + lte/lapi/Make.defs | 23 + lte/lapi/Makefile | 27 + lte/lapi/src/Make.defs | 40 + lte/lapi/src/lapi_dbg.h | 40 + lte/lapi/src/lapi_evt.c | 202 ++ lte/lapi/src/lapi_firmware.c | 167 ++ lte/lapi/src/lapi_log.c | 211 ++ lte/lapi/src/lapi_lwm2m.c | 489 ++++ lte/lapi/src/lapi_net.c | 503 ++++ lte/lapi/src/lapi_other.c | 176 ++ lte/lapi/src/lapi_pdn.c | 264 ++ lte/lapi/src/lapi_pin.c | 405 ++++ lte/lapi/src/lapi_power.c | 316 +++ lte/lapi/src/lapi_psave.c | 583 +++++ lte/lapi/src/lapi_radio.c | 109 + lte/lapi/src/lapi_sim.c | 326 +++ 86 files changed, 21720 insertions(+) create mode 100644 include/lte/lapi.h create mode 100644 include/lte/lte_api.h create mode 100644 include/lte/lte_fw_def.h create mode 100644 include/lte/lte_fwupdate.h create mode 100644 include/lte/lte_log.h create mode 100644 include/lte/lte_lwm2m.h create mode 100644 lte/.gitignore create mode 100644 lte/Make.defs create mode 100644 lte/Makefile create mode 100644 lte/alt1250/Kconfig create mode 100644 lte/alt1250/Make.defs create mode 100644 lte/alt1250/Makefile create mode 100644 lte/alt1250/README.txt create mode 100644 lte/alt1250/alt1250_atcmd.c create mode 100644 lte/alt1250/alt1250_atcmd.h create mode 100644 lte/alt1250/alt1250_container.c create mode 100644 lte/alt1250/alt1250_container.h create mode 100644 lte/alt1250/alt1250_daemon.h create mode 100644 lte/alt1250/alt1250_dbg.h create mode 100644 lte/alt1250/alt1250_devevent.c create mode 100644 lte/alt1250/alt1250_devevent.h create mode 100644 lte/alt1250/alt1250_devif.c create mode 100644 lte/alt1250/alt1250_devif.h create mode 100644 lte/alt1250/alt1250_main.c create mode 100644 lte/alt1250/alt1250_netdev.c create mode 100644 lte/alt1250/alt1250_netdev.h create mode 100644 lte/alt1250/alt1250_postproc.h create mode 100644 lte/alt1250/alt1250_reset_seq.c create mode 100644 lte/alt1250/alt1250_reset_seq.h create mode 100644 lte/alt1250/alt1250_select.c create mode 100644 lte/alt1250/alt1250_select.h create mode 100644 lte/alt1250/alt1250_socket.c create mode 100644 lte/alt1250/alt1250_socket.h create mode 100644 lte/alt1250/alt1250_usockevent.c create mode 100644 lte/alt1250/alt1250_usockevent.h create mode 100644 lte/alt1250/alt1250_usockif.c create mode 100644 lte/alt1250/alt1250_usockif.h create mode 100644 lte/alt1250/alt1250_util.c create mode 100644 lte/alt1250/alt1250_util.h create mode 100644 lte/alt1250/callback_handlers/alt1250_evt.c create mode 100644 lte/alt1250/callback_handlers/alt1250_evt.h create mode 100644 lte/alt1250/usock_handlers/alt1250_accepthdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_bindhdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_closehdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_connecthdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_fwupdate.h create mode 100644 lte/alt1250/usock_handlers/alt1250_getpeernamehdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_getsocknamehdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_getsockopthdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_denyinetsock.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_event.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_fwupdate.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_ifreq.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_ltecmd.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_normal.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_other.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_power.c create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctl_subhdlr.h create mode 100644 lte/alt1250/usock_handlers/alt1250_ioctlhdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_listenhdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_recvfromhdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_sendtohdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_setsockopthdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_shutdownhdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_sms.c create mode 100644 lte/alt1250/usock_handlers/alt1250_sms.h create mode 100644 lte/alt1250/usock_handlers/alt1250_sockethdlr.c create mode 100644 lte/alt1250/usock_handlers/alt1250_usrsock_hdlr.h create mode 100644 lte/lapi/Kconfig create mode 100644 lte/lapi/Make.defs create mode 100644 lte/lapi/Makefile create mode 100644 lte/lapi/src/Make.defs create mode 100644 lte/lapi/src/lapi_dbg.h create mode 100644 lte/lapi/src/lapi_evt.c create mode 100644 lte/lapi/src/lapi_firmware.c create mode 100644 lte/lapi/src/lapi_log.c create mode 100644 lte/lapi/src/lapi_lwm2m.c create mode 100644 lte/lapi/src/lapi_net.c create mode 100644 lte/lapi/src/lapi_other.c create mode 100644 lte/lapi/src/lapi_pdn.c create mode 100644 lte/lapi/src/lapi_pin.c create mode 100644 lte/lapi/src/lapi_power.c create mode 100644 lte/lapi/src/lapi_psave.c create mode 100644 lte/lapi/src/lapi_radio.c create mode 100644 lte/lapi/src/lapi_sim.c diff --git a/include/lte/lapi.h b/include/lte/lapi.h new file mode 100644 index 000000000..7e3b7b091 --- /dev/null +++ b/include/lte/lapi.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * apps/include/lte/lapi.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LAPI_H +#define __APPS_INCLUDE_LTE_LAPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "lte/lte_api.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + + #ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototyppes + ****************************************************************************/ + +/**************************************************************************** + * Name: lapi_evtinit + ****************************************************************************/ + +int lapi_evtinit(FAR const char *mqname); + +/**************************************************************************** + * Name: lapi_evtdestoy + ****************************************************************************/ + +void lapi_evtdestoy(void); + +/**************************************************************************** + * Name: lapi_evtyield + ****************************************************************************/ + +int lapi_evtyield(int timeout_ms); + +/**************************************************************************** + * Name: lapi_req + ****************************************************************************/ + +int lapi_req(uint32_t cmdid, FAR void *inp, size_t insz, FAR void *outp, + size_t outsz, FAR void *cb); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_LTE_LAPI_H */ diff --git a/include/lte/lte_api.h b/include/lte/lte_api.h new file mode 100644 index 000000000..e016970d2 --- /dev/null +++ b/include/lte/lte_api.h @@ -0,0 +1,1580 @@ +/**************************************************************************** + * apps/include/lte/lte_api.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LTE_API_H +#define __APPS_INCLUDE_LTE_LTE_API_H + +/* - Abbreviations and terms + * - PDN : Packet Data Network + * + * Route for transferring packets between the terminal and LTE networks. + * + * - APN : Access Point Name + * + * Settings required when connecting to an LTE network. + * + * - IMSI : International Mobile Subscriber Identity + * + * International subscriber identification number recorded + * on the SIM card. + * + * - IMEI : International Mobile Equipment Identifier + * + * International identification number assigned to + * data communication terminals + * + * - PIN : Personal Identification Number + * + * - MCC : Mobile Country Code + * + * The mobile country code consists of three decimal digits. + * + * - MNC : Mobile Network Code + * + * The mobile network code consists of two or three decimal digits. + * + * - eDRX : extended Discontinuous Reception + * + * Communication technology that reduces power consumption + * by increasing the reception interval of various signals transmitted + * from LTE networks. + * + * - PSM : Power Saving Mode + * + * Communication technology that reduces power consumption + * by not communicating with the LTE network + * for a certain period of time. + * + * - CE : Coverage Enhancement + * + * Communication technology that attempts to resend data and eventually + * restores the original data even if the data is corrupted + * due to weak electric field communication. + * + * - RAT : Radio Access Technology + * + * Physical connection method for a radio based communication network. + * + * - LTE API system + * - Network connection API + * + * Radio ON / OFF, PDN connection establishment / destruction. + * + * - Communication quality and communication state API + * + * Acquisition of radio status, communication status, and local time. + * + * - SIM card control API + * + * Get phone number / IMSI, set the PIN, get SIM status. + * + * - Modem setting API + * + * Get modem firmware version and IMEI. Update communication settings. + * + * - API call type + * + * There are two types of LTE API: synchronous and asynchronous. + * + * - Synchronous API + * - Notifies the processing result as a return value. + * + * - Blocks the task that called the API until + * processing is completed on the modem. + * + * - If the return value is -EPROTO, you can get the error code + * with lte_get_errinfo. + * + * - If the argument attribute is out, the argument must be allocated + * by the caller. + * + * - Asynchronous API + * - The processing result is notified by callback. + * The callback is invoked in the task context. + * + * - Blocks the task that called the API until it requests + * processing from the modem. + * + * - Notifies the processing request result as a return value. + * + * - The callback is registered with the argument of each API. + * Registration is canceled when the processing result is notified. + * + * - The same API cannot be called until the processing result is notified + * by the callback.(-EINPROGRESS is notified with a return value.) + * + * - If the callback reports an error (LTE_RESULT_ERROR), + * detailed error information can be acquired with lte_get_errinfo. + * + * For some APIs, both synchronous and asynchronous APIs are available. + * The correspondence table of API is as follows. + * + * + * | Synchronous API | Asynchronous API | + * | ---------------------------- | --------------------------------- | + * | lte_initialize | | + * | lte_finalize | | + * | lte_set_report_restart | | + * | lte_power_on | | + * | lte_power_off | | + * | lte_set_report_netinfo | | + * | lte_set_report_simstat | | + * | lte_set_report_localtime | | + * | lte_set_report_quality | | + * | lte_set_report_cellinfo | | + * | lte_get_errinfo | | + * | lte_activate_pdn_cancel | | + * | lte_radio_on_sync | lte_radio_on (deprecated) | + * | lte_radio_off_sync | lte_radio_off (deprecated) | + * | lte_activate_pdn_sync | lte_activate_pdn | + * | lte_deactivate_pdn_sync | lte_deactivate_pdn (deprecated) | + * | lte_data_allow_sync | lte_data_allow (deprecated) | + * | lte_get_netinfo_sync | lte_get_netinfo (deprecated) | + * | lte_get_imscap_sync | lte_get_imscap (deprecated) | + * | lte_get_version_sync | lte_get_version (deprecated) | + * | lte_get_phoneno_sync | lte_get_phoneno (deprecated) | + * | lte_get_imsi_sync | lte_get_imsi (deprecated) | + * | lte_get_imei_sync | lte_get_imei (deprecated) | + * | lte_get_pinset_sync | lte_get_pinset (deprecated) | + * | lte_set_pinenable_sync | lte_set_pinenable (deprecated) | + * | lte_change_pin_sync | lte_change_pin (deprecated) | + * | lte_enter_pin_sync | lte_enter_pin (deprecated) | + * | lte_get_localtime_sync | lte_get_localtime (deprecated) | + * | lte_get_operator_sync | lte_get_operator (deprecated) | + * | lte_get_edrx_sync | lte_get_edrx (deprecated) | + * | lte_set_edrx_sync | lte_set_edrx (deprecated) | + * | lte_get_psm_sync | lte_get_psm (deprecated) | + * | lte_set_psm_sync | lte_set_psm (deprecated) | + * | lte_get_ce_sync | lte_get_ce (deprecated) | + * | lte_set_ce_sync | lte_set_ce (deprecated) | + * | lte_get_siminfo_sync | lte_get_siminfo (deprecated) | + * | lte_get_current_edrx_sync | lte_get_current_edrx (deprecated) | + * | lte_get_current_psm_sync | lte_get_current_psm (deprecated) | + * | lte_get_quality_sync | lte_get_quality (deprecated) | + * | lte_get_cellinfo_sync | | + * | lte_get_rat_sync | | + * | lte_set_rat_sync | | + * | lte_get_ratinfo_sync | | + * | lte_acquire_wakelock | | + * | lte_release_wakelock | | + * | lte_send_atcmd_sync | | + * | lte_factory_reset_sync | | + * | lte_set_context_save_cb | | + * | lte_hibernation_resume | | + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Initialize resources used in LTE API. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_initialize(void); + +/* Release resources used in LTE API. + * + * return On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_finalize(void); + +/* Register the callback to notify that the modem has started up. + * + * The callback will be invoked if the modem starts successfully + * after calling lte_power_on. Some APIs have to wait until + * this callback is invoked. If no wait, those API return + * with an error. (-ENETDOWN) + * + * The callback is also invoked when the modem is restarted. + * The cause of the restart can be obtained from the callback argument. + * + * This function must be called after lte_initialize. + * + * Attention to the following + * when LTE_RESTART_MODEM_INITIATED is set. + * - Asynchronous API callbacks for which results have not been + * notified are canceled and becomes available. + * + * - The processing result of the synchronous API + * being called results in an error. (Return value is -ENETDOWN) + * The errno is ENETDOWN for the socket API. + * + * - It should close the socket by user application. + * + * [in] restart_callback: Callback function to notify that + * modem restarted. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_restart(restart_report_cb_t restart_callback); + +/* Power on the modem. + * + * The callback which registered by lte_set_report_restart + * will be invoked if the modem starts successfully. + * + * This function must be called after lte_set_report_restart. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_power_on(void); + +/* Power off the modem + * + * Attention to the following when this API calling. + * - For asynchronous API + * - callback is canceled. + * + * - For synchronous API + * - API returns with an error. + * - The return value is -ENETDOWN for the LTE API. + * - The errno is ENETDOWN for the socket API. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_power_off(void); + +/* With the radio on, to start the LTE network search. + * + * Attention to the following when this API calling. + * - If SIM is PIN locked, the result will be an error. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_radio_on_sync(void); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* With the radio on, to start the LTE network search. + * The use of this API is deprecated. + * Use lte_radio_on_sync() instead. + * + * Attention to the following when this API calling. + * - If SIM is PIN locked, the result will be an error. + * + * [in] callback: Callback function to notify that + * radio on is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_radio_on(radio_on_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Exit LTE network searches with the radio off. + * + * If this function is called when a PDN has already been constructed, + * the PDN is discarded. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_radio_off_sync(void); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Exit LTE network searches with the radio off. + * The use of this API is deprecated. + * Use lte_radio_off_sync() instead. + * + * If this function is called when a PDN has already been constructed, + * the PDN is discarded. + * + * [in] callback: Callback function to notify that + * radio off is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_radio_off(radio_off_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get LTE network information. + * + * The maximum number of PDNs status areas must be allocated + * before calls this API. + * + * [in] pdn_num: Number of pdn_stat allocated by the user. + * The range is from LTE_PDN_SESSIONID_MIN to + * LTE_PDN_SESSIONID_MAX. + * + * [out] info: The LTE network information. + * See lte_netinfo_t + * + * attention Immediately after successful PDN construction + * using lte_activate_pdn_sync() or lte_activate_pdn(), + * session information such as IP address + * may not be acquired correctly. + * If you want to use this API after successfully construction + * the PDN, wait at least 1 second before executing it. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_netinfo_sync(uint8_t pdn_num, FAR lte_netinfo_t *info); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get LTE network information. + * The use of this API is deprecated. + * Use lte_get_netinfo_sync() instead. + * + * [in] callback: Callback function to notify that + * get network information completed. + * + * attention Immediately after successful PDN construction + * using lte_activate_pdn_sync() or lte_activate_pdn(), + * session information such as IP address + * may not be acquired correctly. + * If you want to use this API after successfully construction + * the PDN, wait at least 1 second before executing it. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_netinfo(get_netinfo_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Constructs a PDN with the specified APN settings. + * + * When constructs the initial PDN, + * LTE_APN_TYPE_IA must be set to the APN type. + * + * When PDN construction is successful, + * an IP address is given from the LTE network. + * + * attention Attention to the following when this API calling. + * - The initial PDN construction may take a few minutes + * depending on radio conditions. + * + * - If API is not returned, please check if the APN settings are correct. + * + * [in] apn: The pointer of the apn setting. + * See lte_apn_setting_t for valid parameters. + * + * [out] pdn: The construction PDN information. + * See lte_pdn_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + * If canceling, -ECANCELED is returned. + */ + +int lte_activate_pdn_sync(FAR lte_apn_setting_t *apn, FAR lte_pdn_t *pdn); + +/* Constructs a PDN with the specified APN settings. + * + * When constructs the initial PDN, + * LTE_APN_TYPE_IA must be set to the APN type. + * + * When PDN construction is successful, + * an IP address is given from the LTE network. + * + * attention Attention to the following when this API calling. + * - The initial PDN construction may take a few minutes + * depending on radio conditions. + * + * - If the callback is not notified, please check + * if the APN settings are correct. + * + * [in] apn: The pointer of the apn setting. + * See lte_apn_setting_t for valid parameters. + * + * [in] callback: Callback function to notify that + * PDN activation completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_activate_pdn(FAR lte_apn_setting_t *apn, activate_pdn_cb_t callback); + +/* Cancel PDN construction. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_activate_pdn_cancel(void); + +/* Discard the constructed PDN. + * + * Discards the PDN corresponding to the session ID + * obtained by lte_activate_pdn. + * + * When the discard process is successful, the IP address assigned to + * the modem is released to the LTE network. + * + * [in] session_id: The numeric value of the session ID. + * Use the value obtained by the lte_activate_pdn. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_deactivate_pdn_sync(uint8_t session_id); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Discard the constructed PDN. + * The use of this API is deprecated. + * Use lte_deactivate_pdn_sync() instead. + * + * Discards the PDN corresponding to the session ID + * obtained by lte_activate_pdn. + * + * When the discard process is successful, the IP address assigned to + * the modem is released to the LTE network. + * + * [in] session_id: The numeric value of the session ID. + * Use the value obtained by the lte_activate_pdn. + * + * [in] callback: Callback function to notify that + * LTE PDN deactivation completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_deactivate_pdn(uint8_t session_id, deactivate_pdn_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Allow or disallow to data communication for specified PDN. + * + * attention This function is not supported. + * + * [in] session_id: The numeric value of the session ID. + * Use the value obtained by the lte_activate_pdn. + * + * [in] allow: Allow or disallow to data communication for + * all network. Definition is as below. + * - LTE_DATA_ALLOW + * - LTE_DATA_DISALLOW + * + * [in] roaming_allow: Allow or disallow to data communication for + * roaming network. Definition is as below. + * - LTE_DATA_ALLOW + * - LTE_DATA_DISALLOW + * + * -EOPNOTSUPP is returned. + */ + +int lte_data_allow_sync(uint8_t session_id, uint8_t allow, + uint8_t roaming_allow); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Allow or disallow to data communication for specified PDN. + * The use of this API is deprecated. + * + * attention This function is not supported. + * + * [in] session_id: The numeric value of the session ID. + * Use the value obtained by the lte_activate_pdn. + * + * [in] allow: Allow or disallow to data communication for + * all network. Definition is as below. + * - LTE_DATA_ALLOW + * - LTE_DATA_DISALLOW + * + * [in] roaming_allow: Allow or disallow to data communication for + * roaming network. Definition is as below. + * - LTE_DATA_ALLOW + * - LTE_DATA_DISALLOW + * + * [in] callback: Callback function to notify that + * configuration has changed. + * + * -EOPNOTSUPP is returned. + */ + +int lte_data_allow(uint8_t session_id, uint8_t allow, + uint8_t roaming_allow, data_allow_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get whether the modem supports IMS or not. + * + * [out] imscap: The IMS capability. + * As below value stored. + * - LTE_ENABLE + * - LTE_DISABLE + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_imscap_sync(FAR bool *imscap); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get whether the modem supports IMS or not. + * The use of this API is deprecated. + * Use lte_get_imscap_sync() instead. + * + * [in] callback: Callback function to notify when + * getting IMS capability is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_imscap(get_imscap_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Acquires the FW version information of the modem. + * + * [out] version: The version information of the modem. + * See lte_version_t + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_version_sync(FAR lte_version_t *version); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Acquires the FW version information of the modem. + * The use of this API is deprecated. + * Use lte_get_version_sync() instead. + * + * [in] callback: Callback function to notify when + * getting the version is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_version(get_ver_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get phone number from SIM. + * + * [out] phoneno: A character string indicating phone number. + * It is terminated with '\0'. + * The maximum number of phone number areas + * must be allocated. See LTE_PHONENO_LEN. + * [in] len: Length of the buffer for storing phone number. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_phoneno_sync(FAR char *phoneno); +#else +int lte_get_phoneno_sync(FAR char *phoneno, size_t len); +#endif + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get phone number from SIM. + * The use of this API is deprecated. + * Use lte_get_phoneno_sync() instead. + * + * [in] callback: Callback function to notify when + * getting the phone number is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_phoneno(get_phoneno_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get International Mobile Subscriber Identity from SIM. + * + * [out] imsi: A character string indicating IMSI. + * It is terminated with '\0'. + * The maximum number of IMSI areas + * must be allocated. See LTE_IMSI_LEN. + * [in] len: Length of the buffer for storing IMSI. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_imsi_sync(FAR char *imsi); +#else +int lte_get_imsi_sync(FAR char *imsi, size_t len); +#endif + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get International Mobile Subscriber Identity from SIM. + * The use of this API is deprecated. + * Use lte_get_imsi_sync() instead. + * + * [in] callback: Callback function to notify when + * getting IMSI is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_imsi(get_imsi_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get International Mobile Equipment Identifier from the modem. + * + * [out] imei: A character string indicating IMEI. + * It is terminated with '\0'. + * The maximum number of IMEI areas + * must be allocated. See LTE_IMEI_LEN. + * [in] len: Length of the buffer for storing IMEI. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_imei_sync(FAR char *imei); +#else +int lte_get_imei_sync(FAR char *imei, size_t len); +#endif + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get International Mobile Equipment Identifier from the modem. + * The use of this API is deprecated. + * Use lte_get_imei_sync() instead. + * + * [in] callback: Callback function to notify when + * getting IMEI is completed + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_imei(get_imei_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get Personal Identification Number settings. + * + * [out] pinset: PIN settings information. + * See lte_getpin_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_pinset_sync(FAR lte_getpin_t *pinset); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get Personal Identification Number settings. + * The use of this API is deprecated. + * Use lte_get_pinset_sync() instead. + * + * [in] callback: Callback function to notify when + * getting the PIN setting is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_pinset(get_pinset_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Set Personal Identification Number enable. + * + * [in] enable: "Enable" or "Disable". + * Definition is as below. + * - LTE_ENABLE + * - LTE_DISABLE + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [out] attemptsleft: Number of attempts left. + * Set only if failed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_pinenable_sync(bool enable, FAR char *pincode, + FAR uint8_t *attemptsleft); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Set Personal Identification Number enable. + * The use of this API is deprecated. + * Use lte_set_pinenable_sync() instead. + * + * [in] enable: "Enable" or "Disable". + * Definition is as below. + * - LTE_ENABLE + * - LTE_DISABLE + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] callback: Callback function to notify that + * setting of PIN enables/disables is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_pinenable(bool enable, FAR char *pincode, + set_pinenable_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Change Personal Identification Number. + * + * It can be changed only when PIN is enable. + * + * [in] target_pin: Target of change PIN. + * Definition is as below. + * - LTE_TARGET_PIN + * - LTE_TARGET_PIN2 + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] new_pincode: New PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [out] attemptsleft: Number of attempts left. + * Set only if failed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_change_pin_sync(int8_t target_pin, FAR char *pincode, + FAR char *new_pincode, FAR uint8_t *attemptsleft); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Change Personal Identification Number. + * The use of this API is deprecated. + * Use lte_change_pin_sync() instead. + * + * It can be changed only when PIN is enable. + * + * [in] target_pin: Target of change PIN. + * Definition is as below. + * - LTE_TARGET_PIN + * - LTE_TARGET_PIN2 + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] new_pincode: New PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] callback: Callback function to notify that + * change of PIN is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_change_pin(int8_t target_pin, FAR char *pincode, + FAR char *new_pincode, change_pin_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Enter Personal Identification Number. + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] new_pincode: Always set NULL. + * This parameter is not currently used. + * If this parameter has a value in it, + * this API will error. + * + * [out] simstat: State after PIN enter. + * As below value stored. + * - LTE_PINSTAT_READY + * - LTE_PINSTAT_SIM_PIN + * - LTE_PINSTAT_SIM_PUK + * - LTE_PINSTAT_PH_SIM_PIN + * - LTE_PINSTAT_PH_FSIM_PIN + * - LTE_PINSTAT_PH_FSIM_PUK + * - LTE_PINSTAT_SIM_PIN2 + * - LTE_PINSTAT_SIM_PUK2 + * - LTE_PINSTAT_PH_NET_PIN + * - LTE_PINSTAT_PH_NET_PUK + * - LTE_PINSTAT_PH_NETSUB_PIN + * - LTE_PINSTAT_PH_NETSUB_PUK + * - LTE_PINSTAT_PH_SP_PIN + * - LTE_PINSTAT_PH_SP_PUK + * - LTE_PINSTAT_PH_CORP_PIN + * - LTE_PINSTAT_PH_CORP_PUK + * + * [out] attemptsleft: Number of attempts left. + * Set only if failed. + * If simstat is other than PIN, PUK, PIN2, PUK2, + * set the number of PIN. + * + * note Running this API when the SIM state is + * other than LTE_PINSTAT_SIM_PIN will return an error. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + * + * deprecated This API will be removed in a future version + */ + +int lte_enter_pin_sync(FAR char *pincode, FAR char *new_pincode, + FAR uint8_t *simstat, FAR uint8_t *attemptsleft); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Enter Personal Identification Number. + * The use of this API is deprecated. + * Use lte_enter_pin_sync() instead. + * + * [in] pincode: Current PIN code. Minimum number of digits is 4. + * Maximum number of digits is 8, end with '\0'. + * (i.e. Max 9 byte) + * + * [in] new_pincode: Always set NULL. + * This parameter is not currently used. + * If this parameter has a value in it, + * this API will error. + * + * [in] callback: Callback function to notify that + * PIN enter is completed. + * + * note Running this API when the SIM state is + * other than LTE_PINSTAT_SIM_PIN will return an error. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + * + * deprecated This API will be removed in a future version + */ + +int lte_enter_pin(FAR char *pincode, FAR char *new_pincode, + enter_pin_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get local time. + * + * [out] localtime: Local time. See lte_localtime_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_localtime_sync(FAR lte_localtime_t *localtime); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get local time. + * The use of this API is deprecated. + * Use lte_get_localtime_sync() instead. + * + * [in] callback: Callback function to notify when + * getting local time is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_localtime(get_localtime_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get connected network operator information. + * + * [out] oper: A character string indicating network operator. + * It is terminated with '\0' If it is not connected, + * the first character is '\0'. + * The maximum number of network operator areas + * must be allocated. See LTE_OPERATOR_LEN. + * [in] len: Length of the buffer for storing network operator. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_operator_sync(FAR char *oper); +#else +int lte_get_operator_sync(FAR char *oper, size_t len); +#endif + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get connected network operator information. + * The use of this API is deprecated. + * Use lte_get_operator_sync() instead. + * + * [in] callback: Callback function to notify when + * getting network operator information is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_operator(get_operator_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get eDRX settings. + * + * [out] settings: eDRX settings. See lte_edrx_setting_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_edrx_sync(FAR lte_edrx_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get eDRX settings. + * The use of this API is deprecated. + * Use lte_get_edrx_sync() instead. + * + * [in] callback: Callback function to notify when + * getting eDRX settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_edrx(get_edrx_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Set eDRX settings. + * + * [in] settings: eDRX settings. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_edrx_sync(FAR lte_edrx_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Set eDRX settings. + * The use of this API is deprecated. + * Use lte_set_edrx_sync() instead. + * + * [in] settings: eDRX settings. + * + * [in] callback: Callback function to notify that + * eDRX settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_edrx(FAR lte_edrx_setting_t *settings, set_edrx_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get PSM settings. + * + * [out] settings: PSM settings. See lte_psm_setting_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_psm_sync(FAR lte_psm_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get PSM settings. + * The use of this API is deprecated. + * Use lte_get_psm_sync() instead. + * + * [in] callback: Callback function to notify when + * getting PSM settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_psm(get_psm_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Set PSM settings. + * + * [in] settings: PSM settings. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_psm_sync(FAR lte_psm_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Set PSM settings. + * The use of this API is deprecated. + * Use lte_set_psm_sync() instead. + * + * [in] settings: PSM settings. + * + * [in] callback: Callback function to notify that + * PSM settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_psm(FAR lte_psm_setting_t *settings, set_psm_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get CE settings. + * + * [out] settings: CE settings. See lte_ce_setting_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_ce_sync(FAR lte_ce_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get CE settings. + * The use of this API is deprecated. + * Use lte_get_ce_sync() instead. + * + * [in] callback: Callback function to notify when + * getting CE settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_ce(get_ce_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Set CE settings. + * + * [in] settings: CE settings + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_ce_sync(FAR lte_ce_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Set CE settings. + * The use of this API is deprecated. + * Use lte_set_ce_sync() instead. + * + * [in] settings: CE settings + * + * [in] callback: Callback function to notify that + * CE settings are completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_ce(FAR lte_ce_setting_t *settings, set_ce_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Notifies the SIM status to the application. + * + * The default report setting is disable. + * + * [in] simstat_callback: Callback function to notify that SIM state. + * If NULL is set, + * the report setting is disabled. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_simstat(simstat_report_cb_t simstat_callback); + +/* Notifies the Local time to the application. + * + * The default report setting is disable. + * + * [in] localtime_callback: Callback function to notify that + * local time. If NULL is set, + * the report setting is disabled. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_localtime(localtime_report_cb_t localtime_callback); + +/* Notifies the communication quality information to the application. + * + * Invoke the callback at the specified report interval. + * + * The default report setting is disable. + * + * attention When changing the notification cycle, stop and start again. + * + * [in] quality_callback: Callback function to notify that + * quality information. If NULL is set, + * the report setting is disabled. + * + * [in] period: Reporting cycle in sec (1-4233600) + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_quality(quality_report_cb_t quality_callback, + uint32_t period); + +/* Notifies the LTE network cell information to the application. + * + * Invoke the callback at the specified report interval. + * + * The default report setting is disable. + * + * attention When changing the notification cycle, stop and start again. + * + * [in] cellinfo_callback: Callback function to notify that + * cell information. If NULL is set, + * the report setting is disabled. + * + * [in] period: Reporting cycle in sec (1-4233600) + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_cellinfo(cellinfo_report_cb_t cellinfo_callback, + uint32_t period); + +/* Notifies the LTE network status to the application. + * + * The default report setting is disable. + * + * [in] netinfo_callback: Callback function to notify that + * cell information. If NULL is set, + * the report setting is disabled. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_report_netinfo(netinfo_report_cb_t netinfo_callback); + +/* Get LTE API last error information. + * + * Call this function when LTE_RESULT_ERROR is returned by + * callback function. The detailed error information can be obtained. + * + * [in] info: Pointer of error information. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_errinfo(FAR lte_errinfo_t *info); + +/* Get SIM information such as Mobile Country Code/Mobile Network Code. + * + * [in] option: Indicates which parameter to get. + * Bit setting definition is as below. + * - LTE_SIMINFO_GETOPT_MCCMNC + * - LTE_SIMINFO_GETOPT_SPN + * - LTE_SIMINFO_GETOPT_ICCID + * - LTE_SIMINFO_GETOPT_IMSI + * - LTE_SIMINFO_GETOPT_GID1 + * - LTE_SIMINFO_GETOPT_GID2 + * + * [out] siminfo: SIM information. See lte_siminfo_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_siminfo_sync(uint32_t option, FAR lte_siminfo_t *siminfo); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get SIM information such as Mobile Country Code/Mobile Network Code. + * The use of this API is deprecated. + * Use lte_get_siminfo_sync() instead. + * + * [in] option: Indicates which parameter to get. + * Bit setting definition is as below. + * - LTE_SIMINFO_GETOPT_MCCMNC + * - LTE_SIMINFO_GETOPT_SPN + * - LTE_SIMINFO_GETOPT_ICCID + * - LTE_SIMINFO_GETOPT_IMSI + * - LTE_SIMINFO_GETOPT_GID1 + * - LTE_SIMINFO_GETOPT_GID2 + * + * [in] callback: Callback function to notify that + * get of SIM information is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_siminfo(uint32_t option, get_siminfo_cb_t callback); + +/* Get eDRX dynamic parameter. + * + * deprecated Use lte_get_current_edrx instead. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * [in] callback: Callback function to notify when + * getting eDRX dynamic parameter is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_dynamic_edrx_param(get_dynamic_edrx_param_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get current eDRX settings. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * Get the settings negotiated between the modem and the network. + * + * [out] settings: Current eDRX settings. + * See lte_edrx_setting_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_current_edrx_sync(FAR lte_edrx_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get current eDRX settings. + * The use of this API is deprecated. + * Use lte_get_current_edrx_sync() instead. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * Get the settings negotiated between the modem and the network. + * + * [in] callback: Callback function to notify when + * getting current eDRX settings is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_current_edrx(get_current_edrx_cb_t callback); + +/* Get PSM dynamic parameter. + * + * deprecated Use lte_get_current_psm instead. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * [in] callback: Callback function to notify when + * getting PSM dynamic parameter is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_dynamic_psm_param(get_dynamic_psm_param_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get current PSM settings. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * Get the settings negotiated between the modem and the network. + * + * [OUT] settings: Current PSM settings. + * See lte_psm_setting_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_current_psm_sync(FAR lte_psm_setting_t *settings); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get current PSM settings. + * The use of this API is deprecated. + * Use lte_get_current_psm_sync() instead. + * + * This API can be issued after connect to the LTE network + * with lte_activate_pdn(). + * + * Get the settings negotiated between the modem and the network. + * + * [in] callback: Callback function to notify when + * getting current PSM settings is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_current_psm(get_current_psm_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get communication quality information. + * + * [out] quality: Quality information. See lte_quality_t + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_quality_sync(FAR lte_quality_t *quality); + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* Get communication quality information. + * The use of this API is deprecated. + * Use lte_get_quality_sync() instead. + * + * [in] callback: Callback function to notify when + * getting quality information is completed. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_quality(get_quality_cb_t callback); + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* Get LTE network cell information. + * + * attention This function is not supported yet. + * + * [out] cellinfo: LTE network cell information. + * See lte_cellinfo_t + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_cellinfo_sync(FAR lte_cellinfo_t *cellinfo); + +/* Get RAT type + * + * On success, RAT type shown below is returned. + * - LTE_RAT_CATM + * - LTE_RAT_NBIOT + * On failure, negative value is returned according to . + */ + +int lte_get_rat_sync(void); + +/* Set RAT setting + * + * [in] rat: RAT type. Definition is as below. + * - LTE_RAT_CATM + * - LTE_RAT_NBIOT + * [in] persistent: Flag to keep RAT settings + * after power off the modem. + * Definition is as below. + * - LTE_ENABLE + * - LTE_DISABLE + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_rat_sync(uint8_t rat, bool persistent); + +/* Get RAT information + * + * [out] info: Pointer to the structure that + * stores RAT information + * See lte_ratinfo_t. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_get_ratinfo_sync(FAR lte_ratinfo_t *info); + +/* Acquire the modem wakelock. If any wakelock is acquired, modem can't + * enter to the sleep state. + * Please call this API after calling lte_initialize(). + * Otherwise this API will result in an error. + * Before calling lte_finalize(), must release all wakelocks + * acquired by this API. + * + * On success, return the count of the current modem wakelock. On failure, + * negative value is returned according to . + */ + +int lte_acquire_wakelock(void); + +/* Release the modem wakelock. If all of the wakelock are released, + * modem can enter to the sleep state. + * Please call this API after calling lte_initialize(). + * Otherwise this API will result in an error. + * + * On success, return the count of the current modem wakelock. On failure, + * negative value is returned according to . + */ + +int lte_release_wakelock(void); + +/* Get the number of wakelock counts acquired. + * Please call this API after calling lte_initialize(). + * Otherwise this API will result in an error. + * + * On success, return the count of the current modem wakelock. On failure, + * negative value is returned according to . + */ + +int lte_get_wakelock_count(void); + +/* Send AT command to the modem. + * + * [in] cmd: The AT command data. + * Maximum length is LTE_AT_COMMAND_MAX_LEN. + * AT command is shall begin with "AT" and end with '\r'. + * [in] cmdlen: Length of the AT command data. + * [in] respbuff: The area to store the AT command response. + * [in] respbufflen: Length of the AT command response buffer. + * [in] resplen: The pointer to the area store + * the length of AT command response. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_send_atcmd_sync(FAR const char *cmd, int cmdlen, + FAR char *respbuff, int respbufflen, + FAR int *resplen); + +/* Run factory reset on the modem. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_factory_reset_sync(void); + +/* Set callback function for context save. + * + * [in] callback: Callback function to notify a context data + * when modem entering hibernation mode. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_set_context_save_cb(context_save_cb_t callback); + +/* Resume LTE status from hibernation mode. + * + * [in] res_ctx: Context data for resume daemon. + * + * [in] len : Context data size. + * + * On success, 0 is returned. On failure, + * negative value is returned according to . + */ + +int lte_hibernation_resume(FAR const uint8_t *res_ctx, int len); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_LTE_LTE_API_H */ diff --git a/include/lte/lte_fw_def.h b/include/lte/lte_fw_def.h new file mode 100644 index 000000000..a737e4245 --- /dev/null +++ b/include/lte/lte_fw_def.h @@ -0,0 +1,30 @@ +/**************************************************************************** + * apps/include/lte/lte_fw_def.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LTE_FW_DEF_H +#define __APPS_INCLUDE_LTE_LTE_FW_DEF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#endif /* __APPS_INCLUDE_LTE_LTE_FW_DEF_H */ diff --git a/include/lte/lte_fwupdate.h b/include/lte/lte_fwupdate.h new file mode 100644 index 000000000..0d6af8e69 --- /dev/null +++ b/include/lte/lte_fwupdate.h @@ -0,0 +1,155 @@ +/**************************************************************************** + * apps/include/lte/lte_fwupdate.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LTE_FWUPDATE_H +#define __APPS_INCLUDE_LTE_LTE_FWUPDATE_H + +/* API call type + * + * | Sync API | + * | ----------------------------- | + * | ltefwupdate_initialize | + * | ltefwupdate_injectrest | + * | ltefwupdate_injected_datasize | + * | ltefwupdate_execute | + * | ltefwupdate_result | + * + * attention + * This API notifies the progress of the update by the callback set by + * lte_set_report_restart(). You must call lte_set_report_restart() + * before lte_power_on(). + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "lte_fw_def.h" + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Initialze injection delta image to LTE modem. + * + * Initialize LTE modem delta image injection with some data of top of delta + * image. + * + * [in] initial_data: Pointer to top data of update image. + * [in] len: Size of initial_data. + * + * Return value : Positive value is the injected length. Negative value is + * any error. In error case, the value can be below values. + * + * - LTEFW_RESULT_NOT_ENOUGH_INJECTSTORAGE + * - LTEFW_RESULT_DELTAIMAGE_HDR_CRC_ERROR + * - LTEFW_RESULT_DELTAIMAGE_HDR_UNSUPPORTED + * - EINVAL + * - ENODATA + * + */ + +int ltefwupdate_initialize(FAR const char *initial_data, int len); + +/* Inject rest delta image to LTE modem. + * + * Inject the rest of the delta image following the data injected + * by the ltefwupdate_initialize() and ltefwupdate_injectrest() functions. + * + * [in] rest_data: Pointer to top data of update image. + * [in] len: Size of initial_data. + * + * Return value : Positive value is the injected length. Negative value is + * any error. In error case, the value can be below values. + * + * - LTEFW_RESULT_NOT_ENOUGH_INJECTSTORAGE + * - LTEFW_RESULT_DELTAIMAGE_HDR_CRC_ERROR + * - LTEFW_RESULT_DELTAIMAGE_HDR_UNSUPPORTED + * - EINVAL + * - ENODATA + * + */ + +int ltefwupdate_injectrest(FAR const char *rest_data, int len); + +/* Get length of injected delta image file. + * + * On success, The length of injected data to the modem is returned. + * On failure, a negative value is returned according to . + */ + +int ltefwupdate_injected_datasize(void); + +/* Execute delta update. + * attention When this function is executed, the modem is automatically + * rebooted multiple times. The progress of the update can be checked by + * the callback set by lte_set_report_restart(). + * Before executing this function, the modem must be woken up using + * lte_acquire_wakelock() to safely update the modem. Then + * lte_release_wakelock() is executed when the callback set by + * lte_set_report_restart() is called. + * + * On success, 0 is returned. On failure, + * negative value is returned as below values. + * + * - LTEFW_RESULT_PRECHK_SET_DELTAIMAGE_FAILED + * - LTEFW_RESULT_PRECHK_DELTAIMAGE_MISSING + * - LTEFW_RESULT_PRECHK_OOM + * - LTEFW_RESULT_PRECHK_SIZE_ERROR + * - LTEFW_RESULT_PRECHK_PKG_ERROR + * - LTEFW_RESULT_PRECHK_CRC_ERROR + * - -EPERM + * + */ + +int ltefwupdate_execute(void); + +/* Get the result of delta update. + * Execute this function after LTE_RESTART_MODEM_UPDATED is + * notified to the callback set by lte_set_report_restart(). + * + * On success, 0 is returned. On failure, + * negative value is returned as below values. + + * - LTEFW_RESULT_OK + * - LTEFW_RESULT_DELTAUPDATE_FAILED + * - LTEFW_RESULT_DELTAUPDATE_NORESULT + * + */ + +int ltefwupdate_result(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_LTE_LTE_FWUPDATE_H */ diff --git a/include/lte/lte_log.h b/include/lte/lte_log.h new file mode 100644 index 000000000..35fd01c42 --- /dev/null +++ b/include/lte/lte_log.h @@ -0,0 +1,187 @@ +/**************************************************************************** + * apps/include/lte/lte_log.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LTE_LOG_H +#define __APPS_INCLUDE_LTE_LTE_LOG_H + +/* API call type + * + * | Sync API | + * | --------------- | + * | lte_log_collect | + * | lte_log_getlist | + * | lte_log_open | + * | lte_log_close | + * | lte_log_read | + * | lte_log_remove | + * | lte_log_lseek | + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Collect LTE modem FW logs and store them in the LTE modem storage. + * + * [out] output_fname: Buffer to store the name of the saved file. + * If the saved file name is not needed, set it to NULL. + * [in] len: Buffer length for output_fname. Sets LTE_LOG_NAME_LEN, + * except when the saved file name is not needed. + * + * Return value : Returns 0 on success. On error, a negative value is + * returned. The following values may be returned + * in error cases. + * + * - ENOBUFS + * - ENOTSUP + * + */ + +int lte_log_collect(FAR char *output_fname, size_t len); + +/* Get a list of logs stored in the LTE modem storage. + * + * [in] listsize: Number of arrays in which to store file names. The maximum + * number of arrays is LTE_LOG_LIST_SIZE. + * [in] fnamelen: Buffer length for list. Sets LTE_LOG_NAME_LEN. + * [in] list: Buffer to store the list of saved file names. + * + * Return value : Returns the number of stored file names on success. + * On error, a negative value is returned. The following + * values may be returned in error cases. + * + * - EINVAL + * - ENOBUFS + * - ENOTSUP + * + */ + +int lte_log_getlist(size_t listsize, size_t fnamelen, + char list[listsize][fnamelen]); + +#ifdef CONFIG_LTE_LAPI_LOG_ACCESS + +/* Open a log file on LTE modem. + * + * [in] filename: Log file name to open. + * + * Return value : Returns the file descriptor on success. + * On error, a negative value is returned. The following + * values may be returned in error cases. + * + * - EINVAL + * - ENAMETOOLONG + * - ENOTSUP + * + */ + +int lte_log_open(FAR const char *filename); + +/* Close a log file descriptor. + * + * [in] fd: File descriptor. + * + * Return value : Returns the 0 on success. + * On error, a negative value is returned. The following + * values may be returned in error cases. + * + * - EINVAL + * - ENOTSUP + * + */ + +int lte_log_close(int fd); + +/* Read data from log file on LTE modem. + * + * [in] fd: File descriptor. + * [out] buf: Buffer to read. + * [in] len: Read length. + * + * Return value : Returns the number of bytes read on success. + * On error, a negative value is returned. The following + * values may be returned in error cases. + * + * - EINVAL + * - ENOTSUP + * + */ + +ssize_t lte_log_read(int fd, FAR void *buf, size_t len); + +/* Remove a file on LTE modem. + * + * [in] filename: Log file name to remove. + * + * Return value : Returns the 0 on success. + * On error, a negative value is returned. The following + * values may be returned in error cases. + * + * - ENAMETOOLONG + * - ENOTSUP + * + */ + +int lte_log_remove(FAR const char *filename); + +/* Set the file read offset. + * + * [in] fd: File descriptor. + * [in] offset: The number of offset bytes. + * [in] whence: Reference point of offset. + * Available @a whence are as follows. + * - SEEK_SET + * - SEEK_CUR + * - SEEK_END + * + * Return value : Returns the offset from the beginning of the file on + * success. On error, a negative value is returned. + * The following values may be returned in error cases. + * + * - EINVAL + * - ENOTSUP + * + */ + +int lte_log_lseek(int fd, off_t offset, int whence); + +#endif /* CONFIG_LTE_LAPI_LOG_ACCESS */ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_LTE_LTE_LOG_H */ diff --git a/include/lte/lte_lwm2m.h b/include/lte/lte_lwm2m.h new file mode 100644 index 000000000..c61e2b3d1 --- /dev/null +++ b/include/lte/lte_lwm2m.h @@ -0,0 +1,324 @@ +/**************************************************************************** + * apps/include/lte/lte_lwm2m.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_LTE_LTE_LWM2M_H +#define __APPS_INCLUDE_LTE_LTE_LWM2M_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#define LWM2MSTUB_RESOURCE_HANDLENOCARE (0) +#define LWM2MSTUB_RESOURCE_HANDLEHOST (1) +#define LWM2MSTUB_RESOURCE_HANDLEMODEMH (2) + +#define LWM2MSTUB_MAX_WRITE_SIZE (1500) +#define LWM2MSTUB_MAX_TOKEN_SIZE (8 * 2 + 1) + +#define LWM2MSTUB_MAX_SERVER_NAME (256) +#define LWM2MSTUB_MAX_DEVID (256) +#define LWM2MSTUB_MAX_SEQKEY (256) + +#define LWM2MSTUB_CONDVALID_MINPERIOD (1<<0) +#define LWM2MSTUB_CONDVALID_MAXPERIOD (1<<1) +#define LWM2MSTUB_CONDVALID_GRATERTHAN (1<<2) +#define LWM2MSTUB_CONDVALID_LESSTHAN (1<<3) +#define LWM2MSTUB_CONDVALID_STEP (1<<4) + +#define LWM2MSTUB_FWUP_PEND_DL (0) +#define LWM2MSTUB_FWUP_PEND_UPD (1) +#define LWM2MSTUB_FWUP_COMP_DL (2) +#define LWM2MSTUB_FWUP_FAIL_DL (3) +#define LWM2MSTUB_FWUP_CANCELED (4) + +#define LWM2MSTUB_CMD_REGISTER (0) +#define LWM2MSTUB_CMD_DEREGISTER (1) +#define LWM2MSTUB_CMD_UPDATERESIGER (2) + +#define LWM2MSTUB_STATE_NOTREGISTERD (0) +#define LWM2MSTUB_STATE_REGISTPENDING (1) +#define LWM2MSTUB_STATE_REGISTERD (2) +#define LWM2MSTUB_STATE_REGISTERFAILED (3) +#define LWM2MSTUB_STATE_UPDATEPENDING (4) +#define LWM2MSTUB_STATE_DEREGISTPENDING (5) +#define LWM2MSTUB_STATE_BSHOLDOFF (6) +#define LWM2MSTUB_STATE_BSREQUESTED (7) +#define LWM2MSTUB_STATE_BSONGOING (8) +#define LWM2MSTUB_STATE_BSDONE (9) +#define LWM2MSTUB_STATE_BSFAILED (10) + +#define LWM2MSTUB_RESOP_READ (0) +#define LWM2MSTUB_RESOP_WRITE (1) +#define LWM2MSTUB_RESOP_RW (2) +#define LWM2MSTUB_RESOP_EXEC (3) + +#define LWM2MSTUB_RESINST_SINGLE (0) +#define LWM2MSTUB_RESINST_MULTI (1) + +#define LWM2MSTUB_RESDATA_NONE (0) +#define LWM2MSTUB_RESDATA_STRING (1) +#define LWM2MSTUB_RESDATA_INT (2) +#define LWM2MSTUB_RESDATA_UNSIGNED (3) +#define LWM2MSTUB_RESDATA_FLOAT (4) +#define LWM2MSTUB_RESDATA_BOOL (5) +#define LWM2MSTUB_RESDATA_OPAQUE (6) +#define LWM2MSTUB_RESDATA_TIME (7) +#define LWM2MSTUB_RESDATA_OBJLINK (8) + +#define LWM2MSTUB_SECUREMODE_PSK (0) +#define LWM2MSTUB_SECUREMODE_RPK (1) +#define LWM2MSTUB_SECUREMODE_CERT (2) +#define LWM2MSTUB_SECUREMODE_NOSEC (3) +#define LWM2MSTUB_SECUREMODE_CERTEST (4) + +#define LWM2MSTUB_CONNECT_REGISTER (0) +#define LWM2MSTUB_CONNECT_DEREGISTER (1) +#define LWM2MSTUB_CONNECT_REREGISTER (2) +#define LWM2MSTUB_CONNECT_BOOTSTRAP (3) + +#define LWM2MSTUB_RESP_CHANGED (0) +#define LWM2MSTUB_RESP_CONTENT (1) +#define LWM2MSTUB_RESP_BADREQ (2) +#define LWM2MSTUB_RESP_UNAUTH (3) +#define LWM2MSTUB_RESP_NOURI (4) +#define LWM2MSTUB_RESP_NOTALLOW (5) +#define LWM2MSTUB_RESP_NOTACCEPT (6) +#define LWM2MSTUB_RESP_UNSUPPORT (7) +#define LWM2MSTUB_RESP_INTERNALERROR (8) + +/* Client received "Write" operation */ + +#define LWM2MSTUB_OP_WRITE (0) + +/* Client received "Execute" operation */ + +#define LWM2MSTUB_OP_EXEC (1) + +/* Client received "Write Attributes" operation */ + +#define LWM2MSTUB_OP_WATTR (4) + +/* Client received "Discover" operation */ + +#define LWM2MSTUB_OP_DISCOVER (5) + +/* Client received "Read" operation */ + +#define LWM2MSTUB_OP_READ (6) + +/* Client received "Observe" operation */ + +#define LWM2MSTUB_OP_OBSERVE (7) + +/* Client received "Cancel observation" operation */ + +#define LWM2MSTUB_OP_CANCELOBS (8) + +/* Client is offline now. */ + +#define LWM2MSTUB_OP_OFFLINE (9) + +/* Client is online now. */ + +#define LWM2MSTUB_OP_ONLINE (10) + +/* Client sent observation notification to a server. */ + +#define LWM2MSTUB_OP_SENDNOTICE (11) + +/* Client received wakeup SMS. */ + +#define LWM2MSTUB_OP_RCVWUP (12) + +/* Client received notification acknowledge. */ + +#define LWM2MSTUB_OP_RCVOBSACK (13) + +/* Client ON: LMM2M client exits Client OFF state + * and tries to re-connect server due to explicitly + * AT Command registration request. + */ + +#define LWM2MSTUB_OP_CLIENTON (14) + +/* Client OFF: LWM2M client has exhausted server connection retries. */ + +#define LWM2MSTUB_OP_CLIENTOFF (15) + +/* Confirmable NOTIFY failed. */ + +#define LWM2MSTUB_OP_FAILNOTIFY (16) + +/* Bootstrap finished and completed successfully. */ + +#define LWM2MSTUB_OP_BSFINISH (20) + +/* Registration finished and completed successfully. + * all server observation requests are cleaned, + * the host should clean host objects observation rules too. + */ + +#define LWM2MSTUB_OP_REGSUCCESS (21) + +/* Register update finished and completed successfully. */ + +#define LWM2MSTUB_OP_REGUPDATED (22) + +/* De-register finished and completed successfully. */ + +#define LWM2MSTUB_OP_DEREGSUCCESS (23) + +/* Notification was not saved and not sent to server */ + +#define LWM2MSTUB_OP_NOSENDNOTICE (24) + +struct lwm2mstub_resource_s +{ + int res_id; + int operation; + int inst_type; + int data_type; + int handl; +}; + +struct lwm2mstub_instance_s +{ + int object_id; + int object_inst; + int res_id; + int res_inst; +}; + +struct lwm2mstub_ovcondition_s +{ + uint8_t valid_mask; + unsigned int min_period; + unsigned int max_period; + double gt_cond; + double lt_cond; + double step_val; +}; + +struct lwm2mstub_serverinfo_s +{ + int object_inst; + int state; + bool bootstrap; + bool nonip; + int security_mode; + uint32_t lifetime; + char server_uri[LWM2MSTUB_MAX_SERVER_NAME]; + char device_id[LWM2MSTUB_MAX_DEVID]; + char security_key[LWM2MSTUB_MAX_SEQKEY]; +}; + +typedef void (*lwm2mstub_write_cb_t)(int seq_no, int srv_id, + FAR struct lwm2mstub_instance_s *inst, FAR char *value, + int len); + +typedef void (*lwm2mstub_read_cb_t)(int seq_no, int srv_id, + FAR struct lwm2mstub_instance_s *inst); + +typedef void (*lwm2mstub_exec_cb_t)(int seq_no, int srv_id, + FAR struct lwm2mstub_instance_s *inst); + +typedef void (*lwm2mstub_ovstart_cb_t)(int seq_no, int srv_id, + FAR struct lwm2mstub_instance_s *inst, FAR char *token, + FAR struct lwm2mstub_ovcondition_s *cond); + +typedef void (*lwm2mstub_ovstop_cb_t)(int seq_no, int srv_id, + FAR struct lwm2mstub_instance_s *inst, FAR char *token); + +typedef void (*lwm2mstub_operation_cb_t)(int event); + +typedef void (*lwm2mstub_fwupstate_cb_t)(int event); + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* On powe on state */ + +int lte_setm2m_endpointname(FAR char *name); +int lte_getm2m_endpointname(FAR char *name, int len); + +int lte_getm2m_servernum(void); +int lte_setm2m_serverinfo(FAR struct lwm2mstub_serverinfo_s *info, int id); +int lte_getm2m_serverinfo(FAR struct lwm2mstub_serverinfo_s *info, int id); + +int lte_getm2m_enabled_objectnum(void); +int lte_getm2m_enabled_objects(FAR uint16_t *objids, int objnum); +int lte_enablem2m_objects(FAR uint16_t *objids, int objnum); + +int lte_getm2m_objresourcenum(uint16_t objid); +int lte_getm2m_objresourceinfo(uint16_t objids, int res_num, + FAR struct lwm2mstub_resource_s *reses); +int lte_setm2m_objectdefinition(uint16_t objids, int res_num, + FAR struct lwm2mstub_resource_s *reses); +bool lte_getm2m_qmode(void); +int lte_setm2m_qmode(bool en); + +int lte_apply_m2msetting(void); + +/* After attached */ + +int lte_m2m_connection(int cmd); + +int lte_set_report_m2mwrite(lwm2mstub_write_cb_t cb); +int lte_set_report_m2mread(lwm2mstub_read_cb_t cb); +int lte_set_report_m2mexec(lwm2mstub_exec_cb_t cb); +int lte_set_report_m2movstart(lwm2mstub_ovstart_cb_t cb); +int lte_set_report_m2movstop(lwm2mstub_ovstop_cb_t cb); +int lte_set_report_m2moperation(lwm2mstub_operation_cb_t cb); +int lte_set_report_m2mfwupdate(lwm2mstub_fwupstate_cb_t cb); + +int lte_m2m_readresponse(int seq_no, + FAR struct lwm2mstub_instance_s *inst, + int resp, FAR char *readvalue, int len); +int lte_m2m_writeresponse(int seq_no, + FAR struct lwm2mstub_instance_s *inst, + int resp); +int lte_m2m_executeresp(int seq_no, + FAR struct lwm2mstub_instance_s *inst, + int resp); +int lte_m2m_observeresp(int seq_no, int resp); + +int lte_m2m_observeupdate(FAR char *token, + FAR struct lwm2mstub_instance_s *inst, + FAR char *value, int len); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_LTE_LTE_LWM2M_H */ diff --git a/lte/.gitignore b/lte/.gitignore new file mode 100644 index 000000000..99f41601f --- /dev/null +++ b/lte/.gitignore @@ -0,0 +1,2 @@ +/Kconfig + diff --git a/lte/Make.defs b/lte/Make.defs new file mode 100644 index 000000000..89c366ca2 --- /dev/null +++ b/lte/Make.defs @@ -0,0 +1,36 @@ +############################################################################ +# apps/lte/Make.defs +# +# Copyright 2021 Sony Semiconductor Solutions Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name of Sony Semiconductor Solutions Corporation nor +# the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include $(wildcard lte/*/Make.defs) diff --git a/lte/Makefile b/lte/Makefile new file mode 100644 index 000000000..79ab0d8fb --- /dev/null +++ b/lte/Makefile @@ -0,0 +1,38 @@ +############################################################################ +# apps/lte/Makefile +# +# Copyright 2021 Sony Semiconductor Solutions Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name of Sony Semiconductor Solutions Corporation nor +# the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +MENUDESC = "LTE Libraries and NSH Add-Ons" + +include $(APPDIR)/Directory.mk diff --git a/lte/alt1250/Kconfig b/lte/alt1250/Kconfig new file mode 100644 index 000000000..cfe9a9713 --- /dev/null +++ b/lte/alt1250/Kconfig @@ -0,0 +1,159 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LTE_ALT1250 + tristate "ALT1250 usrsock daemon" + default n + depends on NET_USRSOCK && MODEM_ALT1250 + select NET_USRSOCK_TCP + select PIPES + select NET_USRSOCK_OTHER + ---help--- + Enable support for the alt1250 usrsock daemon + +if LTE_ALT1250 +config LTE_ALT1250_PROGNAME + string "alt1250 program name" + default "alt1250" + +config LTE_ALT1250_PRIORITY + int "alt1250 task priority" + default 100 + +config LTE_ALT1250_STACKSIZE + int "alt1250 stack size" + default 2048 + +config LTE_ALT1250_ENABLE_HIBERNATION_MODE + bool "Enable LTE hibernation mode" + default n + depends on PM + ---help--- + Enable LTE hibernation mode to reduce current + consumption during communication standby. + +menu "SMS configuration" + +config LTE_ALT1250_SMS_TOA + bool "Configure type of address of destination address" + default n + ---help--- + Change the type of address of the destination address. + +choice + prompt "Configure Nature of Address Indicator" + depends on LTE_ALT1250_SMS_TOA + +config LTE_ALT1250_SMS_NAI_UNKNOWN + bool "Unkown" + +config LTE_ALT1250_SMS_NAI_INTERNATIONAL + bool "International number" + +config LTE_ALT1250_SMS_NAI_NATIONAL + bool "National number" + +config LTE_ALT1250_SMS_NAI_NETWORK_SPEC + bool "Network specific number" + +config LTE_ALT1250_SMS_NAI_SUBSCRIBER + bool "Subscriber number" + +config LTE_ALT1250_SMS_NAI_ALPANUMERIC + bool "Alphanumeric" + +config LTE_ALT1250_SMS_NAI_ABBREVIATED + bool "Abbreviated number" + +config LTE_ALT1250_SMS_NAI_RESERVED + bool "Reserved for extension" + +endchoice # Configure Nature of Address Indicator + +choice + prompt "Configure Numbering Plan Indicator" + depends on LTE_ALT1250_SMS_TOA + +config LTE_ALT1250_SMS_NPI_UNKNOWN + bool "Unkown" + +config LTE_ALT1250_SMS_NPI_ISDN + bool "ISDN/telephone numbering plan" + +config LTE_ALT1250_SMS_NPI_DATA + bool "Data numbering plan" + +config LTE_ALT1250_SMS_NPI_TELEX + bool "Telex numbering plan" + +config LTE_ALT1250_SMS_NPI_SERVICE_CENTRE_SPEC + bool "Service Centre Specific plan" + +config LTE_ALT1250_SMS_NPI_SERVICE_CENTRE_SPEC2 + bool "Service Centre Specific plan-2" + +config LTE_ALT1250_SMS_NPI_NATIONAL + bool "National numbering plan" + +config LTE_ALT1250_SMS_NPI_PRIVATE + bool "Private numbering plan" + +config LTE_ALT1250_SMS_NPI_ERMES + bool "ERMES numbering plan" + +config LTE_ALT1250_SMS_NPI_RESERVED + bool "Reserved for extension" + +endchoice # Configure Numbering Plan Indicator + +endmenu # SMS configuration + +config LTE_ALT1250_EXTEND_IOCTL + bool "Enabling extended ioctl handler" + default n + +config LTE_ALT1250_LAUNCH_EVENT_TASK + bool "Launches an internal task to handle events" + default y + ---help--- + Launches an internal task to handle the event. + It is also possible to disable this option and handle events with a user task. + If disabled, use lapi_evtinit() and lapi_evtyield(). + +if LTE_ALT1250_LAUNCH_EVENT_TASK + +config LTE_ALT1250_EVENT_TASK_PRIORITY + int "internal task priority" + default 100 + +config LTE_ALT1250_EVENT_TASK_STACKSIZE + int "internal task stack size" + default 2048 + +endif + +config LTE_ALT1250_CONTAINERS + int "Number of containers" + default 10 + range 1 255 + ---help--- + Determines the maximum number of containers. + The container is a buffer used to communicate with the ALT1250 + that contains the relevant information for communication. + Increasing this value may improve the performance during parallel processing. + On the other hand, decreasing this value will reduce the memory usage. + +config LTE_ALT1250_CONTROL_SOCKETS + int "Number of sockets for control" + default 3 + range 1 10 + ---help--- + Determines the maximum number of sockets used for LAPI and SMS. + +config LTE_ALT1250_DEBUG_MSG + bool "Enable debug output messages" + default n + +endif diff --git a/lte/alt1250/Make.defs b/lte/alt1250/Make.defs new file mode 100644 index 000000000..e5b7a3f92 --- /dev/null +++ b/lte/alt1250/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/lte/alt1250/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LTE_ALT1250),) +CONFIGURED_APPS += $(APPDIR)/lte/alt1250 +endif diff --git a/lte/alt1250/Makefile b/lte/alt1250/Makefile new file mode 100644 index 000000000..138b2bed4 --- /dev/null +++ b/lte/alt1250/Makefile @@ -0,0 +1,87 @@ +############################################################################ +# apps/lte/alt1250/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# alt1250 command + +PROGNAME = $(CONFIG_LTE_ALT1250_PROGNAME) +PRIORITY = $(CONFIG_LTE_ALT1250_PRIORITY) +STACKSIZE = $(CONFIG_LTE_ALT1250_STACKSIZE) +MODULE = $(CONFIG_LTE_ALT1250) + +VPATH += callback_handlers usock_handlers +CSRCS = + +# Framework source files + +CSRCS += alt1250_container.c +CSRCS += alt1250_devevent.c +CSRCS += alt1250_devif.c +CSRCS += alt1250_select.c +CSRCS += alt1250_socket.c +CSRCS += alt1250_usockevent.c +CSRCS += alt1250_usockif.c +CSRCS += alt1250_netdev.c +CSRCS += alt1250_util.c +CSRCS += alt1250_reset_seq.c +CSRCS += alt1250_atcmd.c + +# Callback task sources + +CSRCS += alt1250_evt.c + +# Usersock request handling source files + +CSRCS += alt1250_sockethdlr.c +CSRCS += alt1250_closehdlr.c +CSRCS += alt1250_connecthdlr.c +CSRCS += alt1250_sendtohdlr.c +CSRCS += alt1250_recvfromhdlr.c +CSRCS += alt1250_setsockopthdlr.c +CSRCS += alt1250_getsockopthdlr.c +CSRCS += alt1250_getsocknamehdlr.c +CSRCS += alt1250_getpeernamehdlr.c +CSRCS += alt1250_bindhdlr.c +CSRCS += alt1250_listenhdlr.c +CSRCS += alt1250_accepthdlr.c +CSRCS += alt1250_ioctlhdlr.c +CSRCS += alt1250_shutdownhdlr.c +CSRCS += alt1250_sms.c + +# Usersock ioctl LAPI command handling source files + +CSRCS += alt1250_ioctl_ltecmd.c +CSRCS += alt1250_ioctl_ifreq.c +CSRCS += alt1250_ioctl_normal.c +CSRCS += alt1250_ioctl_event.c +CSRCS += alt1250_ioctl_other.c +CSRCS += alt1250_ioctl_power.c +CSRCS += alt1250_ioctl_fwupdate.c +CSRCS += alt1250_ioctl_denyinetsock.c +CSRCS += alt1250_ioctl_lwm2m.c + +MAINSRC = alt1250_main.c + +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/lte/alt1250 +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/lte/alt1250/callback_handlers +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/lte/alt1250/usock_handlers + +include $(APPDIR)/Application.mk diff --git a/lte/alt1250/README.txt b/lte/alt1250/README.txt new file mode 100644 index 000000000..9ca1c5499 --- /dev/null +++ b/lte/alt1250/README.txt @@ -0,0 +1,68 @@ +NOTICE: +======= + This document should be opened in a text editor with a width of at least 150 characters. + +alt1250 usrsock daemon +====================== + + This software module is a usrsock daemon in NuttX for ALT1250 modem. + The ALT1250 modem is a modem provided by Sony Semiconductor Israel. And it supports LTE Cat-M1 and NB-IoT network. + + +Implementation Structure +======================== + Call registerd functions + <-------------------------------------------------+ + | ++-------------------------------------------------------------------------------------------------------------------------------- | -------------+ +| alt1250_daemon | | +| ~~~~~~~~~~~~~~ Response | | +| +----------------------------------------------------------------------------------+ | | +| | | | | +| V Response _________________________________________________________ | +--------------------------+ | +| +------------- | usrsock handlers | post process | | +-------------> | Event call back task | | +| | +_____________________________________+_________________+ | | +--> | to an application | | +| | | socket handler | postproc_socket | | | | +--------------------------+ | +| | |D | bind handler | postproc_bind | | | | | +| | |I | listen handler | postproc_listen | <-----+ | | | | +| | |S | . | . | | | | | | +| | |P | . | . | Call | | | | | +| | +-----> |A | . | . | Back | | | Event | | +| | | |T |---------------+---------------------+-----------------| | | | Message | | +| | | |C | ioctl handler | lapi power handler | postproc_XXXX | | | | | | +| | | |H | lapi normal handler | postproc_XXXX | | | | | | +| | | | | lapi ifreq handler | postproc_XXXX | ___________________________________________________________________ | +| | | usrsock | lapi ltecmd handler | postproc_XXXX | | Command Reply | Reset Event | Asynchronous Event | Select Event | | +| | | request | | . | . | |-----------------------------------------------------------------| | +| | | | . | . | | Device event handling | | +| | | +-------------------------------------------------------+ +-----------------------------------------------------------------+ | +| | | | | / | ++-- | - | ---------------------------------- | ------------------ | ------------------------------------ | --------------------------------------+ + | | | Send Command | | Event notify + V | V V | +-- /dev/usrsock -- ----------------------------------- /dev/alt1250 ----------------------------------- ++----------------+ +----------------------------------------------------------------------------------+ +| User Sock | | ALT1250 Device Driver | ++----------------+ +----------------------------------------------------------------------------------+ + +---------------------------------------++-----------------------------------------+ + | SPI Driver || GPIO Driver | + +---------------------------------------++-----------------------------------------+ + +Behavior Overview +================= + + Basically, alt1250_daemon receives a request from NutX User Sock and performs the expected processing according to the request. + + Each request is processed by its own "usrsock handler" depending on its type, and the result is returned to the User Sock as a + response. To achieve each of these operations, the "usrsock handler" sends a command to the alt1250 device driver. The post process + function is registerd in the command to process the command response if necessary. + + The command is sent to the ALT1250 via SPI, and the ALT1250 returns a response according to the command to notify alt1250_daemon. + The alt1250_daemon receives the command response from that notification and either returns the response to User Sock or calls the + "post process function" that was registered by the "usrsock handler". "post process" will return a response or send further + commands to ALT1250 depending on the content of the request. + + The ALT1250 may make event notifications, and these notifications are asynchronous. ALT1250 asynchronous events are notified by the + device driver as well as command responses, and when the alt1250_daemon receives them, it passes them to a task for callback to + notify the user application. + diff --git a/lte/alt1250/alt1250_atcmd.c b/lte/alt1250/alt1250_atcmd.c new file mode 100644 index 000000000..fcf52c54c --- /dev/null +++ b/lte/alt1250/alt1250_atcmd.c @@ -0,0 +1,942 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_atcmd.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_atcmd.h" +#include "alt1250_devif.h" +#include "alt1250_postproc.h" +#include "alt1250_container.h" +#include "alt1250_usockevent.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data Type + ****************************************************************************/ + +struct atcmd_postprocarg_t +{ + atcmd_postproc_t proc; + unsigned long arg; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR void *atcmd_oargs[3]; +static int atcmd_reply_len; +static struct atcmd_postprocarg_t postproc_argument; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_internal_atcmd + ****************************************************************************/ + +static int postproc_internal_atcmd(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_NO_ACK; + FAR struct atcmd_postprocarg_t *parg = + (FAR struct atcmd_postprocarg_t *)arg; + + dev->recvfrom_processing = false; + + err_alt1250("Internal ATCMD Resp : %s\n", (FAR char *)reply->outparam[0]); + + if (parg->proc != NULL) + { + ret = parg->proc(dev, reply, + (FAR char *)reply->outparam[0], *(FAR int *)reply->outparam[2], + parg->arg, usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: get_m2mrespstr + ****************************************************************************/ + +static FAR const char *get_m2mrespstr(int resp) +{ + FAR const char *ret = NULL; + + switch (resp) + { + case LWM2MSTUB_RESP_CHANGED: + ret = "2.04"; + break; + case LWM2MSTUB_RESP_CONTENT: + ret = "2.05"; + break; + case LWM2MSTUB_RESP_BADREQ: + ret = "4.00"; + break; + case LWM2MSTUB_RESP_UNAUTH: + ret = "4.01"; + break; + case LWM2MSTUB_RESP_NOURI: + ret = "4.04"; + break; + case LWM2MSTUB_RESP_NOTALLOW: + ret = "4.05"; + break; + case LWM2MSTUB_RESP_NOTACCEPT: + ret = "4.06"; + break; + case LWM2MSTUB_RESP_UNSUPPORT: + ret = "4.15"; + break; + case LWM2MSTUB_RESP_INTERNALERROR: + ret = "5.00"; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: atcmdreply_true_false + ****************************************************************************/ + +int atcmdreply_true_false(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + *usock_result = 0; + + if (strcasestr(rdata, "\nTRUE\r")) + { + *usock_result = 1; + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: atcmdreply_ok_error + ****************************************************************************/ + +int atcmdreply_ok_error(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + *usock_result = check_atreply_ok(rdata, len, NULL); + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: check_atreply_ok + ****************************************************************************/ + +int check_atreply_ok(FAR char *reply, int len, FAR void *arg) +{ + int ret = ERROR; + + if (strstr(reply, "\nOK\r")) + { + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * name: check_atreply_truefalse + ****************************************************************************/ + +int check_atreply_truefalse(FAR char *reply, int len, FAR void *arg) +{ + int ret = ERROR; + FAR struct atreply_truefalse_s *result = + (FAR struct atreply_truefalse_s *)arg; + + if (check_atreply_ok(reply, len, NULL) == OK) + { + ret = OK; + if (strstr(reply, result->target_str)) + { + result->result = true; + } + else + { + result->result = false; + } + } + + return ret; +} + +/**************************************************************************** + * name: send_internal_at_command + ****************************************************************************/ + +static int send_internal_at_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *usock_result) +{ + int ret; + + FAR void *inparam[2]; + + inparam[0] = dev->tx_buff; + inparam[1] = (FAR void *)strlen((FAR const char *)dev->tx_buff); + + atcmd_oargs[0] = dev->rx_buff; + atcmd_oargs[1] = (FAR void *)_RX_BUFF_SIZE; + atcmd_oargs[2] = &atcmd_reply_len; + + postproc_argument.proc = proc; + postproc_argument.arg = arg; + + set_container_ids(container, usockid, LTE_CMDID_SENDATCMD); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, atcmd_oargs, nitems(atcmd_oargs)); + set_container_postproc(container, postproc_internal_atcmd, + (unsigned long)&postproc_argument); + + err_alt1250("Internal ATCMD : %s\n", dev->tx_buff); + + ret = altdevice_send_command(dev->altfd, container, usock_result); + if (ret == REP_NO_ACK) + { + /* In case of no error */ + + dev->recvfrom_processing = true; + } + + return ret; +} + +/**************************************************************************** + * name: lwm2mstub_send_reset + ****************************************************************************/ + +int lwm2mstub_send_reset(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, "ATZ\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_setenable + ****************************************************************************/ + +int lwm2mstub_send_setenable(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=modem_apps.LWM2M.AppEnable,\"%s\"\r", + en ? "true" : "false"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_getenable + ****************************************************************************/ + +int lwm2mstub_send_getenable(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, FAR int32_t *usock_result) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=modem_apps.LWM2M.AppEnable\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, usock_result); +} + +/**************************************************************************** + * name: lwm2mstub_send_getnamemode + ****************************************************************************/ + +int lwm2mstub_send_getnamemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.Config.NameMode\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_setnamemode + ****************************************************************************/ + +int lwm2mstub_send_setnamemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int mode) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.Config.NameMode,%d\r", mode); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_getversion + ****************************************************************************/ + +int lwm2mstub_send_getversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.Config.Version\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_setversion + ****************************************************************************/ + +int lwm2mstub_send_setversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool is_v1_1) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.Config.Version,\"%s\"\r", is_v1_1 ? "1.1" : "1.0"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_getwriteattr + ****************************************************************************/ + +int lwm2mstub_send_getwriteattr(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.HostObjects.HostEnableWriteAttrURCMode\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_setwriteattr + ****************************************************************************/ + +int lwm2mstub_send_setwriteattr(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.HostObjects.HostEnableWriteAttrURCMode,\"%s\"\r", + en ? "true" : "false"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_getautoconnect + ****************************************************************************/ + +int lwm2mstub_send_getautoconnect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.Config.AutoConnect\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_setautoconnect + ****************************************************************************/ + +int lwm2mstub_send_setautoconnect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.Config.AutoConnect,\"%s\"\r", + en ? "true" : "false"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: ltenwop_send_getnwop + ****************************************************************************/ + +int ltenwop_send_getnwop(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%NWOPER?\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: ltenwop_send_setnwoptp + ****************************************************************************/ + +int ltenwop_send_setnwoptp(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int32_t dummy; + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%NWOPER=\"TRUPHONE\"\r"); + return send_internal_at_command(dev, container, -1, NULL, 0, &dummy); +} + +/**************************************************************************** + * name: lwm2mstub_send_getqueuemode + ****************************************************************************/ + +int lwm2mstub_send_getqueuemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.TransportBindings_1_1.Queue\r"); + return send_internal_at_command(dev, container, usockid, + atcmdreply_true_false, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_setqueuemode + ****************************************************************************/ + +int lwm2mstub_send_setqueuemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int en) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.TransportBindings_1_1.Queue,%s\r", + (en == 1) ? "true" : "false"); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_m2mopev + ****************************************************************************/ + +int lwm2mstub_send_m2mopev(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOPEV=%c,100\r", en ? '1' : '0'); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_m2mev + ****************************************************************************/ + +int lwm2mstub_send_m2mev(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MEV=%c\r", en ? '1' : '0'); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_m2mobjcmd + ****************************************************************************/ + +int lwm2mstub_send_m2mobjcmd(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJCMD=%c\r", en ? '1' : '0'); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getepname + ****************************************************************************/ + +int lwm2mstub_send_getepname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.Config.Name\r"); + return send_internal_at_command(dev, container, usockid, + proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getsrvinfo + ****************************************************************************/ + +int lwm2mstub_send_getsrvinfo(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MCMD=SERVERSINFO\r"); + return send_internal_at_command(dev, container, usockid, + proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getresource + ****************************************************************************/ + +int lwm2mstub_send_getresource(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR char *resource) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MCMD=GET_RESOURCE,%s\r", resource); + return send_internal_at_command(dev, container, usockid, proc, + arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getsupobjs + ****************************************************************************/ + +int lwm2mstub_send_getsupobjs(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%GETACFG=LWM2M.Config.SupportedObjects\r"); + return send_internal_at_command(dev, container, usockid, proc, + arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getobjdef + ****************************************************************************/ + +int lwm2mstub_send_getobjdef(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + uint16_t objid) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJDEF=GET,%d\r", objid); + return send_internal_at_command(dev, container, usockid, proc, + arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_changerat + ****************************************************************************/ + +int lwm2mstub_send_changerat(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int rat) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%setacfg=radiom.config.preferred_rat_list,\"%s\"\r", + (rat == LTE_RAT_CATM) ? "CATM" : "NBIOT"); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_getrat + ****************************************************************************/ + +int lwm2mstub_send_getrat(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%getacfg=radiom.config.preferred_rat_list\r"); + return send_internal_at_command(dev, container, usockid, proc, + arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_setepname + ****************************************************************************/ + +int lwm2mstub_send_setepname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, FAR const char *epname) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=\"LWM2M.Config.Name\",\"%s\"\r", epname); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_bsstart + ****************************************************************************/ + +int lwm2mstub_send_bsstart(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MBSCMD=\"START\"\r"); + return send_internal_at_command(dev, container, usockid, + proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_bsdelete + ****************************************************************************/ + +int lwm2mstub_send_bsdelete(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MBSCMD=\"DELETE\"\r"); + return send_internal_at_command(dev, container, usockid, + proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_bscreateobj0 + ****************************************************************************/ + +int lwm2mstub_send_bscreateobj0(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR struct lwm2mstub_serverinfo_s *info) +{ + int i; + int pos; + + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MBSCMD=\"CREATE\",0,0,0,\"%s\",1,\"%s\",2,%d", + info->server_uri, info->bootstrap ? "true" : "false", + info->security_mode); + + if (info->security_mode != LWM2MSTUB_SECUREMODE_NOSEC) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + ",3,\""); + for (i = 0; i < LWM2MSTUB_MAX_DEVID && info->device_id[i]; i++) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], + _TX_BUFF_SIZE - pos, + "%02x", info->device_id[i]); + } + + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "\""); + + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + ",5,\""); + for (i = 0; i < LWM2MSTUB_MAX_SEQKEY && info->security_key[i]; i++) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], + _TX_BUFF_SIZE - pos, + "%02x", info->security_key[i]); + } + + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "\""); + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, ",10,0\r"); + + return send_internal_at_command(dev, container, usockid, proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_bscreateobj1 + ****************************************************************************/ + +int lwm2mstub_send_bscreateobj1(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR struct lwm2mstub_serverinfo_s *info) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MBSCMD=\"CREATE\",1,0,0,0,1,%lu%s\r", info->lifetime, + info->nonip ? ",7,\"N\",22,\"N\"" : ""); + + return send_internal_at_command(dev, container, usockid, proc, arg, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_bsdone + ****************************************************************************/ + +int lwm2mstub_send_bsdone(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + int16_t usockid, FAR int32_t *ures) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MBSCMD=\"DONE\"\r"); + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_setsupobjs + ****************************************************************************/ + +int lwm2mstub_send_setsupobjs(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, FAR uint16_t *objids, int objnum) +{ + int pos; + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%SETACFG=LWM2M.Config.SupportedObjects,0;1"); + + while (objnum > 0) + { + /* Object 0 and Object 1 is mandatory and default */ + + if (*objids != 0 && *objids != 1) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], + _TX_BUFF_SIZE - pos, + ";%d", *objids); + } + + objids++; + objnum--; + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, "\r"); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_setobjdef + ****************************************************************************/ + +int lwm2mstub_send_setobjdef(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, uint16_t objid, int resnum, + FAR struct lwm2mstub_resource_s *resucs) +{ + int pos; + + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJDEF=SET,%d", objid); + + while (resnum > 0) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + ",%d,\"%s\",%d,\"%s\"", resucs->res_id, + resucs->operation == LWM2MSTUB_RESOP_READ ? "R" : + resucs->operation == LWM2MSTUB_RESOP_WRITE ? "W" : + resucs->operation == LWM2MSTUB_RESOP_RW ? "RW" : "X", + resucs->inst_type, + resucs->data_type == LWM2MSTUB_RESDATA_NONE ? "NONE" : + resucs->data_type == LWM2MSTUB_RESDATA_STRING ? "STR" : + resucs->data_type == LWM2MSTUB_RESDATA_INT ? "INT" : + resucs->data_type == LWM2MSTUB_RESDATA_UNSIGNED ? "UINT" : + resucs->data_type == LWM2MSTUB_RESDATA_FLOAT ? "FLT" : + resucs->data_type == LWM2MSTUB_RESDATA_BOOL ? "BOOL" : + resucs->data_type == LWM2MSTUB_RESDATA_OPAQUE ? "OPQ" : + resucs->data_type == LWM2MSTUB_RESDATA_TIME ? "TIME" : "OL"); + resucs++; + resnum--; + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, "\r"); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_registration + ****************************************************************************/ + +int lwm2mstub_send_registration(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int cmd) +{ + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MCMD=%s\r", + cmd == LWM2MSTUB_CONNECT_REGISTER ? "REGISTER" : + cmd == LWM2MSTUB_CONNECT_DEREGISTER ? "DEREGISTER" : + cmd == LWM2MSTUB_CONNECT_REREGISTER ? "REGISTERUPD" : + "BOOTSTARP"); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_evrespwvalue + ****************************************************************************/ + +int lwm2mstub_send_evrespwvalue(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp, + FAR struct lwm2mstub_instance_s *inst, FAR char *retval) +{ + int pos; + FAR const char *resp_str = get_m2mrespstr(resp); + + if (resp_str == NULL) + { + *ures = -EINVAL; + return REP_SEND_ACK; + } + + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJRSP=%d,\"%s\",\"/%d/%d/%d", seq_no, resp_str, + inst->object_id, inst->object_inst, inst->res_id); + + if (inst->res_inst >= 0) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "/%d", inst->res_inst); + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "\",\"%s\"\r", retval); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_evresponse + ****************************************************************************/ + +int lwm2mstub_send_evresponse(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp, + FAR struct lwm2mstub_instance_s *inst) +{ + int pos; + FAR const char *resp_str = get_m2mrespstr(resp); + + if (resp_str == NULL) + { + *ures = -EINVAL; + return REP_SEND_ACK; + } + + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJRSP=%d,\"%s\",\"/%d/%d/%d", seq_no, resp_str, + inst->object_id, inst->object_inst, inst->res_id); + + if (inst->res_inst >= 0) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "/%d", inst->res_inst); + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, "\"\r"); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_evrespwoinst + ****************************************************************************/ + +int lwm2mstub_send_evrespwoinst(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp) +{ + FAR const char *resp_str = get_m2mrespstr(resp); + + if (resp_str == NULL) + { + *ures = -EINVAL; + return REP_SEND_ACK; + } + + snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJRSP=%d,\"%s\"\r", seq_no, resp_str); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} + +/**************************************************************************** + * name: lwm2mstub_send_objevent + ****************************************************************************/ + +int lwm2mstub_send_objevent(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + int16_t usockid, FAR int32_t *ures, + FAR char *token, + FAR struct lwm2mstub_instance_s *inst, + FAR char *retval) +{ + int pos; + + pos = snprintf((FAR char *)dev->tx_buff, _TX_BUFF_SIZE, + "AT%%LWM2MOBJEV=\"%s\",,,0,\"/%d/%d", + token, inst->object_id, inst->object_inst); + + if (inst->res_id >= 0) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "/%d", inst->res_id); + + if (inst->res_inst >= 0) + { + pos += snprintf((FAR char *)&dev->tx_buff[pos], + _TX_BUFF_SIZE - pos, + "/%d", inst->res_id); + } + } + + snprintf((FAR char *)&dev->tx_buff[pos], _TX_BUFF_SIZE - pos, + "\",\"%s\"\r", retval); + + return send_internal_at_command(dev, container, usockid, + atcmdreply_ok_error, 0, ures); +} diff --git a/lte/alt1250/alt1250_atcmd.h b/lte/alt1250/alt1250_atcmd.h new file mode 100644 index 000000000..ee7b846ed --- /dev/null +++ b/lte/alt1250/alt1250_atcmd.h @@ -0,0 +1,215 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_atcmd.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_ATCMD_H +#define __APPS_LTE_ALT1250_ALT1250_ATCMD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "alt1250_dbg.h" +#include "alt1250_devif.h" +#include "alt1250_container.h" + +#include + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +typedef int (*atreply_parser_t)(FAR char *reply, int len, void *arg); +typedef int (*atcmd_postproc_t)(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result); + +struct atreply_truefalse_s +{ + FAR const char *target_str; + FAR bool result; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int atcmdreply_ok_error(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result); + +int check_atreply_ok(FAR char *reply, int len, void *arg); +int check_atreply_truefalse(FAR char *reply, int len, void *arg); + +int lwm2mstub_send_reset(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_getenable(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, FAR int32_t *usock_result); + +int lwm2mstub_send_setenable(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en); + +int lwm2mstub_send_getnamemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_setnamemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int mode); + +int lwm2mstub_send_getversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_setversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool is_v1_1); + +int lwm2mstub_send_getwriteattr(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_setwriteattr(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en); + +int lwm2mstub_send_getautoconnect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_setautoconnect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, bool en); + +int ltenwop_send_getnwop(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int ltenwop_send_setnwoptp(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container); + +int lwm2mstub_send_getqueuemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures); + +int lwm2mstub_send_setqueuemode(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int en); + +int lwm2mstub_send_m2mopev(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en); + +int lwm2mstub_send_m2mobjcmd(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en); + +int lwm2mstub_send_m2mev(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, bool en); + +int lwm2mstub_send_getepname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +int lwm2mstub_send_getsrvinfo(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +int lwm2mstub_send_getresource(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR char *resource); + +int lwm2mstub_send_getsupobjs(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +int lwm2mstub_send_getobjdef(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + uint16_t objid); + +int lwm2mstub_send_setepname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, FAR const char * epname); + +int lwm2mstub_send_bsstart(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +int lwm2mstub_send_bsdelete(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +int lwm2mstub_send_bscreateobj0(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR struct lwm2mstub_serverinfo_s *info); + +int lwm2mstub_send_bscreateobj1(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures, + FAR struct lwm2mstub_serverinfo_s *info); + +int lwm2mstub_send_bsdone(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures); + +int lwm2mstub_send_setsupobjs(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, FAR uint16_t *objids, int objnum); + +int lwm2mstub_send_setobjdef(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, uint16_t objid, int resnum, + FAR struct lwm2mstub_resource_s *resucs); + +int lwm2mstub_send_registration(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int cmd); + +int lwm2mstub_send_evrespwvalue(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp, + FAR struct lwm2mstub_instance_s *inst, char *retval); + +int lwm2mstub_send_evresponse(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp, + FAR struct lwm2mstub_instance_s *inst); + +int lwm2mstub_send_evrespwoinst(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int seq_no, int resp); + +int lwm2mstub_send_objevent(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, char *token, FAR struct lwm2mstub_instance_s *inst, + char *retval); + +int lwm2mstub_send_changerat(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + FAR int32_t *ures, int rat); + +int lwm2mstub_send_getrat(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, int16_t usockid, + atcmd_postproc_t proc, unsigned long arg, FAR int32_t *ures); + +#endif /* __APPS_LTE_ALT1250_ALT1250_ATCMD_H */ diff --git a/lte/alt1250/alt1250_container.c b/lte/alt1250/alt1250_container.c new file mode 100644 index 000000000..aa058019c --- /dev/null +++ b/lte/alt1250/alt1250_container.c @@ -0,0 +1,186 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_container.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_container.h" + +/**************************************************************************** + * Private Data Types + ****************************************************************************/ + +static struct postproc_s postproc_obj[CONFIG_LTE_ALT1250_CONTAINERS]; +static struct alt_container_s container_obj[CONFIG_LTE_ALT1250_CONTAINERS]; +static sq_queue_t free_containers; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: init_containers + ****************************************************************************/ + +void init_containers(void) +{ + int i; + + memset(&container_obj, 0, sizeof(container_obj)); + + sq_init(&free_containers); + + for (i = 0; i < CONFIG_LTE_ALT1250_CONTAINERS; i++) + { + container_obj[i].priv = (unsigned long)&postproc_obj[i]; + sq_addlast(&container_obj[i].node, &free_containers); + } +} + +/**************************************************************************** + * name: container_alloc + ****************************************************************************/ + +FAR struct alt_container_s *container_alloc(void) +{ + FAR struct alt_container_s *ret; + + ret = (FAR struct alt_container_s *)sq_peek(&free_containers); + if (ret) + { + sq_rem(&ret->node, &free_containers); + clear_container(ret); + } + else + { + dbg_alt1250("No more container\n"); + } + + return ret; +} + +/**************************************************************************** + * name: container_free + ****************************************************************************/ + +void container_free(FAR struct alt_container_s *container) +{ + dbg_alt1250("Container free \n", container->cmdid); + + sq_addlast(&container->node, &free_containers); +} + +/**************************************************************************** + * name: set_container_ids + ****************************************************************************/ + +void set_container_ids(FAR struct alt_container_s *container, + int16_t usockid, uint32_t cmdid) +{ + container->sock = usockid; + container->cmdid = cmdid; +} + +/**************************************************************************** + * name: set_container_argument + ****************************************************************************/ + +void set_container_argument(FAR struct alt_container_s *container, + FAR void *argparams[], size_t paramsz) +{ + container->inparam = argparams; + container->inparamlen = paramsz; +} + +/**************************************************************************** + * name: set_container_response + ****************************************************************************/ + +void set_container_response(FAR struct alt_container_s *container, + FAR void *respparams[], size_t paramsz) +{ + container->outparam = respparams; + container->outparamlen = paramsz; +} + +/**************************************************************************** + * name: set_container_postproc + ****************************************************************************/ + +void set_container_postproc(FAR struct alt_container_s *container, + FAR postproc_hdlr_t func, unsigned long arg) +{ + FAR struct postproc_s *pp = (FAR struct postproc_s *)container->priv; + pp->hdlr = func; + pp->priv = arg; +} + +/**************************************************************************** + * name: clear_container + ****************************************************************************/ + +void clear_container(FAR struct alt_container_s *container) +{ + unsigned long priv = container->priv; + memset(container, 0, sizeof(struct alt_container_s)); + container->priv = priv; +} + +/**************************************************************************** + * name: container_free_all + ****************************************************************************/ + +void container_free_all(FAR struct alt_container_s *head) +{ + FAR struct alt_container_s *c; + + while (head) + { + c = head; + head = (FAR struct alt_container_s *)sq_next(&c->node); + container_free(c); + } +} + +/**************************************************************************** + * name: container_pick_listtop + ****************************************************************************/ + +FAR struct alt_container_s *container_pick_listtop( + FAR struct alt_container_s **head) +{ + FAR struct alt_container_s *ret = *head; + + if (ret) + { + *head = (FAR struct alt_container_s *)sq_next(&ret->node); + sq_next(&ret->node) = NULL; + } + + return ret; +} diff --git a/lte/alt1250/alt1250_container.h b/lte/alt1250/alt1250_container.h new file mode 100644 index 000000000..43b5db761 --- /dev/null +++ b/lte/alt1250/alt1250_container.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_container.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_CONTAINER_H +#define __APPS_LTE_ALT1250_ALT1250_CONTAINER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_postproc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONTAINER_SOCKETID(c) ((c)->sock) +#define CONTAINER_CMDID(c) ((c)->cmdid) +#define CONTAINER_ARGUMENT(c) ((c)->inparam) +#define CONTAINER_ARGSIZE(c) ((c)->inparamlen) +#define CONTAINER_RESPONSE(c) ((c)->outparam) +#define CONTAINER_RESPSIZE(c) ((c)->outparamlen) +#define CONTAINER_RESPRES(c) ((c)->result) +#define CONTAINER_POSTPROC(c) ((FAR struct postproc_s *)(c)->priv) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void init_containers(void); + +FAR struct alt_container_s *container_alloc(void); + +void clear_container(FAR struct alt_container_s *container); + +void set_container_ids(FAR struct alt_container_s *container, + int16_t usockid, uint32_t cmdid); + +void set_container_argument(FAR struct alt_container_s *container, + FAR void *inparams[], size_t paramsz); + +void set_container_response(FAR struct alt_container_s *container, + FAR void *outparams[], size_t paramsz); + +void set_container_postproc(FAR struct alt_container_s *container, + FAR postproc_hdlr_t func, unsigned long priv); + +void container_free(FAR struct alt_container_s *container); +void container_free_all(FAR struct alt_container_s *head); + +FAR struct alt_container_s * + container_pick_listtop(FAR struct alt_container_s **head); + +#endif /* __APPS_LTE_ALT1250_ALT1250_CONTAINER_H */ diff --git a/lte/alt1250/alt1250_daemon.h b/lte/alt1250/alt1250_daemon.h new file mode 100644 index 000000000..c385d23ce --- /dev/null +++ b/lte/alt1250/alt1250_daemon.h @@ -0,0 +1,175 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_daemon.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_DAEMON_H +#define __APPS_LTE_ALT1250_ALT1250_DAEMON_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "alt1250_socket.h" +#include "alt1250_usockif.h" +#include "alt1250_util.h" +#include "alt1250_fwupdate.h" +#include "alt1250_sms.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The maximum number of sockets that the ALT1250 modem can open. */ + +#define SOCKET_COUNT 5 + +#define _TX_BUFF_SIZE (1500) +#define _RX_BUFF_SIZE (1500) + +#define ACCEPT_USOCK_REQUEST(dev) (!(dev)->is_usockrcvd && !(dev)->recvfrom_processing) +#define IS_USOCKREQ_RECEIVED(dev) ((dev)->is_usockrcvd) + +#define MODEM_STATE(d) ((d)->modem_state) +#define MODEM_STATE_POFF(d) ((d)->modem_state = MODEM_POWER_OFF) +#define MODEM_STATE_PON(d) ((d)->modem_state = MODEM_POWER_ON) +#define MODEM_STATE_B4PON(d) ((d)->modem_state = MODEM_BEFORE_PON) +#define MODEM_STATE_B4PON_2ND(d) ((d)->modem_state = MODEM_BEFORE_PON_STAGE2) +#define MODEM_STATE_INTENTRST(d) ((d)->modem_state = MODEM_RST_INTENTIONAL) +#define MODEM_STATE_RON(d) ((d)->modem_state = MODEM_RADIO_ON) +#define MODEM_STATE_IS_RON(d) ((d)->modem_state == MODEM_RADIO_ON) +#define MODEM_STATE_IS_POFF(d) ((d)->modem_state == MODEM_POWER_OFF) +#define MODEM_STATE_IS_PON(d) ((d)->modem_state == MODEM_POWER_ON) + +#define MODEM_FWVERSION(d) ((d)->fw_version) + +/**************************************************************************** + * Public Data Types + ****************************************************************************/ + +enum alt1250_state_e +{ + MODEM_POWER_OFF = 0, + MODEM_BEFORE_PON, + MODEM_BEFORE_PON_STAGE2, + MODEM_POWER_ON, + MODEM_RST_INTENTIONAL, + MODEM_RADIO_ON, +}; + +struct usrsock_request_buff_s; + +struct alt1250_s +{ + int usockfd; + int altfd; + int usock_enable; + + int32_t scnt; + int32_t sid; /* Select ID requested to Alt1250 module. + * Negative value indicats no select request */ + FAR sem_t *syncsem; /* Semaphore to synchronize LAPI Caller */ + mqd_t evtq; /* Event queue to communicate "Callback task" */ + struct net_driver_s net_dev; + + enum alt1250_state_e modem_state; + + lte_apn_setting_t apn; + char apn_name[LTE_APN_LEN]; + char user_name[LTE_APN_USER_NAME_LEN]; + char pass[LTE_APN_PASSWD_LEN]; + lte_pdn_t o_pdn; + + struct usock_s sockets[SOCKET_COUNT + CONFIG_LTE_ALT1250_CONTROL_SOCKETS]; + + struct usrsock_request_buff_s usockreq; + bool is_usockrcvd; /* A flag indicates that daemon has already read + * usrsock request */ + bool recvfrom_processing; + + uint8_t tx_buff[_TX_BUFF_SIZE]; + uint8_t rx_buff[_RX_BUFF_SIZE]; + + char fw_version[LTE_VER_NP_PACKAGE_LEN]; + struct update_info_s fwup_info; + + struct sms_info_s sms_info; + bool is_support_lwm2m; + int64_t lwm2m_apply_xid; + bool api_enable; + context_save_cb_t context_cb; + bool is_resuming; + uint32_t quality_report_period; + uint32_t cellinfo_report_period; +}; + +struct alt1250_save_ctx +{ + uint8_t ip_type; + uint8_t auth_type; + uint32_t apn_type; + char apn_name[LTE_APN_LEN]; + char user_name[LTE_APN_USER_NAME_LEN]; + char pass[LTE_APN_PASSWD_LEN]; + + uint32_t d_flags; + +#ifdef CONFIG_NET_IPv4 + in_addr_t d_ipaddr; + in_addr_t d_draddr; + in_addr_t d_netmask; +#endif + +#ifdef CONFIG_NET_IPv6 + net_ipv6addr_t d_ipv6addr; + net_ipv6addr_t d_ipv6draddr; + net_ipv6addr_t d_ipv6netmask; +#endif + + uint16_t checksum; +}; + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +int alt1250_set_api_enable(FAR struct alt1250_s *dev, bool enable); +int alt1250_count_opened_sockets(FAR struct alt1250_s *dev); +int alt1250_is_api_in_progress(FAR struct alt1250_s *dev); +int alt1250_set_context_save_cb(FAR struct alt1250_s *dev, + context_save_cb_t context_cb); +int alt1250_collect_daemon_context(FAR struct alt1250_s *dev); +int alt1250_apply_daemon_context(FAR struct alt1250_s *dev, + FAR struct alt1250_save_ctx *ctx); +#endif + +#endif /* __APPS_LTE_ALT1250_ALT1250_DAEMON_H */ diff --git a/lte/alt1250/alt1250_dbg.h b/lte/alt1250/alt1250_dbg.h new file mode 100644 index 000000000..fa017ff02 --- /dev/null +++ b/lte/alt1250/alt1250_dbg.h @@ -0,0 +1,44 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_dbg.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_DBG_H +#define __APPS_LTE_ALT1250_ALT1250_DBG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_LTE_ALT1250_DEBUG_MSG +# define err_alt1250(v, ...) nerr(v, ##__VA_ARGS__) +# define dbg_alt1250(v, ...) ninfo(v, ##__VA_ARGS__) +#else +# define err_alt1250(v, ...) +# define dbg_alt1250(v, ...) +#endif + +#endif /* __APPS_LTE_ALT1250_ALT1250_DBG_H */ diff --git a/lte/alt1250/alt1250_devevent.c b/lte/alt1250/alt1250_devevent.c new file mode 100644 index 000000000..879e93cca --- /dev/null +++ b/lte/alt1250/alt1250_devevent.c @@ -0,0 +1,453 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_devevent.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_evt.h" +#include "alt1250_devif.h" +#include "alt1250_devevent.h" +#include "alt1250_postproc.h" +#include "alt1250_container.h" +#include "alt1250_usockif.h" +#include "alt1250_usockevent.h" +#include "alt1250_socket.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_select.h" +#include "alt1250_sms.h" +#include "alt1250_netdev.h" +#include "alt1250_reset_seq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IS_PV1_FIRMWARE(d) (!strncmp(MODEM_FWVERSION(d), \ + "RK_02_01_", 9)) +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: handle_replypkt + ****************************************************************************/ + +static int handle_replypkt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR int32_t *usock_result, uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + int ret; + FAR struct usock_s *usock; + FAR struct postproc_s *pp = CONTAINER_POSTPROC(reply); + + usock = usocket_search(dev, CONTAINER_SOCKETID(reply)); + + dbg_alt1250("reply->result: %d\n", CONTAINER_RESPRES(reply)); + + *usock_result = CONTAINER_RESPRES(reply); + *usock_xid = usock ? USOCKET_XID(usock) : -1; + ret = usock ? REP_SEND_ACK : REP_NO_ACK; + + if (pp && pp->hdlr) + { + ret = pp->hdlr(dev, reply, usock, usock_result, usock_xid, ackinfo, + pp->priv); + } + + return ret; +} + +/**************************************************************************** + * Name: perform_alt1250_reply + ****************************************************************************/ + +static int perform_alt1250_reply(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int ret = REP_NO_ACK; + int32_t ack_result = OK; + uint32_t ack_xid = 0; + struct usock_ackinfo_s ackinfo; + + ret = handle_replypkt(dev, container, &ack_result, &ack_xid, &ackinfo); + + if (LTE_IS_ASYNC_CMD(container->cmdid)) + { + ret = REP_NO_ACK; + } + + usock_reply(dev->usockfd, ret, ack_result, ack_xid, &ackinfo); + + return ret; +} + +/**************************************************************************** + * Name: handle_normal_reset + ****************************************************************************/ + +static int handle_normal_reset(FAR struct alt1250_s *dev) +{ + alt1250_clrevtcb(ALT1250_CLRMODE_WO_RESTART); + + dev->recvfrom_processing = false; + dev->lwm2m_apply_xid = -1; + + alt1250_netdev_ifdown(dev); + + usocket_freeall(dev); + + reset_fwupdate_info(dev); + alt1250_reset_sms_info(dev); + reset_usock_device(dev->usockfd); + + return REP_MODEM_RESET; +} + +/**************************************************************************** + * name: handle_intentional_reset + ****************************************************************************/ + +static int handle_intentional_reset(FAR struct alt1250_s *dev) +{ + if (dev->lwm2m_apply_xid >= 0) + { + usockif_sendack(dev->usockfd, 0, (uint32_t)dev->lwm2m_apply_xid, + false); + dev->lwm2m_apply_xid = -1; + } + + alt1250_clrevtcb(ALT1250_CLRMODE_WO_RESTART); + dev->recvfrom_processing = false; + alt1250_netdev_ifdown(dev); + usocket_freeall(dev); + alt1250_reset_sms_info(dev); + reset_usock_device(dev->usockfd); + + MODEM_STATE_PON(dev); + + return REP_NO_ACK; +} + +/**************************************************************************** + * Name: perform_alt1250_resetevt + ****************************************************************************/ + +static int perform_alt1250_resetevt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *rlist) +{ + int ret; + + container_free_all(rlist); + + dev->sid = -1; + + switch (MODEM_STATE(dev)) + { + case MODEM_BEFORE_PON: + ret = handle_poweron_reset(dev); + break; + + case MODEM_BEFORE_PON_STAGE2: + ret = handle_poweron_reset_stage2(dev); + break; + + case MODEM_RST_INTENTIONAL: + ret = handle_intentional_reset(dev); + break; + + default: + ret = handle_normal_reset(dev); + break; + } + + return ret; +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +/**************************************************************************** + * Name: perform_alt1250_apistopevt + ****************************************************************************/ + +static void perform_alt1250_apistopevt(FAR struct alt1250_s *dev) +{ + int ret = OK; + int w_cnt = 0; + + /* The "ALT1250_EVTBIT_STOPAPI" command isn't supported for PV1 firmware */ + + if (IS_PV1_FIRMWARE(dev)) + { + dbg_alt1250("This firmware doesn't support hibernation mode.\n"); + ret = ERROR; + goto exit; + } + + /* All LTE API/Socket requests must be stopped to enter Suspend mode. */ + + ret = alt1250_set_api_enable(dev, false); + + if (ret < 0) + { + dbg_alt1250("Failed to stop API call.\n"); + ret = ERROR; + goto exit; + } + + /* Application need to context data when LTE function resume from + * hibernation. + */ + + if (!dev->context_cb) + { + dbg_alt1250("Context save callback not registered.\n"); + ret = ERROR; + goto exit; + } + + /* When entering Suspend mode, all Sockets must be closed. */ + + ret = alt1250_count_opened_sockets(dev); + + if (ret < 0) + { + dbg_alt1250("Failed to count opened sockets.\n"); + ret = ERROR; + goto exit; + } + else if (ret > 0) + { + dbg_alt1250("There are opened socket, " + "could not entering hibernation mode.\n"); + ret = ERROR; + goto exit; + } + + /* Refuse to enter Suspend mode if the LTE API already running has not yet + * completed. + */ + + ret = alt1250_is_api_in_progress(dev); + + if (ret < 0) + { + dbg_alt1250("Failed to check API call status.\n"); + ret = ERROR; + goto exit; + } + else if (ret > 0) + { + dbg_alt1250("There are in progress API call, " + "could not entering hibernation mode.\n"); + ret = ERROR; + goto exit; + } + + /* When Wakelock is acquired, Suspend mode is rejected because + * it is not possible to enter Suspend mode. + */ + + w_cnt = altdevice_powercontrol(dev->altfd, LTE_CMDID_COUNTWLOCK); + if (w_cnt == 0) + { + ret = OK; + } + else if (w_cnt > 0) + { + dbg_alt1250("Cannot enter hibernation due to wakelock is aquired.\n"); + ret = -EBUSY; + } + else + { + dbg_alt1250("Failed to get wakelock count.\n"); + ret = w_cnt; + } + +exit: + + if (ret < 0) + { + alt1250_set_api_enable(dev, true); + } + + altdevice_powerresponse(dev->altfd, LTE_CMDID_STOPAPI, ret); +} + +/**************************************************************************** + * Name: perform_alt1250_suspendevt + ****************************************************************************/ + +static void perform_alt1250_suspendevt(FAR struct alt1250_s *dev) +{ + /* TODO: Register Select to be notified by ALT1250 when an event is + * received during Sleep for a Socket in Suspend. + */ + + /* Notify the application of the context data required for resume. */ + + alt1250_collect_daemon_context(dev); + + altdevice_powerresponse(dev->altfd, LTE_CMDID_SUSPEND, 0); +} +#endif + +/**************************************************************************** + * Name: perform_netinfo_report_event + ****************************************************************************/ + +uint64_t perform_netinfo_report_event(FAR struct alt1250_s *dev, + uint64_t bitmap) +{ + uint64_t bit = 0ULL; + FAR void **arg; + FAR lte_netinfo_t *info; + FAR lte_pdn_t *pdn; + + if (alt1250_checkcmdid(LTE_CMDID_REPNETINFO, bitmap, &bit)) + { + arg = alt1250_getevtarg(LTE_CMDID_REPNETINFO); + if (arg && arg[0]) + { + /* arg[0]: Network information (see lte_netinfo_t) */ + + info = (FAR lte_netinfo_t *)arg[0]; + if (info->pdn_num == 0) + { + alt1250_netdev_ifdown(dev); + } + else + { + pdn = &info->pdn_stat[0]; + if (pdn->active == LTE_PDN_ACTIVE) + { + alt1250_netdev_ifup(dev, pdn); + } + else + { + alt1250_netdev_ifdown(dev); + } + } + } + } + + return bit; +} + +/**************************************************************************** + * Public functions + ****************************************************************************/ + +/**************************************************************************** + * Name: perform_alt1250events + ****************************************************************************/ + +int perform_alt1250events(FAR struct alt1250_s *dev) +{ + int ret = OK; + uint64_t bitmap; + uint64_t eventbit; + FAR struct alt_container_s *reply_list; + FAR struct alt_container_s *container; + + ret = altdevice_getevent(dev->altfd, &bitmap, &reply_list); + ASSERT(ret == OK); + + if (bitmap & ALT1250_EVTBIT_RESET) + { + /* Handling reset event */ + + ret = perform_alt1250_resetevt(dev, reply_list); + if (ret != REP_MODEM_RESET) + { + /* No need to send reset event to application + * in case of intentional reset + */ + + bitmap &= ~ALT1250_EVTBIT_RESET; + } + } +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + else if (bitmap & ALT1250_EVTBIT_STOPAPI) + { + /* Handling API stop request */ + + perform_alt1250_apistopevt(dev); + } + else if (bitmap & ALT1250_EVTBIT_SUSPEND) + { + /* Handling Suspend request */ + + perform_alt1250_suspendevt(dev); + } +#endif + else + { + /* Handling reply containers */ + + if (bitmap & ALT1250_EVTBIT_REPLY) + { + while ((container = container_pick_listtop(&reply_list)) != NULL) + { + ret = perform_alt1250_reply(dev, container); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + + bitmap &= ~ALT1250_EVTBIT_REPLY; + } + + /* Handling select async event */ + + if ((eventbit = perform_select_event(dev, bitmap)) != 0ULL) + { + bitmap &= ~eventbit; + } + + /* Handling sms report event */ + + if ((eventbit = perform_sms_report_event(dev, bitmap)) != 0ULL) + { + bitmap &= ~eventbit; + } + + /* Handling report network information event */ + + perform_netinfo_report_event(dev, bitmap); + + /* Do not clear the bit here to notify the event task */ + } + + if (bitmap) + { + alt1250_evttask_sendmsg(dev, bitmap); + } + + return ret; +} diff --git a/lte/alt1250/alt1250_devevent.h b/lte/alt1250/alt1250_devevent.h new file mode 100644 index 000000000..03667fe0b --- /dev/null +++ b/lte/alt1250/alt1250_devevent.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_devevent.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_DEVEVENT_H +#define __APPS_LTE_ALT1250_ALT1250_DEVEVENT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "alt1250_daemon.h" + +int perform_alt1250events(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_ALT1250_DEVEVENT_H */ diff --git a/lte/alt1250/alt1250_devif.c b/lte/alt1250/alt1250_devif.c new file mode 100644 index 000000000..42bc4f505 --- /dev/null +++ b/lte/alt1250/alt1250_devif.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_devif.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: ioctl_wrapper + ****************************************************************************/ + +static int ioctl_wrapper(int fd, int cmd, unsigned long arg) +{ + int ret; + + ret = ioctl(fd, cmd, arg); + if (ret < 0) + { + ret = -errno; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: init_alt1250_device + ****************************************************************************/ + +int init_alt1250_device(void) +{ + return open(DEV_ALT1250, O_RDONLY); +} + +/**************************************************************************** + * name: finalize_alt1250_device + ****************************************************************************/ + +void finalize_alt1250_device(int fd) +{ + close(fd); +} + +/**************************************************************************** + * name: altdevice_exchange_selcontainer + ****************************************************************************/ + +FAR struct alt_container_s *altdevice_exchange_selcontainer(int fd, + FAR struct alt_container_s *container) +{ + ioctl(fd, ALT1250_IOC_EXCHGCONTAINER, &container); + return container; +} + +/**************************************************************************** + * name: altdevice_send_command + ****************************************************************************/ + +int altdevice_send_command(int fd, FAR struct alt_container_s *container, + FAR int32_t *usock_res) +{ + int ret; + ret = ioctl_wrapper(fd, ALT1250_IOC_SEND, (unsigned long)container); + if (ret < 0) + { + *usock_res = ret; + if (ret == -ENETRESET) + { + ret = REP_SEND_ACK_WOFREE; + } + else + { + ret = REP_SEND_ACK; + } + } + else + { + /* In case of send successed */ + + ret = container->outparam ? REP_NO_ACK_WOFREE : REP_NO_ACK; + } + + return ret; +} + +/**************************************************************************** + * name: altdevice_powercontrol + ****************************************************************************/ + +int altdevice_powercontrol(int fd, uint32_t cmd) +{ + struct alt_power_s req; + + req.cmdid = cmd; + return ioctl_wrapper(fd, ALT1250_IOC_POWER, (unsigned long)&req); +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +/**************************************************************************** + * name: altdevice_powerresponse + ****************************************************************************/ + +int altdevice_powerresponse(int fd, uint32_t cmd, int resp) +{ + struct alt_power_s req; + + req.cmdid = cmd; + req.resp = resp; + return ioctl_wrapper(fd, ALT1250_IOC_POWER, (unsigned long)&req); +} +#endif + +/**************************************************************************** + * name: altdevice_seteventbuff + ****************************************************************************/ + +int altdevice_seteventbuff(int fd, FAR struct alt_evtbuffer_s *buffer) +{ + return (buffer) ? ioctl_wrapper(fd, ALT1250_IOC_SETEVTBUFF, + (unsigned long)buffer) : -EINVAL; +} + +/**************************************************************************** + * name: altdevice_getevent + ****************************************************************************/ + +int altdevice_getevent(int fd, FAR uint64_t *evtbitmap, + FAR struct alt_container_s **replys) +{ + int ret = -EIO; + struct alt_readdata_s dat; + + if (read(fd, &dat, sizeof(struct alt_readdata_s)) + == sizeof(struct alt_readdata_s)) + { + ret = OK; + *evtbitmap = dat.evtbitmap; + *replys = dat.head; + } + + return ret; +} + +/**************************************************************************** + * name: altdevice_reset + ****************************************************************************/ + +void altdevice_reset(int fd) +{ + altdevice_powercontrol(fd, LTE_CMDID_POWEROFF); + usleep(1); + altdevice_powercontrol(fd, LTE_CMDID_POWERON); +} diff --git a/lte/alt1250/alt1250_devif.h b/lte/alt1250/alt1250_devif.h new file mode 100644 index 000000000..2ae0c4a89 --- /dev/null +++ b/lte/alt1250/alt1250_devif.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_devif.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APSS_LTE_ALT1250_ALT1250_DEVIF_H +#define __APPS_LTE_ALT1250_ALT1250_DEVIF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#define DEV_ALT1250 "/dev/alt1250" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int init_alt1250_device(void); +void finalize_alt1250_device(int fd); +FAR struct alt_container_s *altdevice_exchange_selcontainer(int fd, + FAR struct alt_container_s *container); +int altdevice_send_command(int fd, FAR struct alt_container_s *container, + FAR int32_t *usock_res); +int altdevice_powercontrol(int fd, uint32_t cmd); +int altdevice_seteventbuff(int fd, FAR struct alt_evtbuffer_s *buffers); +int altdevice_getevent(int fd, FAR uint64_t *evtbitmap, + FAR struct alt_container_s **replys); +void altdevice_reset(int fd); +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +int altdevice_powerresponse(int fd, uint32_t cmd, int resp); +#endif + +#endif /* __APPS_LTE_ALT1250_ALT1250_DEVIF_H */ diff --git a/lte/alt1250/alt1250_main.c b/lte/alt1250/alt1250_main.c new file mode 100644 index 000000000..cd7b28170 --- /dev/null +++ b/lte/alt1250/alt1250_main.c @@ -0,0 +1,490 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_devif.h" +#include "alt1250_devevent.h" +#include "alt1250_usockif.h" +#include "alt1250_usockevent.h" +#include "alt1250_container.h" +#include "alt1250_select.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_evt.h" +#include "alt1250_netdev.h" +#include "alt1250_sms.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYNC_CMD_PREFIX "-s" + +#define ALTFDNO (0) +#define USOCKFDNO (1) + +#define SET_POLLIN(fds, fid) { \ + (fds).fd = (fid); \ + (fds).events = POLLIN; \ +} + +#define IS_POLLIN(fds) ((fds).revents & POLLIN) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct alt1250_s *g_daemon = NULL; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: notify_to_lapi_caller + ****************************************************************************/ + +static void notify_to_lapi_caller(sem_t *syncsem) +{ + /* has -s (sync) option? */ + + if (syncsem) + { + /* Notify release to lapi waiting for synchronization */ + + sem_post(syncsem); + } +} + +/**************************************************************************** + * Name: initialize_daemon + ****************************************************************************/ + +static int initialize_daemon(FAR struct alt1250_s *dev) +{ + int ret; + + /* Initialize sub-system */ + + /* Event call back task must be started + * before any device files are opened + */ + + ret = alt1250_evttask_start(); + ASSERT(ret > 0); + + dev->altfd = init_alt1250_device(); + ASSERT(dev->altfd >= 0); + + dev->usockfd = init_usock_device(); + ASSERT(dev->usockfd >= 0); + + ret = altdevice_seteventbuff(dev->altfd, init_event_buffer()); + ASSERT(ret >= 0); + + init_containers(); + init_selectcontainer(dev); + alt1250_sms_initcontainer(dev); + alt1250_netdev_register(dev); + + return OK; +} + +/**************************************************************************** + * Name: finalize_daemon + ****************************************************************************/ + +static void finalize_daemon(FAR struct alt1250_s *dev) +{ + alt1250_netdev_unregister(dev); + alt1250_evtdatadestroy(); + finalize_alt1250_device(dev->altfd); + finalize_usock_device(dev->usockfd); + alt1250_evttask_stop(dev); +} + +/**************************************************************************** + * Name: alt1250_loop + ****************************************************************************/ + +static int alt1250_loop(FAR struct alt1250_s *dev) +{ + int ret; + int pw_stat; + struct pollfd fds[2]; + nfds_t nfds; + bool is_running = true; + + initialize_daemon(dev); + + /* Get modem power status. If modem is turned on, it means resuming from + * hibernation mode. + */ + + pw_stat = altdevice_powercontrol(dev->altfd, LTE_CMDID_GET_POWER_STAT); + + dbg_alt1250("Modem power status = %d\n", pw_stat); + + if (pw_stat) + { + dev->is_resuming = true; + } + else + { + dev->is_resuming = false; + } + + notify_to_lapi_caller(dev->syncsem); + + /* Main loop of this daemon */ + + while (is_running) + { + memset(fds, 0, sizeof(fds)); + + SET_POLLIN(fds[ALTFDNO], dev->altfd); + nfds = 1; + + /* if (!dev->is_usockrcvd && !dev->recvfrom_processing) */ + + if (ACCEPT_USOCK_REQUEST(dev)) + { + SET_POLLIN(fds[USOCKFDNO], dev->usockfd); + nfds++; + } + + ret = poll(fds, nfds, -1); + ASSERT(ret > 0); + ret = OK; + + if (IS_POLLIN(fds[ALTFDNO])) + { + ret = perform_alt1250events(dev); + } + + dbg_alt1250("ret: %u, recvfrom_processing: %d," + " IS_POLLIN: %d, is_usockrcvd: %d\n", + ret, dev->recvfrom_processing, + IS_POLLIN(fds[USOCKFDNO]), dev->is_usockrcvd); + + if ((ret != REP_MODEM_RESET) && (!dev->recvfrom_processing) + && (IS_POLLIN(fds[USOCKFDNO]) || dev->is_usockrcvd)) + { + switch (perform_usockrequest(dev)) + { + case REP_SEND_TERM: + is_running = false; + break; + + case REP_NO_CONTAINER: + + /* Do nothing because request could + * not send to modem driver because of + * no more container. To wait for empty container. + */ + + break; + + default: + dev->is_usockrcvd = false; + break; + } + } + } + + finalize_daemon(dev); + + return OK; +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +/**************************************************************************** + * Name: calc_checksum + ****************************************************************************/ + +static uint16_t calc_checksum(FAR uint8_t *ptr, uint16_t len) +{ + uint32_t ret = 0x00; + uint32_t calctmp = 0x00; + uint16_t i; + + /* Data accumulating */ + + for (i = 0; i < len; i++) + { + calctmp += ptr[i]; + } + + ret = ~((calctmp & 0xffff) + (calctmp >> 16)); + + return (uint16_t)ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + int ret; + FAR char *endptr; + sem_t *syncsem = NULL; + + if (argc > 1) + { + /* The format is "-sXXXXXXXX". + * XXXXXXXXX indicates the pointer address to the semaphore + * that will be posted at the timing when the daemon opens the + * usersock device. + */ + + if (!(strncmp(argv[1], SYNC_CMD_PREFIX, strlen(SYNC_CMD_PREFIX)))) + { + syncsem = (FAR sem_t *)strtol(&argv[1][strlen(SYNC_CMD_PREFIX)], + &endptr, 16); + if (!syncsem || endptr == &argv[1][strlen(SYNC_CMD_PREFIX)] || + *endptr != '\0') + { + return -EINVAL; + } + } + } + + if (g_daemon) + { + fprintf(stderr, "%s is already running! \n", argv[0]); + notify_to_lapi_caller(syncsem); + return -1; + } + + g_daemon = calloc(sizeof(struct alt1250_s), 1); + ASSERT(g_daemon); + + g_daemon->syncsem = syncsem; + g_daemon->evtq = (mqd_t)-1; + g_daemon->sid = -1; + g_daemon->is_usockrcvd = false; + g_daemon->usock_enable = TRUE; + g_daemon->is_support_lwm2m = false; + g_daemon->lwm2m_apply_xid = -1; + g_daemon->api_enable = true; + g_daemon->context_cb = NULL; + MODEM_STATE_POFF(g_daemon); + + reset_fwupdate_info(g_daemon); + + ret = alt1250_loop(g_daemon); + free(g_daemon); + g_daemon = NULL; + + /* Notify lapi that Daemon has finished */ + + notify_to_lapi_caller(syncsem); + + return ret; +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +int alt1250_set_api_enable(FAR struct alt1250_s *dev, bool enable) +{ + if (!dev) + { + return ERROR; + } + + dev->api_enable = enable; + + return OK; +} + +int alt1250_count_opened_sockets(FAR struct alt1250_s *dev) +{ + int ret = 0; + int i = 0; + FAR struct usock_s *sock; + + if (!dev) + { + return ERROR; + } + + for (i = 0; i < nitems(dev->sockets); i++) + { + sock = &dev->sockets[i]; + if (sock->state != SOCKET_STATE_CLOSED) + { + ret++; + } + } + + return ret; +} + +int alt1250_is_api_in_progress(FAR struct alt1250_s *dev) +{ + if (!dev) + { + return ERROR; + } + + return dev->is_usockrcvd ? 1 : 0; +} + +int alt1250_set_context_save_cb(FAR struct alt1250_s *dev, + context_save_cb_t context_cb) +{ + if (!dev) + { + return ERROR; + } + + dev->context_cb = context_cb; + + return OK; +} + +int alt1250_collect_daemon_context(FAR struct alt1250_s *dev) +{ + struct alt1250_save_ctx ctx; + + if (!dev) + { + return ERROR; + } + + if (!dev->context_cb) + { + return ERROR; + } + + memset(&ctx, 0, sizeof(struct alt1250_save_ctx)); + + /* Copy APN settings */ + + ctx.ip_type = dev->apn.ip_type; + ctx.auth_type = dev->apn.auth_type; + ctx.apn_type = dev->apn.apn_type; + memcpy(ctx.apn_name, dev->apn_name, LTE_APN_LEN); + memcpy(ctx.user_name, dev->user_name, LTE_APN_USER_NAME_LEN); + memcpy(ctx.pass, dev->pass, LTE_APN_PASSWD_LEN); + + /* Copy connection information */ + + ctx.d_flags = dev->net_dev.d_flags; + +#ifdef CONFIG_NET_IPv4 + memcpy(&ctx.d_ipaddr, &dev->net_dev.d_ipaddr, sizeof(in_addr_t)); + memcpy(&ctx.d_draddr, &dev->net_dev.d_draddr, sizeof(in_addr_t)); + memcpy(&ctx.d_netmask, &dev->net_dev.d_netmask, sizeof(in_addr_t)); +#endif +#ifdef CONFIG_NET_IPv6 + memcpy(&ctx.d_ipv6addr, &dev->net_dev.d_ipv6addr, sizeof(net_ipv6addr_t)); + memcpy(&ctx.d_ipv6draddr, + &dev->net_dev.d_ipv6draddr, + sizeof(net_ipv6addr_t)); + memcpy(&ctx.d_ipv6netmask, + &dev->net_dev.d_ipv6netmask, + sizeof(net_ipv6addr_t)); +#endif + + /* Save checksum without checksum for validation */ + + ctx.checksum = calc_checksum((FAR uint8_t *)&ctx, + offsetof(struct alt1250_save_ctx, checksum)); + + /* Call user application callback */ + + dev->context_cb((FAR uint8_t *)&ctx, sizeof(ctx)); + + return OK; +} + +int alt1250_apply_daemon_context(FAR struct alt1250_s *dev, + FAR struct alt1250_save_ctx *ctx) +{ + uint16_t checksum; + + if (!dev) + { + return ERROR; + } + + /* Calc checksum without checksum parameter */ + + checksum = calc_checksum((FAR uint8_t *)ctx, + offsetof(struct alt1250_save_ctx, checksum)); + + if (ctx->checksum != checksum) + { + dbg_alt1250("Saved context is invalid.\n"); + return ERROR; + } + + /* Copy APN settings */ + + dev->apn.ip_type = ctx->ip_type; + dev->apn.auth_type = ctx->auth_type; + dev->apn.apn_type = ctx->apn_type; + memcpy(dev->apn_name, ctx->apn_name, LTE_APN_LEN); + memcpy(dev->user_name, ctx->user_name, LTE_APN_USER_NAME_LEN); + memcpy(dev->pass, ctx->pass, LTE_APN_PASSWD_LEN); + + /* Set APN related pointers */ + + dev->apn.apn = dev->apn_name; + dev->apn.user_name = dev->user_name; + dev->apn.password = dev->pass; + + /* Copy connection information */ + + dev->net_dev.d_flags = ctx->d_flags; + +#ifdef CONFIG_NET_IPv4 + memcpy(&dev->net_dev.d_ipaddr, &ctx->d_ipaddr, sizeof(in_addr_t)); + memcpy(&dev->net_dev.d_draddr, &ctx->d_draddr, sizeof(in_addr_t)); + memcpy(&dev->net_dev.d_netmask, &ctx->d_netmask, sizeof(in_addr_t)); +#endif +#ifdef CONFIG_NET_IPv6 + memcpy(&dev->net_dev.d_ipv6addr, &ctx->d_ipv6addr, sizeof(net_ipv6addr_t)); + memcpy(&dev->net_dev.d_ipv6draddr, + &ctx->d_ipv6draddr, + sizeof(net_ipv6addr_t)); + memcpy(&dev->net_dev.d_ipv6netmask, + &ctx->d_ipv6netmask, + sizeof(net_ipv6addr_t)); +#endif + + return OK; +} +#endif diff --git a/lte/alt1250/alt1250_netdev.c b/lte/alt1250/alt1250_netdev.c new file mode 100644 index 000000000..ee9e9602a --- /dev/null +++ b/lte/alt1250/alt1250_netdev.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_netdev.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "alt1250_netdev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: alt1250_netdev_register + ****************************************************************************/ + +void alt1250_netdev_register(FAR struct alt1250_s *dev) +{ + netdev_register(&dev->net_dev, NET_LL_ETHERNET); +} + +/**************************************************************************** + * name: alt1250_netdev_unregister + ****************************************************************************/ + +void alt1250_netdev_unregister(FAR struct alt1250_s *dev) +{ + netdev_unregister(&dev->net_dev); +} + +/**************************************************************************** + * name: alt1250_netdev_ifdown + ****************************************************************************/ + +void alt1250_netdev_ifdown(FAR struct alt1250_s *dev) +{ + dev->net_dev.d_flags = IFF_DOWN; +#ifdef CONFIG_NET_IPv4 + memset(&dev->net_dev.d_ipaddr, 0, sizeof(dev->net_dev.d_ipaddr)); +#endif +#ifdef CONFIG_NET_IPv6 + memset(&dev->net_dev.d_ipv6addr, 0, sizeof(dev->net_dev.d_ipv6addr)); +#endif +} + +/**************************************************************************** + * name: alt1250_netdev_ifup + ****************************************************************************/ + +void alt1250_netdev_ifup(FAR struct alt1250_s *dev, FAR lte_pdn_t *pdn) +{ + int i; + + dev->net_dev.d_flags = IFF_UP; + + for (i = 0; i < pdn->ipaddr_num; i++) + { +#ifdef CONFIG_NET_IPv4 + if (LTE_IPTYPE_V4 == pdn->address[i].ip_type) + { + inet_pton(AF_INET, + (FAR const char *)pdn->address[i].address, + (FAR void *)&dev->net_dev.d_ipaddr); + } +#endif + +#ifdef CONFIG_NET_IPv6 + if (LTE_IPTYPE_V6 == pdn->address[i].ip_type) + { + inet_pton(AF_INET6, + (FAR const char *)pdn->address[i].address, + (FAR void *)&dev->net_dev.d_ipv6addr); + } +#endif + } +} diff --git a/lte/alt1250/alt1250_netdev.h b/lte/alt1250/alt1250_netdev.h new file mode 100644 index 000000000..a6931e37e --- /dev/null +++ b/lte/alt1250/alt1250_netdev.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_netdev.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_NETDEV_H +#define __APPS_LTE_ALT1250_ALT1250_NETDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "alt1250_daemon.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void alt1250_netdev_register(FAR struct alt1250_s *dev); +void alt1250_netdev_unregister(FAR struct alt1250_s *dev); +void alt1250_netdev_ifdown(FAR struct alt1250_s *dev); +void alt1250_netdev_ifup(FAR struct alt1250_s *dev, FAR lte_pdn_t *pdn); + +#endif /* __APPS_LTE_ALT1250_ALT1250_NETDEV_H */ diff --git a/lte/alt1250/alt1250_postproc.h b/lte/alt1250/alt1250_postproc.h new file mode 100644 index 000000000..fcb163a80 --- /dev/null +++ b/lte/alt1250/alt1250_postproc.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_postproc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_POSTPROC_H +#define __APPS_LTE_ALT1250_ALT1250_POSTPROC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_daemon.h" +#include "alt1250_usockif.h" + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +typedef int (*postproc_hdlr_t)(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, FAR struct usock_s *usock, + FAR int32_t *usock_result, uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, unsigned long arg); + +struct postproc_s +{ + FAR postproc_hdlr_t hdlr; + unsigned long priv; +}; + +#endif /* __APPS_LTE_ALT1250_ALT1250_POSTPROC_H */ diff --git a/lte/alt1250/alt1250_reset_seq.c b/lte/alt1250/alt1250_reset_seq.c new file mode 100644 index 000000000..a89e265f6 --- /dev/null +++ b/lte/alt1250/alt1250_reset_seq.c @@ -0,0 +1,399 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_reset_seq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_devif.h" +#include "alt1250_devevent.h" +#include "alt1250_postproc.h" +#include "alt1250_container.h" +#include "alt1250_ioctl_subhdlr.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_reset_seq.h" +#include "alt1250_atcmd.h" +#include "alt1250_evt.h" + +/**************************************************************************** + * Private Data Type + ****************************************************************************/ + +struct reset_arg_s +{ + int seq_no; + unsigned long arg; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct reset_arg_s reset_arg; + +static postproc_hdlr_t ponreset_seq[] = +{ + postproc_fwgetversion, +}; +#define PONRESET_SEQ_NUM (sizeof(ponreset_seq) / sizeof(ponreset_seq[0])) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_ponresetseq + ****************************************************************************/ + +static int postproc_ponresetseq(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, FAR struct usock_s *usock, + FAR int32_t *usock_result, FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, unsigned long arg) +{ + int ret = REP_NO_ACK_WOFREE; + struct reset_arg_s *rarg = (struct reset_arg_s *)arg; + ASSERT(rarg->seq_no < PONRESET_SEQ_NUM); + + ponreset_seq[rarg->seq_no](dev, reply, usock, usock_result, usock_xid, + ackinfo, rarg->arg); + rarg->seq_no++; + if (rarg->seq_no == PONRESET_SEQ_NUM) + { + /* On last postproc, container should be free */ + + dev->recvfrom_processing = false; + ret = REP_NO_ACK; + MODEM_STATE_PON(dev); + } + + return ret; +} + +/**************************************************************************** + * name: send_getversion_onreset + ****************************************************************************/ + +static int send_getversion_onreset(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR int32_t *usock_result) +{ + reset_arg.seq_no = 0; + reset_arg.arg = 0; + + set_container_ids(container, -1, LTE_CMDID_GETVER); + set_container_argument(container, NULL, 0); + set_container_response(container, alt1250_getevtarg(LTE_CMDID_GETVER), 2); + set_container_postproc(container, postproc_ponresetseq, + (unsigned long)&reset_arg); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: str_toupper_case + ****************************************************************************/ + +static void str_toupper_case(FAR char *data, int len) +{ + int i; + + for (i = 0; i < len; i++) + { + data[i] = (char)toupper(data[i]); + } +} + +/**************************************************************************** + * name: recv_atreply_onreset + ****************************************************************************/ + +static int recv_atreply_onreset(atreply_parser_t parse, + FAR struct alt1250_s *dev, + void *arg) +{ + int ret; + uint64_t bitmap; + struct pollfd fds; + nfds_t nfds; + FAR struct alt_container_s *rlist; + FAR struct alt_container_s *container; + FAR char *reply; + int rlen; + + fds.fd = dev->altfd; + fds.events = POLLIN; + nfds = 1; + + ret = poll(&fds, nfds, -1); + ASSERT(ret > 0); + ASSERT(fds.revents & POLLIN); + + ret = altdevice_getevent(dev->altfd, &bitmap, &rlist); + ASSERT(ret == OK); + + if (bitmap & ALT1250_EVTBIT_RESET) + { + /* Reset is happened again... */ + + container_free_all(rlist); + dev->sid = -1; + + ret = REP_MODEM_RESET; + } + else if (bitmap & ALT1250_EVTBIT_REPLY) + { + container = container_pick_listtop(&rlist); + ASSERT(rlist == NULL); + + reply = (FAR char *)container->outparam[0]; + rlen = *(int *)container->outparam[2]; + + str_toupper_case(reply, rlen); + ret = parse(reply, rlen, arg); + ASSERT(ret == OK); + + ret = REP_NO_ACK; + } + else + { + ASSERT(0); /* Should not be here */ + } + + return ret; +} + +/**************************************************************************** + * name: alt1250_lwm2m_ponreset + ****************************************************************************/ + +static int alt1250_lwm2m_ponreset(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container) +{ + int ret = REP_NO_ACK; + int recv_ret; + struct atreply_truefalse_s t_or_f; + int32_t usock_result = OK; + + /* Make sure LwM2M func enabled */ + + t_or_f.target_str = "\nTRUE\r"; + lwm2mstub_send_getenable(dev, container, &usock_result); + if (usock_result == -ENOTSUP) + { + return REP_NO_ACK; + } + + recv_ret = recv_atreply_onreset(check_atreply_truefalse, dev, &t_or_f); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + if (!t_or_f.result) + { + lwm2mstub_send_setenable(dev, container, true); + recv_ret = recv_atreply_onreset(check_atreply_ok, dev, NULL); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + ret = REP_SEND_ACK; + } + + /* Make sure LwM2M AutoConnect is disabled */ + + t_or_f.target_str = "\nFALSE\r"; + lwm2mstub_send_getautoconnect(dev, container); + recv_ret = recv_atreply_onreset(check_atreply_truefalse, dev, &t_or_f); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + if (!t_or_f.result) + { + lwm2mstub_send_setautoconnect(dev, container, false); + recv_ret = recv_atreply_onreset(check_atreply_ok, dev, NULL); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + ret = REP_SEND_ACK; + } + + /* Make sure LwM2M Version is 1.1 */ + + t_or_f.target_str = "\n1.1\r"; + lwm2mstub_send_getversion(dev, container); + recv_ret = recv_atreply_onreset(check_atreply_truefalse, dev, &t_or_f); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + if (!t_or_f.result) + { + lwm2mstub_send_setversion(dev, container, true); + recv_ret = recv_atreply_onreset(check_atreply_ok, dev, NULL); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + ret = REP_SEND_ACK; + } + + /* Make sure LwM2M NameMode is 0:UserName */ + + t_or_f.target_str = "\n0\r"; + lwm2mstub_send_getnamemode(dev, container); + recv_ret = recv_atreply_onreset(check_atreply_truefalse, dev, &t_or_f); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + if (!t_or_f.result) + { + lwm2mstub_send_setnamemode(dev, container, 0); + recv_ret = recv_atreply_onreset(check_atreply_ok, dev, NULL); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + ret = REP_SEND_ACK; + } + + /* Make sure NWOPER is not DEFAULT */ + + t_or_f.target_str = "DEFAULT"; + ltenwop_send_getnwop(dev, container); + recv_ret = recv_atreply_onreset(check_atreply_truefalse, dev, &t_or_f); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + if (t_or_f.result) + { + ltenwop_send_setnwoptp(dev, container); + recv_ret = recv_atreply_onreset(check_atreply_ok, dev, NULL); + if (recv_ret == REP_MODEM_RESET) + { + return recv_ret; + } + + ret = REP_SEND_ACK; + } + + if (ret == REP_SEND_ACK) + { + /* Force Reset is needed. */ + + altdevice_reset(dev->altfd); + } + + dev->is_support_lwm2m = true; + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: handle_poweron_reset_stage2 + ****************************************************************************/ + +int handle_poweron_reset_stage2(FAR struct alt1250_s *dev) +{ + int ret; + int32_t unused; + + FAR struct alt_container_s *container; + + container = container_alloc(); + ASSERT(container != 0); + + ret = send_getversion_onreset(dev, container, &unused); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (ret > 0) + { + /* for blocking next usrsock request */ + + ret = REP_MODEM_RESET; + dev->recvfrom_processing = true; + } + + return ret; +} + +/**************************************************************************** + * name: handle_poweron_reset + ****************************************************************************/ + +int handle_poweron_reset(FAR struct alt1250_s *dev) +{ + int ret = REP_MODEM_RESET; + FAR struct alt_container_s *container; + + container = container_alloc(); + ASSERT(container); + + while (ret == REP_MODEM_RESET) + { + ret = alt1250_lwm2m_ponreset(dev, container); + } + + container_free(container); + + MODEM_STATE_B4PON_2ND(dev); + + if (ret == REP_NO_ACK) + { + /* In this sequence, + * NO_ACK means no force reset. + * In that case, get version is needed to send here. + */ + + handle_poweron_reset_stage2(dev); + ret = REP_MODEM_RESET; + } + + return ret; +} diff --git a/lte/alt1250/alt1250_reset_seq.h b/lte/alt1250/alt1250_reset_seq.h new file mode 100644 index 000000000..720a948ad --- /dev/null +++ b/lte/alt1250/alt1250_reset_seq.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_reset_seq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_RESET_SEQ_H +#define __APPS_LTE_ALT1250_ALT1250_RESET_SEQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_daemon.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int handle_poweron_reset(FAR struct alt1250_s *dev); +int handle_poweron_reset_stage2(FAR struct alt1250_s *dev); +int handle_commit_reset(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_ALT1250_RESET_SEQ_H */ diff --git a/lte/alt1250/alt1250_select.c b/lte/alt1250/alt1250_select.c new file mode 100644 index 000000000..7e8e81f91 --- /dev/null +++ b/lte/alt1250/alt1250_select.c @@ -0,0 +1,368 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_select.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_socket.h" +#include "alt1250_usockif.h" +#include "alt1250_container.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SELECT_CONTAINER_MAX (2) +#define SELECT_MODE_NONBLOCK (0) +#define SELECT_MODE_BLOCK (1) +#define SELECT_MODE_BLOCKCANCEL (2) +#define READSET_BIT (1 << 0) +#define WRITESET_BIT (1 << 1) + +/**************************************************************************** + * Private Data Type + ****************************************************************************/ + +struct select_params_s +{ + int32_t ret; + int32_t err; + int32_t id; + altcom_fd_set readset; + altcom_fd_set writeset; + altcom_fd_set exceptset; +}; + +/**************************************************************************** + * Private Function Prototype + ****************************************************************************/ + +static struct alt_container_s select_container_obj[SELECT_CONTAINER_MAX]; +static FAR struct alt_container_s *g_current_container; +static void *g_selectargs[SELECT_CONTAINER_MAX][6]; +static struct select_params_s g_select_params[SELECT_CONTAINER_MAX]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_select_command + ****************************************************************************/ + +static int send_select_command(FAR struct alt1250_s *dev, + int32_t mode, int32_t id, int32_t maxfds, + FAR altcom_fd_set *readset, + FAR altcom_fd_set *writeset, + FAR altcom_fd_set *exceptset) +{ + FAR void *in[7]; + uint16_t used_setbit = 0; + int32_t usock_result; + struct alt_container_s container = { + 0 + }; + + if (readset) + { + used_setbit |= READSET_BIT; + } + + if (writeset) + { + used_setbit |= WRITESET_BIT; + } + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + in[0] = &mode; + in[1] = &id; + in[2] = &maxfds; + in[3] = &used_setbit; + in[4] = readset; + in[5] = writeset; + in[6] = exceptset; + + set_container_ids(&container, 0, LTE_CMDID_SELECT); + set_container_argument(&container, in, nitems(in)); + + return altdevice_send_command(dev->altfd, &container, &usock_result); +} + +/**************************************************************************** + * Name: select_cancel + ****************************************************************************/ + +static void select_cancel(FAR struct alt1250_s *dev) +{ + int32_t dummy_maxfds = 0; + altcom_fd_set dummy_readset; + altcom_fd_set dummy_writeset; + altcom_fd_set dummy_exceptset; + + if (dev->sid != -1) + { + send_select_command(dev, SELECT_MODE_BLOCKCANCEL, dev->sid, + dummy_maxfds, &dummy_readset, &dummy_writeset, + &dummy_exceptset); + dev->sid = -1; + } +} + +/**************************************************************************** + * name: select_start + ****************************************************************************/ + +static void select_start(FAR struct alt1250_s *dev) +{ + int32_t maxfds = -1; + altcom_fd_set readset; + altcom_fd_set writeset; + altcom_fd_set exceptset; + FAR struct usock_s *usock; + int i; + + dev->sid = (++dev->scnt & 0x7fffffff); + + ALTCOM_FD_ZERO(&readset); + ALTCOM_FD_ZERO(&writeset); + ALTCOM_FD_ZERO(&exceptset); + + for (i = 0; i < SOCKET_COUNT; i++) + { + usock = usocket_search(dev, i); + if (usock && IS_STATE_SELECTABLE(usock)) + { + if (IS_STATE_READABLE(usock)) + { + ALTCOM_FD_SET(USOCKET_ALTSOCKID(usock), &readset); + } + + if (IS_STATE_WRITABLE(usock)) + { + ALTCOM_FD_SET(USOCKET_ALTSOCKID(usock), &writeset); + } + + ALTCOM_FD_SET(USOCKET_ALTSOCKID(usock), &exceptset); + + maxfds = ((maxfds > USOCKET_ALTSOCKID(usock)) ? maxfds : + USOCKET_ALTSOCKID(usock)); + } + } + + if (maxfds != -1) + { + send_select_command(dev, SELECT_MODE_BLOCK, dev->sid, + maxfds + 1, &readset, &writeset, &exceptset); + } +} + +/**************************************************************************** + * name: recv_selectcontainer + ****************************************************************************/ + +static FAR struct alt_container_s *recv_selectcontainer( + FAR struct alt1250_s *dev) +{ + g_current_container = altdevice_exchange_selcontainer(dev->altfd, + g_current_container); + return g_current_container; +} + +/**************************************************************************** + * name: operate_dataavail + ****************************************************************************/ + +static void operate_dataavail(FAR struct alt1250_s *dev, + FAR struct usock_s *usock, + FAR altcom_fd_set *readset, + FAR altcom_fd_set *writeset, + FAR altcom_fd_set *exceptset) +{ + if (IS_STATE_SELECTABLE(usock)) + { + if (ALTCOM_FD_ISSET(USOCKET_ALTSOCKID(usock), exceptset)) + { + dbg_alt1250("exceptset is set. usockid: %d\n", + USOCKET_USOCKID(usock)); + + USOCKET_SET_STATE(usock, SOCKET_STATE_ABORTED); + } + + if (ALTCOM_FD_ISSET(USOCKET_ALTSOCKID(usock), readset)) + { + dbg_alt1250("readset is set. usockid: %d\n", + USOCKET_USOCKID(usock)); + + USOCKET_CLR_SELECTABLE(usock, SELECT_READABLE); + usockif_sendrxready(dev->usockfd, USOCKET_USOCKID(usock)); + } + + if (ALTCOM_FD_ISSET(USOCKET_ALTSOCKID(usock), writeset)) + { + dbg_alt1250("writeset is set. usockid: %d\n", + USOCKET_USOCKID(usock)); + + if (USOCKET_STATE(usock) == SOCKET_STATE_WAITCONN) + { + if (nextstep_check_connectres(dev, usock) == REP_NO_ACK_WOFREE) + { + USOCKET_CLR_SELECTABLE(usock, SELECT_WRITABLE); + } + } + else + { + USOCKET_CLR_SELECTABLE(usock, SELECT_WRITABLE); + usockif_sendtxready(dev->usockfd, USOCKET_USOCKID(usock)); + } + } + } +} + +/**************************************************************************** + * Name: handle_selectevt + ****************************************************************************/ + +static void handle_selectevt(FAR struct alt1250_s *dev, + int32_t altcom_resp, int32_t modem_errno, + int32_t selectreq_id, + FAR altcom_fd_set *readset, + FAR altcom_fd_set *writeset, + FAR altcom_fd_set *exceptset) +{ + int i; + FAR struct usock_s *usock; + + dbg_alt1250("select reply. ret=%ld modem_errno=%ld\n", + altcom_resp, modem_errno); + + if (selectreq_id == dev->sid) + { + altcom_resp = COMBINE_ERRCODE(altcom_resp, modem_errno); + if (altcom_resp >= 0) + { + for (i = 0; i < SOCKET_COUNT; i++) + { + usock = usocket_search(dev, i); + operate_dataavail(dev, usock, readset, writeset, exceptset); + } + + usocket_commitstate(dev); + } + } + + /* For debug */ + + else + { + dbg_alt1250("Select event come wish in no selected. sel_id = %ld\n", + selectreq_id); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: perform_select_event + ****************************************************************************/ + +uint64_t perform_select_event(FAR struct alt1250_s *dev, uint64_t bitmap) +{ + uint64_t bit = 0ULL; + + if (alt1250_checkcmdid(LTE_CMDID_SELECT, bitmap, &bit)) + { + FAR struct alt_container_s *selectcontainer + = recv_selectcontainer(dev); + + /* container->outparam[0]: return code + * container->outparam[1]: error code + * container->outparam[2]: select id + * container->outparam[3]: readset + * container->outparam[4]: writeset + * container->outparam[5]: exceptset + */ + + handle_selectevt(dev, + *((int32_t *)selectcontainer->outparam[0]), + *((int32_t *)selectcontainer->outparam[1]), + *((int32_t *)selectcontainer->outparam[2]), + (altcom_fd_set *)(selectcontainer->outparam[3]), + (altcom_fd_set *)(selectcontainer->outparam[4]), + (altcom_fd_set *)(selectcontainer->outparam[5])); + } + + return bit; +} + +/**************************************************************************** + * name: init_selectcontainer + ****************************************************************************/ + +void init_selectcontainer(FAR struct alt1250_s *dev) +{ + int i; + + memset(select_container_obj, 0, sizeof(select_container_obj)); + + for (i = 0; i < SELECT_CONTAINER_MAX; i++) + { + g_selectargs[i][0] = &g_select_params[i].ret; + g_selectargs[i][1] = &g_select_params[i].err; + g_selectargs[i][2] = &g_select_params[i].id; + g_selectargs[i][3] = &g_select_params[i].readset; + g_selectargs[i][4] = &g_select_params[i].writeset; + g_selectargs[i][5] = &g_select_params[i].exceptset; + + select_container_obj[i].outparam = g_selectargs[i]; + select_container_obj[i].outparamlen = nitems(g_selectargs[i]); + } + + altdevice_exchange_selcontainer(dev->altfd, &select_container_obj[0]); + g_current_container = &select_container_obj[1]; +} + +/**************************************************************************** + * name: restart_select + ****************************************************************************/ + +void restart_select(FAR struct alt1250_s *dev) +{ + select_cancel(dev); + select_start(dev); +} + diff --git a/lte/alt1250/alt1250_select.h b/lte/alt1250/alt1250_select.h new file mode 100644 index 000000000..4336e5f66 --- /dev/null +++ b/lte/alt1250/alt1250_select.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_select.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_SELECT_H +#define __APPS_LTE_ALT1250_ALT1250_SELECT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "alt1250_daemon.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void init_selectcontainer(FAR struct alt1250_s *dev); +uint64_t perform_select_event(FAR struct alt1250_s *dev, uint64_t bitmap); +void restart_select(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_ALT1250_SELECT_H */ diff --git a/lte/alt1250/alt1250_socket.c b/lte/alt1250/alt1250_socket.c new file mode 100644 index 000000000..d6fb6cf28 --- /dev/null +++ b/lte/alt1250/alt1250_socket.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_socket.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_usockif.h" +#include "alt1250_socket.h" +#include "alt1250_select.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usocket_search + ****************************************************************************/ + +FAR struct usock_s *usocket_search(FAR struct alt1250_s *dev, int usockid) +{ + struct usock_s *ret = NULL; + + dbg_alt1250("%s usockid: %d\n", __func__, usockid); + + if (usockid >= 0 && usockid < nitems(dev->sockets)) + { + ret = &dev->sockets[usockid]; + } + + return ret; +} + +/**************************************************************************** + * name: usocket_alloc + ****************************************************************************/ + +FAR struct usock_s *usocket_alloc(FAR struct alt1250_s *dev, int16_t type) +{ + int i; + int base; + int array_num; + FAR struct usock_s *sock; + + switch (type) + { + case SOCK_CTRL: + case SOCK_SMS: + base = SOCKET_COUNT; + array_num = CONFIG_LTE_ALT1250_CONTROL_SOCKETS; + break; + + default: + base = 0; + array_num = SOCKET_COUNT; + break; + } + + sock = &dev->sockets[base]; + + for (i = base; i < base + array_num; i++, sock++) + { + if (sock->state == SOCKET_STATE_CLOSED) + { + sock->usockid = i; + sock->altsockid = -1; + sock->state = SOCKET_STATE_PREALLOC; + sock->select_condition = SELECT_WRITABLE | SELECT_READABLE; + dbg_alt1250("allocated usockid: %d, type: %d\n", i, type); + return sock; + } + } + + return NULL; +} + +/**************************************************************************** + * name: usocket_free + ****************************************************************************/ + +void usocket_free(FAR struct usock_s *sock) +{ + sock->state = SOCKET_STATE_CLOSED; +} + +/**************************************************************************** + * name: usocket_freeall + ****************************************************************************/ + +void usocket_freeall(FAR struct alt1250_s *dev) +{ + int i; + FAR struct usock_s *sock; + + for (i = 0; i < nitems(dev->sockets); i++) + { + sock = &dev->sockets[i]; + usocket_free(sock); + } +} + +/**************************************************************************** + * name: usocket_commitstate + ****************************************************************************/ + +void usocket_commitstate(FAR struct alt1250_s *dev) +{ + restart_select(dev); +} + +/**************************************************************************** + * name: usocket_smssock_num + ****************************************************************************/ + +int usocket_smssock_num(FAR struct alt1250_s *dev) +{ + int i; + int num = 0; + FAR struct usock_s *sock; + + for (i = 0; i < nitems(dev->sockets); i++) + { + sock = &dev->sockets[i]; + if (IS_SMS_SOCKET(sock) && sock->state == SOCKET_STATE_PREALLOC) + { + num++; + } + } + + return num; +} + +/**************************************************************************** + * name: usocket_smssock_readready + ****************************************************************************/ + +void usocket_smssock_readready(FAR struct alt1250_s *dev) +{ + int i; + FAR struct usock_s *sock; + + for (i = 0; i < nitems(dev->sockets); i++) + { + sock = &dev->sockets[i]; + if (IS_SMS_SOCKET(sock) && sock->state == SOCKET_STATE_PREALLOC) + { + usockif_sendrxready(dev->usockfd, USOCKET_USOCKID(sock)); + } + } +} + +/**************************************************************************** + * name: usocket_smssock_abort + ****************************************************************************/ + +void usocket_smssock_abort(FAR struct alt1250_s *dev) +{ + int i; + FAR struct usock_s *sock; + + for (i = 0; i < nitems(dev->sockets); i++) + { + sock = &dev->sockets[i]; + if (IS_SMS_SOCKET(sock) && sock->state == SOCKET_STATE_PREALLOC) + { + usockif_sendabort(dev->usockfd, USOCKET_USOCKID(sock)); + } + } +} diff --git a/lte/alt1250/alt1250_socket.h b/lte/alt1250/alt1250_socket.h new file mode 100644 index 000000000..310fe8a64 --- /dev/null +++ b/lte/alt1250/alt1250_socket.h @@ -0,0 +1,249 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_socket.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_SOCKET_H +#define __APPS_LTE_ALT1250_ALT1250_SOCKET_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "alt1250_usockif.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SELECT_WRITABLE (1 << 1) +#define SELECT_READABLE (1 << 2) +#define SELECTABLE_MASK (SELECT_WRITABLE | SELECT_READABLE) + +#define USOCKET_SET_REQUEST(sock, _reqid, _xid) { \ + (sock)->request.reqid = (_reqid); \ + (sock)->request.xid = (_xid); \ +} + +#define USOCKET_SET_SOCKTYPE(sock, _domain, _type, _protocol) { \ + (sock)->domain = (_domain); \ + (sock)->type = (_type); \ + (sock)->protocol = (_protocol); \ +} + +#define USOCKET_SET_REQADDRLEN(sock, _addrlen) \ + { (sock)->sock_req.addrbuflen.addr.addrlen = (_addrlen); } + +#define USOCKET_SET_REQBACKLOG(sock, _backlog) \ + { (sock)->sock_req.backlog = (_backlog); } + +#define USOCKET_SET_REQBUFLEN(sock, _buflen) \ + { (sock)->sock_req.addrbuflen.buflen = (_buflen); } + +#define USOCKET_SET_REQSOCKOPT(sock, _level, _opt, _optlen) { \ + (sock)->sock_req.opt.level = (_level); \ + (sock)->sock_req.opt.option = (_opt); \ + (sock)->sock_req.opt.optlen = (_optlen); \ +} + +#define USOCKET_REQID(sock) ((sock)->request.reqid) +#define USOCKET_XID(sock) ((sock)->request.xid) +#define USOCKET_DOMAIN(sock) ((sock)->domain) +#define USOCKET_TYPE(sock) ((sock)->type) +#define USOCKET_PROTOCOL(sock) ((sock)->protocol) +#define USOCKET_REQADDRLEN(sock) ((sock)->sock_req.addrbuflen.addr.addrlen) +#define USOCKET_REQADDR(sock) ((sock)->sock_req.addrbuflen.addr.addr) +#define USOCKET_REQBACKLOG(sock) ((sock)->sock_req.backlog) +#define USOCKET_REQBUFLEN(sock) ((sock)->sock_req.addrbuflen.buflen) +#define USOCKET_REQOPTLEVEL(sock) ((sock)->sock_req.opt.level) +#define USOCKET_REQOPTOPT(sock) ((sock)->sock_req.opt.option) +#define USOCKET_REQOPTLEN(sock) ((sock)->sock_req.opt.optlen) +#define USOCKET_REQOPTVAL(sock) ((sock)->sock_req.opt.value) +#define USOCKET_STATE(sock) ((sock)->state) +#define USOCKET_ALTSOCKID(sock) ((sock)->altsockid) +#define USOCKET_USOCKID(sock) ((sock)->usockid) +#define USOCKET_REFID(sock) (&(sock)->refids) + +#define USOCKET_REP_RESPONSE(sock) ((sock)->sock_reply.outparams) +#define USOCKET_REP_RESULT(sock) (&(sock)->sock_reply.rep_result) +#define USOCKET_REP_ERRCODE(sock) (&(sock)->sock_reply.rep_errcode) +#define USOCKET_REP_ADDRLEN(sock) \ + (&(sock)->sock_reply.sock_reply_opt.addr.addrlen) +#define USOCKET_REP_ADDR(sock) \ + (&(sock)->sock_reply.sock_reply_opt.addr.addr) +#define USOCKET_REP_OPTLEN(sock) \ + (&(sock)->sock_reply.sock_reply_opt.opt.optlen) +#define USOCKET_REP_OPTVAL(sock) \ + (&(sock)->sock_reply.sock_reply_opt.opt.value[0]) + +#define USOCKET_SET_RESPONSE(sock, n, p) \ + do \ + { \ + int iii = (n); \ + if (iii < _OUTPUT_ARG_MAX) \ + { \ + (sock)->sock_reply.outparams[iii] = (p); \ + } \ + else \ + { \ + ASSERT(0); \ + } \ + } \ + while(0) + +#define USOCKET_SET_ALTSOCKID(sock, id) { (sock)->altsockid = id; } +#define USOCKET_SET_STATE(sock, st) { (sock)->state = (st); } +#define USOCKET_SET_SELECTABLE(sock, rw) { \ + (sock)->select_condition |= (rw); \ +} +#define USOCKET_CLR_SELECTABLE(sock, rw) { \ + (sock)->select_condition &= ~(rw); \ +} + +#define IS_STATE_SELECTABLE(s) (((s)->state != SOCKET_STATE_CLOSED) \ + && ((s)->state != SOCKET_STATE_PREALLOC) \ + && ((s)->state != SOCKET_STATE_ABORTED) \ + && ((s)->state != SOCKET_STATE_CLOSING) \ + && ((s)->state != SOCKET_STATE_OPEN)) + +#define IS_STATE_READABLE(s) ((s)->select_condition & SELECT_READABLE) +#define IS_STATE_WRITABLE(s) ((s)->select_condition & SELECT_WRITABLE) + +#define IS_SMS_SOCKET(s) ((s)->type == SOCK_SMS) + +#define _OUTPUT_ARG_MAX 7 +#define _OPTVAL_LEN_MAX 16 + +#define usocket_smssock_writeready(d, s) \ + (usockif_sendtxready((d)->usockfd, USOCKET_USOCKID(s))) + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +struct alt1250_s; + +enum socket_state_e +{ + SOCKET_STATE_CLOSED = 0, + SOCKET_STATE_PREALLOC, + SOCKET_STATE_OPEN, + SOCKET_STATE_OPENED, + SOCKET_STATE_CONNECTING, + SOCKET_STATE_WAITCONN, + SOCKET_STATE_CONNECTED, + SOCKET_STATE_ABORTED, + SOCKET_STATE_CLOSING +}; + +struct usock_addr_s +{ + uint32_t addrlen; + struct sockaddr_storage addr; +}; + +struct usock_opt_s +{ + uint32_t optlen; + uint8_t value[_OPTVAL_LEN_MAX]; +}; + +struct usock_s +{ + struct usrsock_request_common_s request; + int16_t domain; + int16_t type; + int16_t protocol; + + enum socket_state_e state; + int select_condition; + int altsockid; + int usockid; + + struct sms_refids_s refids; + + union sock_request_param_u + { + struct + { + /* store the input arguments of connect(), + * recvfrom(), bind(), accept(), getsockname() + */ + + struct usock_addr_s addr; + + /* store the input arguments of sendto(), recvfrom() */ + + uint16_t buflen; + } addrbuflen; + + /* store the input arguments of listen() */ + + uint16_t backlog; + + /* store the input arguments of setsockopt(), getsockopt() */ + + struct + { + int16_t level; + int16_t option; + uint16_t optlen; + uint8_t value[_OPTVAL_LEN_MAX]; + } opt; + } sock_req; + + struct sock_reply_param_s + { + FAR void *outparams[_OUTPUT_ARG_MAX]; + + int rep_result; + int rep_errcode; + + union sock_reply_opt_u + { + /* store the output arguments of recvfrom(), + * accept() ,getsockname() + */ + + struct usock_addr_s addr; + + /* store the input arguments of setsockopt(), getsockopt() */ + + struct usock_opt_s opt; + } sock_reply_opt; + } sock_reply; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +FAR struct usock_s *usocket_search(FAR struct alt1250_s *dev, int usockid); +FAR struct usock_s *usocket_alloc(FAR struct alt1250_s *dev, int16_t type); +void usocket_free(FAR struct usock_s *sock); +void usocket_freeall(FAR struct alt1250_s *dev); +void usocket_commitstate(FAR struct alt1250_s *dev); +int usocket_smssock_num(FAR struct alt1250_s *dev); +void usocket_smssock_readready(FAR struct alt1250_s *dev); +void usocket_smssock_abort(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_ALT1250_SOCKET_H */ diff --git a/lte/alt1250/alt1250_usockevent.c b/lte/alt1250/alt1250_usockevent.c new file mode 100644 index 000000000..839fa547a --- /dev/null +++ b/lte/alt1250/alt1250_usockevent.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_usockevent.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_usockevent.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const usrsock_reqhandler_t handlers[USRSOCK_REQUEST__MAX] = +{ + [USRSOCK_REQUEST_SOCKET] = usockreq_socket, + [USRSOCK_REQUEST_CLOSE] = usockreq_close, + [USRSOCK_REQUEST_CONNECT] = usockreq_connect, + [USRSOCK_REQUEST_SENDTO] = usockreq_sendto, + [USRSOCK_REQUEST_RECVFROM] = usockreq_recvfrom, + [USRSOCK_REQUEST_SETSOCKOPT] = usockreq_setsockopt, + [USRSOCK_REQUEST_GETSOCKOPT] = usockreq_getsockopt, + [USRSOCK_REQUEST_GETSOCKNAME] = usockreq_getsockname, + [USRSOCK_REQUEST_GETPEERNAME] = usockreq_getpeername, + [USRSOCK_REQUEST_BIND] = usockreq_bind, + [USRSOCK_REQUEST_LISTEN] = usockreq_listen, + [USRSOCK_REQUEST_ACCEPT] = usockreq_accept, + [USRSOCK_REQUEST_IOCTL] = usockreq_ioctl, + [USRSOCK_REQUEST_SHUTDOWN] = usockreq_shutdown +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usock_reply + ****************************************************************************/ + +int usock_reply(int ufd, int action_code, int32_t result, + uint32_t xid, FAR struct usock_ackinfo_s *ackinfo) +{ + int ret = OK; + + dbg_alt1250("action code: %08x\n", action_code); + + switch (action_code) + { + case REP_SEND_ACK: + case REP_SEND_ACK_WOFREE: + case REP_SEND_INPROG: + case REP_SEND_TERM: + ret = usockif_sendack(ufd, result, xid, + (action_code == REP_SEND_INPROG)); + break; + + case REP_SEND_DACK: + ret = usockif_senddataack(ufd, result, xid, ackinfo); + break; + + case REP_SEND_ACK_TXREADY: + ret = usockif_sendack(ufd, result, xid, false); + usockif_sendevent(ufd, ackinfo->usockid, USRSOCK_EVENT_SENDTO_READY); + break; + + case REP_SEND_DACK_RXREADY: + ret = usockif_senddataack(ufd, result, xid, ackinfo); + usockif_sendevent(ufd, ackinfo->usockid, + USRSOCK_EVENT_RECVFROM_AVAIL); + break; + } + + return ret; +} + +/**************************************************************************** + * name: perform_usockrequest + ****************************************************************************/ + +int perform_usockrequest(FAR struct alt1250_s *dev) +{ + int ret = OK; + int32_t usock_result; + uint32_t usock_xid; + struct usock_ackinfo_s ackinfo; + + if (!IS_USOCKREQ_RECEIVED(dev)) + { + ret = usockif_readrequest(dev->usockfd, &dev->usockreq); + ASSERT(ret >= 0); + if (IS_IOCTLREQ(dev->usockreq)) + { + ret = usockif_readreqioctl(dev->usockfd, &dev->usockreq); + if (ret < 0) + { + /* In unsupported ioctl command case */ + + usock_reply(dev->usockfd, REP_SEND_ACK_WOFREE, ret, + USOCKREQXID(dev->usockreq), NULL); + return OK; + } + } + + dev->is_usockrcvd = true; + } + + if (!IS_REQID_VALID(dev->usockreq)) + { + ret = REP_SEND_ACK; + usock_result = -EINVAL; + usock_xid = USOCKREQXID(dev->usockreq); + } + else + { + ret = handlers[USOCKREQID(dev->usockreq)](dev, &dev->usockreq, + &usock_result, &usock_xid, + &ackinfo); + } + + ASSERT(ret >= 0); + + usock_reply(dev->usockfd, ret, usock_result, usock_xid, &ackinfo); + + return ret; +} diff --git a/lte/alt1250/alt1250_usockevent.h b/lte/alt1250/alt1250_usockevent.h new file mode 100644 index 000000000..82ca8422e --- /dev/null +++ b/lte/alt1250/alt1250_usockevent.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_usockevent.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_USOCKEVENT_H +#define __APPS_LTE_ALT1250_ALT1250_USOCKEVENT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "alt1250_usockif.h" +#include "alt1250_daemon.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NEED_CONTAINER_FREE (1<<16) +#define W_CONTAINER_FREE(a) ((a) | NEED_CONTAINER_FREE) +#define WO_CONTAINER_FREE(a) (a) + +#define IS_NEED_CONTAINER_FREE(r) ((r) & NEED_CONTAINER_FREE) + +#define REP_SEND_ACK W_CONTAINER_FREE(1) +#define REP_SEND_ACK_WOFREE WO_CONTAINER_FREE(2) +#define REP_SEND_INPROG W_CONTAINER_FREE(3) +#define REP_SEND_DACK W_CONTAINER_FREE(4) +#define REP_SEND_TERM W_CONTAINER_FREE(5) +#define REP_NO_CONTAINER WO_CONTAINER_FREE(6) +#define REP_NO_ACK W_CONTAINER_FREE(7) +#define REP_NO_ACK_WOFREE WO_CONTAINER_FREE(8) +#define REP_MODEM_RESET WO_CONTAINER_FREE(9) +#define REP_SEND_ACK_TXREADY W_CONTAINER_FREE(10) +#define REP_SEND_DACK_RXREADY W_CONTAINER_FREE(11) + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +typedef int (*usrsock_reqhandler_t)(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int usock_reply(int ufd, int action_code, int32_t result, + uint32_t xid, FAR struct usock_ackinfo_s *ackinfo); + +int perform_usockrequest(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_ALT1250_USOCKEVENT_H */ diff --git a/lte/alt1250/alt1250_usockif.c b/lte/alt1250/alt1250_usockif.c new file mode 100644 index 000000000..699b18286 --- /dev/null +++ b/lte/alt1250/alt1250_usockif.c @@ -0,0 +1,394 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_usockif.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_usockif.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: write_to_usock + ****************************************************************************/ + +static int write_to_usock(int fd, FAR void *buf, size_t sz) +{ + int ret; + + ret = write(fd, buf, sz); + if (ret < 0) + { + ret = -errno; + } + else if (ret != sz) + { + ret = -ENOSPC; + } + else + { + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * name: send_dataack + ****************************************************************************/ + +static int send_dataack(int fd, uint32_t ackxid, int32_t ackresult, + uint16_t valuelen, uint16_t valuelen_nontrunc, + FAR uint8_t *value_ptr, FAR uint8_t *buf_ptr) +{ + int ret; + struct usrsock_message_datareq_ack_s dataack; + + dataack.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + dataack.reqack.head.flags = 0; + dataack.reqack.xid = ackxid; + dataack.reqack.result = ackresult; + + dataack.valuelen = valuelen; + dataack.valuelen_nontrunc = valuelen_nontrunc; + + ret = write_to_usock(fd, &dataack, sizeof(dataack)); + if (ret < 0) + { + return ret; + } + + if ((valuelen > 0) && (value_ptr != NULL)) + { + ret = write_to_usock(fd, value_ptr, valuelen); + if (ret < 0) + { + return ret; + } + } + + if ((ackresult > 0) && (buf_ptr != NULL)) + { + ret = write_to_usock(fd, buf_ptr, ackresult); + if (ret < 0) + { + return ret; + } + } + + return OK; +} + +/**************************************************************************** + * name: read_wrapper + ****************************************************************************/ + +static int read_wrapper(int fd, FAR void *buf, size_t sz) +{ + int ret; + + ret = read(fd, buf, sz); + if (ret < 0) + { + ret = -errno; + dbg_alt1250("failed to read usersock: %d\n", errno); + return ret; + } + + if (ret != sz) + { + dbg_alt1250("unexpected read size: %d expected: %u\n", ret, sz); + return -EMSGSIZE; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: init_usock_device + ****************************************************************************/ + +int init_usock_device(void) +{ + return open(DEV_USRSOCK, O_RDWR); +} + +/**************************************************************************** + * name: finalize_usock_device + ****************************************************************************/ + +void finalize_usock_device(int fd) +{ + close(fd); +} + +/**************************************************************************** + * name: reset_usock_device + ****************************************************************************/ + +int reset_usock_device(int fd) +{ + close(fd); + return open(DEV_USRSOCK, O_RDWR); +} + +/**************************************************************************** + * name: usockif_readrequest + ****************************************************************************/ + +int usockif_readrequest(int fd, FAR struct usrsock_request_buff_s *buf) +{ + int ret; + int rsize = 0; + FAR char *pbuf = NULL; + + /* Read common header */ + + ret = read_wrapper(fd, buf, sizeof(struct usrsock_request_common_s)); + if (ret < 0) + { + return ret; + } + + /* Read each request */ + + switch (buf->request.head.reqid) + { + case USRSOCK_REQUEST_SOCKET: + rsize = sizeof(struct usrsock_request_socket_s); + break; + case USRSOCK_REQUEST_CLOSE: + rsize = sizeof(struct usrsock_request_close_s); + break; + case USRSOCK_REQUEST_CONNECT: + rsize = sizeof(struct usrsock_request_connect_s); + break; + case USRSOCK_REQUEST_SENDTO: + rsize = sizeof(struct usrsock_request_sendto_s); + break; + case USRSOCK_REQUEST_RECVFROM: + rsize = sizeof(struct usrsock_request_recvfrom_s); + break; + case USRSOCK_REQUEST_SETSOCKOPT: + rsize = sizeof(struct usrsock_request_setsockopt_s); + break; + case USRSOCK_REQUEST_GETSOCKOPT: + rsize = sizeof(struct usrsock_request_getsockopt_s); + break; + case USRSOCK_REQUEST_GETSOCKNAME: + rsize = sizeof(struct usrsock_request_getsockname_s); + break; + case USRSOCK_REQUEST_GETPEERNAME: + rsize = sizeof(struct usrsock_request_getpeername_s); + break; + case USRSOCK_REQUEST_BIND: + rsize = sizeof(struct usrsock_request_bind_s); + break; + case USRSOCK_REQUEST_LISTEN: + rsize = sizeof(struct usrsock_request_listen_s); + break; + case USRSOCK_REQUEST_ACCEPT: + rsize = sizeof(struct usrsock_request_accept_s); + break; + case USRSOCK_REQUEST_IOCTL: + rsize = sizeof(struct usrsock_request_ioctl_s); + break; + case USRSOCK_REQUEST_SHUTDOWN: + rsize = sizeof(struct usrsock_request_shutdown_s); + break; + default: + dbg_alt1250("unexpected request id: %d\n", buf->request.head.reqid); + return -EINVAL; + break; + } + + pbuf = (FAR char *)buf + sizeof(struct usrsock_request_common_s); + rsize -= sizeof(struct usrsock_request_common_s); + + ret = read_wrapper(fd, pbuf, rsize); + if (ret < 0) + { + return ret; + } + + return sizeof(struct usrsock_request_common_s) + ret; +} + +/**************************************************************************** + * name: usockif_readreqioctl + ****************************************************************************/ + +int usockif_readreqioctl(int fd, FAR struct usrsock_request_buff_s *buf) +{ + FAR struct usrsock_request_ioctl_s *req = &buf->request.ioctl_req; + FAR void *pbuf = &buf->req_ioctl; + int rsize; + + switch (req->cmd) + { + case FIONBIO: + rsize = sizeof(int); + break; + case SIOCLTECMD: + rsize = sizeof(struct lte_ioctl_data_s); + break; + case SIOCSIFFLAGS: + rsize = sizeof(struct ifreq); + break; + case SIOCDENYINETSOCK: + rsize = sizeof(uint8_t); + break; + case SIOCSMSENSTREP: + case SIOCSMSGREFID: + case SIOCSMSSSCA: + rsize = sizeof(struct lte_smsreq_s); + break; + default: + dbg_alt1250("Unsupported command:0x%08lx\n", req->cmd); + return -EINVAL; + break; + } + + if (req->arglen != rsize) + { + dbg_alt1250("unexpected size: %d, expect: %d\n", req->arglen, rsize); + ASSERT(0); + return -EINVAL; + } + + return read_wrapper(fd, pbuf, rsize); +} + +/**************************************************************************** + * name: usockif_readreqaddr + ****************************************************************************/ + +int usockif_readreqaddr(int fd, FAR struct sockaddr_storage *addr, + size_t sz) +{ + if ((sz != sizeof(struct sockaddr_in)) && + (sz != sizeof(struct sockaddr_in6))) + { + dbg_alt1250("Invalid addrlen: %u\n", sz); + return -EINVAL; + } + + return read_wrapper(fd, addr, sz); +} + +/**************************************************************************** + * name: usockif_readreqsendbuf + ****************************************************************************/ + +int usockif_readreqsendbuf(int fd, FAR uint8_t *sendbuf, size_t sz) +{ + return read_wrapper(fd, sendbuf, sz); +} + +/**************************************************************************** + * name: usockif_readreqoption + ****************************************************************************/ + +int usockif_readreqoption(int fd, FAR uint8_t *option, size_t sz) +{ + return read_wrapper(fd, option, sz); +} + +/**************************************************************************** + * name: usockif_discard + ****************************************************************************/ + +void usockif_discard(int fd, size_t sz) +{ + char dummy; + + /* If the seek is called with the exact size, the seek will + * result in an error. In order to avoid this, the process of + * read is performed after seeking the specified size minus one byte. + */ + + if (lseek(fd, sz - 1, SEEK_CUR) >= 0) + { + read(fd, &dummy, 1); + } +} + +/**************************************************************************** + * name: usockif_sendack + ****************************************************************************/ + +int usockif_sendack(int fd, int32_t usock_result, uint32_t usock_xid, + bool inprogress) +{ + struct usrsock_message_req_ack_s ack; + + ack.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + ack.head.flags = + (inprogress == true) ? USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS: 0; + ack.xid = usock_xid; + ack.result = usock_result; + + return write_to_usock(fd, &ack, sizeof(ack)); +} + +/**************************************************************************** + * name: usockif_senddataack + ****************************************************************************/ + +int usockif_senddataack(int fd, int32_t usock_result, uint32_t usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + return send_dataack(fd, usock_xid, usock_result, ackinfo->valuelen, + ackinfo->valuelen_nontrunc, ackinfo->value_ptr, + ackinfo->buf_ptr); +} + +/**************************************************************************** + * name: usockif_sendevent + ****************************************************************************/ + +int usockif_sendevent(int fd, int usockid, int event) +{ + struct usrsock_message_socket_event_s msg; + + msg.head.msgid = USRSOCK_MESSAGE_SOCKET_EVENT; + msg.head.flags = USRSOCK_MESSAGE_FLAG_EVENT; + msg.usockid = usockid; + msg.head.events = event; + + return write_to_usock(fd, &msg, sizeof(msg)); +} diff --git a/lte/alt1250/alt1250_usockif.h b/lte/alt1250/alt1250_usockif.h new file mode 100644 index 000000000..a6802c483 --- /dev/null +++ b/lte/alt1250/alt1250_usockif.h @@ -0,0 +1,129 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_usockif.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_USOCKIF_H +#define __APPS_LTE_ALT1250_ALT1250_USOCKIF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#define DEV_USRSOCK "/dev/usrsock" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IS_IOCTLREQ(r) ((r).request.head.reqid == USRSOCK_REQUEST_IOCTL) +#define IS_REQID_VALID(r) ((r).request.head.reqid < USRSOCK_REQUEST__MAX) +#define USOCKREQID(r) ((r).request.head.reqid) +#define USOCKREQXID(r) ((r).request.head.xid) + +#define usockif_sendclose(fff, iii) \ + usockif_sendevent((fff), (iii), USRSOCK_EVENT_REMOTE_CLOSED) + +#define usockif_sendabort(fff, iii) \ + usockif_sendevent((fff), (iii), USRSOCK_EVENT_ABORT) + +#define usockif_sendtxready(fff, iii) \ + usockif_sendevent((fff), (iii), USRSOCK_EVENT_SENDTO_READY) + +#define usockif_sendrxready(fff, iii) \ + usockif_sendevent((fff), (iii), USRSOCK_EVENT_RECVFROM_AVAIL) + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +union usrsock_requests_u +{ + struct usrsock_request_common_s head; + + struct usrsock_request_socket_s sock_req; + struct usrsock_request_close_s close_req; + struct usrsock_request_bind_s bind_req; + struct usrsock_request_connect_s conn_req; + struct usrsock_request_listen_s listen_req; + struct usrsock_request_accept_s accept_req; + struct usrsock_request_sendto_s send_req; + struct usrsock_request_recvfrom_s recv_req; + struct usrsock_request_setsockopt_s sopt_req; + struct usrsock_request_getsockopt_s gopt_req; + struct usrsock_request_getsockname_s name_req; + struct usrsock_request_getpeername_s pname_req; + struct usrsock_request_ioctl_s ioctl_req; + struct usrsock_request_shutdown_s shutdown_req; +}; +#define USOCK_HDR_SIZE sizeof(struct usrsock_request_common_s) + +union usrsock_request_ioctl_u +{ + struct lte_ioctl_data_s ltecmd; + struct ifreq ifreq; + uint8_t sock_type; + struct lte_smsreq_s smsreq; +}; + +struct usrsock_request_buff_s +{ + union usrsock_requests_u request; + union usrsock_request_ioctl_u req_ioctl; +}; + +struct usock_ackinfo_s +{ + uint16_t valuelen; + uint16_t valuelen_nontrunc; + FAR uint8_t *value_ptr; + FAR uint8_t *buf_ptr; + int usockid; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int init_usock_device(void); +void finalize_usock_device(int fd); +int reset_usock_device(int fd); + +int usockif_readrequest(int fd, FAR struct usrsock_request_buff_s *buf); +int usockif_readreqioctl(int fd, FAR struct usrsock_request_buff_s *buf); +int usockif_readreqaddr(int fd, FAR struct sockaddr_storage *addr, + size_t sz); +int usockif_readreqsendbuf(int fd, FAR uint8_t *sendbuf, size_t sz); +int usockif_readreqoption(int fd, FAR uint8_t *option, size_t sz); + +void usockif_discard(int fd, size_t sz); +int usockif_sendack(int fd, int32_t usock_result, uint32_t usock_xid, + bool inprogress); +int usockif_senddataack(int fd, int32_t usock_result, uint32_t usock_xid, + FAR struct usock_ackinfo_s *ackinfo); +int usockif_sendevent(int fd, int usockid, int event); + +#endif /* __APPS_LTE_ALT1250_ALT1250_USOCKIF_H */ diff --git a/lte/alt1250/alt1250_util.c b/lte/alt1250/alt1250_util.c new file mode 100644 index 000000000..b211df6c1 --- /dev/null +++ b/lte/alt1250/alt1250_util.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_util.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "alt1250_daemon.h" +#include "alt1250_util.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: alt1250_saveapn + ****************************************************************************/ + +void alt1250_saveapn(FAR struct alt1250_s *dev, FAR lte_apn_setting_t *apn) +{ + memcpy(&dev->apn, apn, sizeof(lte_apn_setting_t)); + strncpy(dev->apn_name, (FAR const char *)apn->apn, LTE_APN_LEN); + if ((apn->auth_type != LTE_APN_AUTHTYPE_NONE) && (apn->user_name)) + { + strncpy(dev->user_name, (FAR const char *)apn->user_name, + LTE_APN_USER_NAME_LEN); + } + + if ((apn->auth_type != LTE_APN_AUTHTYPE_NONE) && (apn->password)) + { + strncpy(dev->pass, (FAR const char *)apn->password, + LTE_APN_PASSWD_LEN); + } + + dev->apn.apn = dev->apn_name; + dev->apn.user_name = dev->user_name; + dev->apn.password = dev->pass; +} + +/**************************************************************************** + * Name: alt1250_getapn + ****************************************************************************/ + +void alt1250_getapn(FAR struct alt1250_s *dev, FAR lte_apn_setting_t *apn) +{ + memcpy(apn, &dev->apn, sizeof(lte_apn_setting_t)); +} diff --git a/lte/alt1250/alt1250_util.h b/lte/alt1250/alt1250_util.h new file mode 100644 index 000000000..62108a1e3 --- /dev/null +++ b/lte/alt1250/alt1250_util.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * apps/lte/alt1250/alt1250_util.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_ALT1250_UTIL_H +#define __APPS_LTE_ALT1250_ALT1250_UTIL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "alt1250_daemon.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void alt1250_saveapn(FAR struct alt1250_s *dev, FAR lte_apn_setting_t *apn); +void alt1250_getapn(FAR struct alt1250_s *dev, FAR lte_apn_setting_t *apn); + +#endif /* __APPS_LTE_ALT1250_ALT1250_UTIL_H */ diff --git a/lte/alt1250/callback_handlers/alt1250_evt.c b/lte/alt1250/callback_handlers/alt1250_evt.c new file mode 100644 index 000000000..99d9aea83 --- /dev/null +++ b/lte/alt1250/callback_handlers/alt1250_evt.c @@ -0,0 +1,2148 @@ +/**************************************************************************** + * apps/lte/alt1250/callback_handlers/alt1250_evt.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "alt1250_dbg.h" +#include "lte/lapi.h" +#include "lte/lte_api.h" + +#include "alt1250_evt.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TABLE_CONTENT(cid, acid, outp) \ + { .cmdid = LTE_CMDID_##cid, .altcid = APICMDID_##acid, \ + .outparam = outp, .outparamlen = nitems(outp) } + +#define TABLE_CONTENT_NOARG(cid, acid) \ + { .cmdid = LTE_CMDID_##cid, .altcid = APICMDID_##acid, \ + .outparam = NULL, .outparamlen = 0 } + +#define NCBTABLES (8 + ALTCOM_NSOCKET) /* 8 is the maximum number of events */ + +#define IS_REPORT_API(cmdid) \ + ( LTE_ISCMDGRP_EVENT(cmdid) || cmdid == LTE_CMDID_SETRESTART ) + +#define EVTTASK_NAME "lteevt_task" +#define LAPIEVT_QNAME "/lapievt" + +#define clr_evtcb(info) reg_evtcb(info, 0, NULL) +#define search_free_evtcb() search_evtcb(0) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint64_t lte_set_report_restart_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API +static uint64_t lte_radio_on_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_radio_off_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ +static uint64_t lte_activate_pdn_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API +static uint64_t lte_deactivate_pdn_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_netinfo_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_imscap_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_version_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_phoneno_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_imsi_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_imei_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_pinset_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_set_pinenable_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_change_pin_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_enter_pin_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_localtime_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_operator_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_set_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_set_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_ce_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_set_ce_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_siminfo_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_current_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_current_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +static uint64_t lte_get_quality_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable); +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ +static uint64_t lte_set_report_netinfo_exec_cb(FAR void *cb, +FAR void **cbarg, FAR bool *set_writable); +static uint64_t lte_set_report_simstat_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lte_set_report_localtime_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lte_set_report_quality_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lte_set_report_cellinfo_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t tls_config_verify_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); + +static uint64_t lwm2m_read_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_write_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_exec_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_ovstart_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_ovstop_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_operation_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); +static uint64_t lwm2m_fwupdate_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable); + +static void *get_cbfunc(uint32_t cmdid); +static uint64_t alt1250_evt_search(uint32_t cmdid); + +/**************************************************************************** + * Private Data Types + ****************************************************************************/ + +struct cbinfo_s +{ + uint32_t cmdid; + uint64_t (*cb)(FAR void *cb, FAR void **cbarg, FAR bool *set_writable); +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_LTE_ALT1250_LAUNCH_EVENT_TASK +static int g_cbpid; +#endif + +/* event argument for LTE_CMDID_SETRESTART */ + +static uint32_t g_reason; +static void *g_setrestartargs[] = +{ + &g_reason +}; + +/* event argument for LTE_CMDID_GETVER */ + +static int g_getverret; +static lte_version_t g_ver; +static void *g_getverargs[] = +{ + &g_getverret, &g_ver +}; + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* event argument for LTE_CMDID_RADIOON */ + +static int g_radioonret; +static void *g_radioonargs[] = +{ + &g_radioonret +}; + +/* event argument for LTE_CMDID_RADIOOFF */ + +static int g_radiooffret; +static void *g_radiooffargs[] = +{ + &g_radiooffret +}; + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* event argument for LTE_CMDID_ACTPDN */ + +static int g_actpdnret; +static lte_pdn_t g_pdn; +static void *g_actpdnargs[] = +{ + &g_actpdnret, &g_pdn +}; + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +/* event argument for LTE_CMDID_DEACTPDN */ + +static int g_deactpdnret; +static void *g_deactpdnargs[] = +{ + &g_deactpdnret +}; + +/* event argument for LTE_CMDID_GETNETINFO */ + +static int g_getnetinforet; +static lte_pdn_t g_pdninfo[LTE_SESSION_ID_MAX]; +static lte_netinfo_t g_netinfo = +{ + .pdn_stat = g_pdninfo +}; + +static uint8_t g_pdn_num = LTE_SESSION_ID_MAX; +static void *g_netinfoargs[] = +{ + &g_getnetinforet, &g_netinfo, &g_pdn_num +}; + +/* event argument for LTE_CMDID_IMSCAP */ + +static int g_imscapret; +static bool g_imscap; +static void *g_imscapargs[] = +{ + &g_imscapret, &g_imscap +}; + +/* event argument for LTE_CMDID_GETPHONE */ + +static int g_getphoneret; +static uint8_t g_getphoneerrcause; +static char g_phoneno[LTE_PHONENO_LEN]; +#ifndef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +static size_t g_phonenolen = LTE_PHONENO_LEN; +#endif +static void *g_getphoneargs[] = +{ +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &g_getphoneret, &g_getphoneerrcause, g_phoneno +#else + &g_getphoneret, &g_getphoneerrcause, g_phoneno, &g_phonenolen +#endif +}; + +/* event argument for LTE_CMDID_GETIMSI */ + +static int g_getimsiret; +static uint8_t g_getimsierrcause; +static char g_imsi[LTE_SIMINFO_IMSI_LEN]; +#ifndef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +static size_t g_imsilen = LTE_SIMINFO_IMSI_LEN; +#endif +static void *g_getimsiargs[] = +{ +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &g_getimsiret, &g_getimsierrcause, g_imsi +#else + &g_getimsiret, &g_getimsierrcause, g_imsi, &g_imsilen +#endif +}; + +/* event argument for LTE_CMDID_GETIMEI */ + +static int g_getimeiret; +static char g_imei[LTE_IMEI_LEN]; +#ifndef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +static size_t g_imeilen = LTE_IMEI_LEN; +#endif +static void *g_getimeiargs[] = +{ +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &g_getimeiret, g_imei +#else + &g_getimeiret, g_imei, &g_imeilen +#endif +}; + +/* event argument for LTE_CMDID_GETPINSET */ + +static int g_getpinsetret; +static lte_getpin_t g_pinset; +static void *g_getpinsetargs[] = +{ + &g_getpinsetret, &g_pinset +}; + +/* event argument for LTE_CMDID_PINENABLE */ + +static int g_pinenableret; +static uint8_t g_pineattleft; +static void *g_pinenableargs[] = +{ + &g_pinenableret, &g_pineattleft +}; + +/* event argument for LTE_CMDID_CHANGEPIN */ + +static int g_changepinret; +static uint8_t g_chanattleft; +static void *g_changepinargs[] = +{ + &g_changepinret, &g_chanattleft +}; + +/* event argument for LTE_CMDID_ENTERPIN */ + +static int g_enterpinret; +static uint8_t g_entpinsimstat; +static uint8_t g_entpinattleft; +static void *g_enterpinargs[] = +{ + &g_enterpinret, &g_entpinsimstat, &g_entpinattleft +}; + +/* event argument for LTE_CMDID_GETLTIME */ + +static int g_getltimeret; +static lte_localtime_t g_ltime; +static void *g_getltimeargs[] = +{ + &g_getltimeret, &g_ltime +}; + +/* event argument for LTE_CMDID_GETOPER */ + +static int g_getoperret; +static char g_oper[LTE_OPERATOR_LEN]; +#ifndef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +static size_t g_operlen = LTE_OPERATOR_LEN; +#endif +static void *g_getoperargs[] = +{ +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &g_getoperret, g_oper +#else + &g_getoperret, g_oper, &g_operlen +#endif +}; + +/* event argument for LTE_CMDID_GETEDRX */ + +static int g_getedrxret; +static lte_edrx_setting_t g_getedrx; +static bool g_is_getedrxevt; +static void *g_getedrxargs[] = +{ + &g_getedrxret, &g_getedrx, &g_is_getedrxevt +}; + +/* event argument for LTE_CMDID_SETEDRX */ + +static int g_setedrxret; +static void *g_setedrxargs[] = +{ + &g_setedrxret +}; + +/* event argument for LTE_CMDID_GETPSM */ + +static int g_getpsmret; +static lte_psm_setting_t g_getpsm; +static bool g_is_getpsmevt; +static void *g_getpsmargs[] = +{ + &g_getpsmret, &g_getpsm, &g_is_getpsmevt +}; + +/* event argument for LTE_CMDID_SETPSM */ + +static int g_setpsmret; +static void *g_setpsmargs[] = +{ + &g_setpsmret +}; + +/* event argument for LTE_CMDID_GETCE */ + +static int g_getceret; +static lte_ce_setting_t g_getce; +static void *g_getceargs[] = +{ + &g_getceret, &g_getce +}; + +/* event argument for LTE_CMDID_SETCE */ + +static int g_setceret; +static void *g_setceargs[] = +{ + &g_setceret +}; + +/* event argument for LTE_CMDID_GETSIMINFO */ + +static int g_setsiminforet; +static lte_siminfo_t g_siminfo; +static void *g_getsiminfoargs[] = +{ + &g_setsiminforet, &g_siminfo +}; + +/* event argument for LTE_CMDID_GETCEDRX */ + +static int g_getcedrxret; +static lte_edrx_setting_t g_getcedrx; +static bool g_is_getcedrxevt; +static void *g_getcedrxargs[] = +{ + &g_getcedrxret, &g_getcedrx, &g_is_getcedrxevt +}; + +/* event argument for LTE_CMDID_GETCPSM */ + +static int g_getcpsmret; +static lte_psm_setting_t g_getcpsm; +static bool g_is_getcpsmevt; +static void *g_getcpsmargs[] = +{ + &g_getcpsmret, &g_getcpsm, &g_is_getcpsmevt +}; + +/* event argument for LTE_CMDID_GETQUAL */ + +static int g_getqualret; +static lte_quality_t g_getqual; +static void *g_getqualargs[] = +{ + &g_getqualret, &g_getqual +}; + +/* event argument for LTE_CMDID_GETCELL */ + +static int g_getcellret; +static lte_neighbor_cell_t g_neighbors[LTE_NEIGHBOR_CELL_MAX]; +static lte_cellinfo_t g_getcell = +{ + .neighbors = g_neighbors +} +; +static void *g_getcellargs[] = +{ + &g_getcellret, &g_getcell +}; + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +/* event argument for LTE_CMDID_GETRAT */ + +static int g_getratret; +static void *g_getratargs[] = +{ + &g_getratret +}; + +/* event argument for LTE_CMDID_SETRAT */ + +static int g_setratret; +static void *g_setratargs[] = +{ + &g_setratret +}; + +/* event argument for LTE_CMDID_GETRATINFO */ + +static int g_getratinforet; +static lte_ratinfo_t g_ratinfo; +static void *g_getratinfoargs[] = +{ + &g_getratinforet, &g_ratinfo +}; + +/* event argument for LTE_CMDID_REPNETINFO */ + +static lte_pdn_t g_reppdninfo[LTE_SESSION_ID_MAX]; +static lte_netinfo_t g_repnetinfo = +{ + .pdn_stat = g_reppdninfo +}; + +static uint8_t g_ndnsaddrs; +static struct sockaddr_storage g_dnsaddrs[ALTCOM_DNS_SERVERS]; +static void *g_repnetinfoargs[] = +{ + &g_repnetinfo, &g_ndnsaddrs, g_dnsaddrs +}; + +/* event argument for LTE_CMDID_REPSIMSTAT */ + +static uint32_t g_repsimstat; +static void *g_repsimstatargs[] = +{ + &g_repsimstat +}; + +/* event argument for LTE_CMDID_REPLTIME */ + +static lte_localtime_t g_repltime; +static void *g_repltimeargs[] = +{ + &g_repltime +}; + +/* event argument for LTE_CMDID_REPQUAL */ + +static lte_quality_t g_repqual; +static void *g_repqualargs[] = +{ + &g_repqual +}; + +/* event argument for LTE_CMDID_REPCELL */ + +static lte_neighbor_cell_t g_repneighbors[LTE_NEIGHBOR_CELL_MAX]; +static lte_cellinfo_t g_repcell = +{ + .neighbors = g_repneighbors +}; + +static void *g_repcellargs[] = +{ + &g_repcell +}; + +/* event argument for LTE_CMDID_GETERRINFO */ + +static lte_errinfo_t g_geterrinfo; +static void *g_geterrinfoargs[] = +{ + &g_geterrinfo +}; + +/* event argument for LTE_CMDID_TLS_CONFIG_VERIFY_CALLBACK */ + +static uint32_t g_crt; +static int32_t g_depth; +static void *g_vrfycbargs[] = +{ + &g_crt, &g_depth +}; + +/* event argument for LTE_CMDID_SMS_REPORT_RECV */ + +static uint16_t g_smsmsg_index; +static uint16_t g_smsrecv_sz; +static uint8_t g_sms_maxnum; +static uint8_t g_sms_seqnum; +static struct sms_deliver_msg_max_s g_recvmsg; +static void *g_smsreportargs[] = +{ + &g_smsmsg_index, &g_smsrecv_sz, &g_sms_maxnum, &g_sms_seqnum, &g_recvmsg +}; + +/* event argument for LTE_CMDID_LWM2M_READ_EVT */ + +static struct lwm2mstub_instance_s g_lwm2mread_inst; +static void *g_lwm2mreadargs[] = +{ + NULL, NULL, &g_lwm2mread_inst +}; + +/* event argument for LTE_CMDID_LWM2M_WRITE_EVT */ + +static struct lwm2mstub_instance_s g_lwm2mwrite_inst; +static char g_lwm2mwrite_value[LWM2MSTUB_MAX_WRITE_SIZE]; +static void *g_lwm2mwriteargs[] = +{ + NULL, NULL, &g_lwm2mwrite_inst, g_lwm2mwrite_value, + NULL, (void *)LWM2MSTUB_MAX_WRITE_SIZE +}; + +/* event argument for LTE_CMDID_LWM2M_EXEC_EVT */ + +static struct lwm2mstub_instance_s g_lwm2mexec_inst; +static void *g_lwm2mexecargs[] = +{ + NULL, NULL, &g_lwm2mexec_inst, NULL +}; + +/* event argument for LTE_CMDID_LWM2M_OVSTART_EVT */ + +static struct lwm2mstub_instance_s g_lwm2movstart_inst; +static char g_lwm2movstart_token[LWM2MSTUB_MAX_TOKEN_SIZE]; +static struct lwm2mstub_ovcondition_s g_lwm2movstart_cond; +static void *g_lwm2movstartargs[] = +{ + NULL, NULL, &g_lwm2movstart_inst, g_lwm2movstart_token, + (void *)LWM2MSTUB_MAX_TOKEN_SIZE, &g_lwm2movstart_cond +}; + +/* event argument for LTE_CMDID_LWM2M_OVSTOP_EVT */ + +static struct lwm2mstub_instance_s g_lwm2movstop_inst; +static char g_lwm2movstop_token[LWM2MSTUB_MAX_TOKEN_SIZE]; +static void *g_lwm2movstopargs[] = +{ + NULL, NULL, &g_lwm2movstop_inst, &g_lwm2movstop_token, + (void *)LWM2MSTUB_MAX_TOKEN_SIZE +}; + +/* event argument for LTE_CMDID_LWM2M_SERVEROP_EVT */ + +static void *g_lwm2moperationargs[] = +{ + NULL +}; + +/* event argument for LTE_CMDID_LWM2M_FWUP_EVT */ + +static void *g_lwm2mfwupargs[] = +{ + NULL +}; + +static struct alt_evtbuffer_s g_evtbuff; +static struct alt_evtbuf_inst_s g_evtbuffers[] = +{ + TABLE_CONTENT(SETRESTART, POWER_ON, g_setrestartargs), + TABLE_CONTENT(GETVER, GET_VERSION, g_getverargs), +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + TABLE_CONTENT(RADIOON, RADIO_ON, g_radioonargs), + TABLE_CONTENT(RADIOOFF, RADIO_OFF, g_radiooffargs), +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + TABLE_CONTENT(ACTPDN, ACTIVATE_PDN, g_actpdnargs), +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + TABLE_CONTENT(DEACTPDN, DEACTIVATE_PDN, g_deactpdnargs), + TABLE_CONTENT(GETNETINFO, GET_NETINFO, g_netinfoargs), + TABLE_CONTENT(IMSCAP, GET_IMS_CAP, g_imscapargs), + TABLE_CONTENT(GETPHONE, GET_PHONENO, g_getphoneargs), + TABLE_CONTENT(GETIMSI, GET_IMSI, g_getimsiargs), + TABLE_CONTENT(GETIMEI, GET_IMEI, g_getimeiargs), + TABLE_CONTENT(GETPINSET, GET_PINSET, g_getpinsetargs), + TABLE_CONTENT(PINENABLE, SET_PIN_LOCK, g_pinenableargs), + TABLE_CONTENT(CHANGEPIN, SET_PIN_CODE, g_changepinargs), + TABLE_CONTENT(ENTERPIN, ENTER_PIN, g_enterpinargs), + TABLE_CONTENT(GETLTIME, GET_LTIME, g_getltimeargs), + TABLE_CONTENT(GETOPER, GET_OPERATOR, g_getoperargs), + TABLE_CONTENT(GETEDRX, GET_EDRX, g_getedrxargs), + TABLE_CONTENT(SETEDRX, SET_EDRX, g_setedrxargs), + TABLE_CONTENT(GETPSM, GET_PSM, g_getpsmargs), + TABLE_CONTENT(SETPSM, SET_PSM, g_setpsmargs), + TABLE_CONTENT(GETCE, GET_CE, g_getceargs), + TABLE_CONTENT(SETCE, SET_CE, g_setceargs), + TABLE_CONTENT(GETSIMINFO, GET_SIMINFO, g_getsiminfoargs), + TABLE_CONTENT(GETCEDRX, GET_DYNAMICEDRX, g_getcedrxargs), + TABLE_CONTENT(GETCPSM, GET_DYNAMICPSM, g_getcpsmargs), + TABLE_CONTENT(GETQUAL, GET_QUALITY, g_getqualargs), + TABLE_CONTENT(GETCELL, GET_CELLINFO, g_getcellargs), +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + TABLE_CONTENT(GETRAT, GET_RAT, g_getratargs), + TABLE_CONTENT(SETRAT, SET_RAT, g_setratargs), + TABLE_CONTENT(GETRATINFO, GET_RAT, g_getratinfoargs), + TABLE_CONTENT(REPNETINFO, REPORT_NETINFO, g_repnetinfoargs), + TABLE_CONTENT_NOARG(REPEVT_DUMMY, REPORT_EVT), + TABLE_CONTENT(REPSIMSTAT, UNKNOWN, g_repsimstatargs), + TABLE_CONTENT(REPLTIME, UNKNOWN, g_repltimeargs), + TABLE_CONTENT(REPQUAL, REPORT_QUALITY, g_repqualargs), + TABLE_CONTENT(REPCELL, REPORT_CELLINFO, g_repcellargs), + TABLE_CONTENT(GETERRINFO, ERRINFO, g_geterrinfoargs), + TABLE_CONTENT(TLS_CONFIG_VERIFY, TLS_CONFIG_VERIFY_CALLBACK, + g_vrfycbargs), + TABLE_CONTENT(SMS_REPORT_RECV, SMS_REPORT_RECV, g_smsreportargs), + + /* For Unsolicited event */ + + TABLE_CONTENT_NOARG(LWM2M_URC_DUMMY, URC_EVENT), + TABLE_CONTENT(LWM2M_READ_EVT, UNKNOWN, g_lwm2mreadargs), + TABLE_CONTENT(LWM2M_WRITE_EVT, UNKNOWN, g_lwm2mwriteargs), + TABLE_CONTENT(LWM2M_EXEC_EVT, UNKNOWN, g_lwm2mexecargs), + TABLE_CONTENT(LWM2M_OVSTART_EVT, UNKNOWN, g_lwm2movstartargs), + TABLE_CONTENT(LWM2M_OVSTOP_EVT, UNKNOWN, g_lwm2movstopargs), + TABLE_CONTENT(LWM2M_SERVEROP_EVT, UNKNOWN, g_lwm2moperationargs), + TABLE_CONTENT(LWM2M_FWUP_EVT, UNKNOWN, g_lwm2mfwupargs), + + /* Add the command ID of LTE_CMDID_SELECT to the table so that the driver + * can identify the bitmap of the select event. + * The output parameter is NULL since a container for select is used. + */ + + TABLE_CONTENT_NOARG(SELECT, SOCK_SELECT) +}; + +static struct cbinfo_s g_execbtable[] = +{ + {LTE_CMDID_SETRESTART, lte_set_report_restart_exec_cb}, +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + {LTE_CMDID_GETVER, lte_get_version_exec_cb}, + {LTE_CMDID_RADIOON, lte_radio_on_exec_cb}, + {LTE_CMDID_RADIOOFF, lte_radio_off_exec_cb}, +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + {LTE_CMDID_ACTPDN, lte_activate_pdn_exec_cb}, +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + {LTE_CMDID_DEACTPDN, lte_deactivate_pdn_exec_cb}, + {LTE_CMDID_GETNETINFO, lte_get_netinfo_exec_cb}, + {LTE_CMDID_IMSCAP, lte_get_imscap_exec_cb}, + {LTE_CMDID_GETPHONE, lte_get_phoneno_exec_cb}, + {LTE_CMDID_GETIMSI, lte_get_imsi_exec_cb}, + {LTE_CMDID_GETIMEI, lte_get_imei_exec_cb}, + {LTE_CMDID_GETPINSET, lte_get_pinset_exec_cb}, + {LTE_CMDID_PINENABLE, lte_set_pinenable_exec_cb}, + {LTE_CMDID_CHANGEPIN, lte_change_pin_exec_cb}, + {LTE_CMDID_ENTERPIN, lte_enter_pin_exec_cb}, + {LTE_CMDID_GETLTIME, lte_get_localtime_exec_cb}, + {LTE_CMDID_GETOPER, lte_get_operator_exec_cb}, + {LTE_CMDID_GETEDRX, lte_get_edrx_exec_cb}, + {LTE_CMDID_SETEDRX, lte_set_edrx_exec_cb}, + {LTE_CMDID_GETPSM, lte_get_psm_exec_cb}, + {LTE_CMDID_SETPSM, lte_set_psm_exec_cb}, + {LTE_CMDID_GETCE, lte_get_ce_exec_cb}, + {LTE_CMDID_SETCE, lte_set_ce_exec_cb}, + {LTE_CMDID_GETSIMINFO, lte_get_siminfo_exec_cb}, + {LTE_CMDID_GETCEDRX, lte_get_current_edrx_exec_cb}, + {LTE_CMDID_GETCPSM, lte_get_current_psm_exec_cb}, + {LTE_CMDID_GETQUAL, lte_get_quality_exec_cb}, +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + {LTE_CMDID_REPNETINFO, lte_set_report_netinfo_exec_cb}, + {LTE_CMDID_REPSIMSTAT, lte_set_report_simstat_exec_cb}, + {LTE_CMDID_REPLTIME, lte_set_report_localtime_exec_cb}, + {LTE_CMDID_REPQUAL, lte_set_report_quality_exec_cb}, + {LTE_CMDID_REPCELL, lte_set_report_cellinfo_exec_cb}, + {LTE_CMDID_TLS_CONFIG_VERIFY, tls_config_verify_exec_cb}, + {LTE_CMDID_LWM2M_READ_EVT, lwm2m_read_evt_cb}, + {LTE_CMDID_LWM2M_WRITE_EVT, lwm2m_write_evt_cb}, + {LTE_CMDID_LWM2M_EXEC_EVT, lwm2m_exec_evt_cb}, + {LTE_CMDID_LWM2M_OVSTART_EVT, lwm2m_ovstart_evt_cb}, + {LTE_CMDID_LWM2M_OVSTOP_EVT, lwm2m_ovstop_evt_cb}, + {LTE_CMDID_LWM2M_SERVEROP_EVT, lwm2m_operation_evt_cb}, + {LTE_CMDID_LWM2M_FWUP_EVT, lwm2m_fwupdate_evt_cb}, +}; + +static struct cbinfo_s g_cbtable[NCBTABLES]; +static sem_t g_cbtablelock; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint64_t lte_set_report_restart_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + restart_report_cb_t callback = (restart_report_cb_t)cb; + FAR uint32_t *param = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*param); + } + + return 0ULL; +} + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +static uint64_t lte_radio_on_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + radio_on_cb_t callback = (radio_on_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +static uint64_t lte_radio_off_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + radio_off_cb_t callback = (radio_off_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +static uint64_t lte_activate_pdn_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + activate_pdn_cb_t callback = (activate_pdn_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_pdn_t *pdn = (FAR lte_pdn_t *)cbarg[1]; + + if (callback) + { + callback(*result, pdn); + } + + return 0ULL; +} + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +static uint64_t lte_deactivate_pdn_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + deactivate_pdn_cb_t callback = (deactivate_pdn_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +static uint64_t lte_get_netinfo_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_netinfo_cb_t callback = (get_netinfo_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_netinfo_t *info = (FAR lte_netinfo_t *)cbarg[1]; + + if (callback) + { + callback(*result, info); + } + + return 0ULL; +} + +static uint64_t lte_get_imscap_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_imscap_cb_t callback = (get_imscap_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR bool *imscap = (FAR bool *)cbarg[1]; + + if (callback) + { + callback(*result, *imscap); + } + + return 0ULL; +} + +static uint64_t lte_get_version_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_ver_cb_t callback = (get_ver_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_version_t *version = (FAR lte_version_t *)cbarg[1]; + + if (callback) + { + callback(*result, version); + } + + return 0ULL; +} + +static uint64_t lte_get_phoneno_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_phoneno_cb_t callback = (get_phoneno_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR uint8_t *errcause = (FAR uint8_t *)cbarg[1]; + FAR char *phoneno = (FAR char *)cbarg[2]; + + if (callback) + { + callback(*result, *errcause, phoneno); + } + + return 0ULL; +} + +static uint64_t lte_get_imsi_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_imsi_cb_t callback = (get_imsi_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR uint8_t *errcause = (FAR uint8_t *)cbarg[1]; + FAR char *imsi = (FAR char *)cbarg[2]; + + if (callback) + { + callback(*result, *errcause, imsi); + } + + return 0ULL; +} + +static uint64_t lte_get_imei_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_imei_cb_t callback = (get_imei_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR char *imei = (FAR char *)cbarg[1]; + + if (callback) + { + callback(*result, imei); + } + + return 0ULL; +} + +static uint64_t lte_get_pinset_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_pinset_cb_t callback = (get_pinset_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_getpin_t *pinset = (FAR lte_getpin_t *)cbarg[1]; + + if (callback) + { + callback(*result, pinset); + } + + return 0ULL; +} + +static uint64_t lte_set_pinenable_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + set_pinenable_cb_t callback = (set_pinenable_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR uint8_t *attemptsleft = (FAR uint8_t *)cbarg[1]; + + if (callback) + { + callback(*result, *attemptsleft); + } + + return 0ULL; +} + +static uint64_t lte_change_pin_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + change_pin_cb_t callback = (change_pin_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR uint8_t *attemptsleft = (FAR uint8_t *)cbarg[1]; + + if (callback) + { + callback(*result, *attemptsleft); + } + + return 0ULL; +} + +static uint64_t lte_enter_pin_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + enter_pin_cb_t callback = (enter_pin_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR uint8_t *simstat = (FAR uint8_t *)cbarg[1]; + FAR uint8_t *attemptsleft = (FAR uint8_t *)cbarg[2]; + + if (callback) + { + callback(*result, *simstat, *attemptsleft); + } + + return 0ULL; +} + +static uint64_t lte_get_localtime_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_localtime_cb_t callback = (get_localtime_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_localtime_t *localtime = (FAR lte_localtime_t *)cbarg[1]; + + if (callback) + { + callback(*result, localtime); + } + + return 0ULL; +} + +static uint64_t lte_get_operator_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_operator_cb_t callback = (get_operator_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR char *oper = (FAR char *)cbarg[1]; + + if (callback) + { + callback(*result, oper); + } + + return 0ULL; +} + +static uint64_t lte_get_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_edrx_cb_t callback = (get_edrx_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_edrx_setting_t *settings = (FAR lte_edrx_setting_t *)cbarg[1]; + FAR bool *is_getedrxevt = (FAR bool *)cbarg[2]; + + if (!(*is_getedrxevt)) + { + return alt1250_evt_search(LTE_CMDID_GETCEDRX); + } + + if (callback) + { + callback(*result, settings); + *is_getedrxevt = false; + } + + return 0ULL; +} + +static uint64_t lte_set_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + set_edrx_cb_t callback = (set_edrx_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +static uint64_t lte_get_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_psm_cb_t callback = (get_psm_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_psm_setting_t *settings = (FAR lte_psm_setting_t *)cbarg[1]; + FAR bool *is_getpsmevt = (FAR bool *)cbarg[2]; + + if (!(*is_getpsmevt)) + { + return alt1250_evt_search(LTE_CMDID_GETCPSM); + } + + if (callback) + { + callback(*result, settings); + *is_getpsmevt = false; + } + + return 0ULL; +} + +static uint64_t lte_set_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + set_psm_cb_t callback = (set_psm_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +static uint64_t lte_get_ce_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_ce_cb_t callback = (get_ce_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_ce_setting_t *settings = (FAR lte_ce_setting_t *)cbarg[1]; + + if (callback) + { + callback(*result, settings); + } + + return 0ULL; +} + +static uint64_t lte_set_ce_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + set_ce_cb_t callback = (set_ce_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*result); + } + + return 0ULL; +} + +static uint64_t lte_get_siminfo_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_siminfo_cb_t callback = (get_siminfo_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_siminfo_t *siminfo = (FAR lte_siminfo_t *)cbarg[1]; + + if (callback) + { + callback(*result, siminfo); + } + + return 0ULL; +} + +static uint64_t lte_get_current_edrx_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_current_edrx_cb_t callback = (get_current_edrx_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_edrx_setting_t *settings = (FAR lte_edrx_setting_t *)cbarg[1]; + FAR bool *is_getcedrxevt = (FAR bool *)cbarg[2]; + + if (!(*is_getcedrxevt)) + { + return alt1250_evt_search(LTE_CMDID_GETEDRX); + } + + if (callback) + { + callback(*result, settings); + *is_getcedrxevt = false; + } + + return 0ULL; +} + +static uint64_t lte_get_current_psm_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_current_psm_cb_t callback = (get_current_psm_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_psm_setting_t *settings = (FAR lte_psm_setting_t *)cbarg[1]; + FAR bool *is_getcpsmevt = (FAR bool *)cbarg[2]; + + if (!(*is_getcpsmevt)) + { + return alt1250_evt_search(LTE_CMDID_GETPSM); + } + + if (callback) + { + callback(*result, settings); + *is_getcpsmevt = false; + } + + return 0ULL; +} + +static uint64_t lte_get_quality_exec_cb(FAR void *cb, FAR void **cbarg, + FAR bool *set_writable) +{ + get_quality_cb_t callback = (get_quality_cb_t)cb; + FAR uint32_t *result = (FAR uint32_t *)cbarg[0]; + FAR lte_quality_t *quality = (FAR lte_quality_t *)cbarg[1]; + + if (callback) + { + callback(*result, quality); + } + + return 0ULL; +} + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +static uint64_t lte_set_report_netinfo_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + netinfo_report_cb_t callback = (netinfo_report_cb_t)cb; + FAR lte_netinfo_t *info = (FAR lte_netinfo_t *)cbarg[0]; + FAR uint8_t ndnsaddrs = *((FAR uint8_t *)cbarg[1]); + FAR struct sockaddr_storage *dnsaddr = + (FAR struct sockaddr_storage *)cbarg[2]; +#if defined(CONFIG_NETDB_DNSCLIENT) + socklen_t addrlen; + uint8_t i; +#endif + +#if defined(CONFIG_NETDB_DNSCLIENT) + DEBUGASSERT(ndnsaddrs <= ALTCOM_DNS_SERVERS); + + ndnsaddrs = (ndnsaddrs > ALTCOM_DNS_SERVERS) ? + ALTCOM_DNS_SERVERS : ndnsaddrs; + + for (i = 0; (i < ndnsaddrs) && (i < CONFIG_NETDB_DNSSERVER_NAMESERVERS); + i++) + { + addrlen = (dnsaddr[i].ss_family == AF_INET) ? + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + dns_add_nameserver((FAR const struct sockaddr *)&dnsaddr[i], addrlen); + } +#endif + + if (callback) + { + callback(info); + } + + return 0ULL; +} + +static uint64_t lte_set_report_simstat_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + simstat_report_cb_t callback = (simstat_report_cb_t)cb; + FAR uint32_t *simstat = (FAR uint32_t *)cbarg[0]; + + if (callback) + { + callback(*simstat); + } + + return 0ULL; +} + +static uint64_t lte_set_report_localtime_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + localtime_report_cb_t callback = (localtime_report_cb_t)cb; + FAR lte_localtime_t *localtime = (FAR lte_localtime_t *)cbarg[0]; + + if (callback) + { + callback(localtime); + } + + return 0ULL; +} + +static uint64_t lte_set_report_quality_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + quality_report_cb_t callback = (quality_report_cb_t)cb; + FAR lte_quality_t *quality = (FAR lte_quality_t *)cbarg[0]; + + if (callback) + { + callback(quality); + } + + return 0ULL; +} + +static uint64_t lte_set_report_cellinfo_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + cellinfo_report_cb_t callback = (cellinfo_report_cb_t)cb; + FAR lte_cellinfo_t *cellinfo = (FAR lte_cellinfo_t *)cbarg[0]; + + if (callback) + { + callback(cellinfo); + } + + return 0ULL; +} + +static uint64_t tls_config_verify_exec_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + void (*callback)(FAR void **cbarg) = cb; + void *arg[2]; + + uint32_t crt = *((FAR uint32_t *)cbarg[0]); + int32_t depth = *((FAR int32_t *)cbarg[1]); + + arg[0] = &crt; + arg[1] = &depth; + + /* Here, need to set the status of the event argument to "writable". + * The callback function below will send a response command to ALT1250 + * for this event. After receiving the response command, + * ALT1250 may send this event again. + * If the status of the event argument is "not writable", the ALTCOM driver + * will discard this event. + */ + + alt1250_setevtarg_writable(LTE_CMDID_TLS_CONFIG_VERIFY); + *set_writable = true; + + /* Use a callback to pass event arguments. */ + + callback(arg); + + return 0ULL; +} + +static uint64_t lwm2m_read_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_read_cb_t callback = (lwm2mstub_read_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0], (int)cbarg[1], + (struct lwm2mstub_instance_s *)cbarg[2]); + } + + return 0ULL; +} + +static uint64_t lwm2m_write_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_write_cb_t callback = (lwm2mstub_write_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0], (int)cbarg[1], + (struct lwm2mstub_instance_s *)cbarg[2], + (char *)cbarg[3], (int)cbarg[4]); + } + + return 0ULL; +} + +static uint64_t lwm2m_exec_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_exec_cb_t callback = (lwm2mstub_exec_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0], (int)cbarg[1], + (struct lwm2mstub_instance_s *)cbarg[2]); + } + + return 0ULL; +} + +static uint64_t lwm2m_ovstart_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_ovstart_cb_t callback = (lwm2mstub_ovstart_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0], (int)cbarg[1], + (struct lwm2mstub_instance_s *)cbarg[2], (char *)cbarg[3], + (struct lwm2mstub_ovcondition_s *)cbarg[5]); + } + + return 0ULL; +} + +static uint64_t lwm2m_ovstop_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_ovstop_cb_t callback = (lwm2mstub_ovstop_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0], (int)cbarg[1], + (struct lwm2mstub_instance_s *)cbarg[2], (char *)cbarg[3]); + } + + return 0ULL; +} + +static uint64_t lwm2m_operation_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_operation_cb_t callback = (lwm2mstub_operation_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0]); + } + + return 0ULL; +} + +static uint64_t lwm2m_fwupdate_evt_cb(FAR void *cb, + FAR void **cbarg, FAR bool *set_writable) +{ + lwm2mstub_fwupstate_cb_t callback = (lwm2mstub_fwupstate_cb_t)cb; + + if (callback) + { + callback((int)cbarg[0]); + } + + return 0ULL; +} + +/**************************************************************************** + * Name: evtbuffer_init + ****************************************************************************/ + +static FAR struct alt_evtbuffer_s *evtbuffer_init(void) +{ + int i; + + for (i = 0; i < nitems(g_evtbuffers); i++) + { + nxmutex_init(&g_evtbuffers[i].stat_lock); + g_evtbuffers[i].stat = ALTEVTBUF_ST_WRITABLE; + } + + g_evtbuff.ninst = nitems(g_evtbuffers); + g_evtbuff.inst = g_evtbuffers; + + return &g_evtbuff; +} + +/**************************************************************************** + * Name: clear_callback + ****************************************************************************/ + +static void clear_callback(uint32_t cmdid) +{ + int i; + + sem_wait(&g_cbtablelock); + + for (i = 0; i < nitems(g_cbtable); i++) + { + if (g_cbtable[i].cmdid == cmdid) + { + g_cbtable[i].cmdid = 0; + g_cbtable[i].cb = NULL; + break; + } + } + + sem_post(&g_cbtablelock); +} + +/**************************************************************************** + * Name: errno2result + ****************************************************************************/ + +static void errno2result(FAR int32_t *result_ptr) +{ + if (result_ptr && *result_ptr < 0) + { + if (*result_ptr == -ECANCELED) + { + *result_ptr = LTE_RESULT_CANCEL; + } + else + { + *result_ptr = LTE_RESULT_ERROR; + } + } +} + +/**************************************************************************** + * Name: exec_callback + ****************************************************************************/ + +static uint64_t exec_callback(uint32_t cmdid, + uint64_t (*func)(FAR void *cb, FAR void **arg, FAR bool *set_writable), + FAR void **arg, FAR bool *set_writable) +{ + uint64_t evtbitmap = 0ULL; + FAR int32_t *result = NULL; + FAR void *callback = NULL; + + callback = get_cbfunc(cmdid); + if (callback) + { + if (!IS_REPORT_API(cmdid)) + { + /* APIs that have result as a callback argument + * change the value before execution. + */ + + result = (int32_t *)arg[0]; + errno2result(result); + } + + evtbitmap = func(callback, arg, set_writable); + return evtbitmap; + } + + /* When callback is not found, + * GETPSM and GETEDRX, REPNETINFO, REPSIMSTAT, REPLTIME will + * execute func() and update the evtbitmap + */ + + if (cmdid == LTE_CMDID_GETPSM || cmdid == LTE_CMDID_GETEDRX || + cmdid == LTE_CMDID_REPNETINFO || cmdid == LTE_CMDID_REPSIMSTAT || + cmdid == LTE_CMDID_REPLTIME) + { + evtbitmap = func(NULL, arg, set_writable); + } + + return evtbitmap; +} + +/**************************************************************************** + * Name: get_evtarg + ****************************************************************************/ + +static FAR void **get_evtarg(int idx) +{ + FAR alt_evtbuf_inst_t *inst = &g_evtbuffers[idx]; + + return inst->outparam; +} + +/**************************************************************************** + * Name: get_cmdid_byidx + ****************************************************************************/ + +static FAR uint32_t get_cmdid_byidx(int idx) +{ + FAR alt_evtbuf_inst_t *inst = &g_evtbuffers[idx]; + + return inst->cmdid; +} + +/**************************************************************************** + * Name: update_evtarg_writable + ****************************************************************************/ + +static void update_evtarg_writable(int idx) +{ + FAR alt_evtbuf_inst_t *inst = &g_evtbuffers[idx]; + + nxmutex_lock(&inst->stat_lock); + + inst->stat = ALTEVTBUF_ST_WRITABLE; + + nxmutex_unlock(&inst->stat_lock); +} + +/**************************************************************************** + * Name: update_evtarg_writableall + ****************************************************************************/ + +static void update_evtarg_writableall(void) +{ + int idx; + + for (idx = 0; idx < nitems(g_evtbuffers); idx++) + { + FAR alt_evtbuf_inst_t *inst = &g_evtbuffers[idx]; + + nxmutex_lock(&inst->stat_lock); + + inst->stat = ALTEVTBUF_ST_WRITABLE; + + nxmutex_unlock(&inst->stat_lock); + } +} + +/**************************************************************************** + * Name: get_execfunc + ****************************************************************************/ + +static void *get_execfunc(int idx) +{ + int i; + uint32_t cmdid; + + cmdid = get_cmdid_byidx(idx); + + for (i = 0; i < nitems(g_execbtable); i++) + { + if (g_execbtable[i].cmdid == cmdid) + { + return g_execbtable[i].cb; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: get_cbfunc + ****************************************************************************/ + +static void *get_cbfunc(uint32_t cmdid) +{ + int i; + FAR void *ret = NULL; + + sem_wait(&g_cbtablelock); + + for (i = 0; i < nitems(g_cbtable); i++) + { + if (g_cbtable[i].cmdid == cmdid) + { + ret = g_cbtable[i].cb; + break; + } + } + + sem_post(&g_cbtablelock); + + return ret; +} + +/**************************************************************************** + * Name: alt1250_search_execcb + ****************************************************************************/ + +static uint64_t alt1250_search_execcb(uint64_t evtbitmap) +{ + int idx; + uint64_t ret = 0ULL; + uint64_t l_evtbitmap = 0ULL; + uint64_t (*func)(FAR void *cb, FAR void **arg, FAR bool *set_writable); + bool set_writable; + + for (idx = 0; idx < nitems(g_evtbuffers); idx++) + { + if (evtbitmap & (1ULL << idx)) + { + dbg_alt1250("idx=%d\n", idx); + + set_writable = false; + + func = get_execfunc(idx); + l_evtbitmap = exec_callback(g_evtbuffers[idx].cmdid, func, + get_evtarg(idx), &set_writable); + + ret |= l_evtbitmap; + + if (l_evtbitmap == 0ULL) + { + if (LTE_ISCMDGRP_NORMAL(g_evtbuffers[idx].cmdid)) + { + clear_callback(g_evtbuffers[idx].cmdid); + } + } + + if (l_evtbitmap == 0ULL) + { + if (!set_writable) + { + update_evtarg_writable(idx); + } + } + } + } + + dbg_alt1250("evtbitmap=0x%llx\n", ret); + + return ret; +} + +/**************************************************************************** + * Name: alt1250_evt_search + ****************************************************************************/ + +static uint64_t alt1250_evt_search(uint32_t cmdid) +{ + int idx; + + uint64_t evtbitmap = 0ULL; + + for (idx = 0; idx < nitems(g_evtbuffers); idx++) + { + if (g_evtbuffers[idx].cmdid == cmdid) + { + evtbitmap = (1ULL << idx); + } + } + + return evtbitmap; +} + +/**************************************************************************** + * Name: reg_evtcb + ****************************************************************************/ + +static int reg_evtcb(struct cbinfo_s *info, uint32_t cmdid, FAR void *cb) +{ + if (info == NULL) + { + return ERROR; + } + + info->cmdid = cmdid; + info->cb = cb; + + return OK; +} + +/**************************************************************************** + * Name: search_evtcb + ****************************************************************************/ + +static struct cbinfo_s *search_evtcb(uint32_t cmdid) +{ + int i; + + for (i = 0; i < nitems(g_cbtable); i++) + { + if (g_cbtable[i].cmdid == cmdid) + { + return &g_cbtable[i]; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: register_evtcb + ****************************************************************************/ + +static int register_evtcb(uint32_t cmdid, FAR void *cb) +{ + if (search_evtcb(cmdid) == NULL) + { + if (reg_evtcb(search_free_evtcb(), cmdid, cb) == ERROR) + { + return -EBUSY; + } + + return OK; + } + else + { + return IS_REPORT_API(cmdid) ? -EALREADY : -EINPROGRESS; + } +} + +/**************************************************************************** + * Name: clear_evtcb + ****************************************************************************/ + +static int clear_evtcb(uint32_t cmdid) +{ + clr_evtcb(search_evtcb(cmdid)); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: alt1250_setevtbuff + ****************************************************************************/ + +FAR struct alt_evtbuffer_s *init_event_buffer(void) +{ + sem_init(&g_cbtablelock, 0, 1); + return evtbuffer_init(); +} + +/**************************************************************************** + * Name: alt1250_evtdatadestroy + ****************************************************************************/ + +int alt1250_evtdatadestroy(void) +{ + sem_destroy(&g_cbtablelock); + + return 0; +} + +/**************************************************************************** + * Name: alt1250_regevtcb + ****************************************************************************/ + +int alt1250_regevtcb(uint32_t cmdid, FAR void *cb) +{ + int ret; + + sem_wait(&g_cbtablelock); + + if (cb == NULL) + { + ret = clear_evtcb(cmdid); + } + else + { + ret = register_evtcb(cmdid, cb); + } + + sem_post(&g_cbtablelock); + + return ret; +} + +/**************************************************************************** + * Name: alt1250_execcb + ****************************************************************************/ + +void alt1250_execcb(uint64_t evtbitmap) +{ + uint64_t l_evtbitmap = 0ULL; + + if (evtbitmap & ALT1250_EVTBIT_RESET) + { + /* call LTE_CMDID_SETRESTART */ + + alt1250_search_execcb(alt1250_evt_search(LTE_CMDID_SETRESTART)); + + update_evtarg_writableall(); + } + else + { + l_evtbitmap = alt1250_search_execcb(evtbitmap); + + if (l_evtbitmap != 0ULL) + { + alt1250_search_execcb(l_evtbitmap); + } + } +} + +/**************************************************************************** + * Name: alt1250_getevtarg + ****************************************************************************/ + +FAR void **alt1250_getevtarg(uint32_t cmdid) +{ + int i; + + for (i = 0; i < nitems(g_evtbuffers); i++) + { + if (g_evtbuffers[i].cmdid == cmdid) + { + return g_evtbuffers[i].outparam; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: alt1250_checkcmdid + ****************************************************************************/ + +bool alt1250_checkcmdid(uint32_t cmdid, uint64_t evtbitmap, + FAR uint64_t *bit) +{ + int idx; + bool ret = false; + + for (idx = 0; idx < nitems(g_evtbuffers); idx++) + { + if (evtbitmap & (1ULL << idx)) + { + dbg_alt1250("idx=%d\n", idx); + + if (g_evtbuffers[idx].cmdid == cmdid) + { + ret = true; + *bit = 1ULL << idx; + break; + } + } + } + + return ret; +} + +/**************************************************************************** + * Name: alt1250_setevtarg_writable + ****************************************************************************/ + +void alt1250_setevtarg_writable(uint32_t cmdid) +{ + int idx; + FAR alt_evtbuf_inst_t *inst = NULL; + + for (idx = 0; idx < nitems(g_evtbuffers); idx++) + { + if (g_evtbuffers[idx].cmdid == cmdid) + { + inst = &g_evtbuffers[idx]; + + nxmutex_lock(&inst->stat_lock); + + inst->stat = ALTEVTBUF_ST_WRITABLE; + + nxmutex_unlock(&inst->stat_lock); + + break; + } + } +} + +/**************************************************************************** + * Name: alt1250_clrevtcb + ****************************************************************************/ + +int alt1250_clrevtcb(uint8_t mode) +{ + int ret = OK; + int i; + + sem_wait(&g_cbtablelock); + + if (mode == ALT1250_CLRMODE_WO_RESTART) + { + for (i = 0; i < nitems(g_cbtable); i++) + { + if (g_cbtable[i].cmdid != LTE_CMDID_SETRESTART) + { + g_cbtable[i].cb = NULL; + g_cbtable[i].cmdid = 0; + } + } + } + else if (mode == ALT1250_CLRMODE_ALL) + { + memset(g_cbtable, 0, sizeof(struct cbinfo_s) * NCBTABLES); + } + else + { + ret = -EINVAL; + } + + sem_post(&g_cbtablelock); + + return ret; +} + +#ifdef CONFIG_LTE_ALT1250_LAUNCH_EVENT_TASK +static int internal_evttask(int argc, FAR char *argv[]) +{ + int ret; + bool is_running = true; + + ret = lapi_evtinit(LAPIEVT_QNAME); + if (ret < 0) + { + dbg_alt1250("lapi_evtinit() failed: %d\n", ret); + goto errout; + } + + while (is_running) + { + ret = lapi_evtyield(-1); + if (ret == 0) + { + dbg_alt1250("lapi_evtyield() finish normaly\n"); + is_running = false; + } + else if (ret < 0) + { + dbg_alt1250("lapi_evtyield() failed: %d\n", ret); + } + } + +errout: + lapi_evtdestoy(); + + return 0; +} +#endif + +static int evt_qsend(FAR mqd_t *mqd, uint64_t evtbitmap) +{ + int ret = ERROR; + + if (*mqd != (mqd_t)-1) + { + ret = mq_send(*mqd, (FAR const char *)&evtbitmap, sizeof(evtbitmap), + 0); + if (ret < 0) + { + ret = -errno; + dbg_alt1250("failed to send mq: %d\n", errno); + } + } + + return ret; +} + +int alt1250_evttask_sendmsg(FAR struct alt1250_s *dev, uint64_t msg) +{ + return evt_qsend(&dev->evtq, msg); +} + +int alt1250_evttask_start(void) +{ +#ifdef CONFIG_LTE_ALT1250_LAUNCH_EVENT_TASK + g_cbpid = task_create(EVTTASK_NAME, CONFIG_LTE_ALT1250_EVENT_TASK_PRIORITY, + CONFIG_LTE_ALT1250_EVENT_TASK_STACKSIZE, internal_evttask, NULL); + return g_cbpid; +#else + return 1; /* Always success */ +#endif +} + +void alt1250_evttask_stop(FAR struct alt1250_s *dev) +{ + if (alt1250_evttask_sendmsg(dev, 0ULL) == OK) + { +#ifdef CONFIG_LTE_ALT1250_LAUNCH_EVENT_TASK + int stat; + + waitpid(g_cbpid, &stat, WEXITED); +#endif + } + + alt1250_evttask_msgclose(dev); +} + +void alt1250_evttask_msgclose(FAR struct alt1250_s *dev) +{ + if (dev->evtq != (mqd_t)-1) + { + /* FIXME: In case of the event callback task is not launched yet, + * this message may be dropped. + * Now, above behavior is not rescued.. + */ + + mq_close(dev->evtq); + mq_unlink(LAPIEVT_QNAME); + } +} + +int alt1250_evttask_msgconnect(FAR const char *qname, + FAR struct alt1250_s *dev) +{ + int ret = OK; + + alt1250_evttask_msgclose(dev); + + dev->evtq = mq_open(qname, O_WRONLY); + if (dev->evtq == (mqd_t)-1) + { + ret = -errno; + dbg_alt1250("failed to open mq(%s): %d\n", qname, errno); + } + + return ret; +} + +uint32_t alt1250_search_registered_callback(FAR int *index) +{ + uint32_t ret = 0x00; + int i; + + for (i = *index; i < NCBTABLES; i++) + { + if (g_cbtable[i].cb != NULL && IS_LTE_REPORT_EVENT(g_cbtable[i].cmdid)) + { + ret = g_cbtable[i].cmdid; + *index = i; + break; + } + } + + return ret; +} + +int alt1250_get_report_ltecmd(FAR struct alt1250_s *dev, + uint32_t cmdid, + FAR struct lte_ioctl_data_s *ltecmd) +{ + int ret = OK; + static int result; + static int32_t param; + static FAR void *inparam[2]; + static FAR void *outparam[1]; + + /* Generate ltecmd: + * cmdid : LAPI command ID + * inparam : Array of input arguments + * (First argument is callback pointer.) + * inparamlen : Size of inparam array + * outparam : Array of output arguments + * (The result parameter only.) + * outparamlen: Size of outparam array + */ + + ltecmd->cmdid = cmdid; + ltecmd->inparam = inparam; + ltecmd->outparam = outparam; + ltecmd->outparamlen = 1; + + inparam[0] = get_cbfunc(cmdid); + outparam[0] = (FAR void *)&result; + + switch (cmdid) + { + case LTE_CMDID_REPNETINFO: + ltecmd->inparamlen = 1; + break; + case LTE_CMDID_REPSIMSTAT: + param = cmdid; + inparam[1] = (FAR void *)¶m; + ltecmd->inparamlen = 2; + break; + case LTE_CMDID_REPLTIME: + param = cmdid; + inparam[1] = (FAR void *)¶m; + ltecmd->inparamlen = 2; + break; + case LTE_CMDID_REPQUAL: + param = dev->quality_report_period; + inparam[1] = (FAR void *)¶m; + ltecmd->inparamlen = 2; + break; + case LTE_CMDID_REPCELL: + param = dev->cellinfo_report_period; + inparam[1] = (FAR void *)¶m; + ltecmd->inparamlen = 2; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} diff --git a/lte/alt1250/callback_handlers/alt1250_evt.h b/lte/alt1250/callback_handlers/alt1250_evt.h new file mode 100644 index 000000000..2ad8cd6a8 --- /dev/null +++ b/lte/alt1250/callback_handlers/alt1250_evt.h @@ -0,0 +1,74 @@ +/**************************************************************************** + * apps/lte/alt1250/callback_handlers/alt1250_evt.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_CALLBACK_HANDLERS_ALT1250_EVT_H +#define __APPS_LTE_ALT1250_CALLBACK_HANDLERS_ALT1250_EVT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "alt1250_daemon.h" +#include "alt1250_util.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Represents when to clear the callback function */ + +/* Clear callbacks at all */ + +#define ALT1250_CLRMODE_ALL (0) + +/* Clear callbacks without restart callback */ + +#define ALT1250_CLRMODE_WO_RESTART (1) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +FAR struct alt_evtbuffer_s *init_event_buffer(void); +int alt1250_evtdatadestroy(void); +int alt1250_regevtcb(uint32_t id, FAR void *cb); +void alt1250_execcb(uint64_t evtbitmap); +FAR void **alt1250_getevtarg(uint32_t cmdid); +bool alt1250_checkcmdid(uint32_t cmdid, uint64_t evtbitmap, + FAR uint64_t *bit); +void alt1250_setevtarg_writable(uint32_t cmdid); +int alt1250_clrevtcb(uint8_t mode); + +int alt1250_evttask_start(void); +void alt1250_evttask_stop(FAR struct alt1250_s *dev); +int alt1250_evttask_sendmsg(FAR struct alt1250_s *dev, uint64_t msg); +void alt1250_evttask_msgclose(FAR struct alt1250_s *dev); +int alt1250_evttask_msgconnect(FAR const char *qname, + FAR struct alt1250_s *dev); +uint32_t alt1250_search_registered_callback(FAR int *index); +int alt1250_get_report_ltecmd(FAR struct alt1250_s *dev, + uint32_t cmdid, + FAR struct lte_ioctl_data_s *ltecmd); + +#endif /* __APPS_LTE_ALT1250_CALLBACK_HANDLERS_ALT1250_EVT_H */ diff --git a/lte/alt1250/usock_handlers/alt1250_accepthdlr.c b/lte/alt1250/usock_handlers/alt1250_accepthdlr.c new file mode 100644 index 000000000..f9565be0b --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_accepthdlr.c @@ -0,0 +1,255 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_accepthdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_devif.h" +#include "alt1250_socket.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_accepterr + ****************************************************************************/ + +static int postproc_accepterr(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = -EBUSY; + + return ret; +} + +/**************************************************************************** + * name: send_close_command + ****************************************************************************/ + +static int send_close_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int altsock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[1]; + + /* This member is referenced only when sending a command and + * not when receiving a response, so local variable is used. + */ + + inparam[0] = &altsock; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_CLOSE); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_accepterr, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: postproc_accept + ****************************************************************************/ + +static int postproc_accept(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + int altsock_res; + FAR struct usock_s *accept_sock; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: socket fd + * resp[1]: error code + * resp[2]: addrlen + * resp[3]: accepted address + */ + + altsock_res = COMBINE_ERRCODE(*(int *)(resp[0]), *(int *)(resp[1])); + if (altsock_res >= 0) + { + USOCKET_SET_SELECTABLE(usock, SELECT_READABLE); + + accept_sock = usocket_alloc(dev, USOCKET_TYPE(usock)); + if (!accept_sock) + { + ret = send_close_command(dev, reply, usock, altsock_res, + usock_result); + *usock_xid = USOCKET_XID(usock); + } + else + { + USOCKET_SET_ALTSOCKID(accept_sock, altsock_res); + USOCKET_SET_STATE(accept_sock, SOCKET_STATE_CONNECTED); + + *usock_result = sizeof(uint16_t); + *usock_xid = USOCKET_XID(usock); + + ackinfo->valuelen = MIN(USOCKET_REQADDRLEN(usock), + *(uint16_t *)(resp[2])); + ackinfo->valuelen_nontrunc = *(uint16_t *)(resp[2]); + ackinfo->value_ptr = resp[3]; + ackinfo->buf_ptr = (FAR uint8_t *)&USOCKET_USOCKID(accept_sock); + + ret = REP_SEND_DACK; + } + + usocket_commitstate(dev); + } + else + { + *usock_result = altsock_res; + *usock_xid = USOCKET_XID(usock); + } + + return ret; +} + +/**************************************************************************** + * name: send_accept_command + ****************************************************************************/ + +static int send_accept_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + uint16_t addrlen, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[2]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &addrlen; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDRLEN(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDR(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_ACCEPT); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_accept, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_accept + ****************************************************************************/ + +int usockreq_accept(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_accept_s *request = &req->request.accept_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + socklen_t addrlen; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQADDRLEN(usock, request->max_addrlen); + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + if (USOCKET_DOMAIN(usock) == AF_INET) + { + addrlen = sizeof(struct sockaddr_in); + } + else + { + addrlen = sizeof(struct sockaddr_in6); + } + + ret = send_accept_command(dev, container, usock, addrlen, usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_bindhdlr.c b/lte/alt1250/usock_handlers/alt1250_bindhdlr.c new file mode 100644 index 000000000..527cf9361 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_bindhdlr.c @@ -0,0 +1,184 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_bindhdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_bind_command + ****************************************************************************/ + +static int send_bind_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[3]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &USOCKET_REQADDRLEN(usock); + inparam[2] = &USOCKET_REQADDR(usock); + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_BIND); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_sockcommon, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_bind + ****************************************************************************/ + +int nextstep_bind(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + return send_bind_command(dev, reply, usock, usock_result); +} + +/**************************************************************************** + * name: usockreq_bind + ****************************************************************************/ + +int usockreq_bind(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_bind_s *request = &req->request.bind_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQADDRLEN(usock, request->addrlen); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqaddr(dev->usockfd, + &USOCKET_REQADDR(usock), + USOCKET_REQADDRLEN(usock)); + if (*usock_result < 0) + { + container_free(container); + return REP_SEND_ACK; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqaddr(dev->usockfd, + &USOCKET_REQADDR(usock), + USOCKET_REQADDRLEN(usock)); + if (*usock_result < 0) + { + container_free(container); + return REP_SEND_ACK; + } + + ret = nextstep_bind(dev, container, usock, usock_result, usock_xid, + ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_closehdlr.c b/lte/alt1250/usock_handlers/alt1250_closehdlr.c new file mode 100644 index 000000000..053195321 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_closehdlr.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_closehdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_close_command + ****************************************************************************/ + +static int send_close_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[1]; + + /* This member is referenced only when sending a command and + * not when receiving a response, so local variable is used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_CLOSE); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_sockcommon, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_sockcommon + ****************************************************************************/ + +int postproc_sockcommon(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + switch (USOCKET_REQID(usock)) + { + case USRSOCK_REQUEST_SENDTO: + { + USOCKET_SET_SELECTABLE(usock, SELECT_WRITABLE); + usocket_commitstate(dev); + } + break; + + case USRSOCK_REQUEST_CLOSE: + { + usocket_free(usock); + } + break; + + default: + break; + } + + return ret; +} + +/**************************************************************************** + * name: usockreq_close + ****************************************************************************/ + +int usockreq_close(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_close_s *request = + &req->request.close_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + + if (IS_SMS_SOCKET(usock)) + { + ret = alt1250_sms_fin(dev, usock, usock_result); + } + else + { + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + usocket_free(usock); + ret = REP_SEND_ACK_WOFREE; + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + USOCKET_SET_STATE(usock, SOCKET_STATE_CLOSING); + usocket_commitstate(dev); + + ret = send_close_command(dev, container, usock, usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (*usock_result < 0) + { + usocket_free(usock); + } + + break; + } + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_connecthdlr.c b/lte/alt1250/usock_handlers/alt1250_connecthdlr.c new file mode 100644 index 000000000..d18ee7277 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_connecthdlr.c @@ -0,0 +1,342 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_connecthdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int16_t g_request_level = SOL_SOCKET; +static int16_t g_request_option = SO_ERROR; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_connect + ****************************************************************************/ + +static int postproc_getsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + * resp[2]: optlen + * resp[3]: optval + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + *usock_result = *(int32_t *)(resp[3]); + *usock_xid = USOCKET_XID(usock); + + dbg_alt1250("connect result = %d\n", *usock_result); + + if (*usock_result > 0) + { + *usock_result = -(*usock_result); + } + + if (*usock_result == 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_CONNECTED); + } + else + { + USOCKET_SET_STATE(usock, SOCKET_STATE_OPENED); + } + } + else + { + USOCKET_SET_STATE(usock, SOCKET_STATE_OPENED); + } + + USOCKET_SET_SELECTABLE(usock, SELECT_WRITABLE); + usocket_commitstate(dev); + + return ret; +} + +/**************************************************************************** + * name: postproc_connect + ****************************************************************************/ + +static int postproc_connect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + dbg_alt1250("%s connect result:%d\n", __func__, *usock_result); + + if (*usock_result >= 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_CONNECTED); + } + else if (*usock_result == -EINPROGRESS) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_WAITCONN); + ret = REP_NO_ACK; + } + else + { + USOCKET_SET_STATE(usock, SOCKET_STATE_OPENED); + } + + usocket_commitstate(dev); + + return ret; +} + +/**************************************************************************** + * name: send_connect_command + ****************************************************************************/ + +static int send_connect_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[3]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &USOCKET_REQADDRLEN(usock); + inparam[2] = &USOCKET_REQADDR(usock); + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_CONNECT); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_connect, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_check_connectres + ****************************************************************************/ + +int nextstep_check_connectres(FAR struct alt1250_s *dev, + FAR struct usock_s *usock) +{ + int ret = REP_NO_CONTAINER; + int32_t usock_result; + struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + container = container_alloc(); + if (container != NULL) + { + ret = send_getsockopt_command(dev, container, usock, + g_request_level, g_request_option, + sizeof(int), &g_request_level, + &g_request_option, postproc_getsockopt, + 0, &usock_result); + } + else + { + /* If there is no container, the state is not + * updated. This guarantees that a select request + * will be sent. When the response is received, + * it can try to acquire a container. There is a + * possibility that the container is free at that + * timing. + */ + + dbg_alt1250("no container\n"); + } + + return ret; +} + +/**************************************************************************** + * name: nextstep_connect + ****************************************************************************/ + +int nextstep_connect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + + dbg_alt1250("%s start\n", __func__); + + ret = send_connect_command(dev, reply, usock, usock_result); + + if (*usock_result >= 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_CONNECTING); + usocket_commitstate(dev); + } + + return ret; +} + +/**************************************************************************** + * usockreq_connect + ****************************************************************************/ + +int usockreq_connect(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_connect_s *request = &req->request.conn_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQADDRLEN(usock, request->addrlen); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqaddr(dev->usockfd, + &USOCKET_REQADDR(usock), + USOCKET_REQADDRLEN(usock)); + if (*usock_result < 0) + { + container_free(container); + return REP_SEND_ACK; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqaddr(dev->usockfd, + &USOCKET_REQADDR(usock), + USOCKET_REQADDRLEN(usock)); + if (*usock_result < 0) + { + container_free(container); + return REP_SEND_ACK; + } + + ret = nextstep_connect(dev, container, usock, usock_result, + usock_xid, ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_fwupdate.h b/lte/alt1250/usock_handlers/alt1250_fwupdate.h new file mode 100644 index 000000000..b4fa0a364 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_fwupdate.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_fwupdate.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_FWUPDATE_H +#define __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_FWUPDATE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LTE_IMAGE_PERT_SIZE (256) + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +struct delta_header_s +{ + uint32_t chunk_code; + uint32_t reserved; + char np_package[LTE_VER_NP_PACKAGE_LEN]; + uint32_t pert_crc; + uint32_t hdr_crc; +}; + +struct update_info_s +{ + int hdr_injected; + int act_injected; + + struct delta_header_s hdr; + char img_pert[LTE_IMAGE_PERT_SIZE]; +}; + +#endif /* __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_FWUPDATE_H */ diff --git a/lte/alt1250/usock_handlers/alt1250_getpeernamehdlr.c b/lte/alt1250/usock_handlers/alt1250_getpeernamehdlr.c new file mode 100644 index 000000000..aa4259325 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_getpeernamehdlr.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_getpeernamehdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_getpeername + ****************************************************************************/ + +int usockreq_getpeername(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_getpeername_s *request = + &req->request.pname_req; + + dbg_alt1250("%s start\n", __func__); + + /* Not support */ + + *usock_result = -ENOTSUP; + *usock_xid = request->head.xid; + + return REP_SEND_ACK_WOFREE; +} diff --git a/lte/alt1250/usock_handlers/alt1250_getsocknamehdlr.c b/lte/alt1250/usock_handlers/alt1250_getsocknamehdlr.c new file mode 100644 index 000000000..b751ddc2e --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_getsocknamehdlr.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_getsocknamehdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_getsockname + ****************************************************************************/ + +static int postproc_getsockname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + * resp[2]: addrlen + * resp[3]: address + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + *usock_result = 0; + *usock_xid = USOCKET_XID(usock); + + ackinfo->valuelen = MIN(USOCKET_REQADDRLEN(usock), + *(uint16_t *)(resp[2])); + ackinfo->valuelen_nontrunc = *(uint16_t *)(resp[2]); + ackinfo->value_ptr = resp[3]; + ackinfo->buf_ptr = NULL; + + if (ackinfo->valuelen != 0) + { + ret = REP_SEND_DACK; + } + } + + return ret; +} + +/**************************************************************************** + * name: send_getsockname_command + ****************************************************************************/ + +static int send_getsockname_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + uint16_t addrlen, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[2]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &addrlen; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDRLEN(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDR(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), + LTE_CMDID_GETSOCKNAME); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_getsockname, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_getsockname + ****************************************************************************/ + +int nextstep_getsockname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + socklen_t addrlen; + + dbg_alt1250("%s start\n", __func__); + + if (USOCKET_DOMAIN(usock) == AF_INET) + { + addrlen = sizeof(struct sockaddr_in); + } + else + { + addrlen = sizeof(struct sockaddr_in6); + } + + return send_getsockname_command(dev, reply, usock, addrlen, usock_result); +} + +/**************************************************************************** + * name: usockreq_getsockname + ****************************************************************************/ + +int usockreq_getsockname(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_getsockname_s *request = &req->request.name_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQADDRLEN(usock, request->max_addrlen); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = nextstep_getsockname(dev, container, usock, usock_result, + usock_xid, ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} + diff --git a/lte/alt1250/usock_handlers/alt1250_getsockopthdlr.c b/lte/alt1250/usock_handlers/alt1250_getsockopthdlr.c new file mode 100644 index 000000000..b2b65688d --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_getsockopthdlr.c @@ -0,0 +1,233 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_getsockopthdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int postproc_getsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: ret code + * resp[1]: error code + * resp[2]: optlen + * resp[3]: optval + */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + *usock_result = 0; + *usock_xid = USOCKET_XID(usock); + + ackinfo->valuelen = MIN(USOCKET_REQOPTLEN(usock), + *(uint16_t *)(resp[2])); + ackinfo->valuelen_nontrunc = *(uint16_t *)(resp[2]); + ackinfo->value_ptr = resp[3]; + ackinfo->buf_ptr = NULL; + + if (ackinfo->valuelen != 0) + { + ret = REP_SEND_DACK; + } + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_getsockopt + ****************************************************************************/ + +int nextstep_getsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + return send_getsockopt_command(dev, reply, usock, + USOCKET_REQOPTLEVEL(usock), + USOCKET_REQOPTOPT(usock), + USOCKET_REQOPTLEN(usock), + &USOCKET_REQOPTLEVEL(usock), + &USOCKET_REQOPTOPT(usock), + postproc_getsockopt, 0, usock_result); +} + +/**************************************************************************** + * name: send_getsockopt_command + ****************************************************************************/ + +int send_getsockopt_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int16_t level, + int16_t option, + uint16_t valuelen, + FAR int16_t *requested_level, + FAR int16_t *requested_option, + FAR postproc_hdlr_t func, + unsigned long priv, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[4]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &level; + inparam[2] = &option; + inparam[3] = &valuelen; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_OPTLEN(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_OPTVAL(usock)); + USOCKET_SET_RESPONSE(usock, idx++, requested_level); + USOCKET_SET_RESPONSE(usock, idx++, requested_option); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_GETSOCKOPT); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, func, priv); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: usockreq_getsockopt + ****************************************************************************/ + +int usockreq_getsockopt(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_getsockopt_s *request = &req->request.gopt_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + if (request->max_valuelen > _OPTVAL_LEN_MAX) + { + *usock_result = -EINVAL; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQSOCKOPT(usock, request->level, request->option, + request->max_valuelen); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = nextstep_getsockopt(dev, container, usock, usock_result, + usock_xid, ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_denyinetsock.c b/lte/alt1250/usock_handlers/alt1250_ioctl_denyinetsock.c new file mode 100644 index 000000000..8de3ff142 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_denyinetsock.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_denyinetsock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_netdev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_denyinetsock + ****************************************************************************/ + +int usockreq_ioctl_denyinetsock(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + uint8_t sock_type = req->req_ioctl.sock_type; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + + if (sock_type == DENY_INET_SOCK_ENABLE) + { + /* Block to create INET socket */ + + dev->usock_enable = FALSE; + } + else if (sock_type == DENY_INET_SOCK_DISABLE) + { + /* Allow to create INET socket */ + + dev->usock_enable = TRUE; + } + else + { + dbg_alt1250("unexpected sock_type:0x%02x\n", sock_type); + *usock_result = -EINVAL; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_event.c b/lte/alt1250/usock_handlers/alt1250_ioctl_event.c new file mode 100644 index 000000000..aeeb61903 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_event.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_event.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_ioctl_subhdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_eventnotice_command + ****************************************************************************/ + +static int send_eventnotice_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *usock_result) +{ + set_container_ids(container, USOCKET_USOCKID(usock), ltecmd->cmdid); + set_container_argument(container, ltecmd->inparam, ltecmd->inparamlen); + set_container_response(container, ltecmd->outparam, ltecmd->outparamlen); + set_container_postproc(container, NULL, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_event + ****************************************************************************/ + +int usockreq_ioctl_event(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + FAR struct usock_s *usock = NULL; + int ret = REP_SEND_ACK_WOFREE; + uint32_t cmdid = LTE_PURE_CMDID(ltecmd->cmdid); + FAR struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + ret = alt1250_regevtcb(cmdid, ltecmd->cb); + if (ret < 0) + { + *usock_result = ret; + return REP_SEND_ACK_WOFREE; + } + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + if (dev->is_resuming) + { + /* In resuming phase, report API callback can be registered without + * sending modem command. Modem command will be sent in calling + * resume API. + */ + + if (ltecmd->cmdid == LTE_CMDID_REPQUAL) + { + dev->quality_report_period = *((uint32_t *)ltecmd->inparam[1]); + } + else if (ltecmd->cmdid == LTE_CMDID_REPCELL) + { + dev->cellinfo_report_period = *((uint32_t *)ltecmd->inparam[1]); + } + + *usock_result = ret; + return REP_SEND_ACK_WOFREE; + } +#endif + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + alt1250_regevtcb(cmdid, NULL); + return REP_NO_CONTAINER; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + + if (IS_LWM2M_EVENT(cmdid)) + { + ret = send_m2mnotice_command(cmdid, dev, container, usock, ltecmd, + usock_result); + } + else + { + ret = send_eventnotice_command(dev, container, usock, ltecmd, + usock_result); + } + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (*usock_result == -ENOSYS) + { + /* -ENOSYS means that there is no composer. + * There are cases where the LAPI command ID group is an event, + * but no composer is needed. + * In that case, it is necessary to send OK to usrsock after + * registering the callback function. + */ + + ret = REP_SEND_ACK_WOFREE; + *usock_result = OK; + } + else if (*usock_result < 0) + { + /* clear callback */ + + alt1250_regevtcb(cmdid, NULL); + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_fwupdate.c b/lte/alt1250/usock_handlers/alt1250_ioctl_fwupdate.c new file mode 100644 index 000000000..291c4ec6b --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_fwupdate.c @@ -0,0 +1,464 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_fwupdate.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_fwupdate.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DELTA_MAGICNO (('D') + ('T' << 8) + ('F' << 16) + ('W' << 24)) +#define IS_IN_RANGE(a, l, h) (((a) >= (l)) && ((a) < (h))) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: postprochdlr_fwgetimglen + ****************************************************************************/ + +static int postproc_fwgetimglen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + if (CONTAINER_RESPRES(reply) >= 0) + { + /* When modem returned non-zero value, + * some data have already injected. + * But additional header is not counted. + * Here is adjustement code for it. + */ + + if (dev->fwup_info.act_injected == -1) + { + /* First call */ + + dev->fwup_info.act_injected = CONTAINER_RESPRES(reply); + dev->fwup_info.hdr_injected = (dev->fwup_info.act_injected > 0) ? + sizeof(struct delta_header_s) : 0; + } + else if (dev->fwup_info.act_injected >= LTE_IMAGE_PERT_SIZE) + { + /* Injection is already done until pert area. */ + + if (CONTAINER_RESPRES(reply) == 0) + { + /* Modem should returl non-zero value. + * This is error case because of mis-matched. + */ + + /* Notice: This case can be happened in normal case + * when injection done just until pert area. + * But it can't be rescued. + */ + + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + } + else + { + dev->fwup_info.act_injected = CONTAINER_RESPRES(reply); + } + } + + if (dev->fwup_info.act_injected == -1) + { + CONTAINER_RESPRES(reply) = -ENODATA; + } + else + { + /* Reply size should include header injected size */ + + CONTAINER_RESPRES(reply) = + dev->fwup_info.act_injected + dev->fwup_info.hdr_injected; + } + } + else + { + /* In error case from modem, injection is reset. */ + + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + } + + *usock_result = CONTAINER_RESPRES(reply); + + return REP_SEND_ACK; +} + +/**************************************************************************** + * Name: postprochdlr_fwupdate_injection + ****************************************************************************/ + +static int postproc_fwupdate_injection(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int app_injected = (int)arg; + + if (CONTAINER_RESPRES(reply) < 0) + { + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + } + else if (app_injected >= 0) + { + CONTAINER_RESPRES(reply) = app_injected; + } + + *usock_result = CONTAINER_RESPRES(reply); + + return REP_SEND_ACK; +} + +/**************************************************************************** + * Name: fwupdate_dummy_postproc + ****************************************************************************/ + +static int postproc_fwupdate_dummy(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + *usock_result = CONTAINER_RESPRES(reply); + + return REP_SEND_ACK; +} + +/**************************************************************************** + * Name: store_injection_data + ****************************************************************************/ + +static bool store_injection_data(FAR char *dist, FAR int *ofst, int sz, + FAR uint8_t **src, FAR int *len) +{ + bool ret = false; + int rest; + + if (IS_IN_RANGE(*ofst, 0, sz)) + { + rest = sz - *ofst; + rest = (rest > *len) ? *len : rest; + memcpy(&dist[*ofst], *src, rest); + *len -= rest; + *ofst += rest; + *src += rest; + if (*ofst == sz) + { + ret = true; + } + } + + return ret; +} + +/**************************************************************************** + * Name: verify_header_crc32 + ****************************************************************************/ + +static bool verify_header_crc32(FAR struct alt1250_s *dev) +{ + uint32_t crc_result = crc32((uint8_t *)&dev->fwup_info.hdr, + sizeof(struct delta_header_s)); + + return (crc_result == 0); +} + +/**************************************************************************** + * Name: verify_pert_crc32 + ****************************************************************************/ + +static bool verify_pert_crc32(FAR struct alt1250_s *dev) +{ + uint32_t crc_result = crc32((uint8_t *)dev->fwup_info.img_pert, + LTE_IMAGE_PERT_SIZE); + return (crc_result == dev->fwup_info.hdr.pert_crc); +} + +/**************************************************************************** + * Name: fwupdate_header_injection + ****************************************************************************/ + +static int fwupdate_header_injection(FAR struct alt1250_s *dev, + FAR struct lte_ioctl_data_s *cmd, + FAR bool *send_pert) +{ + FAR uint8_t *data = (FAR uint8_t *)cmd->inparam[0]; + int len = *(FAR int *)cmd->inparam[1]; + bool init = *(FAR bool *)cmd->inparam[2]; + bool filled_all; + + if (init) + { + dev->fwup_info.act_injected = 0; + dev->fwup_info.hdr_injected = 0; + } + + *send_pert = false; + + /* Make sure lte_get_version() and + * ltefwupdate_injected_datasize() have been already called. + */ + + if ((dev->fw_version[0] == 'R') && (dev->fw_version[1] == 'K') + && (dev->fwup_info.act_injected != -1) && (len > 0)) + { + /* Check if under header injection phase */ + + if (dev->fwup_info.act_injected == 0) + { + filled_all + = store_injection_data((char *)&dev->fwup_info.hdr, + &dev->fwup_info.hdr_injected, + sizeof(struct delta_header_s), &data, + &len); + if (filled_all) + { + if (!verify_header_crc32(dev) || + (dev->fwup_info.hdr.chunk_code != DELTA_MAGICNO) || + strncmp(dev->fw_version, dev->fwup_info.hdr.np_package, + LTE_VER_NP_PACKAGE_LEN)) + { + /* CRC error or Version mis-match */ + + dbg_alt1250("FWUP: Error CRC Header\n"); + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + return -EINVAL; + } + } + } + + /* Check if under pert injection phase */ + + if ((dev->fwup_info.hdr_injected >= sizeof(struct delta_header_s)) && + (len > 0)) + { + filled_all + = store_injection_data(dev->fwup_info.img_pert, + &dev->fwup_info.act_injected, + LTE_IMAGE_PERT_SIZE, &data, &len); + if (filled_all) + { + if (!verify_pert_crc32(dev)) + { + /* CRC error */ + + dbg_alt1250("FWUP: Error CRC Pertition\n"); + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + return -EINVAL; + } + else + { + *send_pert = true; + } + } + } + + return len; + } + else + { + dbg_alt1250("FWUP: Not initialized.\n"); + return -ENODATA; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_fwupdate + ****************************************************************************/ + +int usockreq_ioctl_fwupdate(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + FAR struct usock_s *usock = NULL; + int ret = REP_SEND_ACK_WOFREE; + FAR struct alt_container_s *container; + postproc_hdlr_t postproc_hdlr = NULL; + bool send_cmd = true; + int postproc_priv = -1; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + /* FW Update APIs are all synchronouse. */ + + if ((ltecmd->cmdid & LTE_CMDOPT_ASYNC_BIT) || (ltecmd->cb != NULL)) + { + *usock_result = -EINVAL; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + /* Special operation for each commands */ + + switch (ltecmd->cmdid) + { + case LTE_CMDID_INJECTIMAGE: + { + *usock_result = fwupdate_header_injection(dev, ltecmd, &send_cmd); + if (*usock_result < 0) + { + container_free(container); + return REP_SEND_ACK_WOFREE; + } + else + { + /* That send_cmd is set to true means + * that pert image should be sent. + */ + + if (send_cmd) + { + /* Need to care for reply value as actual injected + * size from application point of view + */ + + postproc_priv + = *(FAR int *)ltecmd->inparam[1] - *usock_result; + ltecmd->inparam[0] = dev->fwup_info.img_pert; + *(FAR int *)ltecmd->inparam[1] = LTE_IMAGE_PERT_SIZE; + *(FAR bool *)ltecmd->inparam[2] = true; + } + else if (*usock_result > 0) + { + send_cmd = true; + } + else /* In case of *result == 0 */ + { + /* No send injecting data to modem, + * but the data is all accepted. + */ + + *usock_result = *(FAR int *)ltecmd->inparam[1]; + container_free(container); + } + + postproc_hdlr = postproc_fwupdate_injection; + } + } + break; + + case LTE_CMDID_GETIMAGELEN: + { + postproc_hdlr = postproc_fwgetimglen; + } + break; + + case LTE_CMDID_EXEUPDATE: + { + /* When execution starts, injection is reset */ + + reset_fwupdate_info(dev); + postproc_hdlr = postproc_fwupdate_dummy; + } + break; + + default: + { + *usock_result = -EINVAL; + container_free(container); + return REP_SEND_ACK_WOFREE; + } + break; + } + + if (send_cmd) + { + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + + set_container_ids(container, USOCKET_USOCKID(usock), ltecmd->cmdid); + set_container_argument(container, ltecmd->inparam, ltecmd->inparamlen); + set_container_response(container, ltecmd->outparam, + ltecmd->outparamlen); + set_container_postproc(container, postproc_hdlr, postproc_priv); + + ret = altdevice_send_command(dev->altfd, container, usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + + return ret; +} + +void reset_fwupdate_info(FAR struct alt1250_s *dev) +{ + dev->fwup_info.hdr_injected = 0; + dev->fwup_info.act_injected = -1; + dev->fw_version[0] = '\0'; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_ifreq.c b/lte/alt1250/usock_handlers/alt1250_ioctl_ifreq.c new file mode 100644 index 000000000..1bae245f1 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_ifreq.c @@ -0,0 +1,409 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_ifreq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_netdev.h" + +/**************************************************************************** + * Private Function Prototype + ****************************************************************************/ + +static int postproc_radiooff(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_radioon(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_actpdn(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_reportnet(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_actpdn_command + ****************************************************************************/ + +static int send_actpdn_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[1]; + + /* This member is referenced only when sending a command and + * not when receiving a response, so local variable is used. + */ + + inparam[0] = &dev->apn; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, &dev->o_pdn); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_ACTPDN); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_actpdn, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_radio_command + ****************************************************************************/ + +static int send_radio_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result, bool on) +{ + int idx = 0; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), + on ? LTE_CMDID_RADIOON : LTE_CMDID_RADIOOFF); + set_container_argument(container, NULL, 0); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, + on ? postproc_radioon : postproc_radiooff, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: postproc_radiooff + ****************************************************************************/ + +static int postproc_radiooff(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = (CONTAINER_RESPRES(reply) == 0) ? altcom_result : + CONTAINER_RESPRES(reply); + + alt1250_netdev_ifdown(dev); + + return ret; +} + +/**************************************************************************** + * name: postproc_actpdn + ****************************************************************************/ + +static int postproc_actpdn(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + FAR lte_pdn_t *pdn = resp[1]; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = (CONTAINER_RESPRES(reply) == 0) ? altcom_result : + CONTAINER_RESPRES(reply); + + if (*usock_result == 0) + { + /* After connecting to the LTE network, + * wait for the modem to register the network interface. + */ + + usleep(ALT1250_NETIF_READY_DELAY); + alt1250_netdev_ifup(dev, pdn); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_radioon + ****************************************************************************/ + +static int postproc_radioon(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = (CONTAINER_RESPRES(reply) == 0) ? altcom_result : + CONTAINER_RESPRES(reply); + + if (*usock_result == 0) + { + ret = send_reportnet_command(dev, reply, usock, postproc_reportnet, 0, + usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_reportnet + ****************************************************************************/ + +static int postproc_reportnet(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = (CONTAINER_RESPRES(reply) == 0) ? altcom_result : + CONTAINER_RESPRES(reply); + + if (*usock_result == 0) + { + ret = send_actpdn_command(dev, reply, usock, usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: do_ifup + ****************************************************************************/ + +static int do_ifup(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = + &req->request.ioctl_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = send_radio_command(dev, container, usock, usock_result, true); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + return ret; +} + +/**************************************************************************** + * name: do_ifdown + ****************************************************************************/ + +static int do_ifdown(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = + &req->request.ioctl_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = send_radio_command(dev, container, usock, usock_result, false); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_reportnet_command + ****************************************************************************/ + +int send_reportnet_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR postproc_hdlr_t func, + unsigned long priv, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[1]; + uint8_t enable = 1; + + /* This member is referenced only when sending a command and + * not when receiving a response, so local variable is used. + */ + + inparam[0] = &enable; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_REPNETINFO); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, func, priv); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: usockreq_ioctl_ifreq + ****************************************************************************/ + +int usockreq_ioctl_ifreq(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct ifreq *if_req = &req->req_ioctl.ifreq; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + if (if_req->ifr_flags & IFF_UP) + { + ret = do_ifup(dev, req, usock_result, usock_xid, ackinfo); + } + else if (if_req->ifr_flags & IFF_DOWN) + { + ret = do_ifdown(dev, req, usock_result, usock_xid, ackinfo); + } + else + { + dbg_alt1250("unexpected ifr_flags:0x%02x\n", if_req->ifr_flags); + *usock_result = -EINVAL; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_ltecmd.c b/lte/alt1250/usock_handlers/alt1250_ioctl_ltecmd.c new file mode 100644 index 000000000..82e211f6f --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_ltecmd.c @@ -0,0 +1,122 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_ltecmd.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_ioctl_subhdlr.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern int usockreq_ioctl_extend(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_ltecmd + ****************************************************************************/ + +int usockreq_ioctl_ltecmd(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + int ret = REP_SEND_ACK_WOFREE; + usrsock_reqhandler_t ioctl_subhdlr = NULL; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = -EINVAL; + *usock_xid = request->head.xid; + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + if (dev->is_resuming && + !IS_LTE_REPORT_EVENT(ltecmd->cmdid) && + ltecmd->cmdid != LTE_CMDID_SETEVTCTX && + ltecmd->cmdid != LTE_CMDID_RESUME) + { + dbg_alt1250("Don't allow to call any API in resuming " + "phase.(cmdid=%lx)\n", + ltecmd->cmdid); + return ret; + } +#endif + + if (LTE_ISCMDGRP_NORMAL(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_normal; + } + else if (LTE_ISCMDGRP_EVENT(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_event; + } + else if (LTE_ISCMDGRP_NOMDM(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_other; + } + else if (LTE_ISCMDGRP_POWER(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_power; + } + else if (LTE_ISCMDGRP_FWUPDATE(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_fwupdate; + } + else if (LTE_ISCMDGRP_LWM2M(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_lwm2m; + } +#ifdef CONFIG_LTE_ALT1250_EXTEND_IOCTL + else if (LTE_ISCMDGRP_EXTEND(ltecmd->cmdid)) + { + ioctl_subhdlr = usockreq_ioctl_extend; + } +#endif + + if (ioctl_subhdlr != NULL) + { + ret = ioctl_subhdlr(dev, req, usock_result, usock_xid, ackinfo); + } + + return ret; +} + diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c b/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c new file mode 100644 index 000000000..ea82ad92b --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c @@ -0,0 +1,964 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_lwm2m.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_atcmd.h" +#include "alt1250_ioctl_subhdlr.h" +#include "alt1250_usrsock_hdlr.h" + +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: atcmdreply_getepname + ****************************************************************************/ + +static int atcmdreply_getepname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char *name; + void **param = (void **)arg; + char *outbuf = (char *)param[0]; + int outbuflen = (int)param[1]; + + *usock_result = check_atreply_ok(rdata, len, NULL); + if (*usock_result == OK) + { + name = strtok_r(rdata, " \r\n", &rdata); + if (name) + { + memset(outbuf, 0, outbuflen); + strncpy(outbuf, name, outbuflen); + *usock_result = outbuf[outbuflen - 1] == 0 + ? strlen(outbuf) : outbuflen; + } + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: strcpy_until + ****************************************************************************/ + +static char strcpy_until(char *dst, int n, char **src, char *delim) +{ + char *tmp = *src; + + if (dst) + { + dst[n - 1] = '\0'; + n--; + } + + while (*tmp && !strchr(delim, *tmp)) + { + if (dst && (n > 0)) + { + *dst++ = *tmp; + n--; + } + + tmp++; + } + + if (dst && (n > 0)) + { + *dst = '\0'; + } + + *src = tmp + 1; + + return *tmp; +} + +/**************************************************************************** + * name: atcmdreply_getsrvinfo_step4 + ****************************************************************************/ + +static int atcmdreply_getsrvinfo_step4(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char *tmp; + int ret = REP_SEND_ACK; + FAR struct lwm2mstub_serverinfo_s *info + = (FAR struct lwm2mstub_serverinfo_s *)(((void **)arg)[0]); + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + info->object_inst = 0; + + if ((tmp = strstr(rdata, "%LWM2MCMD: ")) != NULL) + { + tmp += strlen("%LWM2MCMD: "); + info->nonip = strstr(tmp, "\"N\"") ? true : false; + + *usock_result = 0; + } + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_getsrvinfo_step3 + ****************************************************************************/ + +static int atcmdreply_getsrvinfo_step3(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char *tmp; + int ret = REP_SEND_ACK; + FAR struct lwm2mstub_serverinfo_s *info + = (FAR struct lwm2mstub_serverinfo_s *)(((void **)arg)[0]); + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + info->object_inst = 0; + + if ((tmp = strstr(rdata, "%LWM2MCMD: ")) != NULL) + { + tmp += strlen("%LWM2MCMD: "); + strcpy_until(NULL, 0, &tmp, ","); + strcpy_until(NULL, 0, &tmp, ","); + strcpy_until(NULL, 0, &tmp, ","); + strcpy_until(NULL, 0, &tmp, ","); + info->security_mode = atoi(tmp); + + ret = lwm2mstub_send_getresource(dev, reply, + CONTAINER_SOCKETID(reply), + atcmdreply_getsrvinfo_step4, + arg, usock_result, "1,0,22"); + } + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_getsrvinfo_step2 + ****************************************************************************/ + +static int atcmdreply_getsrvinfo_step2(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char *tmp; + int ret = REP_SEND_ACK; + FAR struct lwm2mstub_serverinfo_s *info + = (FAR struct lwm2mstub_serverinfo_s *)(((void **)arg)[0]); + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + info->object_inst = 0; + + if ((tmp = strstr(rdata, "%LWM2MCMD: ")) != NULL) + { + tmp += strlen("%LWM2MCMD: "); + info->bootstrap = strstr(tmp, "\"false\"") ? false : true; + + ret = lwm2mstub_send_getresource(dev, reply, + CONTAINER_SOCKETID(reply), + atcmdreply_getsrvinfo_step3, + arg, usock_result, "0,0,2"); + } + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_getsrvinfo_step1 + ****************************************************************************/ + +static int atcmdreply_getsrvinfo_step1(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char *tmp; + int ret = REP_SEND_ACK; + + FAR struct lwm2mstub_serverinfo_s *info + = (FAR struct lwm2mstub_serverinfo_s *)(((void **)arg)[0]); + + *usock_result = -EIO; + + /* Expected reply format + * %LWM2MCMD: ,,,, + */ + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + info->object_inst = 0; + info->device_id[0] = '\0'; + info->security_key[0] = '\0'; + + if ((tmp = strstr(rdata, "%LWM2MCMD: ")) != NULL) + { + tmp += strlen("%LWM2MCMD: "); + + strcpy_until(info->server_uri, LWM2MSTUB_MAX_SERVER_NAME, + &tmp, ",\r\n"); + strcpy_until(NULL, 0, &tmp, ",\r\n"); /* Skip Server ID */ + strcpy_until(NULL, 0, &tmp, ",\r\n"); /* Skip Life time */ + strcpy_until(NULL, 0, &tmp, ",\r\n"); /* Skip Binding */ + info->state = atoi(tmp); + + ret = lwm2mstub_send_getresource(dev, reply, + CONTAINER_SOCKETID(reply), + atcmdreply_getsrvinfo_step2, + arg, usock_result, "0,0,1"); + } + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_getenobjnum + ****************************************************************************/ + +static int atcmdreply_getenobjnum(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + *usock_result = 1; + + rdata += 2; /* avoid "\r\n" */ + while (*rdata != '\r') + { + if (*rdata == ';') + { + (*usock_result)++; + } + + rdata++; + } + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: atcmdreply_getenobjects + ****************************************************************************/ + +static int atcmdreply_getenobjects(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + int i; + FAR uint16_t *objids = (FAR uint16_t *)(((void **)arg)[0]); + int objnum = (int)(((void **)arg)[1]); + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + i = 0; + rdata += 2; /* avoid "\r\n" */ + objids[i++] = atoi(rdata); + while (strcpy_until(NULL, 0, &rdata, ";\r\n") == ';' && i < objnum) + { + objids[i++] = atoi(rdata); + } + + *usock_result = i; + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: atcmdreply_getobjresnum + ****************************************************************************/ + +static int atcmdreply_getobjresnum(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char term; + + *usock_result = -ENODEV; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + *usock_result = -EIO; + if ((rdata = strstr(rdata, "%OBJECTDEF: ")) != NULL) + { + *usock_result = 0; + rdata += strlen("%OBJECTDEF: "); + term = ','; + while (term == ',') + { + if ((term = strcpy_until(NULL, 0, &rdata, ",\r\n")) == ',' + && (term = strcpy_until(NULL, 0, &rdata, ",\r\n")) == ',' + && (term = strcpy_until(NULL, 0, &rdata, ",\r\n")) == ',' + && (term = strcpy_until(NULL, 0, &rdata, ",\r\n")) == ',') + { + /* the commas must be 4 for one resource definitions */ + + (*usock_result)++; + } + } + } + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: resoperation_code + ****************************************************************************/ + +static int resoperation_code(const char *s) +{ + return s[0] == 'W' ? LWM2MSTUB_RESOP_WRITE : + s[0] == 'X' ? LWM2MSTUB_RESOP_EXEC : + s[0] != 'R' ? -1 : + s[1] == 'W' ? LWM2MSTUB_RESOP_RW : LWM2MSTUB_RESOP_READ; +} + +/**************************************************************************** + * name: resdatatype_code + ****************************************************************************/ + +static int resdatatype_code(const char *s) +{ + int ret = -1; + + if (!strcmp(s, "\"none\"")) + { + ret = LWM2MSTUB_RESDATA_NONE; + } + else if (!strcmp(s, "str")) + { + ret = LWM2MSTUB_RESDATA_STRING; + } + else if (!strcmp(s, "int")) + { + ret = LWM2MSTUB_RESDATA_INT; + } + else if (!strcmp(s, "uint")) + { + ret = LWM2MSTUB_RESDATA_UNSIGNED; + } + else if (!strcmp(s, "flt")) + { + ret = LWM2MSTUB_RESDATA_FLOAT; + } + else if (!strcmp(s, "bool")) + { + ret = LWM2MSTUB_RESDATA_BOOL; + } + else if (!strcmp(s, "opq")) + { + ret = LWM2MSTUB_RESDATA_OPAQUE; + } + else if (!strcmp(s, "time")) + { + ret = LWM2MSTUB_RESDATA_TIME; + } + else if (!strcmp(s, "ol")) + { + ret = LWM2MSTUB_RESDATA_OBJLINK; + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_getobjdef + ****************************************************************************/ + +static int atcmdreply_getobjdef(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + char tmp[8]; + char term; + FAR struct lwm2mstub_resource_s *reses + = (FAR struct lwm2mstub_resource_s *)(((void **)arg)[0]); + int resnum = (int)(((void **)arg)[1]); + + *usock_result = -ENODEV; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + *usock_result = -EIO; + if ((rdata = strstr(rdata, "%OBJECTDEF: ")) != NULL) + { + *usock_result = 0; + rdata += strlen("%OBJECTDEF: "); + term = strcpy_until(NULL, 0, &rdata, ",\r\n"); + + /* ,,,, */ + + while (term == ',' && *usock_result < resnum) + { + reses[*usock_result].res_id = atoi(rdata); + term = strcpy_until(NULL, 0, &rdata, ",\r\n"); + + term = strcpy_until(tmp, 8, &rdata, ",\r\n"); + reses[*usock_result].operation = resoperation_code(tmp); + + reses[*usock_result].inst_type = atoi(rdata); + term = strcpy_until(NULL, 0, &rdata, ",\r\n"); + + term = strcpy_until(tmp, 8, &rdata, ",\r\n"); + reses[*usock_result].data_type = resdatatype_code(tmp); + + (*usock_result)++; + } + } + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: atcmdreply_getrat + ****************************************************************************/ + +static int atcmdreply_getrat(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + *usock_result = -ENODEV; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + *usock_result = -EIO; + if (strstr(rdata, "CATM") != NULL) + { + *usock_result = LTE_RAT_CATM; + } + else if (strstr(rdata, "NBIOT") != NULL) + { + *usock_result = LTE_RAT_NBIOT; + } + } + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: atcmdreply_setsrvinfo_step4 + ****************************************************************************/ + +static int atcmdreply_setsrvinfo_step4(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK; + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + ret = lwm2mstub_send_bsdone(dev, reply, CONTAINER_SOCKETID(reply), + usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_setsrvinfo_step3 + ****************************************************************************/ + +static int atcmdreply_setsrvinfo_step3(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK; + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + ret = lwm2mstub_send_bscreateobj1(dev, reply, + CONTAINER_SOCKETID(reply), + atcmdreply_setsrvinfo_step4, arg, + usock_result, + (FAR struct lwm2mstub_serverinfo_s *)arg); + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_setsrvinfo_step2 + ****************************************************************************/ + +static int atcmdreply_setsrvinfo_step2(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK; + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + ret = lwm2mstub_send_bscreateobj0(dev, reply, + CONTAINER_SOCKETID(reply), + atcmdreply_setsrvinfo_step3, arg, + usock_result, + (FAR struct lwm2mstub_serverinfo_s *)arg); + } + + return ret; +} + +/**************************************************************************** + * name: atcmdreply_setsrvinfo_step1 + ****************************************************************************/ + +static int atcmdreply_setsrvinfo_step1(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR char *rdata, int len, unsigned long arg, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK; + + *usock_result = -EIO; + + if (check_atreply_ok(rdata, len, NULL) == OK) + { + ret = lwm2mstub_send_bsdelete(dev, reply, CONTAINER_SOCKETID(reply), + atcmdreply_setsrvinfo_step2, arg, usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: perform_m2m_applysetting + ****************************************************************************/ + +static int perform_m2m_applysetting(FAR struct alt1250_s *dev, + FAR int32_t *usock_result, + uint32_t xid) +{ + dbg_alt1250("%s called\n", __func__); + + if (dev->lwm2m_apply_xid >= 0) + { + *usock_result = -EINPROGRESS; + dbg_alt1250("Apply is in progress\n"); + return REP_SEND_ACK; + } + + *usock_result = OK; + dev->lwm2m_apply_xid = (int64_t)xid; + + MODEM_STATE_INTENTRST(dev); + altdevice_reset(dev->altfd); + + return REP_NO_ACK; /* Ack is replied after received reset event */ +} + +/**************************************************************************** + * name: commands_on_any_state + ****************************************************************************/ + +static int commands_on_any_state(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK; + + switch (ltecmd->cmdid) + { + case LTE_CMDID_LWM2M_GETEP: + ret = lwm2mstub_send_getepname(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getepname, + (unsigned long)ltecmd->outparam, + usock_result); + break; + + case LTE_CMDID_LWM2M_GETSRVNUM: + *usock_result = -EOPNOTSUPP; + break; + + case LTE_CMDID_LWM2M_GETSRVINFO: + ret = lwm2mstub_send_getsrvinfo(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getsrvinfo_step1, + (unsigned long)ltecmd->outparam, + usock_result); + break; + + case LTE_CMDID_LWM2M_GETACTIVEOBJNUM: + ret = lwm2mstub_send_getsupobjs(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getenobjnum, 0, + usock_result); + break; + + case LTE_CMDID_LWM2M_GETACTIVEOBJ: + ret = lwm2mstub_send_getsupobjs(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getenobjects, + (unsigned long)ltecmd->outparam, + usock_result); + break; + + case LTE_CMDID_LWM2M_GETOBJRESNUM: + ret = lwm2mstub_send_getobjdef(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getobjresnum, + 0, usock_result, + *((uint16_t *)ltecmd->inparam)); + break; + + case LTE_CMDID_LWM2M_GETOBJRESOURCE: + ret = lwm2mstub_send_getobjdef(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getobjdef, + (unsigned long)ltecmd->outparam, + usock_result, + *((uint16_t *)ltecmd->inparam)); + break; + + case LTE_CMDID_LWM2M_GETRAT: + ret = lwm2mstub_send_getrat(dev, container, + USOCKET_USOCKID(usock), + atcmdreply_getrat, + (unsigned long)ltecmd->outparam, + usock_result); + break; + + case LTE_CMDID_LWM2M_GETQMODE: + ret = lwm2mstub_send_getqueuemode(dev, container, + USOCKET_USOCKID(usock), + usock_result); + break; + } + + return ret; +} + +/**************************************************************************** + * name: commands_on_poweron_state + ****************************************************************************/ + +static int commands_on_poweron_state(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *usock_result) +{ + int ret; + + switch (ltecmd->cmdid) + { + case LTE_CMDID_LWM2M_SETEP: + ret = lwm2mstub_send_setepname( + dev, container, USOCKET_USOCKID(usock), + usock_result, (const char *)ltecmd->inparam); + break; + + case LTE_CMDID_LWM2M_SETSRVINFO: + ret = lwm2mstub_send_bsstart( + dev, container, USOCKET_USOCKID(usock), + atcmdreply_setsrvinfo_step1, + (unsigned long)ltecmd->inparam[0], + usock_result); + break; + + case LTE_CMDID_LWM2M_SETACTIVEOBJ: + ret = lwm2mstub_send_setsupobjs( + dev, container, USOCKET_USOCKID(usock), + usock_result, + (uint16_t *)ltecmd->inparam[0], (int)ltecmd->inparam[1]); + break; + + case LTE_CMDID_LWM2M_SETOBJRESOURCE: + ret = lwm2mstub_send_setobjdef( + dev, container, USOCKET_USOCKID(usock), + usock_result, (uint16_t)(uint32_t)ltecmd->inparam[0], + (int)ltecmd->inparam[1], + (struct lwm2mstub_resource_s *)ltecmd->inparam[2]); + break; + + case LTE_CMDID_LWM2M_CHANGERAT: + ret = lwm2mstub_send_changerat(dev, container, + USOCKET_USOCKID(usock), + usock_result, + *((int *)ltecmd->inparam)); + break; + + case LTE_CMDID_LWM2M_SETQMODE: + ret = lwm2mstub_send_setqueuemode(dev, container, + USOCKET_USOCKID(usock), + usock_result, + (int)ltecmd->inparam); + break; + + case LTE_CMDID_LWM2M_APPLY_SETTING: + ret = perform_m2m_applysetting(dev, usock_result, + USOCKET_XID(usock)); + break; + + default: + ret = commands_on_any_state(dev, container, usock, ltecmd, + usock_result); + break; + } + + return ret; +} + +/**************************************************************************** + * name: commands_on_radioon_state + ****************************************************************************/ + +static int commands_on_radioon_state(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *usock_result) +{ + int ret; + + switch (ltecmd->cmdid) + { + case LTE_CMDID_LWM2M_CONNECT: + ret = lwm2mstub_send_registration( + dev, container, USOCKET_USOCKID(usock), usock_result, + (int)ltecmd->inparam + ); + break; + + case LTE_CMDID_LWM2M_READRESP: + ret = lwm2mstub_send_evrespwvalue( + dev, container, USOCKET_USOCKID(usock), usock_result, + (int)ltecmd->inparam[0], + (int)ltecmd->inparam[1], + (struct lwm2mstub_instance_s *)ltecmd->inparam[2], + (char *)ltecmd->inparam[3] + ); + break; + + case LTE_CMDID_LWM2M_WRITERESP: + ret = lwm2mstub_send_evresponse( + dev, container, USOCKET_USOCKID(usock), usock_result, + (int)ltecmd->inparam[0], + (int)ltecmd->inparam[1], + (struct lwm2mstub_instance_s *)ltecmd->inparam[2] + ); + break; + + case LTE_CMDID_LWM2M_OBSERVERESP: + ret = lwm2mstub_send_evrespwoinst( + dev, container, USOCKET_USOCKID(usock), usock_result, + (int)ltecmd->inparam[0], + (int)ltecmd->inparam[1] + ); + break; + + case LTE_CMDID_LWM2M_EXECRESP: + ret = lwm2mstub_send_evresponse( + dev, container, USOCKET_USOCKID(usock), usock_result, + (int)ltecmd->inparam[0], + (int)ltecmd->inparam[1], + (struct lwm2mstub_instance_s *)ltecmd->inparam[2] + ); + break; + + case LTE_CMDID_LWM2M_OBSERVEUPDATE: + ret = lwm2mstub_send_objevent( + dev, container, USOCKET_USOCKID(usock), usock_result, + (char *)ltecmd->inparam[0], + (struct lwm2mstub_instance_s *)ltecmd->inparam[1], + (char *)ltecmd->inparam[2] + ); + break; + + default: + ret = commands_on_any_state(dev, container, usock, ltecmd, + usock_result); + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_m2mnotice_command + ****************************************************************************/ + +int send_m2mnotice_command(uint32_t cmdid, + FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *ures) +{ + int ret = REP_SEND_ACK; + *ures = OK; + + switch (cmdid) + { + case LTE_CMDID_LWM2M_READ_EVT: + case LTE_CMDID_LWM2M_WRITE_EVT: + case LTE_CMDID_LWM2M_EXEC_EVT: + case LTE_CMDID_LWM2M_OVSTART_EVT: + case LTE_CMDID_LWM2M_OVSTOP_EVT: + + /* TODO: Now unregister any events makes all event notify stop. + * This will be fixed in near future. + */ + + ret = lwm2mstub_send_m2mobjcmd( + dev, container, USOCKET_USOCKID(usock), ures, + (ltecmd->cb != NULL)); + break; + + case LTE_CMDID_LWM2M_SERVEROP_EVT: + ret = lwm2mstub_send_m2mopev( + dev, container, USOCKET_USOCKID(usock), ures, + (ltecmd->cb != NULL)); + break; + + case LTE_CMDID_LWM2M_FWUP_EVT: + ret = lwm2mstub_send_m2mev( + dev, container, USOCKET_USOCKID(usock), ures, + (ltecmd->cb != NULL)); + break; + + default: + *ures = -EINVAL; + break; + } + + return ret; +} + +/**************************************************************************** + * name: usockreq_ioctl_lwm2m + ****************************************************************************/ + +int usockreq_ioctl_lwm2m(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *ures, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + FAR struct usock_s *usock = NULL; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s called with : %08lx\n", __func__, ltecmd->cmdid); + + *ures = -EOPNOTSUPP; + *usock_xid = request->head.xid; + + if (dev->is_support_lwm2m) + { + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + *ures = -EBADFD; + return ret; + } + + container = container_alloc(); + if (container == NULL) + { + return REP_NO_CONTAINER; + } + + *ures = -EINVAL; + ret = REP_SEND_ACK; + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + + if (MODEM_STATE_IS_PON(dev)) + { + /* These commands is available just in power on state */ + + ret = commands_on_poweron_state(dev, container, usock, ltecmd, + ures); + } + else if (MODEM_STATE_IS_RON(dev)) + { + ret = commands_on_radioon_state(dev, container, usock, ltecmd, + ures); + } + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_normal.c b/lte/alt1250/usock_handlers/alt1250_ioctl_normal.c new file mode 100644 index 000000000..7eaed8757 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_normal.c @@ -0,0 +1,577 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_normal.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_util.h" +#include "alt1250_ioctl_subhdlr.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_netdev.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RADIOON_SYNC (0) +#define RADIOON_ASYNC (1) + +#define REPLY_RETCODE(rep, altrep) (((rep) == 0) ? (altrep) : (rep)) + +/* RK_02_01_01_10xxx FW version that does not support logging feature */ + +#define IS_LOG_UNAVAIL_FWVERSION(d) (!strncmp(MODEM_FWVERSION(d), \ + "RK_02_01_01", 11)) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +static int send_resume_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + int index); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_reportnet + ****************************************************************************/ + +static int postproc_reportnet(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long is_async) +{ + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = REPLY_RETCODE(CONTAINER_RESPRES(reply), altcom_result); + + return (is_async) ? REP_NO_ACK: REP_SEND_ACK; +} + +/**************************************************************************** + * name: postproc_radioon + ****************************************************************************/ + +static int postproc_radioon(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = REPLY_RETCODE(CONTAINER_RESPRES(reply), altcom_result); + + if (*usock_result == 0) + { + ret = send_reportnet_command(dev, reply, usock, postproc_reportnet, + arg, usock_result); + + MODEM_STATE_RON(dev); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_actpdn + ****************************************************************************/ + +static int postproc_actpdn(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long is_async) +{ + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + FAR lte_pdn_t *pdn = resp[1]; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = REPLY_RETCODE(CONTAINER_RESPRES(reply), altcom_result); + + if (*usock_result == 0) + { + /* After connecting to the LTE network, + * wait for the modem to register the network interface. + */ + + usleep(ALT1250_NETIF_READY_DELAY); + alt1250_netdev_ifup(dev, pdn); + } + + return (is_async) ? REP_NO_ACK: REP_SEND_ACK; +} + +/**************************************************************************** + * name: postproc_fwgetversion + ****************************************************************************/ + +int postproc_fwgetversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + FAR void **resp = CONTAINER_RESPONSE(reply); + int altcom_result = *((int *)(resp[0])); + lte_version_t *version = (lte_version_t *)(resp[1]); + + dbg_alt1250("%s start\n", __func__); + + *usock_result = REPLY_RETCODE(CONTAINER_RESPRES(reply), altcom_result); + + if (*usock_result == 0) + { + /* Keep version information on the device context */ + + strncpy(dev->fw_version, version->np_package, LTE_VER_NP_PACKAGE_LEN); + } + + return usock ? REP_SEND_ACK : REP_NO_ACK; +} + +/**************************************************************************** + * name: send_lapi_command + ****************************************************************************/ + +int send_lapi_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR postproc_hdlr_t hdlr, + unsigned long priv, + FAR int32_t *usock_result) +{ + set_container_ids(container, USOCKET_USOCKID(usock), ltecmd->cmdid); + set_container_argument(container, ltecmd->inparam, ltecmd->inparamlen); + set_container_response(container, ltecmd->outparam, ltecmd->outparamlen); + set_container_postproc(container, hdlr, priv); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +/**************************************************************************** + * name: postproc_setreport + ****************************************************************************/ + +static int postproc_setreport(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int index = (int)arg + 1; + + /* Register next report command */ + + return send_resume_command(dev, reply, usock, usock_result, index); +} + +/**************************************************************************** + * name: send_getversion_command + ****************************************************************************/ + +static int send_getversion_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_GETVER); + set_container_argument(container, NULL, 0); + set_container_response(container, alt1250_getevtarg(LTE_CMDID_GETVER), 2); + set_container_postproc(container, postproc_fwgetversion, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_register_command + ****************************************************************************/ + +static int send_register_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct lte_ioctl_data_s *ltecmd, + int index) +{ + set_container_ids(container, USOCKET_USOCKID(usock), ltecmd->cmdid); + set_container_argument(container, ltecmd->inparam, ltecmd->inparamlen); + set_container_response(container, ltecmd->outparam, ltecmd->outparamlen); + set_container_postproc(container, postproc_setreport, index); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_resume_command + ****************************************************************************/ + +static int send_resume_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + int index) +{ + int ret; + int cb_index = index; + uint32_t cmdid; + struct lte_ioctl_data_s ltecmd; + + /* Search report CB from table from index */ + + cmdid = alt1250_search_registered_callback(&cb_index); + if (cmdid != 0x00) + { + ret = alt1250_get_report_ltecmd(dev, cmdid, <ecmd); + if (ret == OK) + { + /* Register report command */ + + ret = send_register_command(dev, container, usock, usock_result, + <ecmd, cb_index); + } + else + { + *usock_result = ret; + ret = REP_SEND_ACK; + } + } + else + { + /* Finally, get firmware version from ALT1250 */ + + ret = send_getversion_command(dev, container, usock, usock_result); + } + + return ret; +} + +/**************************************************************************** + * name: lte_context_resume + ****************************************************************************/ + +static int lte_context_resume(FAR struct alt1250_s *dev, + FAR struct lte_ioctl_data_s *cmd, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + FAR uint8_t *ctx_data = (FAR uint8_t *)cmd->inparam[0]; + int len = *(FAR int *)cmd->inparam[1]; + int ret = REP_SEND_ACK; + int power = 0; + + if (!dev->is_resuming) + { + dbg_alt1250("Modem is not in a resuming mode.\n"); + *usock_result = -EPERM; + goto error; + } + + if (len != sizeof(struct alt1250_save_ctx)) + { + dbg_alt1250("Context data size is invalid(%d!=%d).\n", + sizeof(struct alt1250_save_ctx), len); + *usock_result = -EINVAL; + goto error; + } + + ret = alt1250_apply_daemon_context(dev, + (FAR struct alt1250_save_ctx *) + ctx_data); + if (ret < 0) + { + dbg_alt1250("Failed to apply saved alt1250 context(%d).\n", ret); + *usock_result = -EINVAL; + goto error; + } + + /* Retry mode is released in order to resume reception from ALT 1250. */ + + ret = altdevice_powercontrol(dev->altfd, LTE_CMDID_RETRYDISABLE); + if (ret != OK) + { + dbg_alt1250("Failed to stop retry mode(%d).\n", ret); + *usock_result = ret; + ret = REP_SEND_ACK; + goto error; + } + + /* If the ALT1250 is not powered on, return Resume as failure. */ + + power = altdevice_powercontrol(dev->altfd, LTE_CMDID_GET_POWER_STAT); + if (!power) + { + dbg_alt1250("Modem is turned off.\n"); + *usock_result = -ENETDOWN; + return REP_SEND_ACK; + } + + /* Register events so that event notifications are made to the + * report-based Callbacks registered in advance with lte_set_report*(). + */ + + ret = send_resume_command(dev, container, usock, usock_result, 0); + + if (*usock_result != OK) + { + dbg_alt1250("Failed to send resume commands.\n"); + } + + /* Resume phase is over */ + + dev->is_resuming = false; + + return ret; + +error: + altdevice_powercontrol(dev->altfd, LTE_CMDID_POWEROFF); + + /* Resume phase is over */ + + dev->is_resuming = false; + + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_normal + ****************************************************************************/ + +int usockreq_ioctl_normal(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + FAR struct usock_s *usock = NULL; + int ret = REP_SEND_ACK_WOFREE; + uint32_t cmdid = LTE_PURE_CMDID(ltecmd->cmdid); + FAR struct alt_container_s *container; + postproc_hdlr_t postproc_hdlr = NULL; + unsigned long priv = 0; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + if (LTE_IS_ASYNC_CMD(ltecmd->cmdid) && (ltecmd->cb != NULL)) + { + ret = alt1250_regevtcb(cmdid, ltecmd->cb); + if (ret < 0) + { + container_free(container); + *usock_result = ret; + return REP_SEND_ACK_WOFREE; + } + + ltecmd->outparam = alt1250_getevtarg(cmdid); + + /* The outparam is a array of "*void". + * In asynchronouse API case, the array size is known + * by container in the alt1250 driver. + * So don't need to set the outparamlen here. + */ + } + + switch (cmdid) + { + case LTE_CMDID_ACTPDN: + { + alt1250_saveapn(dev, (FAR lte_apn_setting_t *)ltecmd->inparam[0]); + + /* The handler is set for post process */ + + postproc_hdlr = postproc_actpdn; + priv = LTE_IS_ASYNC_CMD(ltecmd->cmdid); + } + break; + + case LTE_CMDID_DEACTPDN: + { + alt1250_netdev_ifdown(dev); + } + break; + + case LTE_CMDID_TLS_SSL_BIO: + { + /* Override socket id on input parameter from usock file descriptor + * to alt1250 device's socket descriptor + */ + + *(FAR int *)(ltecmd->inparam[5]) = USOCKET_ALTSOCKID(usock); + } + break; + + case LTE_CMDID_GETVER: + { + /* The handler is set for post process, + * but it will be avoided when the command is asynchronouse. + */ + + postproc_hdlr = postproc_fwgetversion; + } + break; + + case LTE_CMDID_RADIOON: + { + /* The handler is set for post process */ + + postproc_hdlr = postproc_radioon; + priv = LTE_IS_ASYNC_CMD(ltecmd->cmdid) ? + RADIOON_ASYNC : RADIOON_SYNC; + } + break; + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + case LTE_CMDID_RESUME: + return lte_context_resume(dev, ltecmd, container, usock, + usock_result); +#endif + + case LTE_CMDID_SAVE_LOG: + case LTE_CMDID_GET_LOGLIST: + case LTE_CMDID_LOGOPEN: + case LTE_CMDID_LOGCLOSE: + case LTE_CMDID_LOGREAD: + case LTE_CMDID_LOGLSEEK: + case LTE_CMDID_LOGREMOVE: + { + if (IS_LOG_UNAVAIL_FWVERSION(dev)) + { + container_free(container); + *usock_result = -ENOTSUP; + return REP_SEND_ACK_WOFREE; + } + } + break; + + case LTE_CMDID_RADIOOFF: + { + MODEM_STATE_PON(dev); + alt1250_netdev_ifdown(dev); + } + break; + + default: + break; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + ret = send_lapi_command(dev, container, usock, ltecmd, postproc_hdlr, priv, + usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (*usock_result < 0) + { + /* In error case, clear callback */ + + if (LTE_IS_ASYNC_CMD(ltecmd->cmdid) && (ltecmd->cb != NULL)) + { + alt1250_regevtcb(cmdid, NULL); + } + } + else if ((ltecmd->cmdid == LTE_CMDID_ACTPDN) || + (cmdid == LTE_CMDID_TLS_SSL_HANDSHAKE)) + { + /* The request from usersock cannot be accepted until the + * response is returned, so the REP_SEND_INPROG is returned + * to delay usock response and make this daemon to be able + * to handle other requests. + */ + + ret = REP_SEND_INPROG; + } + else if (LTE_IS_ASYNC_CMD(ltecmd->cmdid)) + { + ret = REP_SEND_ACK_WOFREE; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_other.c b/lte/alt1250/usock_handlers/alt1250_ioctl_other.c new file mode 100644 index 000000000..5010c84d5 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_other.c @@ -0,0 +1,249 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_other.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_util.h" +#include "alt1250_ioctl_subhdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: perform_setrestart + ****************************************************************************/ + +static int perform_setrestart(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + + *usock_result = alt1250_regevtcb(ltecmd->cmdid, ltecmd->cb); + + return REP_SEND_ACK_WOFREE; +} + +/**************************************************************************** + * name: perform_seteventctx + ****************************************************************************/ + +static int perform_seteventctx(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + FAR struct lte_evtctx_in_s *in = ltecmd->inparam[0]; + FAR struct lte_evtctx_out_s *out = ltecmd->outparam[0]; + + if ((in != NULL) && (in->mqname != NULL) && (out != NULL)) + { + /* No need to check strlen here. + * On current NuttX(v10.1) checks strlen of mssage queue name + * as MAX_MQUEUE_PATH. + */ + + *usock_result = alt1250_evttask_msgconnect(in->mqname, dev); + out->handle = alt1250_execcb; + } + + return REP_SEND_ACK_WOFREE; +} + +/**************************************************************************** + * name: perform_geterrinfo + ****************************************************************************/ + +static int perform_geterrinfo(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + + void **arg = alt1250_getevtarg(LTE_CMDID_GETERRINFO); + + if (arg && arg[0] && ltecmd->outparam && ltecmd->outparam[0]) + { + memcpy(ltecmd->outparam[0], arg[0], sizeof(lte_errinfo_t)); + *usock_result = OK; + } + + return REP_SEND_ACK_WOFREE; +} + +/**************************************************************************** + * name: perform_saveapn + ****************************************************************************/ + +static int perform_saveapn(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + + if (ltecmd->inparam && ltecmd->inparam[0]) + { + alt1250_saveapn(dev, + (FAR lte_apn_setting_t *)(ltecmd->inparam[0])); + *usock_result = OK; + } + + return REP_SEND_ACK_WOFREE; +} + +/**************************************************************************** + * name: perform_getapn + ****************************************************************************/ + +static int perform_getapn(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + + if (ltecmd->outparam && ltecmd->outparam[0]) + { + alt1250_getapn(dev, + (FAR lte_apn_setting_t *)(ltecmd->outparam[0])); + *usock_result = OK; + } + + return REP_SEND_ACK_WOFREE; +} + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE +/**************************************************************************** + * name: perform_setctxcb + ****************************************************************************/ + +static int perform_setctxcb(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + + *usock_result = alt1250_set_context_save_cb(dev, ltecmd->cb); + + return REP_SEND_ACK_WOFREE; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: alt1250_geterrinfo + ****************************************************************************/ + +void alt1250_geterrinfo(FAR lte_errinfo_t *errinfo) +{ + void **arg = alt1250_getevtarg(LTE_CMDID_GETERRINFO); + + if (arg && arg[0]) + { + memcpy(errinfo, arg[0], sizeof(lte_errinfo_t)); + } +} + +/**************************************************************************** + * name: usockreq_ioctl_other + ****************************************************************************/ + +int usockreq_ioctl_other(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + int ret = REP_SEND_ACK_WOFREE; + usrsock_reqhandler_t func = NULL; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = -EINVAL; + *usock_xid = request->head.xid; + + switch (ltecmd->cmdid) + { + case LTE_CMDID_SETRESTART: + func = perform_setrestart; + break; + + case LTE_CMDID_SETEVTCTX: + func = perform_seteventctx; + break; + + case LTE_CMDID_GETERRINFO: + func = perform_geterrinfo; + break; + + case LTE_CMDID_SAVEAPN: + func = perform_saveapn; + break; + + case LTE_CMDID_GETAPN: + func = perform_getapn; + break; + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + case LTE_CMDID_SETCTXCB: + func = perform_setctxcb; + break; +#endif + + default: + break; + } + + if (func != NULL) + { + ret = func(dev, req, usock_result, usock_xid, ackinfo); + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_power.c b/lte/alt1250/usock_handlers/alt1250_ioctl_power.c new file mode 100644 index 000000000..21e62462d --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_power.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_power.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_devif.h" +#include "alt1250_evt.h" +#include "alt1250_ioctl_subhdlr.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_netdev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl_power + ****************************************************************************/ + +int usockreq_ioctl_power(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_ioctl_data_s *ltecmd = &req->req_ioctl.ltecmd; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + switch (ltecmd->cmdid) + { + case LTE_CMDID_POWERON: + case LTE_CMDID_TAKEWLOCK: + case LTE_CMDID_GIVEWLOCK: + case LTE_CMDID_COUNTWLOCK: + *usock_result = altdevice_powercontrol(dev->altfd, ltecmd->cmdid); + if (MODEM_STATE_IS_POFF(dev) && ltecmd->cmdid == LTE_CMDID_POWERON) + { + /* For special reset sequence on power-on case */ + + MODEM_STATE_B4PON(dev); + } + break; + + case LTE_CMDID_POWEROFF: + alt1250_clrevtcb(ALT1250_CLRMODE_WO_RESTART); + *usock_result = altdevice_powercontrol(dev->altfd, ltecmd->cmdid); + MODEM_STATE_POFF(dev); + alt1250_netdev_ifdown(dev); + break; + + case LTE_CMDID_FIN: + alt1250_clrevtcb(ALT1250_CLRMODE_ALL); + ret = REP_SEND_TERM; + MODEM_STATE_POFF(dev); + break; + +#ifdef CONFIG_LTE_ALT1250_ENABLE_HIBERNATION_MODE + case LTE_CMDID_RETRYDISABLE: + case LTE_CMDID_GET_POWER_STAT: + *usock_result = altdevice_powercontrol(dev->altfd, ltecmd->cmdid); + break; +#endif + + default: + *usock_result = -EINVAL; + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_ioctl_subhdlr.h b/lte/alt1250/usock_handlers/alt1250_ioctl_subhdlr.h new file mode 100644 index 000000000..6ce7a1b74 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctl_subhdlr.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctl_subhdlr.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_IOCTL_SUBHDLR_H +#define __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_IOCTL_SUBHDLR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "alt1250_daemon.h" +#include "alt1250_usockif.h" +#include "alt1250_usockevent.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int usockreq_ioctl_ltecmd(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_ifreq(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_normal(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_event(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_other(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_power(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_fwupdate(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl_denyinetsock(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int send_m2mnotice_command(uint32_t cmdid, + FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR int32_t *ures); + +int usockreq_ioctl_lwm2m(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +#endif /* __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_IOCTL_SUBHDLR_H */ diff --git a/lte/alt1250/usock_handlers/alt1250_ioctlhdlr.c b/lte/alt1250/usock_handlers/alt1250_ioctlhdlr.c new file mode 100644 index 000000000..8861c6643 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_ioctlhdlr.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_ioctlhdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_ioctl_subhdlr.h" +#include "alt1250_sms.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_ioctl + ****************************************************************************/ + +int usockreq_ioctl(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = + &req->request.ioctl_req; + FAR struct usock_s *usock; + int ret = REP_SEND_ACK_WOFREE; + usrsock_reqhandler_t ioctl_subhdlr = NULL; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = -EBADFD; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock) + { + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + + switch (request->cmd) + { + case FIONBIO: + + /* ALT1250 doesn't use this command. Only return OK. */ + + *usock_result = OK; + break; + case SIOCLTECMD: + ioctl_subhdlr = usockreq_ioctl_ltecmd; + break; + case SIOCSIFFLAGS: + ioctl_subhdlr = usockreq_ioctl_ifreq; + break; + case SIOCDENYINETSOCK: + ioctl_subhdlr = usockreq_ioctl_denyinetsock; + break; + case SIOCSMSENSTREP: + case SIOCSMSGREFID: + case SIOCSMSSSCA: + ioctl_subhdlr = usockreq_ioctl_sms; + default: + *usock_result = -EINVAL; + break; + } + + if (ioctl_subhdlr != NULL) + { + ret = ioctl_subhdlr(dev, req, usock_result, usock_xid, ackinfo); + } + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_listenhdlr.c b/lte/alt1250/usock_handlers/alt1250_listenhdlr.c new file mode 100644 index 000000000..1475008d5 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_listenhdlr.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_listenhdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_devif.h" +#include "alt1250_socket.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_listen_command + ****************************************************************************/ + +static int send_listen_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + uint16_t backlog, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[2]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &backlog; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_LISTEN); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_sockcommon, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_listen + ****************************************************************************/ + +int nextstep_listen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + return send_listen_command(dev, reply, usock, USOCKET_REQBACKLOG(usock), + usock_result); +} + +/**************************************************************************** + * name: usockreq_listen + ****************************************************************************/ + +int usockreq_listen(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_listen_s *request = + &req->request.listen_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQBACKLOG(usock, request->backlog); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = nextstep_listen(dev, container, usock, usock_result, usock_xid, + ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} + diff --git a/lte/alt1250/usock_handlers/alt1250_recvfromhdlr.c b/lte/alt1250/usock_handlers/alt1250_recvfromhdlr.c new file mode 100644 index 000000000..460287ae8 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_recvfromhdlr.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_recvfromhdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_daemon.h" +#include "alt1250_container.h" +#include "alt1250_devif.h" +#include "alt1250_socket.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint16_t _rx_max_buflen; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: postproc_recvfrom + ****************************************************************************/ + +static int postproc_recvfrom(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + int rsize; + uint16_t addr_len = *(uint16_t *)(resp[2]); + + dbg_alt1250("%s start\n", __func__); + + dev->recvfrom_processing = false; + + /* resp[0]: recv size + * resp[1]: error code + * resp[2]: address length + * resp[3]: address + * resp[4]: buffer + */ + + rsize = COMBINE_ERRCODE(*(int *)(resp[0]), *(int *)(resp[1])); + + *usock_result = rsize; + *usock_xid = USOCKET_XID(usock); + + dbg_alt1250("recv %d bytes\n", rsize); + + if (rsize >= 0) + { + ackinfo->valuelen = MIN(USOCKET_REQADDRLEN(usock), addr_len); + ackinfo->valuelen_nontrunc = addr_len; /* Total size of addrlen */ + ackinfo->value_ptr = resp[3]; /* Receive from address */ + ackinfo->buf_ptr = resp[4]; /* Actual received data */ + + if ((rsize == 0) && (_rx_max_buflen != 0)) + { + usockif_sendclose(dev->usockfd, USOCKET_USOCKID(usock)); + } + + if ((rsize != 0) || (ackinfo->valuelen != 0)) + { + ret = REP_SEND_DACK; + } + } + + USOCKET_SET_SELECTABLE(usock, SELECT_READABLE); + usocket_commitstate(dev); + + return ret; +} + +/**************************************************************************** + * name: send_recvfrom_command + ****************************************************************************/ + +static int send_recvfrom_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int32_t flags, + uint16_t buflen, + int16_t addrlen, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[4]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &flags; + inparam[2] = &buflen; + inparam[3] = &addrlen; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDRLEN(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ADDR(usock)); + USOCKET_SET_RESPONSE(usock, idx++, dev->rx_buff); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_RECVFROM); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx++); + set_container_postproc(container, postproc_recvfrom, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_recvfrom + ****************************************************************************/ + +int usockreq_recvfrom(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_recvfrom_s *request = &req->request.recv_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret; + socklen_t addrlen; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQADDRLEN(usock, request->max_addrlen); + USOCKET_SET_REQBUFLEN(usock, request->max_buflen); + + if (IS_SMS_SOCKET(usock)) + { + ret = alt1250_sms_recv(dev, request, usock, usock_result, ackinfo); + } + else + { + /* Check if this socket is connected. */ + + if ((SOCK_STREAM == USOCKET_TYPE(usock)) && + (USOCKET_STATE(usock) != SOCKET_STATE_CONNECTED)) + { + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -ENOTCONN; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + if (USOCKET_DOMAIN(usock) == AF_INET) + { + addrlen = sizeof(struct sockaddr_in); + } + else + { + addrlen = sizeof(struct sockaddr_in6); + } + + _rx_max_buflen = MIN(request->max_buflen, _RX_BUFF_SIZE); + + ret = send_recvfrom_command(dev, container, usock, request->flags, + _rx_max_buflen, addrlen, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (*usock_result >= 0) + { + dev->recvfrom_processing = true; + } + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_sendtohdlr.c b/lte/alt1250/usock_handlers/alt1250_sendtohdlr.c new file mode 100644 index 000000000..9bd43b8a2 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_sendtohdlr.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_sendtohdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_sendto_command + ****************************************************************************/ + +static int send_sendto_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct usrsock_request_sendto_s *req, + uint16_t buflen, + FAR struct sockaddr_storage *addr, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[6]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &req->flags; + inparam[2] = &req->addrlen; + inparam[3] = &buflen; + inparam[4] = addr; + inparam[5] = dev->tx_buff; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_SENDTO); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_sockcommon, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_sendto + ****************************************************************************/ + +int usockreq_sendto(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_sendto_s *request = &req->request.send_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + struct sockaddr_storage addr; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQBUFLEN(usock, request->buflen); + + if (IS_SMS_SOCKET(usock)) + { + ret = alt1250_sms_send(dev, request, usock, usock_result); + } + else + { + /* Check if this socket is connected. */ + + if ((SOCK_STREAM == USOCKET_TYPE(usock)) && + (USOCKET_STATE(usock) != SOCKET_STATE_CONNECTED)) + { + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -ENOTCONN; + return REP_SEND_ACK_WOFREE; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + if (request->addrlen > 0) + { + /* Read address. */ + + ret = usockif_readreqaddr(dev->usockfd, &addr, request->addrlen); + if (ret < 0) + { + *usock_result = ret; + container_free(container); + return REP_SEND_ACK_WOFREE; + } + } + + /* Check if the request has data. */ + + if (request->buflen > 0) + { + size_t sendlen = MIN(request->buflen, _TX_BUFF_SIZE); + + ret = usockif_readreqsendbuf(dev->usockfd, dev->tx_buff, sendlen); + if (ret < 0) + { + *usock_result = ret; + container_free(container); + return REP_SEND_ACK_WOFREE; + } + + /* If the send size exceeds TX_BUFF_SIZE, + * use seek to discard the exceeded buffer. + */ + + if (request->buflen > sendlen) + { + usockif_discard(dev->usockfd, request->buflen - sendlen); + } + + ret = send_sendto_command(dev, container, usock, request, sendlen, + (request->addrlen > 0 ? &addr : NULL), + usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + else if(request->buflen == 0) + { + container_free(container); + ret = REP_SEND_ACK_WOFREE; + *usock_result = 0; + USOCKET_SET_SELECTABLE(usock, SELECT_WRITABLE); + usocket_commitstate(dev); + } + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_setsockopthdlr.c b/lte/alt1250/usock_handlers/alt1250_setsockopthdlr.c new file mode 100644 index 000000000..72d033708 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_setsockopthdlr.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_setsockopthdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_setsockopt_command + ****************************************************************************/ + +static int send_setsockopt_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[5]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &USOCKET_REQOPTLEVEL(usock); + inparam[2] = &USOCKET_REQOPTOPT(usock); + inparam[3] = &USOCKET_REQOPTLEN(usock); + inparam[4] = USOCKET_REQOPTVAL(usock); + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_SETSOCKOPT); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_sockcommon, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: nextstep_setsockopt + ****************************************************************************/ + +int nextstep_setsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + return send_setsockopt_command(dev, reply, usock, usock_result); +} + +/**************************************************************************** + * name: usockreq_setsockopt + ****************************************************************************/ + +int usockreq_setsockopt(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_setsockopt_s *request = &req->request.sopt_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + *usock_xid = request->head.xid; + + usock = usocket_search(dev, request->usockid); + if (usock == NULL) + { + dbg_alt1250("Failed to get socket context: %u\n", + request->usockid); + *usock_result = -EBADFD; + return REP_SEND_ACK_WOFREE; + } + + if (request->valuelen > _OPTVAL_LEN_MAX) + { + *usock_result = -EINVAL; + return REP_SEND_ACK_WOFREE; + } + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_REQSOCKOPT(usock, request->level, request->option, + request->valuelen); + + switch (USOCKET_STATE(usock)) + { + case SOCKET_STATE_CLOSED: + case SOCKET_STATE_CLOSING: + dbg_alt1250("Unexpected state: %d\n", USOCKET_STATE(usock)); + *usock_result = -EBADFD; + ret = REP_SEND_ACK_WOFREE; + break; + + case SOCKET_STATE_PREALLOC: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqoption(dev->usockfd, + USOCKET_REQOPTVAL(usock), + USOCKET_REQOPTLEN(usock)); + if (ret < 0) + { + return REP_SEND_ACK; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + + default: + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + *usock_result = usockif_readreqoption(dev->usockfd, + USOCKET_REQOPTVAL(usock), + USOCKET_REQOPTLEN(usock)); + if (ret < 0) + { + return REP_SEND_ACK; + } + + ret = nextstep_setsockopt(dev, container, usock, usock_result, + usock_xid, ackinfo, 0); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_shutdownhdlr.c b/lte/alt1250/usock_handlers/alt1250_shutdownhdlr.c new file mode 100644 index 000000000..3c23dd2dc --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_shutdownhdlr.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_shutdownhdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: usockreq_shutdown + ****************************************************************************/ + +int usockreq_shutdown(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_shutdown_s *request = + &req->request.shutdown_req; + + dbg_alt1250("%s start\n", __func__); + + /* Not support */ + + *usock_result = -ENOTSUP; + *usock_xid = request->head.xid; + + return REP_SEND_ACK_WOFREE; +} diff --git a/lte/alt1250/usock_handlers/alt1250_sms.c b/lte/alt1250/usock_handlers/alt1250_sms.c new file mode 100644 index 000000000..0a2dea196 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_sms.c @@ -0,0 +1,1050 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_sms.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" +#include "alt1250_sms.h" +#include "alt1250_evt.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_LTE_ALT1250_SMS_TOA) +# if defined(CONFIG_LTE_ALT1250_SMS_NAI_UNKNOWN) +# define ALT1250_SMS_NAI SMS_NAI_UNKNOWN +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_INTERNATIONAL) +# define ALT1250_SMS_NAI SMS_NAI_INTERNATIONAL +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_NATIONAL) +# define ALT1250_SMS_NAI SMS_NAI_NATIONAL +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_NETWORK_SPEC) +# define ALT1250_SMS_NAI SMS_NAI_NETWORK_SPEC +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_SUBSCRIBER) +# define ALT1250_SMS_NAI SMS_NAI_SUBSCRIBER +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_ALPANUMERIC) +# define ALT1250_SMS_NAI SMS_NAI_ALPANUMERIC +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_ABBREVIATED) +# define ALT1250_SMS_NAI SMS_NAI_ABBREVIATED +# elif defined(CONFIG_LTE_ALT1250_SMS_NAI_RESERVED) +# define ALT1250_SMS_NAI SMS_NAI_RESERVED +# endif +# if defined(CONFIG_LTE_ALT1250_SMS_NPI_UNKNOWN) +# define ALT1250_SMS_NPI SMS_NPI_UNKNOWN +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_ISDN) +# define ALT1250_SMS_NPI SMS_NPI_ISDN +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_DATA) +# define ALT1250_SMS_NPI SMS_NPI_DATA +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_TELEX) +# define ALT1250_SMS_NPI SMS_NPI_TELEX +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_SERVICE_CENTRE_SPEC) +# define ALT1250_SMS_NPI SMS_NPI_SERVICE_CENTRE_SPEC +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_SERVICE_CENTRE_SPEC2) +# define ALT1250_SMS_NPI SMS_NPI_SERVICE_CENTRE_SPEC2 +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_NATIONAL) +# define ALT1250_SMS_NPI SMS_NPI_NATIONAL +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_PRIVATE) +# define ALT1250_SMS_NPI SMS_NPI_PRIVATE +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_ERMES) +# define ALT1250_SMS_NPI SMS_NPI_ERMES +# elif defined(CONFIG_LTE_ALT1250_SMS_NPI_RESERVED) +# define ALT1250_SMS_NPI SMS_NPI_RESERVED +# endif +#endif /* CONFIG_LTE_ALT1250_SMS_TOA */ + +/* RK_02_01_01_10xxx FW version that does not support SMS feature */ + +#define IS_SMS_UNAVAIL_FWVERSION(d) (!strncmp(MODEM_FWVERSION(d), \ + "RK_02_01_01", 11)) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct alt_container_s g_sms_container; +static struct postproc_s g_sms_postproc; + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +static int postproc_smsinit(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_smsinit_reopen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_smsfin(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_smsfin_reopen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_smssend(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_smsdelete(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_smsinit_command + ****************************************************************************/ + +static int send_smsinit_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + int usockid, + FAR postproc_hdlr_t func, + FAR int32_t *usock_result) +{ + /* Dummy variable to receive replies by the container. + * No one refers to this address. + */ + + FAR void *dummy_output = NULL; + + clear_container(container); + set_container_ids(container, usockid, LTE_CMDID_SMS_INIT); + set_container_argument(container, NULL, 0); + set_container_response(container, &dummy_output, 1); + set_container_postproc(container, func, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_smsfin_command + ****************************************************************************/ + +static int send_smsfin_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + int usockid, + FAR postproc_hdlr_t func, + FAR int32_t *usock_result) +{ + /* Dummy variable to receive replies by the container. + * No one refers to this address. + */ + + FAR void *dummy_output = NULL; + + clear_container(container); + set_container_ids(container, usockid, LTE_CMDID_SMS_FIN); + set_container_argument(container, NULL, 0); + set_container_response(container, &dummy_output, 1); + set_container_postproc(container, func, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_smssend_command + ****************************************************************************/ + +static int send_smssend_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct sms_send_msg_s *msg, + FAR uint16_t msg_len, + FAR int32_t *usock_result) +{ + int idx = 0; + + FAR void *inparam[6]; + uint8_t chset = SMS_CHSET_UCS2; + + /* Thease members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = msg; + inparam[1] = &msg_len; + inparam[2] = &dev->sms_info.en_status_report; + inparam[3] = &dev->sms_info.dest_scaddr; + inparam[4] = &chset; +#if defined(CONFIG_LTE_ALT1250_SMS_TOA) + inparam[5] = &dev->sms_info.dest_toa; +#else + inparam[5] = NULL; +#endif + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REFID(usock)); + USOCKET_SET_RESPONSE(usock, idx++, &USOCKET_REQBUFLEN(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_SMS_SEND); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_smssend, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_smsdelete_command + ****************************************************************************/ + +static int send_smsdelete_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + uint16_t msg_index, + FAR int32_t *usock_result) +{ + /* Dummy variable to receive replies by the container. + * No one refers to this address. + */ + + FAR void *dummy_output = NULL; + FAR void *inparam[1]; + + /* This member is referenced only when sending a command and + * not when receiving a response, so local variables is used. + */ + + inparam[0] = &msg_index; + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_SMS_DELETE); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, &dummy_output, 1); + set_container_postproc(container, postproc_smsdelete, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: send_smsreportrecv_command + ****************************************************************************/ + +static int send_smsreportrecv_command(FAR struct alt1250_s *dev, + FAR int32_t *usock_result) +{ + struct alt_container_s container = { + 0 + }; + + set_container_ids(&container, 0, LTE_CMDID_SMS_REPORT_RECV); + + return altdevice_send_command(dev->altfd, &container, usock_result); +} + +/**************************************************************************** + * name: reset_sms_info + ****************************************************************************/ + +void reset_sms_info(FAR struct alt1250_s *dev) +{ + SMS_SET_STATE(&dev->sms_info, SMS_STATE_UNINIT); + dev->sms_info.msg_index = 0; + dev->sms_info.read_msglen = 0; + dev->sms_info.total_msglen = 0; + dev->sms_info.is_first_msg = false; +#if defined(CONFIG_LTE_ALT1250_SMS_TOA) + dev->sms_info.dest_toa = SMS_SET_TOA(ALT1250_SMS_NAI, ALT1250_SMS_NPI); +#endif +} + +/**************************************************************************** + * name: fill_recv_ackinfo + ****************************************************************************/ + +static bool fill_recv_ackinfo(FAR struct alt1250_s *dev, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR void **arg; + FAR uint8_t *msg_head; + uint16_t remain_msglen; + + /* arg[0]: sms msg index + * arg[1]: sms msg length + * arg[2]: Maximum number of msg for concatenate sms. + * arg[3]: Current number of msg for concatenate sms. + * arg[4]: sms msg + */ + + arg = alt1250_getevtarg(LTE_CMDID_SMS_REPORT_RECV); + + assert(arg && arg[4]); + + msg_head = (FAR uint8_t *)arg[4]; + remain_msglen = dev->sms_info.msglen - dev->sms_info.read_msglen; + + if (!dev->sms_info.is_first_msg) + { + /* In the case of a concatenated SMS, the header information is only + * given to the first SMS. Therefore, if the SMS is not the first + * one, the header information is shifted and read. + */ + + msg_head += sizeof(struct sms_recv_msg_header_s); + remain_msglen -= sizeof(struct sms_recv_msg_header_s); + } + + *usock_result = MIN(USOCKET_REQBUFLEN(usock), remain_msglen); + + ackinfo->valuelen = 0; + ackinfo->valuelen_nontrunc = 0; + ackinfo->value_ptr = NULL; + ackinfo->buf_ptr = msg_head + dev->sms_info.read_msglen; + + /* return is empty */ + + return (USOCKET_REQBUFLEN(usock) < remain_msglen) ? false : true; +} + +/**************************************************************************** + * name: notify_read_ready + ****************************************************************************/ + +static void notify_read_ready(FAR struct alt1250_s *dev, uint16_t msg_index, + uint16_t msg_len) +{ + dev->sms_info.msg_index = msg_index; + dev->sms_info.msglen = msg_len; + dev->sms_info.read_msglen = 0; + + usocket_smssock_readready(dev); +} + +/**************************************************************************** + * name: notify_abort + ****************************************************************************/ + +static void notify_abort(FAR struct alt1250_s *dev) +{ + reset_sms_info(dev); + usocket_smssock_abort(dev); +} + +/**************************************************************************** + * name: update_concat_size + ****************************************************************************/ + +static void update_concat_size(FAR struct alt1250_s *dev, uint16_t msg_index, + uint16_t msg_len, uint8_t max_num, + uint8_t seq_num, + FAR struct sms_recv_msg_header_s *sms_msg) +{ + int32_t usock_result = OK; + + dev->sms_info.total_msglen += sms_msg->datalen; + + if (max_num == seq_num) + { + /* In case of last of concatenated sms */ + + /* Send only SMS FIN command to avoid receiving the next SMS REPORT + * command. If SMS REPORT response is sent before SMS FIN command + * is sent, unexpected SMS REPORT command may be received. + */ + + send_smsfin_command(dev, &g_sms_container, 0, + postproc_smsfin_reopen, &usock_result); + if (usock_result < 0) + { + notify_abort(dev); + } + else + { + SMS_SET_STATE(&dev->sms_info, SMS_STATE_REOPEN); + + dev->sms_info.is_first_msg = true; + } + } + else + { + send_smsreportrecv_command(dev, &usock_result); + if (usock_result < 0) + { + notify_abort(dev); + } + } +} + +/**************************************************************************** + * name: handle_recvmsg + ****************************************************************************/ + +static void handle_recvmsg(FAR struct alt1250_s *dev, uint16_t msg_index, + uint16_t msg_len, uint8_t max_num, + uint8_t seq_num, + FAR struct sms_recv_msg_header_s *sms_msg) +{ + if (max_num == 0) + { + /* In case of not concatenated sms */ + + dev->sms_info.total_msglen = sms_msg->datalen; + dev->sms_info.is_first_msg = true; + + SMS_SET_STATE(&dev->sms_info, SMS_STATE_READ_READY); + + /* Notify usrsock of the read ready event. */ + + notify_read_ready(dev, msg_index, msg_len); + } + else + { + /* In case of concatenated sms */ + + SMS_SET_STATE(&dev->sms_info, SMS_STATE_CALC_SIZE); + + dev->sms_info.msg_index = msg_index; + + update_concat_size(dev, msg_index, msg_len, max_num, seq_num, sms_msg); + } +} + +/**************************************************************************** + * name: postproc_smsinit + ****************************************************************************/ + +static int postproc_smsinit(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK_TXREADY; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = CONTAINER_RESPRES(reply); + if (*usock_result < 0) + { + ret = REP_SEND_ACK; + } + else + { + *usock_result = USOCKET_USOCKID(usock); + ackinfo->usockid = USOCKET_USOCKID(usock); + SMS_SET_STATE(&dev->sms_info, SMS_STATE_WAITMSG); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_smsinit_reopen + ****************************************************************************/ + +static int postproc_smsinit_reopen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + *usock_result = CONTAINER_RESPRES(reply); + if (*usock_result >= 0) + { + SMS_SET_STATE(&dev->sms_info, SMS_STATE_WAITMSG_CONCAT); + } + else + { + notify_abort(dev); + } + + return REP_NO_ACK_WOFREE; +} + +/**************************************************************************** + * name: postproc_smsfin + ****************************************************************************/ + +static int postproc_smsfin(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + *usock_xid = USOCKET_XID(usock); + *usock_result = CONTAINER_RESPRES(reply); + + usocket_free(usock); + + return REP_SEND_ACK; +} + +/**************************************************************************** + * name: postproc_smsfin_reopen + ****************************************************************************/ + +static int postproc_smsfin_reopen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + dbg_alt1250("%s start\n", __func__); + + if (SMS_STATE(&dev->sms_info) == SMS_STATE_UNINIT) + { + dbg_alt1250("All sms sockets are closed\n"); + } + else + { + send_smsinit_command(dev, reply, 0, postproc_smsinit_reopen, + usock_result); + if (*usock_result < 0) + { + notify_abort(dev); + } + } + + return REP_NO_ACK_WOFREE; +} + +/**************************************************************************** + * name: postproc_smssend + ****************************************************************************/ + +static int postproc_smssend(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK_TXREADY; + + dbg_alt1250("%s start\n", __func__); + + /* resp[0]: referese ID list */ + + *usock_xid = USOCKET_XID(usock); + *usock_result = CONTAINER_RESPRES(reply); + + if (*usock_result == -EPROTO) + { + lte_errinfo_t errinfo; + alt1250_geterrinfo(&errinfo); + *usock_result = (errinfo.err_indicator & LTE_ERR_INDICATOR_ERRCODE) ? + -errinfo.err_result_code : *usock_result; + } + + ackinfo->usockid = USOCKET_USOCKID(usock); + + return ret; +} + +/**************************************************************************** + * name: postproc_smsdelete + ****************************************************************************/ + +static int postproc_smsdelete(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + + dbg_alt1250("%s start\n", __func__); + + *usock_xid = USOCKET_XID(usock); + *usock_result = CONTAINER_RESPRES(reply); + if (*usock_result >= 0) + { + ret = send_smsreportrecv_command(dev, usock_result); + if (*usock_result >= 0) + { + /* In case of success */ + + ret = REP_SEND_DACK; + fill_recv_ackinfo(dev, usock, usock_result, ackinfo); + + dev->sms_info.is_first_msg = false; + } + } + + return ret; +} + +/**************************************************************************** + * name: sms_report_event + ****************************************************************************/ + +static void sms_report_event(FAR struct alt1250_s *dev, uint16_t msg_index, + uint16_t msg_len, uint8_t max_num, + uint8_t seq_num, + FAR struct sms_recv_msg_header_s *sms_msg) +{ + dbg_alt1250("%s start\n", __func__); + + assert(msg_len >= sizeof(struct sms_recv_msg_header_s)); + + switch (SMS_STATE(&dev->sms_info)) + { + case SMS_STATE_UNINIT: + dbg_alt1250("All sms sockets are closed\n"); + break; + + case SMS_STATE_REOPEN: + dbg_alt1250("Receive report msg in REOPEN state\n"); + break; + + case SMS_STATE_READ_READY: + + /* Notify usrsock of the read ready event. */ + + notify_read_ready(dev, msg_index, msg_len); + break; + + case SMS_STATE_WAITMSG: + handle_recvmsg(dev, msg_index, msg_len, max_num, seq_num, sms_msg); + break; + + case SMS_STATE_WAITMSG_CONCAT: + if (dev->sms_info.msg_index != msg_index) + { + /* In case of unexpected SMS received. + * Therefore, start over from the beginning. + */ + + handle_recvmsg(dev, msg_index, msg_len, max_num, seq_num, + sms_msg); + } + else + { + /* In case of expected concatenated SMS received. */ + + sms_msg->datalen = dev->sms_info.total_msglen; + + SMS_SET_STATE(&dev->sms_info, SMS_STATE_READ_READY); + + /* Notify usrsock of the read ready event. */ + + notify_read_ready(dev, msg_index, msg_len); + } + break; + + case SMS_STATE_CALC_SIZE: + update_concat_size(dev, msg_index, msg_len, max_num, seq_num, + sms_msg); + break; + + default: + dbg_alt1250("Receive report msg in unexpected state: %d\n", + SMS_STATE(&dev->sms_info)); + break; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: alt1250_sms_init + ****************************************************************************/ + +int alt1250_sms_init(FAR struct alt1250_s *dev, FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct usock_ackinfo_s *ackinfo) +{ + int ret = REP_SEND_ACK_WOFREE; + FAR struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + if (IS_SMS_UNAVAIL_FWVERSION(dev)) + { + dbg_alt1250("This ALT1250 FW version does not support SMS.\n"); + *usock_result = -ENOTSUP; + return REP_SEND_ACK_WOFREE; + } + + if (SMS_STATE(&dev->sms_info) == SMS_STATE_UNINIT) + { + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = send_smsinit_command(dev, container, USOCKET_USOCKID(usock), + postproc_smsinit, usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + else + { + ret = REP_SEND_ACK_TXREADY; + ackinfo->usockid = USOCKET_USOCKID(usock); + } + + return ret; +} + +/**************************************************************************** + * name: alt1250_sms_fin + ****************************************************************************/ + +int alt1250_sms_fin(FAR struct alt1250_s *dev, FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK_WOFREE; + FAR struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = OK; + + if (usocket_smssock_num(dev) == 1) + { + if (SMS_STATE(&dev->sms_info) == SMS_STATE_REOPEN) + { + return REP_NO_CONTAINER; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + ret = send_smsfin_command(dev, container, USOCKET_USOCKID(usock), + postproc_smsfin, usock_result); + + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + alt1250_reset_sms_info(dev); + + if (*usock_result < 0) + { + usocket_free(usock); + } + } + else + { + usocket_free(usock); + } + + return ret; +} + +/**************************************************************************** + * name: alt1250_sms_send + ****************************************************************************/ + +int alt1250_sms_send(FAR struct alt1250_s *dev, + FAR struct usrsock_request_sendto_s *req, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int ret = REP_SEND_ACK_WOFREE; + FAR struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + if (SMS_STATE(&dev->sms_info) == SMS_STATE_REOPEN) + { + /* Sending the SMS send command now will fail because the + * SMS fin command has already been sent. + * Therefore, return REP_NO_CONTAINER and wait for the status to + * become ready to send. + */ + + return REP_NO_CONTAINER; + } + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + if (req->addrlen > 0) + { + /* Ignore destination address. */ + + usockif_discard(dev->usockfd, req->addrlen); + } + + if (req->buflen > 0 && + req->buflen <= sizeof(struct sms_send_msg_s) + (SMS_MAX_DATALEN * 2)) + { + ret = usockif_readreqsendbuf(dev->usockfd, dev->tx_buff, req->buflen); + if (ret < 0) + { + *usock_result = ret; + container_free(container); + return REP_SEND_ACK_WOFREE; + } + + ret = send_smssend_command(dev, container, usock, + (FAR struct sms_send_msg_s *)dev->tx_buff, + req->buflen, + usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + else + { + /* In case of invalid buffer length */ + + *usock_result = -EINVAL; + container_free(container); + ret = REP_SEND_ACK_WOFREE; + } + + return ret; +} + +/**************************************************************************** + * name: alt1250_sms_recv + ****************************************************************************/ + +int alt1250_sms_recv(FAR struct alt1250_s *dev, + FAR struct usrsock_request_recvfrom_s *req, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct usock_ackinfo_s *ackinfo) +{ + int ret = REP_SEND_ACK_WOFREE; + FAR struct alt_container_s *container; + + dbg_alt1250("%s start\n", __func__); + + if (SMS_STATE(&dev->sms_info) == SMS_STATE_REOPEN) + { + return REP_NO_CONTAINER; + } + + if (fill_recv_ackinfo(dev, usock, usock_result, ackinfo)) + { + /* In case of buffer is empty */ + + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + return REP_NO_CONTAINER; + } + + /* If the application has read all data, + * change the status to SMS_STATE_WAITMSG. + */ + + dev->sms_info.total_msglen -= (dev->sms_info.msglen - + sizeof(struct sms_recv_msg_header_s)); + if (dev->sms_info.total_msglen == 0) + { + SMS_SET_STATE(&dev->sms_info, SMS_STATE_WAITMSG); + } + + /* Delete the SMS in the ALT1250 because one SMS was read. */ + + ret = send_smsdelete_command(dev, container, usock, + dev->sms_info.msg_index, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + } + else + { + /* In case of buffer is not empty */ + + ret = REP_SEND_DACK_RXREADY; + dev->sms_info.read_msglen += req->max_buflen; + ackinfo->usockid = USOCKET_USOCKID(usock); + } + + return ret; +} + +/**************************************************************************** + * name: usockreq_ioctl_sms + ****************************************************************************/ + +int usockreq_ioctl_sms(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_ioctl_s *request = &req->request.ioctl_req; + FAR struct lte_smsreq_s *smsreq = &req->req_ioctl.smsreq; + FAR struct usock_s *usock; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start\n", __func__); + + *usock_result = -EBADFD; + + usock = usocket_search(dev, request->usockid); + if (usock) + { + switch (request->cmd) + { + case SIOCSMSENSTREP: + *usock_result = OK; + dev->sms_info.en_status_report = smsreq->smsru.enable; + break; + + case SIOCSMSGREFID: + *usock_result = OK; + ret = REP_SEND_DACK; + ackinfo->valuelen = sizeof(struct lte_smsreq_s); + ackinfo->valuelen_nontrunc = sizeof(struct lte_smsreq_s); + ackinfo->value_ptr = (FAR uint8_t *)USOCKET_REFID(usock); + ackinfo->buf_ptr = NULL; + break; + + case SIOCSMSSSCA: + *usock_result = OK; + memcpy(&dev->sms_info.dest_scaddr, &smsreq->smsru.scaddr, + sizeof(struct sms_sc_addr_s)); + break; + + default: + *usock_result = -EINVAL; + break; + } + } + + return ret; +} + +/**************************************************************************** + * name: perform_sms_report_event + ****************************************************************************/ + +uint64_t perform_sms_report_event(FAR struct alt1250_s *dev, uint64_t bitmap) +{ + uint64_t bit = 0ULL; + FAR void **arg; + + if (alt1250_checkcmdid(LTE_CMDID_SMS_REPORT_RECV, bitmap, &bit)) + { + arg = alt1250_getevtarg(LTE_CMDID_SMS_REPORT_RECV); + if (arg && arg[0] && arg[1] && arg[2] && arg[3] && arg[4]) + { + /* arg[0]: sms msg index + * arg[1]: sms msg length + * arg[2]: Maximum number of msg for concatenate sms. + * arg[3]: Current number of msg for concatenate sms. + * arg[4]: sms msg + */ + + sms_report_event(dev, *((FAR uint16_t *)arg[0]), + *((FAR uint16_t *)arg[1]), + *((FAR uint8_t *)arg[2]), + *((FAR uint8_t *)arg[3]), + (FAR struct sms_recv_msg_header_s *)arg[4]); + } + + alt1250_setevtarg_writable(LTE_CMDID_SMS_REPORT_RECV); + } + + return bit; +} + +/**************************************************************************** + * name: alt1250_sms_initcontainer + ****************************************************************************/ + +void alt1250_sms_initcontainer(FAR struct alt1250_s *dev) +{ + g_sms_container.priv = (unsigned long)&g_sms_postproc; + clear_container(&g_sms_container); +} + +/**************************************************************************** + * name: alt1250_reset_sms_info + ****************************************************************************/ + +void alt1250_reset_sms_info(FAR struct alt1250_s *dev) +{ + notify_abort(dev); +} diff --git a/lte/alt1250/usock_handlers/alt1250_sms.h b/lte/alt1250/usock_handlers/alt1250_sms.h new file mode 100644 index 000000000..477e7d924 --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_sms.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_sms.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SMS_H +#define __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SMS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "alt1250_container.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SMS_STATE(info) ((info)->sms_state) +#define SMS_MSG_INDEX(info) ((info)->msg_index) + +#define SMS_STATE_STR(ss) \ + ((ss) == SMS_STATE_UNINIT ? "SMS_STATE_UNINIT" : \ + (ss) == SMS_STATE_WAITMSG ? "SMS_STATE_WAITMSG" : \ + (ss) == SMS_STATE_READ_READY ? "SMS_STATE_READ_READY" : \ + (ss) == SMS_STATE_CALC_SIZE ? "SMS_STATE_CALC_SIZE" : \ + (ss) == SMS_STATE_REOPEN ? "SMS_STATE_REOPEN" : \ + (ss) == SMS_STATE_WAITMSG_CONCAT ? "SMS_STATE_WAITMSG_CONCAT" : \ + "ERROR UNKOWN STATE") + +#define SMS_SET_STATE(info, s) { \ + dbg_alt1250("[SMS stat] state: %s -> %s\n", \ + SMS_STATE_STR((info)->sms_state), SMS_STATE_STR(s)); \ + (info)->sms_state = (s); \ +} +#define SMS_SET_MSG_INDEX(info, x) ((info)->msg_index = (x)) + +/**************************************************************************** + * Public Data Type + ****************************************************************************/ + +enum sms_state_e +{ + SMS_STATE_UNINIT = 0, + SMS_STATE_WAITMSG, + SMS_STATE_READ_READY, + SMS_STATE_CALC_SIZE, + SMS_STATE_REOPEN, + SMS_STATE_WAITMSG_CONCAT +}; + +struct sms_info_s +{ + enum sms_state_e sms_state; + uint16_t msg_index; + unsigned short msglen; + unsigned short read_msglen; + unsigned short total_msglen; + bool is_first_msg; + + bool en_status_report; + struct sms_sc_addr_s dest_scaddr; +#if defined(CONFIG_LTE_ALT1250_SMS_TOA) + uint8_t dest_toa; +#endif +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int alt1250_sms_init(FAR struct alt1250_s *dev, FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct usock_ackinfo_s *ackinfo); +int alt1250_sms_fin(FAR struct alt1250_s *dev, FAR struct usock_s *usock, + FAR int32_t *usock_result); +int alt1250_sms_send(FAR struct alt1250_s *dev, + FAR struct usrsock_request_sendto_s *req, + FAR struct usock_s *usock, + FAR int32_t *usock_result); +int alt1250_sms_recv(FAR struct alt1250_s *dev, + FAR struct usrsock_request_recvfrom_s *req, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR struct usock_ackinfo_s *ackinfo); +int usockreq_ioctl_sms(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); +uint64_t perform_sms_report_event(FAR struct alt1250_s *dev, + uint64_t bitmap); +void alt1250_sms_initcontainer(FAR struct alt1250_s *dev); +void alt1250_reset_sms_info(FAR struct alt1250_s *dev); + +#endif /* __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SMS_H */ diff --git a/lte/alt1250/usock_handlers/alt1250_sockethdlr.c b/lte/alt1250/usock_handlers/alt1250_sockethdlr.c new file mode 100644 index 000000000..c0687a3cb --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_sockethdlr.c @@ -0,0 +1,471 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_sockethdlr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "alt1250_dbg.h" +#include "alt1250_container.h" +#include "alt1250_socket.h" +#include "alt1250_devif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" +#include "alt1250_usrsock_hdlr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IS_SUPPORTED_INET_DOMAIN(d) (((d) == AF_INET) || ((d) == AF_INET6)) + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +static int postproc_getfl(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +static int postproc_setfl(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * name: send_fctl_command + ****************************************************************************/ + +static int send_fctl_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int32_t cmd, + int32_t val, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[3]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &USOCKET_ALTSOCKID(usock); + inparam[1] = &cmd; + inparam[2] = &val; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_FCNTL); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, cmd == ALTCOM_SETFL ? postproc_setfl : + cmd == ALTCOM_GETFL ? postproc_getfl : NULL, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * name: postproc_setfl + ****************************************************************************/ + +static int postproc_setfl(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + /* resp[0]: command return code + * resp[1]: alt1250 errno + */ + + dbg_alt1250("%s start\n", __func__); + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_OPENED); + usocket_commitstate(dev); + + switch (USOCKET_REQID(usock)) + { + case USRSOCK_REQUEST_SOCKET: + *usock_result = USOCKET_USOCKID(usock); + dbg_alt1250("allocated usockid: %d\n", *usock_result); + break; + + /* Below cases are for SOCK_STREAM type socket + * SOCK_STREAM type socket can not be opend on alt1250 side, + * because of LAPI command. It is also using SOCK_STREAM + * type socket to send ioctl() to communicate with daemon. + * So, on BSD-socket spec, aftre socket() API succeeded, + * connect(), bind(), etc, can be called. And on the call, + * socket on alt1250 side should be fixed, therefore, + * open_altsocket() will be called on those cases. + */ + + case USRSOCK_REQUEST_CONNECT: + ret = nextstep_connect(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + case USRSOCK_REQUEST_BIND: + ret = nextstep_bind(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + case USRSOCK_REQUEST_LISTEN: + ret = nextstep_listen(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + case USRSOCK_REQUEST_SETSOCKOPT: + ret = nextstep_setsockopt(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + case USRSOCK_REQUEST_GETSOCKOPT: + ret = nextstep_getsockopt(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + case USRSOCK_REQUEST_GETSOCKNAME: + ret = nextstep_getsockname(dev, reply, usock, usock_result, + usock_xid, ackinfo, arg); + break; + + default: + dbg_alt1250("unexpected sequense. reqid:0x%02x\n", + USOCKET_REQID(usock)); + *usock_result = -EFAULT; + break; + } + } + else + { + USOCKET_SET_STATE(usock, SOCKET_STATE_PREALLOC); + if (USOCKET_TYPE(usock) == SOCK_DGRAM) + { + usocket_free(usock); + } + + usocket_commitstate(dev); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_getfl + ****************************************************************************/ + +static int postproc_getfl(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + /* resp[0]: command return code + * resp[1]: alt1250 errno + */ + + dbg_alt1250("%s start\n", __func__); + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + /* Set non-blocking flag of socket fd */ + + *usock_result |= ALTCOM_O_NONBLOCK; + + ret = send_fctl_command(dev, reply, usock, ALTCOM_SETFL, *usock_result, + usock_result); + } + + if (*usock_result < 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_PREALLOC); + if (USOCKET_TYPE(usock) == SOCK_DGRAM) + { + /* In DGRAM case, it is a part of socket() API sequence. + * The socket() API is not returned on application layer. + * So, internal socket should be free here. + */ + + usocket_free(usock); + } + + usocket_commitstate(dev); + } + + return ret; +} + +/**************************************************************************** + * name: postproc_socket + ****************************************************************************/ + +static int postproc_socket(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg) +{ + int ret = REP_SEND_ACK; + FAR void **resp = CONTAINER_RESPONSE(reply); + + /* resp[0]: altcom_sockfd + * resp[1]: alt1250 errno + */ + + dbg_alt1250("%s start\n", __func__); + + *usock_xid = USOCKET_XID(usock); + *usock_result = COMBINE_ERRCODE(*(int *)resp[0], *(int *)resp[1]); + + if (*usock_result >= 0) + { + /* In case of success socket allocation */ + + USOCKET_SET_ALTSOCKID(usock, *usock_result); + + ret = send_fctl_command(dev, reply, usock, ALTCOM_GETFL, 0, + usock_result); + } + + if (*usock_result < 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_PREALLOC); + if (USOCKET_TYPE(usock) == SOCK_DGRAM) + { + /* In DGRAM case, it is a part of socket() API sequence. + * The socket() API is not returned on application layer. + * So, internal socket should be free here. + */ + + usocket_free(usock); + } + + usocket_commitstate(dev); + } + + return ret; +} + +/**************************************************************************** + * name: send_socket_command + ****************************************************************************/ + +static int send_socket_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int16_t domain, + int16_t type, + int16_t protocol, + FAR int32_t *usock_result) +{ + int idx = 0; + FAR void *inparam[3]; + + /* These members are referenced only when sending a command and + * not when receiving a response, so local variables are used. + */ + + inparam[0] = &domain; + inparam[1] = &type; + inparam[2] = &protocol; + + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_RESULT(usock)); + USOCKET_SET_RESPONSE(usock, idx++, USOCKET_REP_ERRCODE(usock)); + + set_container_ids(container, USOCKET_USOCKID(usock), LTE_CMDID_SOCKET); + set_container_argument(container, inparam, nitems(inparam)); + set_container_response(container, USOCKET_REP_RESPONSE(usock), idx); + set_container_postproc(container, postproc_socket, 0); + + return altdevice_send_command(dev->altfd, container, usock_result); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * name: open_altsocket + ****************************************************************************/ + +int open_altsocket(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result) +{ + int ret; + + dbg_alt1250("%s start\n", __func__); + + ret = send_socket_command(dev, container, usock, + USOCKET_DOMAIN(usock), USOCKET_TYPE(usock), + USOCKET_PROTOCOL(usock), + usock_result); + if (*usock_result >= 0) + { + USOCKET_SET_STATE(usock, SOCKET_STATE_OPEN); + usocket_commitstate(dev); + } + + return ret; +} + +/**************************************************************************** + * name: usockreq_socket + ****************************************************************************/ + +int usockreq_socket(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo) +{ + FAR struct usrsock_request_socket_s *request = &req->request.sock_req; + FAR struct usock_s *usock; + FAR struct alt_container_s *container; + int ret = REP_SEND_ACK_WOFREE; + + dbg_alt1250("%s start type=%d\n", __func__, request->type); + + *usock_xid = request->head.xid; + + if (!IS_SUPPORTED_INET_DOMAIN(request->domain)) + { + dbg_alt1250("Not support this domain: %u\n", request->domain); + *usock_result = -EAFNOSUPPORT; + return REP_SEND_ACK_WOFREE; + } + else if (!dev->usock_enable && IS_SUPPORTED_INET_DOMAIN(request->domain) && + request->type != SOCK_CTRL) + { + /* If domain is AF_INET while usock_enable is false, + * set usockid to -EPROTONOSUPPORT to fallback kernel + * network stack. + */ + + *usock_result = -EPROTONOSUPPORT; + return REP_SEND_ACK_WOFREE; + } + + if (!dev->api_enable) + { + dbg_alt1250("Don't allow to call any API now.\n"); + *usock_result = -EBUSY; + return REP_SEND_ACK_WOFREE; + } + + usock = usocket_alloc(dev, request->type); + if (usock == NULL) + { + dbg_alt1250("socket alloc faild\n"); + *usock_result = -EBUSY; + return REP_SEND_ACK_WOFREE; + } + + *usock_result = USOCKET_USOCKID(usock); + + USOCKET_SET_REQUEST(usock, request->head.reqid, request->head.xid); + USOCKET_SET_SOCKTYPE(usock, request->domain, request->type, + request->protocol); + + switch (request->type) + { + case SOCK_STREAM: + case SOCK_CTRL: + dbg_alt1250("allocated usockid: %d\n", *usock_result); + break; + + case SOCK_SMS: + ret = alt1250_sms_init(dev, usock, usock_result, ackinfo); + if (*usock_result < 0) + { + usocket_free(usock); + } + break; + + case SOCK_DGRAM: + case SOCK_RAW: + dbg_alt1250("allocated usockid: %d\n", *usock_result); + container = container_alloc(); + if (container == NULL) + { + dbg_alt1250("no container\n"); + usocket_free(usock); + return REP_NO_CONTAINER; + } + + ret = open_altsocket(dev, container, usock, usock_result); + if (IS_NEED_CONTAINER_FREE(ret)) + { + container_free(container); + } + + if (*usock_result < 0) + { + usocket_free(usock); + } + break; + + default: + dbg_alt1250("Not support this type: %u\n", request->type); + *usock_result = -EAFNOSUPPORT; + usocket_free(usock); + break; + } + + return ret; +} diff --git a/lte/alt1250/usock_handlers/alt1250_usrsock_hdlr.h b/lte/alt1250/usock_handlers/alt1250_usrsock_hdlr.h new file mode 100644 index 000000000..7bd85b2ae --- /dev/null +++ b/lte/alt1250/usock_handlers/alt1250_usrsock_hdlr.h @@ -0,0 +1,234 @@ +/**************************************************************************** + * apps/lte/alt1250/usock_handlers/alt1250_usrsock_hdlr.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SOCKETHDLR_H +#define __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SOCKETHDLR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "alt1250_daemon.h" +#include "alt1250_usockif.h" +#include "alt1250_usockevent.h" +#include "alt1250_postproc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define COMBINE_ERRCODE(res, ecode) (((res) < 0) ? -(ecode) : (res)) + +#define ALT1250_NETIF_READY_DELAY (150 * 1000) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void reset_fwupdate_info(FAR struct alt1250_s *dev); + +int usockreq_socket(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_close(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_connect(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_sendto(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_recvfrom(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_setsockopt(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_getsockopt(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_getsockname(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_getpeername(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_bind(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_listen(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_accept(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_ioctl(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int usockreq_shutdown(FAR struct alt1250_s *dev, + FAR struct usrsock_request_buff_s *req, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo); + +int open_altsocket(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR int32_t *usock_result); + +int nextstep_connect(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int nextstep_check_connectres(FAR struct alt1250_s *dev, + FAR struct usock_s *usock); + +int nextstep_bind(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int nextstep_listen(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int nextstep_setsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int nextstep_getsockopt(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int nextstep_getsockname(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int postproc_sockcommon(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +int send_getsockopt_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + int16_t level, + int16_t option, + uint16_t valuelen, + FAR int16_t *requested_level, + FAR int16_t *requested_option, + FAR postproc_hdlr_t func, + unsigned long priv, + FAR int32_t *usock_result); + +int send_reportnet_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR postproc_hdlr_t func, + unsigned long priv, + FAR int32_t *usock_result); + +int send_lapi_command(FAR struct alt1250_s *dev, + FAR struct alt_container_s *container, + FAR struct usock_s *usock, + FAR struct lte_ioctl_data_s *ltecmd, + FAR postproc_hdlr_t hdlr, + unsigned long priv, + FAR int32_t *usock_result); + +int postproc_fwgetversion(FAR struct alt1250_s *dev, + FAR struct alt_container_s *reply, + FAR struct usock_s *usock, + FAR int32_t *usock_result, + FAR uint32_t *usock_xid, + FAR struct usock_ackinfo_s *ackinfo, + unsigned long arg); + +void alt1250_geterrinfo(FAR lte_errinfo_t *errinfo); + +#endif /* __APPS_LTE_ALT1250_USOCK_HANDLERS_ALT1250_SOCKETHDLR_H */ diff --git a/lte/lapi/Kconfig b/lte/lapi/Kconfig new file mode 100644 index 000000000..61af77282 --- /dev/null +++ b/lte/lapi/Kconfig @@ -0,0 +1,49 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig LTE_LAPI + bool "LTE Configuration Library" + default n + ---help--- + Enable the LTE Configuration Library. + +if LTE_LAPI + +config LTE_LAPI_DEBUG_MSG + bool "Enable debug output messages" + default n + depends on DEBUG_NET_ERROR + +config LTE_LAPI_KEEP_COMPATIBILITY + bool "Keep the LTE library compatible." + default n + ---help--- + lte_get_operator_sync, lte_get_imsi_sync, lte_get_imei_sync, lte_get_phoneno_sync, + these functions have changed their specifications to specify the length of the + argument string. Functions in the old spec will be discarded, but enabling this + option makes you be able to use them. + Furthermore, this option will be removed in the near future, and functions in + the old spec will be completely discarded. + +config LTE_LAPI_LOG_ACCESS + bool "Enable the log access API" + default n + ---help--- + Enable these log access APIs: lte_log_open, lte_log_close, + lte_log_read, lte_log_lseek, lte_log_remove. + +config LTE_LAPI_ENABLE_DEPRECATED_API + bool "Enable deprecated API" + default y + ---help--- + If your application does not use the deprecated APIs, + this option can help to reduce memory usage. + Deprecated APIs are asynchronous APIs except lte_activate_pdn. + See include/lte/lte_api.h for a list of asynchronous APIs. + Deprecated APIs will be removed in the future, + please use the synchronous API instead. + +endif + diff --git a/lte/lapi/Make.defs b/lte/lapi/Make.defs new file mode 100644 index 000000000..77996b20e --- /dev/null +++ b/lte/lapi/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/lte/lapi/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LTE_LAPI),) +CONFIGURED_APPS += $(APPDIR)/lte/lapi +endif diff --git a/lte/lapi/Makefile b/lte/lapi/Makefile new file mode 100644 index 000000000..55d9362f7 --- /dev/null +++ b/lte/lapi/Makefile @@ -0,0 +1,27 @@ +############################################################################ +# apps/lte/lapi/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# LTE Lapi Application + +include $(APPDIR)/lte/lapi/src/Make.defs + +include $(APPDIR)/Application.mk diff --git a/lte/lapi/src/Make.defs b/lte/lapi/src/Make.defs new file mode 100644 index 000000000..7ea2d4760 --- /dev/null +++ b/lte/lapi/src/Make.defs @@ -0,0 +1,40 @@ +############################################################################ +# apps/lte/lapi/src/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LTE_LAPI),) + +CSRCS = lapi_evt.c \ + lapi_firmware.c \ + lapi_net.c \ + lapi_other.c \ + lapi_pdn.c \ + lapi_pin.c \ + lapi_power.c \ + lapi_psave.c \ + lapi_radio.c \ + lapi_sim.c \ + lapi_lwm2m.c \ + lapi_log.c + +DEPPATH += --dep-path src +VPATH += :src +CFLAGS += ${shell $(INCDIR) "$(CC)" $(APPDIR)/lte/lapi/src} + +endif diff --git a/lte/lapi/src/lapi_dbg.h b/lte/lapi/src/lapi_dbg.h new file mode 100644 index 000000000..0ad8e1e80 --- /dev/null +++ b/lte/lapi/src/lapi_dbg.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_dbg.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_LTE_LAPI_LAPI_DBG_H +#define __APPS_LTE_LAPI_LAPI_DBG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_LTE_LAPI_DEBUG_MSG +# define lapi_printf nerr +#else +# define lapi_printf(v, ...) +#endif + +#endif /* __APPS_LTE_LAPI_LAPI_DBG_H */ diff --git a/lte/lapi/src/lapi_evt.c b/lte/lapi/src/lapi_evt.c new file mode 100644 index 000000000..cc047584b --- /dev/null +++ b/lte/lapi/src/lapi_evt.c @@ -0,0 +1,202 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_evt.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define EVENT_MAX 64 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static mqd_t g_mqd; +static struct lte_evtctx_out_s g_evtctx; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lapi_evtinit + ****************************************************************************/ + +int lapi_evtinit(FAR const char *mqname) +{ + int ret = OK; + struct mq_attr attr = + { + 0 + }; + + struct lte_evtctx_in_s in; + FAR void *inarg[] = + { + &in + }; + + FAR void *outarg[] = + { + &g_evtctx + }; + + attr.mq_maxmsg = EVENT_MAX; + attr.mq_msgsize = sizeof(uint64_t); + + g_mqd = mq_open(mqname, O_CREAT | O_RDONLY | O_EXCL, 0666, &attr); + if (g_mqd == (mqd_t)-1) + { + lapi_printf("failed to open mq(%s): %d\n", mqname, errno); + return -errno; + } + + in.mqname = mqname; + ret = lapi_req(LTE_CMDID_SETEVTCTX, (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), NULL); + if (ret < 0) + { + lapi_printf("failed to lapi request: %d\n", ret); + mq_close(g_mqd); + mq_unlink(mqname); + } + + return ret; +} + +/**************************************************************************** + * Name: lapi_evtdestoy + ****************************************************************************/ + +void lapi_evtdestoy(void) +{ + mq_close(g_mqd); +} + +/**************************************************************************** + * Name: lapi_evtyield + ****************************************************************************/ + +int lapi_evtyield(int timeout_ms) +{ + int ret; + ssize_t sz; + uint64_t buf; + struct timespec ts; + bool is_exit = false; + + if (timeout_ms >= 0) + { + if (clock_gettime(CLOCK_REALTIME, &ts) != OK) + { + return -errno; + } + + ts.tv_sec += timeout_ms / 1000; + timeout_ms -= timeout_ms / 1000; + ts.tv_nsec += timeout_ms * 1000 * 1000; + } + + while (!is_exit) + { + if (timeout_ms >= 0) + { + sz = mq_timedreceive(g_mqd, (FAR void *)&buf, sizeof(buf), NULL, + &ts); + if (sz < 0) + { + ret = -errno; + if (errno != ETIMEDOUT) + { + lapi_printf("failed to mq_receive: %d\n", errno); + } + + is_exit = true; + continue; + } + } + else + { + sz = mq_receive(g_mqd, (FAR void *)&buf, sizeof(buf), NULL); + if (sz < 0) + { + ret = -errno; + lapi_printf("failed to mq_receive: %d\n", errno); + is_exit = true; + continue; + } + } + + if (buf == 0ULL) + { + ret = OK; + is_exit = true; + } + else + { + g_evtctx.handle(buf); + } + } + + return ret; +} + +/**************************************************************************** + * Name: lapi_evtsend + ****************************************************************************/ + +int lapi_evtsend(uint64_t evtbitmap) +{ + int ret; + + ret = mq_send(g_mqd, (FAR const char *)&evtbitmap, sizeof(evtbitmap), 0); + if (ret < 0) + { + ret = -errno; + lapi_printf("failed to send mq: %d\n", errno); + } + + return ret; +} diff --git a/lte/lapi/src/lapi_firmware.c b/lte/lapi/src/lapi_firmware.c new file mode 100644 index 000000000..a02113f0a --- /dev/null +++ b/lte/lapi/src/lapi_firmware.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_firmware.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "lte/lapi.h" +#include "lte/lte_api.h" +#include "lte/lte_fwupdate.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int fw_inject_internal(FAR const char *data, int len, bool init) +{ + FAR void *inarg[3] = + { + (FAR void *)data, &len, &init + }; + + int dummy_arg; /* Dummy for blocking API call */ + + if (data == NULL || len < 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_INJECTIMAGE, + (FAR void *)inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, NULL); +} + +static int fw_generic_request(int cmdid) +{ + int dummy_arg; /* Dummy for blocking API call */ + + return lapi_req(cmdid, NULL, 0, (FAR void *)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_get_version_sync(FAR lte_version_t *version) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, version + }; + + if (version == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETVER, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + return (ret == 0) ? result : ret; +} + +int ltefwupdate_initialize(FAR const char *initial_data, int len) +{ + return fw_inject_internal(initial_data, len, true); +} + +int ltefwupdate_injectrest(FAR const char *rest_data, int len) +{ + return fw_inject_internal(rest_data, len, false); +} + +int ltefwupdate_injected_datasize(void) +{ + return fw_generic_request(LTE_CMDID_GETIMAGELEN); +} + +int ltefwupdate_execute(void) +{ + int ret; + + /* If wakelock is not acquired, firmware update + * cannot be performed. + */ + + ret = lte_get_wakelock_count(); + if (ret <= 0) + { + if (ret == 0) + { + lapi_printf("wakelock is not acquired\n"); + ret = -EPERM; + } + + return ret; + } + + return fw_generic_request(LTE_CMDID_EXEUPDATE); +} + +int ltefwupdate_result(void) +{ + return fw_generic_request(LTE_CMDID_GETUPDATERES); +} + +int lte_factory_reset_sync(void) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_FACTORY_RESET, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + + return ret; +} + +/* Asynchronous APIs */ + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_get_version(get_ver_cb_t callback) +{ + printf("This API is discarded. Please use lte_get_version_sync().\n"); + return -ENOTSUP; +} +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + diff --git a/lte/lapi/src/lapi_log.c b/lte/lapi/src/lapi_log.c new file mode 100644 index 000000000..547b1b1fd --- /dev/null +++ b/lte/lapi/src/lapi_log.c @@ -0,0 +1,211 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_log.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "lte/lapi.h" +#include "lte/lte_log.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lte_log_collect + ****************************************************************************/ + +int lte_log_collect(FAR char *output_fname, size_t len) +{ + FAR void *inarg[] = + { + (FAR void *)&len + }; + + FAR void *outarg[] = + { + output_fname, (FAR void *)&len + }; + + if ((output_fname != NULL) && (len != LTE_LOG_NAME_LEN)) + { + return -ENOBUFS; + } + + len = LTE_LOG_NAME_LEN; + + return lapi_req(LTE_CMDID_SAVE_LOG, + inarg, nitems(inarg), + outarg, nitems(outarg), + NULL); +} + +/**************************************************************************** + * Name: lte_log_getlist + ****************************************************************************/ + +int lte_log_getlist(size_t listsize, size_t fnamelen, + char list[listsize][fnamelen]) +{ + FAR void *inarg[] = + { + (FAR void *)fnamelen + }; + + FAR void *outarg[] = + { + list, (FAR void *)listsize, (FAR void *)fnamelen + }; + + if ((listsize == 0) || (list == NULL)) + { + return -EINVAL; + } + + if (fnamelen != LTE_LOG_NAME_LEN) + { + return -ENOBUFS; + } + + return lapi_req(LTE_CMDID_GET_LOGLIST, + inarg, nitems(inarg), + outarg, nitems(outarg), + NULL); +} + +#ifdef CONFIG_LTE_LAPI_LOG_ACCESS + +/**************************************************************************** + * Name: lte_log_open + ****************************************************************************/ + +int lte_log_open(FAR const char *filename) +{ + int dummy_arg; /* Dummy for blocking API call */ + FAR void *inarg[] = + { + (FAR void *)filename + }; + + if (filename == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LOGOPEN, + inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, + NULL); +} + +/**************************************************************************** + * Name: lte_log_close + ****************************************************************************/ + +int lte_log_close(int fd) +{ + int dummy_arg; /* Dummy for blocking API call */ + FAR void *inarg[] = + { + (FAR void *)fd + }; + + return lapi_req(LTE_CMDID_LOGCLOSE, + inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, + NULL); +} + +/**************************************************************************** + * Name: lte_log_read + ****************************************************************************/ + +ssize_t lte_log_read(int fd, FAR void *buf, size_t len) +{ + FAR void *inarg[] = + { + (FAR void *)fd, (FAR void *)len + }; + + FAR void *outarg[] = + { + buf, (FAR void *)len + }; + + if ((buf == NULL) || (len == 0)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LOGREAD, + inarg, nitems(inarg), + outarg, nitems(outarg), + NULL); +} + +/**************************************************************************** + * Name: lte_log_lseek + ****************************************************************************/ + +int lte_log_lseek(int fd, off_t offset, int whence) +{ + int dummy_arg; /* Dummy for blocking API call */ + FAR void *inarg[] = + { + (FAR void *)fd, (FAR void *)&offset, (FAR void *)whence + }; + + return lapi_req(LTE_CMDID_LOGLSEEK, + inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, + NULL); +} + +/**************************************************************************** + * Name: lte_log_remove + ****************************************************************************/ + +int lte_log_remove(FAR const char *filename) +{ + int dummy_arg; /* Dummy for blocking API call */ + FAR void *inarg[] = + { + (FAR void *)filename + }; + + if (filename == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LOGREMOVE, + inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, + NULL); +} + +#endif /* CONFIG_LTE_LAPI_LOG_ACCESS */ diff --git a/lte/lapi/src/lapi_lwm2m.c b/lte/lapi/src/lapi_lwm2m.c new file mode 100644 index 000000000..8542f6807 --- /dev/null +++ b/lte/lapi/src/lapi_lwm2m.c @@ -0,0 +1,489 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_lwm2m.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "lte/lapi.h" +#include "lte/lte_api.h" +#include "lte/lte_lwm2m.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: check_instance + ****************************************************************************/ + +static int check_instance(FAR struct lwm2mstub_instance_s *inst) +{ + int ret = OK; + + if (inst->object_id < 0 || inst->object_inst < 0 || inst->res_id < 0) + { + ret = ERROR; + } + + return ret; +} + +/**************************************************************************** + * Name: insert_sort + ****************************************************************************/ + +static void insert_sort(FAR uint16_t *array, int sz) +{ + int i; + int j; + uint16_t tmp; + + for (i = 1; i < sz; i++) + { + j = i; + while (j > 0 && array[j - 1] > array[j]) + { + tmp = array[j - 1]; + array[j - 1] = array[j]; + array[j] = tmp; + j--; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lte_m2m_connection + ****************************************************************************/ + +int lte_m2m_connection(int cmd) +{ + if (cmd < LWM2MSTUB_CONNECT_REGISTER || cmd > LWM2MSTUB_CONNECT_BOOTSTRAP) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_CONNECT, (FAR void **)cmd, + 1, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_m2m_readresponse + ****************************************************************************/ + +int lte_m2m_readresponse(int seq_no, FAR struct lwm2mstub_instance_s *inst, + int resp, FAR char *readvalue, int len) +{ + FAR void *inarg[5] = { + (FAR void *)seq_no, (FAR void *)resp, inst, readvalue, (FAR void *)len + }; + + if (!inst || !readvalue || len <= 0 || check_instance(inst) != OK) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_READRESP, + (FAR void *)&inarg, 5, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_m2m_writeresponse + ****************************************************************************/ + +int lte_m2m_writeresponse(int seq_no, FAR struct lwm2mstub_instance_s *inst, + int resp) +{ + FAR void *inarg[3] = { + (FAR void *)seq_no, (FAR void *)resp, inst + }; + + if (!inst || check_instance(inst) != OK) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_WRITERESP, + (FAR void *)&inarg, 3, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_m2m_executeresp + ****************************************************************************/ + +int lte_m2m_executeresp(int seq_no, FAR struct lwm2mstub_instance_s *inst, + int resp) +{ + FAR void *inarg[3] = { + (FAR void *)seq_no, (FAR void *)resp, inst + }; + + if (!inst || check_instance(inst) != OK) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_EXECRESP, + (FAR void *)&inarg, 3, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_m2m_observeresp + ****************************************************************************/ + +int lte_m2m_observeresp(int seq_no, int resp) +{ + FAR void *inarg[2] = { + (FAR void *)seq_no, (FAR void *)resp + }; + + return lapi_req(LTE_CMDID_LWM2M_OBSERVERESP, + (FAR void *)&inarg, 2, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_m2m_observeupdate + ****************************************************************************/ + +int lte_m2m_observeupdate(FAR char *token, + FAR struct lwm2mstub_instance_s *inst, + FAR char *value, int len) +{ + FAR void *inarg[4] = { + token, inst, value, (FAR void *)len + }; + + if (!token || !inst || !value || len <= 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_OBSERVEUPDATE, + (FAR void *)&inarg, 4, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_setm2m_endpointname + ****************************************************************************/ + +int lte_setm2m_endpointname(FAR char *name) +{ + return lapi_req(LTE_CMDID_LWM2M_SETEP, (FAR void **)name, + 1, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_endpointname + ****************************************************************************/ + +int lte_getm2m_endpointname(FAR char *name, int len) +{ + FAR void *outarg[2] = { + name, (FAR void *)len + }; + + if (!name || len <= 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_GETEP, NULL, + 0, (FAR void *)&outarg, 2, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_servernum + ****************************************************************************/ + +int lte_getm2m_servernum(void) +{ + int dummy_arg; /* Dummy for blocking API call */ + return lapi_req(LTE_CMDID_LWM2M_GETSRVNUM, NULL, 0, + (FAR void **)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_setm2m_servernum + ****************************************************************************/ + +int lte_setm2m_serverinfo(FAR struct lwm2mstub_serverinfo_s *info, int id) +{ + FAR void *inarg[2] = { + info, (FAR void *)id + }; + + if (!info) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_SETSRVINFO, &inarg, 2, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_serverinfo + ****************************************************************************/ + +int lte_getm2m_serverinfo(FAR struct lwm2mstub_serverinfo_s *info, int id) +{ + FAR void *outarg[2] = { + info, (FAR void *)id + }; + + if (!info) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_GETSRVINFO, NULL, 0, &outarg, 2, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_enabled_objectnum + ****************************************************************************/ + +int lte_getm2m_enabled_objectnum(void) +{ + int dummy_arg; /* Dummy for blocking API call */ + return lapi_req(LTE_CMDID_LWM2M_GETACTIVEOBJNUM, NULL, 0, + (FAR void *)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_enabled_objects + ****************************************************************************/ + +int lte_getm2m_enabled_objects(FAR uint16_t *objids, int objnum) +{ + FAR void *outarg[2] = { + objids, (FAR void *)objnum + }; + + if (!objids || objnum <= 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_GETACTIVEOBJ, NULL, 0, &outarg, 2, NULL); +} + +/**************************************************************************** + * Name: lte_enablem2m_objects + ****************************************************************************/ + +int lte_enablem2m_objects(FAR uint16_t *objids, int objnum) +{ + FAR void *inarg[2] = { + objids, (FAR void *)objnum + }; + + if (!objids || objnum <= 0) + { + return -EINVAL; + } + + insert_sort(objids, objnum); + + return lapi_req(LTE_CMDID_LWM2M_SETACTIVEOBJ, &inarg, 2, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_objresourcenum + ****************************************************************************/ + +int lte_getm2m_objresourcenum(uint16_t objid) +{ + int dummy_arg; /* Dummy for blocking API call */ + return lapi_req(LTE_CMDID_LWM2M_GETOBJRESNUM, &objid, 1, + (FAR void *)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_objresourceinfo + ****************************************************************************/ + +int lte_getm2m_objresourceinfo(uint16_t objid, int res_num, + FAR struct lwm2mstub_resource_s *reses) +{ + FAR void *outarg[2] = { + reses, (FAR void *)res_num + }; + + if (!reses || res_num <= 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_LWM2M_GETOBJRESOURCE, + &objid, 1, outarg, 2, NULL); +} + +/**************************************************************************** + * Name: lte_setm2m_rat + ****************************************************************************/ + +int lte_setm2m_rat(int rat) +{ + int dummy_arg; /* Dummy for blocking API call */ + + switch (rat) + { + case LTE_RAT_CATM: + case LTE_RAT_NBIOT: + break; + default: + return -EINVAL; + break; + } + + return lapi_req(LTE_CMDID_LWM2M_CHANGERAT, &rat, 1, + (FAR void *)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_getm2m_rat + ****************************************************************************/ + +int lte_getm2m_rat(void) +{ + int dummy_arg; /* Dummy for blocking API call */ + return lapi_req(LTE_CMDID_LWM2M_GETRAT, NULL, 0, + (FAR void *)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_setm2m_objectdefinition + ****************************************************************************/ + +int lte_setm2m_objectdefinition(uint16_t objids, int res_num, + FAR struct lwm2mstub_resource_s *resucs) +{ + FAR void *inarg[3] = { + (FAR void *)(uint32_t)objids, (FAR void *)res_num, resucs + }; + + return lapi_req(LTE_CMDID_LWM2M_SETOBJRESOURCE, inarg, 3, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_apply_m2msetting + ****************************************************************************/ + +int lte_apply_m2msetting(void) +{ + return lapi_req(LTE_CMDID_LWM2M_APPLY_SETTING, NULL, 0, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_set_report_m2mwrite + ****************************************************************************/ + +int lte_set_report_m2mwrite(lwm2mstub_write_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_WRITE_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2mread + ****************************************************************************/ + +int lte_set_report_m2mread(lwm2mstub_read_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_READ_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2mexec + ****************************************************************************/ + +int lte_set_report_m2mexec(lwm2mstub_exec_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_EXEC_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2movstart + ****************************************************************************/ + +int lte_set_report_m2movstart(lwm2mstub_ovstart_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_OVSTART_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2movstop + ****************************************************************************/ + +int lte_set_report_m2movstop(lwm2mstub_ovstop_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_OVSTOP_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2moperation + ****************************************************************************/ + +int lte_set_report_m2moperation(lwm2mstub_operation_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_SERVEROP_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_set_report_m2mfwupdate + ****************************************************************************/ + +int lte_set_report_m2mfwupdate(lwm2mstub_fwupstate_cb_t cb) +{ + return lapi_req(LTE_CMDID_LWM2M_FWUP_EVT, NULL, 0, NULL, 0, cb); +} + +/**************************************************************************** + * Name: lte_getm2m_qmode + ****************************************************************************/ + +bool lte_getm2m_qmode(void) +{ + int dummy_arg; /* Dummy for blocking API call */ + return lapi_req(LTE_CMDID_LWM2M_GETQMODE, NULL, 0, + (FAR void **)&dummy_arg, 0, NULL); +} + +/**************************************************************************** + * Name: lte_set_report_m2mfwupdate + ****************************************************************************/ + +int lte_setm2m_qmode(bool en) +{ + return lapi_req(LTE_CMDID_LWM2M_SETQMODE, + (FAR void **)(en ? 1 : 0), 1, NULL, 0, NULL); +} diff --git a/lte/lapi/src/lapi_net.c b/lte/lapi/src/lapi_net.c new file mode 100644 index 000000000..e68583b35 --- /dev/null +++ b/lte/lapi/src/lapi_net.c @@ -0,0 +1,503 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_net.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CELLINFO_PERIOD_MIN (1) +#define CELLINFO_PERIOD_MAX (4233600) + +#define QUALITY_PERIOD_MIN (1) +#define QUALITY_PERIOD_MAX (4233600) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lte_get_netinfo_inparam_check(uint8_t pdn_num) +{ + if (LTE_SESSION_ID_MIN > pdn_num || LTE_SESSION_ID_MAX < pdn_num) + { + return -EINVAL; + } + + return OK; +} + +static int lte_set_rat_inparam_check(uint8_t rat, bool persistent) +{ + if (rat != LTE_RAT_CATM && + rat != LTE_RAT_NBIOT) + { + lapi_printf("RAT type is invalid [%d].\n", rat); + return -EINVAL; + } + + if (persistent != LTE_ENABLE && + persistent != LTE_DISABLE) + { + lapi_printf("persistent is invalid [%d].\n", persistent); + return -EINVAL; + } + + return OK; +} + +static int lte_set_report_cellinfo_inparam_check( + cellinfo_report_cb_t callback, uint32_t period) +{ + if (callback) + { + if (CELLINFO_PERIOD_MIN > period || CELLINFO_PERIOD_MAX < period) + { + lapi_printf("Invalid parameter.\n"); + return -EINVAL; + } + } + + return OK; +} + +static int lte_set_report_quality_inparam_check(quality_report_cb_t callback, + uint32_t period) +{ + if (callback) + { + if (QUALITY_PERIOD_MIN > period || QUALITY_PERIOD_MAX < period) + { + lapi_printf("Invalid parameter.\n"); + return -EINVAL; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_get_netinfo_sync(uint8_t pdn_num, FAR lte_netinfo_t *info) +{ + int ret; + int result; + FAR void *inarg[] = + { + &pdn_num + }; + + FAR void *outarg[] = + { + &result, info, &pdn_num + }; + + if (lte_get_netinfo_inparam_check(pdn_num) || info == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETNETINFO, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_localtime_sync(FAR lte_localtime_t *localtime) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, localtime + }; + + if (localtime == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETLTIME, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_operator_sync(FAR char *oper) +#else +int lte_get_operator_sync(FAR char *oper, size_t len) +#endif +{ + int ret; + int result; + FAR void *outarg[] = + { +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &result, oper +#else + &result, oper, &len +#endif + }; + + if (oper == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETOPER, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_quality_sync(FAR lte_quality_t *quality) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, quality + }; + + if (quality == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETQUAL, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_cellinfo_sync(FAR lte_cellinfo_t *cellinfo) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, cellinfo + }; + + if (cellinfo == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETCELL, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_rat_sync(void) +{ + int ret; + int result; + lte_ratinfo_t ratinfo; + FAR void *outarg[] = + { + &result, &ratinfo + }; + + ret = lapi_req(LTE_CMDID_GETRAT, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = ratinfo.rat; + } + + return ret; +} + +int lte_set_rat_sync(uint8_t rat, bool persistent) +{ + int ret; + int result; + FAR void *inarg[] = + { + &rat, &persistent + }; + + FAR void *outarg[] = + { + &result + }; + + if (lte_set_rat_inparam_check(rat, persistent)) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_SETRAT, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_ratinfo_sync(FAR lte_ratinfo_t *info) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, info + }; + + if (info == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETRATINFO, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +/* Asynchronous APIs */ + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_get_netinfo(get_netinfo_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETNETINFO | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_localtime(get_localtime_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETLTIME | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_operator(get_operator_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETOPER | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_quality(get_quality_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETQUAL | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +int lte_set_report_netinfo(netinfo_report_cb_t callback) +{ + int ret; + int result; + FAR void *inarg[] = + { + callback + }; + + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_REPNETINFO, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + callback); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_report_localtime(localtime_report_cb_t callback) +{ + int ret; + int result; + int32_t id = LTE_CMDID_REPLTIME; + FAR void *inarg[] = + { + callback, &id + }; + + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_REPLTIME, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + callback); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_report_quality(quality_report_cb_t callback, uint32_t period) +{ + int ret; + int result; + FAR void *inarg[] = + { + callback, &period + }; + + FAR void *outarg[] = + { + &result + }; + + if (lte_set_report_quality_inparam_check(callback, period)) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_REPQUAL, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + callback); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_report_cellinfo(cellinfo_report_cb_t callback, + uint32_t period) +{ + int ret; + int result; + FAR void *inarg[] = + { + callback, &period + }; + + FAR void *outarg[] = + { + &result + }; + + if (lte_set_report_cellinfo_inparam_check(callback, period)) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_REPCELL, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + callback); + if (ret == 0) + { + ret = result; + } + + return ret; +} diff --git a/lte/lapi/src/lapi_other.c b/lte/lapi/src/lapi_other.c new file mode 100644 index 000000000..4897bed85 --- /dev/null +++ b/lte/lapi/src/lapi_other.c @@ -0,0 +1,176 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_other.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ATCMD_HEADER "AT" +#define ATCMD_HEADER_LEN (2) +#define ATCMD_FOOTER '\r' +#define ATCMD_FOOTER_LEN (1) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lapi_req + ****************************************************************************/ + +int lapi_req(uint32_t cmdid, FAR void *inp, size_t ilen, FAR void *outp, + size_t olen, FAR void *cb) +{ + int ret; + int sock; + struct lte_ioctl_data_s cmd; + + sock = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL); + if (sock < 0) + { + ret = -errno; + lapi_printf("failed to open socket:%d\n", errno); + } + else + { + cmd.cmdid = cmdid; + cmd.inparam = inp; + cmd.inparamlen = ilen; + cmd.outparam = outp; + cmd.outparamlen = olen; + cmd.cb = cb; + + ret = ioctl(sock, SIOCLTECMD, (unsigned long)&cmd); + if (ret < 0) + { + ret = -errno; + lapi_printf("failed to ioctl:%d\n", errno); + } + + close(sock); + } + + return ret; +} + +int lte_data_allow_sync(uint8_t session_id, uint8_t allow, + uint8_t roaming_allow) +{ + lapi_printf("lte_data_allow_sync() is not supported.\n"); + + return -EOPNOTSUPP; +} + +int lte_data_allow(uint8_t session_id, uint8_t allow, + uint8_t roaming_allow, data_allow_cb_t callback) +{ + lapi_printf("lte_data_allow() is not supported.\n"); + + return -EOPNOTSUPP; +} + +int lte_get_errinfo(FAR lte_errinfo_t *info) +{ + int ret; + + FAR void *outarg[] = + { + info + }; + + if (!info) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETERRINFO, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + + return ret; +} + +int lte_send_atcmd_sync(FAR const char *cmd, int cmdlen, + FAR char *respbuff, int respbufflen, FAR int *resplen) +{ + int32_t ret; + FAR void *inarg[] = + { + (FAR void *)cmd, (FAR void *)cmdlen + }; + + FAR void *outarg[] = + { + respbuff, (FAR void *)respbufflen, resplen + }; + + if (!cmd + || (ATCMD_HEADER_LEN + ATCMD_FOOTER_LEN) > cmdlen + || LTE_AT_COMMAND_MAX_LEN < cmdlen + || !respbuff || !respbufflen || !resplen) + { + return -EINVAL; + } + + if (0 != strncmp(cmd, ATCMD_HEADER, ATCMD_HEADER_LEN)) + { + return -EINVAL; + } + + if (ATCMD_FOOTER != cmd[cmdlen - ATCMD_FOOTER_LEN]) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_SENDATCMD, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + + return ret; +} diff --git a/lte/lapi/src/lapi_pdn.c b/lte/lapi/src/lapi_pdn.c new file mode 100644 index 000000000..5fc0451b0 --- /dev/null +++ b/lte/lapi/src/lapi_pdn.c @@ -0,0 +1,264 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_pdn.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lte_activate_pdn_inparam_check(FAR lte_apn_setting_t *apn) +{ + int32_t mask = 0; + + if (!apn) + { + lapi_printf("apn is null.\n"); + return -EINVAL; + } + + if ((!apn->apn) || (strnlen((char *)apn->apn, LTE_APN_LEN) >= LTE_APN_LEN)) + { + lapi_printf("apn is length overflow.\n"); + return -EINVAL; + } + + if ((apn->ip_type < LTE_IPTYPE_V4) || + (apn->ip_type > LTE_IPTYPE_NON)) + { + lapi_printf("ip type is invalid. iptype=%d\n", apn->ip_type); + return -EINVAL; + } + + if ((apn->auth_type < LTE_APN_AUTHTYPE_NONE) || + (apn->auth_type > LTE_APN_AUTHTYPE_CHAP)) + { + lapi_printf("auth type is invalid. authtype=%d\n", apn->auth_type); + return -EINVAL; + } + + if (apn->user_name && apn->password) + { + if (strnlen((FAR char *)apn->user_name, LTE_APN_USER_NAME_LEN) >= + LTE_APN_USER_NAME_LEN) + { + lapi_printf("username is length overflow.\n"); + return -EINVAL; + } + + if (strnlen((FAR char *)apn->password, LTE_APN_PASSWD_LEN) >= + LTE_APN_PASSWD_LEN) + { + lapi_printf("password is length overflow.\n"); + return -EINVAL; + } + } + else + { + if (apn->auth_type != LTE_APN_AUTHTYPE_NONE) + { + lapi_printf("authentication information is invalid.\n"); + return -EINVAL; + } + } + + mask = (LTE_APN_TYPE_DEFAULT | + LTE_APN_TYPE_MMS | LTE_APN_TYPE_SUPL | LTE_APN_TYPE_DUN | + LTE_APN_TYPE_HIPRI | LTE_APN_TYPE_FOTA | LTE_APN_TYPE_IMS | + LTE_APN_TYPE_CBS | LTE_APN_TYPE_IA | LTE_APN_TYPE_EMERGENCY); + if (0 == (apn->apn_type & mask)) + { + lapi_printf("apn type is invalid. apntype=%08ld / mask=%08ld \n", + apn->apn_type, mask); + return -EINVAL; + } + + return OK; +} + +static int lte_deactivate_pdn_inparam_check(uint8_t session_id) +{ + if (LTE_SESSION_ID_MIN > session_id || + LTE_SESSION_ID_MAX < session_id) + { + lapi_printf("Invalid session id %d.\n", session_id); + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_activate_pdn_sync(FAR lte_apn_setting_t *apn, FAR lte_pdn_t *pdn) +{ + int ret; + int result; + FAR void *inarg[] = + { + apn + }; + + FAR void *outarg[] = + { + &result, pdn + }; + + if (lte_activate_pdn_inparam_check(apn) || pdn == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_ACTPDN, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_deactivate_pdn_sync(uint8_t session_id) +{ + int ret; + int result; + FAR void *inarg[] = + { + &session_id + }; + + FAR void *outarg[] = + { + &result + }; + + if (lte_deactivate_pdn_inparam_check(session_id)) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_DEACTPDN, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +/* Asynchronous APIs */ + +int lte_activate_pdn(FAR lte_apn_setting_t *apn, activate_pdn_cb_t callback) +{ + FAR void *inarg[] = + { + apn + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_activate_pdn_inparam_check(apn)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_ACTPDN | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_deactivate_pdn(uint8_t session_id, deactivate_pdn_cb_t callback) +{ + FAR void *inarg[] = + { + &session_id + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_deactivate_pdn_inparam_check(session_id)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_DEACTPDN | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + +int lte_activate_pdn_cancel(void) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_ACTPDNCAN, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} diff --git a/lte/lapi/src/lapi_pin.c b/lte/lapi/src/lapi_pin.c new file mode 100644 index 000000000..31135b7fa --- /dev/null +++ b/lte/lapi/src/lapi_pin.c @@ -0,0 +1,405 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_pin.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SETPIN_TARGETPIN_MIN LTE_TARGET_PIN +#define SETPIN_TARGETPIN_MAX LTE_TARGET_PIN2 + +#define APICMD_SETPINLOCK_PINCODE_LEN 9 + +#define SETPIN_MIN_PIN_LEN (4) +#define SETPIN_MAX_PIN_LEN ((APICMD_SETPINLOCK_PINCODE_LEN) - 1) + +#define APICMD_ENTERPIN_PINCODE_LEN 9 +#define ENTERPIN_MIN_PIN_LEN (4) +#define ENTERPIN_MAX_PIN_LEN ((APICMD_ENTERPIN_PINCODE_LEN) - 1) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lte_change_pin_inparam_check(int8_t target_pin, FAR char *pincode, + FAR char *new_pincode) +{ + uint8_t pinlen = 0; + + if (!pincode || !new_pincode) + { + lapi_printf("Input argument is NULL.\n"); + return -EINVAL; + } + + if (SETPIN_TARGETPIN_MIN > target_pin || SETPIN_TARGETPIN_MAX < target_pin) + { + lapi_printf("Unsupport change type. type:%d\n", target_pin); + return -EINVAL; + } + + pinlen = strnlen(pincode, APICMD_SETPINLOCK_PINCODE_LEN); + if (pinlen < SETPIN_MIN_PIN_LEN || SETPIN_MAX_PIN_LEN < pinlen) + { + return -EINVAL; + } + + pinlen = strnlen(new_pincode, APICMD_SETPINLOCK_PINCODE_LEN); + if (pinlen < SETPIN_MIN_PIN_LEN || SETPIN_MAX_PIN_LEN < pinlen) + { + return -EINVAL; + } + + return OK; +} + +static int lte_enter_pin_inparam_check(FAR char *pincode, + FAR char *new_pincode) +{ + uint8_t pinlen = 0; + + if (!pincode) + { + lapi_printf("Input argument is NULL.\n"); + return -EINVAL; + } + + pinlen = strnlen(pincode, APICMD_SETPINLOCK_PINCODE_LEN); + if (pinlen < ENTERPIN_MIN_PIN_LEN || ENTERPIN_MAX_PIN_LEN < pinlen) + { + lapi_printf("Invalid PIN code length.length:%d\n", pinlen); + return -EINVAL; + } + + if (new_pincode) + { + lapi_printf("lte_enter_pin() doesn't support entering PUK code.\n"); + lapi_printf("lte_enter_pin_sync() doesn't support entering" + " PUK code.\n"); + return -EINVAL; + } + + return OK; +} + +static int lte_set_pinenable_inparam_check(bool enable, FAR char *pincode) +{ + uint8_t pinlen = 0; + + if (!pincode) + { + lapi_printf("Input argument is NULL.\n"); + return -EINVAL; + } + + pinlen = strnlen(pincode, APICMD_SETPINLOCK_PINCODE_LEN); + if (pinlen < SETPIN_MIN_PIN_LEN || SETPIN_MAX_PIN_LEN < pinlen) + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_get_pinset_sync(FAR lte_getpin_t *pinset) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, pinset + }; + + if (pinset == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETPINSET, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_pinenable_sync(bool enable, FAR char *pincode, + FAR uint8_t *attemptsleft) +{ + int ret; + int result; + FAR void *inarg[] = + { + &enable, pincode + }; + + FAR void *outarg[] = + { + &result, attemptsleft + }; + + if (lte_set_pinenable_inparam_check(enable, pincode) || + attemptsleft == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_PINENABLE, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_change_pin_sync(int8_t target_pin, FAR char *pincode, + FAR char *new_pincode, FAR uint8_t *attemptsleft) +{ + int ret; + int result; + FAR void *inarg[] = + { + &target_pin, pincode, new_pincode + }; + + FAR void *outarg[] = + { + &result, attemptsleft + }; + + if (lte_change_pin_inparam_check(target_pin, pincode, new_pincode) || + attemptsleft == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_CHANGEPIN, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_enter_pin_sync(FAR char *pincode, FAR char *new_pincode, + FAR uint8_t *simstat, FAR uint8_t *attemptsleft) +{ + int ret; + int result; + FAR void *inarg[] = + { + pincode, new_pincode + }; + + FAR void *outarg[] = + { + &result, simstat, attemptsleft + }; + + lte_getpin_t pinset = + { + 0 + }; + + if (lte_enter_pin_inparam_check(pincode, new_pincode) || simstat == NULL || + attemptsleft == NULL) + { + return -EINVAL; + } + + ret = lte_get_pinset_sync(&pinset); + if (ret < 0) + { + lapi_printf("Failed to get pinset.%d\n", ret); + return ret; + } + + if (simstat) + { + *simstat = pinset.status; + } + + if (attemptsleft) + { + if (pinset.status == LTE_PINSTAT_SIM_PUK) + { + *attemptsleft = pinset.puk_attemptsleft; + } + else + { + *attemptsleft = pinset.pin_attemptsleft; + } + } + + if (pinset.enable == LTE_DISABLE) + { + lapi_printf( + "PIN lock is disable. Don't need to run lte_enter_pin_sync().\n"); + return -EPERM; + } + else if (pinset.status != LTE_PINSTAT_SIM_PIN) + { + if (pinset.status == LTE_PINSTAT_SIM_PUK) + { + lapi_printf( + "This SIM is PUK locked. lte_enter_pin_sync() can't be used.\n"); + } + else + { + lapi_printf("PIN is already unlocked. " + "Don't need to run lte_enter_pin_sync(). status:%d\n", + pinset.status); + } + + return -EPERM; + } + + ret = lapi_req(LTE_CMDID_ENTERPIN, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +/* Asynchronous APIs */ + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_get_pinset(get_pinset_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETPINSET | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_set_pinenable(bool enable, FAR char *pincode, + set_pinenable_cb_t callback) +{ + FAR void *inarg[] = + { + &enable, pincode + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_set_pinenable_inparam_check(enable, pincode)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_PINENABLE | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_change_pin(int8_t target_pin, FAR char *pincode, + FAR char *new_pincode, change_pin_cb_t callback) +{ + FAR void *inarg[] = + { + &target_pin, pincode, new_pincode + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_change_pin_inparam_check(target_pin, pincode, new_pincode)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_CHANGEPIN | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_enter_pin(FAR char *pincode, FAR char *new_pincode, + enter_pin_cb_t callback) +{ + FAR void *inarg[] = + { + pincode, new_pincode + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_enter_pin_inparam_check(pincode, new_pincode)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_ENTERPIN | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + diff --git a/lte/lapi/src/lapi_power.c b/lte/lapi/src/lapi_power.c new file mode 100644 index 000000000..c37e45474 --- /dev/null +++ b/lte/lapi/src/lapi_power.c @@ -0,0 +1,316 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_power.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DAEMON_NAME "alt1250" +#define DAEMON_PRI 100 +#define DAEMON_STACK_SZ 2048 +#define CMD_PREFIX "-s" +#define ADDR_LEN (strlen(CMD_PREFIX) + 9) /* 32bit + '\0' */ + +#define RETRY_INTERVAL 100 +#define RETRY_OVER 3 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int alt1250_main(int argc, FAR char *argv[]); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_lock = SEM_INITIALIZER(1); +static sem_t g_sync; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lapi_lock + ****************************************************************************/ + +static inline void lapi_lock(FAR sem_t *lock) +{ + int ret; + + do + { + ret = sem_wait(lock); + } + while (ret == -EINTR); +} + +/**************************************************************************** + * Name: lapi_unlock + ****************************************************************************/ + +static inline void lapi_unlock(FAR sem_t *lock) +{ + sem_post(lock); +} + +/**************************************************************************** + * Name: is_daemon_running + ****************************************************************************/ + +static bool is_daemon_running(void) +{ + int sock; + bool is_run = false; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + if (errno == ENETDOWN) + { + is_run = false; + } + else + { + is_run = true; + } + } + else + { + close(sock); + is_run = true; + } + + return is_run; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lte_initialize + ****************************************************************************/ + +int lte_initialize(void) +{ + int ret = 0; + + lapi_lock(&g_lock); + + if (!is_daemon_running()) + { + FAR char *argv[2]; + char addr[ADDR_LEN]; + + sem_init(&g_sync, 0, 0); + + /* address -> ascii */ + + snprintf(addr, ADDR_LEN, "%s%08lx", CMD_PREFIX, + (unsigned long)&g_sync); + + argv[0] = addr; + argv[1] = NULL; /* termination */ + + ret = task_create(DAEMON_NAME, DAEMON_PRI, DAEMON_STACK_SZ, + alt1250_main, argv); + if (ret < 0) + { + ret = -errno; + lapi_printf("failed to create task:%d\n", errno); + } + else + { + ret = 0; + sem_wait(&g_sync); + } + } + else + { + ret = -EALREADY; + } + + lapi_unlock(&g_lock); + + return ret; +} + +/**************************************************************************** + * Name: lte_finalize + ****************************************************************************/ + +int lte_finalize(void) +{ + int ret = 0; + int count = 0; + + lapi_lock(&g_lock); + + while (count < RETRY_OVER) + { + ret = lapi_req(LTE_CMDID_FIN, NULL, 0, NULL, 0, NULL); + if (ret >= 0) + { + sem_wait(&g_sync); + sem_destroy(&g_sync); + break; + } + + usleep(RETRY_INTERVAL); + count++; + } + + if (ret == -ENETDOWN) + { + ret = -EALREADY; + } + + lapi_unlock(&g_lock); + + return ret; +} + +/**************************************************************************** + * Name: lte_set_report_restart + ****************************************************************************/ + +int lte_set_report_restart(restart_report_cb_t callback) +{ + return lapi_req(LTE_CMDID_SETRESTART, NULL, 0, NULL, 0, callback); +} + +/**************************************************************************** + * Name: lte_power_on + ****************************************************************************/ + +int lte_power_on(void) +{ + return lapi_req(LTE_CMDID_POWERON, NULL, 0, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_power_off + ****************************************************************************/ + +int lte_power_off(void) +{ + int ret; + int count = 0; + + while (count < RETRY_OVER) + { + ret = lapi_req(LTE_CMDID_POWEROFF, NULL, 0, NULL, 0, NULL); + if ((ret >= 0) || (ret == -EALREADY)) + { + break; + } + + usleep(RETRY_INTERVAL); + count++; + } + + return ret; +} + +/**************************************************************************** + * Name: lte_acquire_wakelock + ****************************************************************************/ + +int lte_acquire_wakelock(void) +{ + return lapi_req(LTE_CMDID_TAKEWLOCK, NULL, 0, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_release_wakelock + ****************************************************************************/ + +int lte_release_wakelock(void) +{ + return lapi_req(LTE_CMDID_GIVEWLOCK, NULL, 0, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_get_wakelock_count + ****************************************************************************/ + +int lte_get_wakelock_count(void) +{ + return lapi_req(LTE_CMDID_COUNTWLOCK, NULL, 0, NULL, 0, NULL); +} + +/**************************************************************************** + * Name: lte_set_context_save_cb + ****************************************************************************/ + +int lte_set_context_save_cb(context_save_cb_t callback) +{ + return lapi_req(LTE_CMDID_SETCTXCB, NULL, 0, NULL, 0, callback); +} + +/**************************************************************************** + * Name: lte_hibernation_resume + ****************************************************************************/ + +int lte_hibernation_resume(FAR const uint8_t *res_ctx, int len) +{ + FAR void *inarg[] = + { + (FAR void *)res_ctx, + &len + }; + + int dummy_arg; /* Dummy for blocking API call */ + + if (res_ctx == NULL || len < 0) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_RESUME, + (FAR void *)inarg, nitems(inarg), + (FAR void *)&dummy_arg, 0, NULL); +} diff --git a/lte/lapi/src/lapi_psave.c b/lte/lapi/src/lapi_psave.c new file mode 100644 index 000000000..10defd44c --- /dev/null +++ b/lte/lapi/src/lapi_psave.c @@ -0,0 +1,583 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_psave.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +#include "lapi_dbg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALTCOMBS_EDRX_CYCLE_WBS1_MIN (LTE_EDRX_CYC_512) +#define ALTCOMBS_EDRX_CYCLE_WBS1_MAX (LTE_EDRX_CYC_262144) +#define ALTCOMBS_EDRX_CYCLE_NBS1_MIN (LTE_EDRX_CYC_2048) +#define ALTCOMBS_EDRX_CYCLE_NBS1_MAX (LTE_EDRX_CYC_1048576) +#define ALTCOMBS_EDRX_PTW_WBS1_MIN (LTE_EDRX_PTW_128) +#define ALTCOMBS_EDRX_PTW_WBS1_MAX (LTE_EDRX_PTW_2048) +#define ALTCOMBS_EDRX_PTW_NBS1_MIN (LTE_EDRX_PTW_256) +#define ALTCOMBS_EDRX_PTW_NBS1_MAX (LTE_EDRX_PTW_4096) +#define ALTCOMBS_PSM_UNIT_T3324_MIN (LTE_PSM_T3324_UNIT_2SEC) +#define ALTCOMBS_PSM_UNIT_T3324_MAX (LTE_PSM_T3324_UNIT_6MIN) +#define ALTCOMBS_PSM_UNIT_T3412_MIN (LTE_PSM_T3412_UNIT_2SEC) +#define ALTCOMBS_PSM_UNIT_T3412_MAX (LTE_PSM_T3412_UNIT_320HOUR) +#define ALTCOMBS_EDRX_INVALID (255) + +#define APICMD_EDRX_ACTTYPE_NOTUSE (0) /* eDRX is not running */ +#define APICMD_EDRX_ACTTYPE_ECGSMIOT (1) /* EC-GSM-IoT (A/Gb mode) */ +#define APICMD_EDRX_ACTTYPE_GSM (2) /* GSM (A/Gb mode) */ +#define APICMD_EDRX_ACTTYPE_IU (3) /* UTRAN (Iu mode) */ +#define APICMD_EDRX_ACTTYPE_WBS1 (4) /* E-UTRAN (WB-S1 mode) */ +#define APICMD_EDRX_ACTTYPE_NBS1 (5) /* E-UTRAN (NB-S1 mode) */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lte_set_edrx_inparam_check(FAR lte_edrx_setting_t *settings) +{ + int32_t ret = 0; + + if (!settings) + { + lapi_printf("Input argument is NULL.\n"); + return -EINVAL; + } + + if (settings->act_type != LTE_EDRX_ACTTYPE_WBS1 && + settings->act_type != LTE_EDRX_ACTTYPE_NBS1 && + settings->act_type != LTE_EDRX_ACTTYPE_ECGSMIOT && + settings->act_type != LTE_EDRX_ACTTYPE_GSM && + settings->act_type != LTE_EDRX_ACTTYPE_IU && + settings->act_type != LTE_EDRX_ACTTYPE_NOTUSE) + { + lapi_printf("Input argument act_type is invalid.\n"); + return -EINVAL; + } + + ret = lte_get_rat_sync(); + if (ret < 0 && ret != -ENOTSUP) + { + lapi_printf("Unable to read RAT setting from the device." + " ret: [%ld].\n", + ret); + return ret; + } + else if (ret == -ENOTSUP) + { + /* act_type check for protocol version V1 */ + + if (LTE_EDRX_ACTTYPE_NOTUSE != settings->act_type && + LTE_EDRX_ACTTYPE_WBS1 != settings->act_type) + { + lapi_printf("Operation is not allowed[act_type : %d].\n", + settings->act_type); + return -EPERM; + } + } + else + { + /* act_type check for version V4 or later */ + + if (!((ret == LTE_RAT_CATM + && settings->act_type == LTE_EDRX_ACTTYPE_WBS1) || + (ret == LTE_RAT_NBIOT + && settings->act_type == LTE_EDRX_ACTTYPE_NBS1) || + (settings->act_type == LTE_EDRX_ACTTYPE_NOTUSE))) + { + lapi_printf("Operation is not allowed[act_type : %d," + " RAT : %ld].\n", + settings->act_type, ret); + return -EPERM; + } + } + + if (settings->enable) + { + if (settings->act_type == LTE_EDRX_ACTTYPE_WBS1) + { + if (!(ALTCOMBS_EDRX_CYCLE_WBS1_MIN <= settings->edrx_cycle && + settings->edrx_cycle <= ALTCOMBS_EDRX_CYCLE_WBS1_MAX)) + { + lapi_printf("Input argument edrx_cycle is invalid.\n"); + return -EINVAL; + } + + if (!(ALTCOMBS_EDRX_PTW_WBS1_MIN <= settings->ptw_val && + settings->ptw_val <= ALTCOMBS_EDRX_PTW_WBS1_MAX)) + { + lapi_printf("Input argument ptw is invalid.\n"); + return -EINVAL; + } + } + + if (settings->act_type == LTE_EDRX_ACTTYPE_NBS1) + { + if (!(ALTCOMBS_EDRX_CYCLE_NBS1_MIN <= settings->edrx_cycle && + settings->edrx_cycle <= ALTCOMBS_EDRX_CYCLE_NBS1_MAX)) + { + lapi_printf("Input argument edrx_cycle is invalid.\n"); + return -EINVAL; + } + + if (!(ALTCOMBS_EDRX_PTW_NBS1_MIN <= settings->ptw_val && + settings->ptw_val <= ALTCOMBS_EDRX_PTW_NBS1_MAX)) + { + lapi_printf("Input argument ptw is invalid.\n"); + return -EINVAL; + } + } + } + + return OK; +} + +static int lte_set_psm_inparam_check(FAR lte_psm_setting_t *settings) +{ + if (!settings) + { + lapi_printf("Input argument is NULL.\n"); + return -EINVAL; + } + + if (LTE_ENABLE == settings->enable) + { + if (settings->req_active_time.unit < LTE_PSM_T3324_UNIT_2SEC || + settings->req_active_time.unit > LTE_PSM_T3324_UNIT_DEACT) + { + lapi_printf("Invalid rat_time unit :%d\n", + settings->req_active_time.unit); + return -EINVAL; + } + + if (settings->req_active_time.time_val < LTE_PSM_TIMEVAL_MIN || + settings->req_active_time.time_val > LTE_PSM_TIMEVAL_MAX) + { + lapi_printf("Invalid rat_time time_val :%d\n", + settings->req_active_time.time_val); + return -EINVAL; + } + + if (settings->ext_periodic_tau_time.unit < LTE_PSM_T3412_UNIT_2SEC || + settings->ext_periodic_tau_time.unit > LTE_PSM_T3412_UNIT_DEACT) + { + lapi_printf("Invalid tau_time unit :%d\n", + settings->ext_periodic_tau_time.unit); + return -EINVAL; + } + + if (settings->ext_periodic_tau_time.time_val < LTE_PSM_TIMEVAL_MIN || + settings->ext_periodic_tau_time.time_val > LTE_PSM_TIMEVAL_MAX) + { + lapi_printf("Invalid tau_time time_val :%d\n", + settings->ext_periodic_tau_time.time_val); + return -EINVAL; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_get_edrx_sync(FAR lte_edrx_setting_t *settings) +{ + int ret; + int result; + bool is_edrxevt; + FAR void *outarg[] = + { + &result, settings, &is_edrxevt + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETEDRX, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_edrx_sync(FAR lte_edrx_setting_t *settings) +{ + int ret; + int result; + FAR void *inarg[] = + { + settings + }; + + FAR void *outarg[] = + { + &result + }; + + ret = lte_set_edrx_inparam_check(settings); + if (ret < 0) + { + return ret; + } + + ret = lapi_req(LTE_CMDID_SETEDRX, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_psm_sync(FAR lte_psm_setting_t *settings) +{ + int ret; + int result; + int32_t id = LTE_CMDID_GETPSM; + bool is_psmevt; + FAR void *inarg[] = + { + &id + }; + + FAR void *outarg[] = + { + &result, settings, &is_psmevt + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETPSM, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_psm_sync(FAR lte_psm_setting_t *settings) +{ + int ret; + int result; + FAR void *inarg[] = + { + settings + }; + + FAR void *outarg[] = + { + &result + }; + + if (lte_set_psm_inparam_check(settings)) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_SETPSM, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_ce_sync(FAR lte_ce_setting_t *settings) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, settings + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETCE, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_ce_sync(FAR lte_ce_setting_t *settings) +{ + int ret; + int result; + FAR void *inarg[] = + { + settings + }; + + FAR void *outarg[] = + { + &result + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_SETCE, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_current_edrx_sync(FAR lte_edrx_setting_t *settings) +{ + int ret; + int result; + bool is_getcedrxevt; + FAR void *outarg[] = + { + &result, settings, &is_getcedrxevt + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETCEDRX, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_current_psm_sync(FAR lte_psm_setting_t *settings) +{ + int ret; + int result; + bool is_getcpsmevt; + FAR void *outarg[] = + { + &result, settings, &is_getcpsmevt + }; + + if (settings == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETCPSM, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +/* Asynchronous APIs */ + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_get_edrx(get_edrx_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETEDRX | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_set_edrx(FAR lte_edrx_setting_t *settings, set_edrx_cb_t callback) +{ + int ret; + FAR void *inarg[] = + { + settings + }; + + if (callback == NULL) + { + return -EINVAL; + } + + ret = lte_set_edrx_inparam_check(settings); + if (ret < 0) + { + return ret; + } + + return lapi_req(LTE_CMDID_SETEDRX | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_get_psm(get_psm_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETPSM | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_set_psm(FAR lte_psm_setting_t *settings, set_psm_cb_t callback) +{ + FAR void *inarg[] = + { + settings + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_set_psm_inparam_check(settings)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_SETPSM | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_get_ce(get_ce_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETCE | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_set_ce(FAR lte_ce_setting_t *settings, set_ce_cb_t callback) +{ + FAR void *inarg[] = + { + settings + }; + + if (settings == NULL || callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_SETCE | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_get_current_edrx(get_current_edrx_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETCEDRX | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_dynamic_edrx_param(get_dynamic_edrx_param_cb_t callback) +{ + return lte_get_current_edrx(callback); +} + +int lte_get_current_psm(get_current_psm_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETCPSM | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_dynamic_psm_param(get_dynamic_psm_param_cb_t callback) +{ + return lte_get_current_psm(callback); +} +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + diff --git a/lte/lapi/src/lapi_radio.c b/lte/lapi/src/lapi_radio.c new file mode 100644 index 000000000..0ba12362f --- /dev/null +++ b/lte/lapi/src/lapi_radio.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_radio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int lte_radio_on_sync(void) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_RADIOON, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_radio_off_sync(void) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_RADIOOFF, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_radio_on(radio_on_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_RADIOON | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_radio_off(radio_off_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_RADIOOFF | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ + diff --git a/lte/lapi/src/lapi_sim.c b/lte/lapi/src/lapi_sim.c new file mode 100644 index 000000000..dcf7efc1b --- /dev/null +++ b/lte/lapi/src/lapi_sim.c @@ -0,0 +1,326 @@ +/**************************************************************************** + * apps/lte/lapi/src/lapi_sim.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "lte/lte_api.h" +#include "lte/lapi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lte_get_siminfo_inparam_check(uint32_t option) +{ + uint32_t mask = 0; + + mask = (LTE_SIMINFO_GETOPT_MCCMNC | + LTE_SIMINFO_GETOPT_SPN | + LTE_SIMINFO_GETOPT_ICCID | + LTE_SIMINFO_GETOPT_IMSI | + LTE_SIMINFO_GETOPT_GID1 | + LTE_SIMINFO_GETOPT_GID2); + + if (0 == (option & mask)) + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Synchronous APIs */ + +int lte_get_siminfo_sync(uint32_t option, FAR lte_siminfo_t *siminfo) +{ + int ret; + int result; + FAR void *inarg[] = + { + &option + }; + + FAR void *outarg[] = + { + &result, siminfo + }; + + if (lte_get_siminfo_inparam_check(option) || siminfo == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETSIMINFO, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_get_imscap_sync(FAR bool *imscap) +{ + int ret; + int result; + FAR void *outarg[] = + { + &result, imscap + }; + + if (imscap == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_IMSCAP, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_imsi_sync(FAR char *imsi) +#else +int lte_get_imsi_sync(FAR char *imsi, size_t len) +#endif +{ + int ret; + int result; + uint8_t errcause; + FAR void *outarg[] = + { +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &result, &errcause, imsi +#else + &result, &errcause, imsi, &len +#endif + }; + + if (imsi == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETIMSI, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_imei_sync(FAR char *imei) +#else +int lte_get_imei_sync(FAR char *imei, size_t len) +#endif +{ + int ret; + int result; + FAR void *outarg[] = + { +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &result, imei +#else + &result, imei, &len +#endif + }; + + if (imei == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETIMEI, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY +int lte_get_phoneno_sync(FAR char *phoneno) +#else +int lte_get_phoneno_sync(FAR char *phoneno, size_t len) +#endif +{ + int ret; + int result; + uint8_t errcause; + FAR void *outarg[] = + { +#ifdef CONFIG_LTE_LAPI_KEEP_COMPATIBILITY + &result, &errcause, phoneno +#else + &result, &errcause, phoneno, &len +#endif + }; + + if (phoneno == NULL) + { + return -EINVAL; + } + + ret = lapi_req(LTE_CMDID_GETPHONE, + NULL, 0, + (FAR void *)outarg, nitems(outarg), + NULL); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +int lte_set_report_simstat(simstat_report_cb_t callback) +{ + int ret; + int result; + int32_t id = LTE_CMDID_REPSIMSTAT; + FAR void *inarg[] = + { + callback, &id + }; + + FAR void *outarg[] = + { + &result + }; + + ret = lapi_req(LTE_CMDID_REPSIMSTAT, + (FAR void *)inarg, nitems(inarg), + (FAR void *)outarg, nitems(outarg), + callback); + if (ret == 0) + { + ret = result; + } + + return ret; +} + +/* Asynchronous APIs */ + +#ifdef CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API + +int lte_get_siminfo(uint32_t option, get_siminfo_cb_t callback) +{ + FAR void *inarg[] = + { + &option + }; + + if (callback == NULL) + { + return -EINVAL; + } + + if (lte_get_siminfo_inparam_check(option)) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETSIMINFO | LTE_CMDOPT_ASYNC_BIT, + (FAR void *)inarg, nitems(inarg), + NULL, 0, callback); +} + +int lte_get_imscap(get_imscap_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_IMSCAP | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_imsi(get_imsi_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETIMSI | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_imei(get_imei_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETIMEI | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} + +int lte_get_phoneno(get_phoneno_cb_t callback) +{ + if (callback == NULL) + { + return -EINVAL; + } + + return lapi_req(LTE_CMDID_GETPHONE | LTE_CMDOPT_ASYNC_BIT, + NULL, 0, NULL, 0, callback); +} +#endif /* CONFIG_LTE_LAPI_ENABLE_DEPRECATED_API */ +