/**************************************************************************** * 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 FAR void *get_cbfunc(uint32_t cmdid); static uint64_t alt1250_evt_search(uint32_t cmdid); /**************************************************************************** * Private Data Types ****************************************************************************/ struct cbinfo_s { uint32_t cmdid; CODE 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 FAR 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 FAR void *g_radioonargs[] = { &g_radioonret }; /* event argument for LTE_CMDID_RADIOOFF */ static int g_radiooffret; static FAR 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 FAR 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 FAR 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 FAR 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 FAR 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 FAR 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 FAR 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 FAR 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 FAR void *g_getpinsetargs[] = { &g_getpinsetret, &g_pinset }; /* event argument for LTE_CMDID_PINENABLE */ static int g_pinenableret; static uint8_t g_pineattleft; static FAR void *g_pinenableargs[] = { &g_pinenableret, &g_pineattleft }; /* event argument for LTE_CMDID_CHANGEPIN */ static int g_changepinret; static uint8_t g_chanattleft; static FAR 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 FAR 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 FAR 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 FAR 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 FAR void *g_getedrxargs[] = { &g_getedrxret, &g_getedrx, &g_is_getedrxevt }; /* event argument for LTE_CMDID_SETEDRX */ static int g_setedrxret; static FAR 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 FAR void *g_getpsmargs[] = { &g_getpsmret, &g_getpsm, &g_is_getpsmevt }; /* event argument for LTE_CMDID_SETPSM */ static int g_setpsmret; static FAR void *g_setpsmargs[] = { &g_setpsmret }; /* event argument for LTE_CMDID_GETCE */ static int g_getceret; static lte_ce_setting_t g_getce; static FAR void *g_getceargs[] = { &g_getceret, &g_getce }; /* event argument for LTE_CMDID_SETCE */ static int g_setceret; static FAR void *g_setceargs[] = { &g_setceret }; /* event argument for LTE_CMDID_GETSIMINFO */ static int g_setsiminforet; static lte_siminfo_t g_siminfo; static FAR 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 FAR 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 FAR 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 FAR 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 FAR 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 FAR void *g_getratargs[] = { &g_getratret }; /* event argument for LTE_CMDID_SETRAT */ static int g_setratret; static FAR void *g_setratargs[] = { &g_setratret }; /* event argument for LTE_CMDID_GETRATINFO */ static int g_getratinforet; static lte_ratinfo_t g_ratinfo; static FAR 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 FAR void *g_repnetinfoargs[] = { &g_repnetinfo, &g_ndnsaddrs, g_dnsaddrs }; /* event argument for LTE_CMDID_REPSIMSTAT */ static uint32_t g_repsimstat; static FAR void *g_repsimstatargs[] = { &g_repsimstat }; /* event argument for LTE_CMDID_REPLTIME */ static lte_localtime_t g_repltime; static FAR void *g_repltimeargs[] = { &g_repltime }; /* event argument for LTE_CMDID_REPQUAL */ static lte_quality_t g_repqual; static FAR 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 FAR void *g_repcellargs[] = { &g_repcell }; /* event argument for LTE_CMDID_GETERRINFO */ static lte_errinfo_t g_geterrinfo; static FAR 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 FAR 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 FAR 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 FAR 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 FAR void *g_lwm2mwriteargs[] = { NULL, NULL, &g_lwm2mwrite_inst, g_lwm2mwrite_value, NULL, (FAR void *)LWM2MSTUB_MAX_WRITE_SIZE }; /* event argument for LTE_CMDID_LWM2M_EXEC_EVT */ static struct lwm2mstub_instance_s g_lwm2mexec_inst; static FAR 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 FAR void *g_lwm2movstartargs[] = { NULL, NULL, &g_lwm2movstart_inst, g_lwm2movstart_token, (FAR 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 FAR void *g_lwm2movstopargs[] = { NULL, NULL, &g_lwm2movstop_inst, &g_lwm2movstop_token, (FAR void *)LWM2MSTUB_MAX_TOKEN_SIZE }; /* event argument for LTE_CMDID_LWM2M_SERVEROP_EVT */ static FAR void *g_lwm2moperationargs[] = { NULL }; /* event argument for LTE_CMDID_LWM2M_FWUP_EVT */ static FAR 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]; 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); } if (info->pdn_num > 0) { FAR lte_pdn_t *pdn = &info->pdn_stat[0]; FAR lte_ipaddr_t *ipaddr = &pdn->address[0]; /* ALT1250 can only connect one PDN, so check the first PDN. */ if ((pdn->ipaddr_num == 1) && (ipaddr->ip_type == LTE_IPTYPE_V4)) { dns_set_queryfamily(AF_INET); } else if ((pdn->ipaddr_num == 1) && (ipaddr->ip_type == LTE_IPTYPE_V6)) { dns_set_queryfamily(AF_INET6); } else { dns_set_queryfamily(AF_UNSPEC); } } else { dns_set_queryfamily(AF_UNSPEC); } #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) { CODE void (*callback)(FAR void **cbarg) = cb; FAR 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], (FAR 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], (FAR struct lwm2mstub_instance_s *)cbarg[2], (FAR 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], (FAR 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], (FAR struct lwm2mstub_instance_s *)cbarg[2], (FAR char *)cbarg[3], (FAR 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], (FAR struct lwm2mstub_instance_s *)cbarg[2], (FAR 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, CODE 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 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 FAR 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 FAR 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; CODE 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 FAR 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; }