[T106][ZXW-27]create lynq DEV environment in zxw yocto system
Change-Id: I5cd94f103ddf630475190ed5cdcac6553611b56d
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-log/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/Makefile b/cap/zx297520v3/src/lynq/lib/liblynq-log/Makefile
new file mode 100755
index 0000000..06b216e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/Makefile
@@ -0,0 +1,63 @@
+PREFIX = ../install
+CROSS = arm-none-linux-
+ROOT = $(PREFIX)/$(CROSS:%-=%)
+
+#For Yocto use
+
+RFX_TEST_CLIENT = false
+RFX_TEST_AOSP = false
+
+$(warning ########## log-riltel BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+
+
+SUBDIRS += log-riltel
+
+
+
+
+
+$(warning ########## log-riltel SUBDIRS $(SUBDIRS) ##########)
+export SIM_COUNT?=1
+
+.PHONY: all build clean pack_rootfs
+
+all: build
+
+build: clean
+
+clean:
+ $(warning ########## clean ril ##########)
+ for i in $(SUBDIRS); do \
+ (cd $$i && make clean); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
+build:
+ $(warning ########## build ril ##########)
+ for i in $(SUBDIRS); do \
+ (cd $$i && make); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
+install:
+ $(warning ########## install ril ##########)
+ for i in $(SUBDIRS); do \
+ (cd $$i && make install); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
+pack_rootfs:
+ $(warning ########## pack_rootfs ril ##########)
+ for i in $(SUBDIRS); do \
+ (cd $$i && make pack_rootfs); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/NOTICE b/cap/zx297520v3/src/lynq/lib/liblynq-log/NOTICE
new file mode 100755
index 0000000..c5b1efa
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/README b/cap/zx297520v3/src/lynq/lib/liblynq-log/README
new file mode 100755
index 0000000..9a7e82f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/README
@@ -0,0 +1,13 @@
+WHAT IT DOES?
+=============
+MTK ril proxy core library
+
+HOW IT WAS BUILT?
+==================
+This module is source code released.
+
+HOW TO USE IT?
+==============
+MTK ril proxy daemon will use this library to communicate with GSM and C2K RILD.
+
+All the source code of this folder were written by MediaTek co..
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h
new file mode 100755
index 0000000..dd8c7c0
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/liblog.h
@@ -0,0 +1,39 @@
+#ifndef __LIBLOG_H__
+#define __LIBLOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOG_ENABLE 0
+
+//#if LOG_ENABLE
+#if !LOG_ENABLE
+
+#define ENABLE(X) (1<<(X))
+#define LOG_LEVEL_ENABLE ENABLE(LOG_VERBOSE)
+
+typedef enum
+{
+ LOG_VERBOSE = 0,
+ LOG_ERROR,
+ LOG_WARNING,
+ LOG_INFO,
+ LOG_DEBUG,
+ LOG_LEVEL_MAX
+}log_level_enum;
+
+const static char * LogLevelNameInfoTable[LOG_LEVEL_MAX] =
+{
+ "[VERBOSE]","[ERROR]","[WARNING]","[INFO]","[DEBUG]" //lt add @2021.7.22 for []
+};
+#endif //LOG_ENABLE
+
+void lynq_log_global_output(log_level_enum Level,const char *format,...);
+void lynq_log_configuration_set(char *log_name,char log_data_arr);
+void lynq_log_configuration_init(char *log_name);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__LOG_H__
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h
new file mode 100755
index 0000000..667ae1a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/include/liblog/lynq_deflog.h
@@ -0,0 +1,41 @@
+#ifndef __LYNQ_DEFLOG_H__
+#define __LYNQ_DEFLOG_H__
+#include "liblog.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lynq_log_configuration_init(char *log_name);
+void lynq_log_configuration_set(char *log_name,char log_data_arr);
+void lynq_log_verbose(const char *format,...);
+void lynq_log_error(const char *format,...);
+void lynq_log_warning(const char *format,...);
+void lynq_log_info(const char *format,...);
+void lynq_log_debug(const char *format,...);
+
+
+#ifndef USER_LOG_TAG
+#define LYVERBLOG(X...) lynq_log_global_output(LOG_VERBOSE,X)
+#define LYERRLOG(X...) lynq_log_global_output(LOG_ERROR,X)
+#define LYWARNLOG(X...) lynq_log_global_output(LOG_WARNING,X)
+#define LYINFLOG(X...) lynq_log_global_output(LOG_INFO,X)
+#define LYDBGLOG(X...) lynq_log_global_output(LOG_DEBUG,X)
+#define LYLOGSET(a) lynq_log_configuration_set(USER_LOG_TAG,a)
+#define LYLOGEINIT(Y) lynq_log_configuration_init(Y)
+#else
+#define LYVERBLOG(X...)
+#define LYERRLOG(X...)
+#define LYWARNLOG(X...)
+#define LYINFLOG(X...)
+#define LYDBGLOG(X...)
+#define LYLOGSET(a)
+#define LYLOGEINIT(Y)
+#endif
+
+char* lynq_read_log_version();
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__LYNQ_DEFLOG_H__
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c
new file mode 100755
index 0000000..7bbbeac
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/log.c
@@ -0,0 +1,367 @@
+#include "liblog.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+//#include <log/log.h>
+#include <include/lynq_uci.h>
+
+#define LOG_NAME_LEN 128
+#define LOG_OUT_LEN 2*1024+100 //lt add @2021.9.22 for write outbuf define len
+#define LOG_LEN 2*1024 //lt add @2021.9.22 for write buf define len
+#define LOG_UCI_MODULE "lynq_log"
+#define LOG_UCI_FILE "lynq_uci"
+static unsigned int log_level = 0;
+static unsigned char log_name_arr[LOG_NAME_LEN] = {0};
+
+int lynq_log_set_value(char *key, char *value);
+int lynq_log_get_value(char *key, char *tmp);
+
+void lynq_log_global_output(log_level_enum Level,const char *format,...)
+{
+#if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+
+ if(Level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> Level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[Level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s", LogLevelNameInfoTable[Level], buf);//lt add @2021.7.22 for write outbuf
+ switch(Level) //lt mod @2021.9.22 for matching MTK log level
+ {
+ case LOG_VERBOSE:
+ __android_log_print(ANDROID_LOG_VERBOSE,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ break;
+ case LOG_ERROR:
+ __android_log_print(ANDROID_LOG_ERROR,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ break;
+ case LOG_WARNING:
+ __android_log_print(ANDROID_LOG_WARN,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ break;
+ case LOG_INFO:
+ __android_log_print(ANDROID_LOG_INFO,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ break;
+ case LOG_DEBUG:
+ __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "%s",out_buf); //lt add @2021.7.22 for write syslog.log
+ break;
+ default :
+ __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "Log Level is Error!!!!!!"); //lt add @2021.9.22 for write syslog.log
+ break;
+ }
+
+ }
+ return ;
+#endif //LOG_ENABLE
+}
+
+void lynq_log_configuration_set(char *log_name,char log_data_arr)
+{
+ char log_data_str[32] = {0};
+ if(log_name == NULL)
+ {
+ return ;
+ }
+ if(log_data_arr < LOG_LEVEL_MAX)
+ {
+ sprintf(log_data_str,"%d",log_data_arr);
+ if((strlen(log_name)) < LOG_NAME_LEN)
+ {
+ lynq_log_set_value(log_name, log_data_str);//lt mod @2021.8.3 for uci
+ }
+ }
+ lynq_log_configuration_init(log_name);
+ return ;
+}
+
+void lynq_deal_with_level(unsigned int get_log_level)
+{
+ switch(get_log_level)
+ {
+ case LOG_DEBUG:
+ log_level |= ENABLE(LOG_DEBUG);
+ case LOG_INFO:
+ log_level |= ENABLE(LOG_INFO);
+ case LOG_WARNING:
+ log_level |= ENABLE(LOG_WARNING);
+ case LOG_ERROR:
+ log_level |= ENABLE(LOG_ERROR);
+ case LOG_VERBOSE:
+ log_level |= ENABLE(LOG_VERBOSE);
+ break;
+ default:
+ log_level |= ENABLE(LOG_VERBOSE);
+ break;
+ }
+ return ;
+}
+
+void lynq_log_configuration_init(char *log_name)
+{
+ char get_propty_log_data[32] ={0};
+ unsigned int get_log_level = 0;
+ if(log_name == NULL)
+ {
+ return ;
+ }
+ if((strlen(log_name)) < LOG_NAME_LEN)
+ {
+ strcpy(log_name_arr,log_name);
+ if(0 == lynq_log_get_value(log_name,get_propty_log_data))//lt mod @2021.8.3 for uci
+ {
+ get_log_level = atoi(get_propty_log_data);
+ }
+ else
+ {
+ lynq_log_configuration_set(log_name, get_log_level);//lt add @2021.09.06 for uci
+ }
+ }
+ lynq_deal_with_level(get_log_level);
+ return ;
+}
+
+//lt add @2021.8.3 for in encapsulating the UCI set function
+int lynq_log_set_value(char *key, char *value)
+{
+ return lynq_set_value(LOG_UCI_MODULE, key, value);
+}
+
+//lt add @2021.8.3 for in encapsulating the UCI get function
+int lynq_log_get_value(char *key, char *tmp)
+{
+ return lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, key, tmp);
+}
+
+//lt add @2022.1.5 for add fota lib name.
+char* lynq_read_log_version()
+{
+ return "LOG-V1.0";
+}
+
+/**
+ * @brief Verbose logs are printed and stored
+ *
+ * @param log data
+ * @return void
+ */
+void lynq_log_verbose(const char *format,...)
+{
+#if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+ log_level_enum lynq_level = LOG_VERBOSE;
+
+ if(lynq_level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> lynq_level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+ __android_log_print(ANDROID_LOG_VERBOSE,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ }
+ return ;
+#endif //LOG_ENABLE
+}
+
+/**
+ * @brief Error logs are printed and stored
+ *
+ * @param log data
+ * @return void
+ */
+void lynq_log_error(const char *format,...)
+{
+#if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+ log_level_enum lynq_level = LOG_ERROR;
+
+ if(lynq_level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> lynq_level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+ __android_log_print(ANDROID_LOG_ERROR,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ }
+ return ;
+#endif //LOG_ENABLE
+ return ;
+}
+
+/**
+ * @brief Warning logs are printed and stored
+ *
+ * @param log data
+ * @return void
+ */
+void lynq_log_warning(const char *format,...)
+{
+ #if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+ log_level_enum lynq_level = LOG_WARNING;
+
+ if(lynq_level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> lynq_level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+ __android_log_print(ANDROID_LOG_WARN,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ }
+ return ;
+#endif //LOG_ENABLE
+ return ;
+}
+
+/**
+ * @brief Info logs are printed and stored
+ *
+ * @param log data
+ * @return void
+ */
+void lynq_log_info(const char *format,...)
+{
+ #if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+ log_level_enum lynq_level = LOG_INFO;
+
+ if(lynq_level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> lynq_level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+ __android_log_print(ANDROID_LOG_INFO,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ }
+ return ;
+#endif //LOG_ENABLE
+ return ;
+}
+
+/**
+ * @brief debug logs are printed and stored
+ *
+ * @param log data
+ * @return void
+ */
+void lynq_log_debug(const char *format,...)
+{
+#if LOG_ENABLE
+
+ char out_buf[LOG_OUT_LEN] = {0};
+ char buf[LOG_LEN] = {0};
+ log_level_enum lynq_level = LOG_DEBUG;
+
+ if(lynq_level >= LOG_LEVEL_MAX)
+ return;
+ if((log_level >> lynq_level)&0x00000001)
+ {
+ va_list args;
+ //TagName
+ if(log_name_arr[0] > 0)
+ {
+ printf("[%s]",log_name_arr);
+ }
+
+ //LevelName
+ printf("%s:",LogLevelNameInfoTable[lynq_level]); //lt dele @2021.7.22 for []
+
+ va_start(args,format);
+ vprintf(format,args);
+ vsnprintf(buf, sizeof(buf), format, args); //lt add @2021.7.22 for write buf
+ va_end(args);
+ printf("\r\n");
+
+ sprintf(out_buf, "%s %s",LogLevelNameInfoTable[lynq_level], buf);//lt add @2021.7.22 for write outbuf
+ __android_log_print(ANDROID_LOG_DEBUG,log_name_arr, "%s",out_buf); //lt add @2021.9.22 for write syslog.log
+ }
+ return ;
+#endif //LOG_ENABLE
+ return ;
+}
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile
new file mode 100755
index 0000000..37d7896
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-log/log-riltel/makefile
@@ -0,0 +1,62 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -DKEEP_ALIVE \
+ -DECALL_SUPPORT \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/../include/liblog \
+ -I$(ROOT)$(includedir) \
+ -I$(ROOT)$(includedir)/logger \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -llynq-uci \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-log.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+ $(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+ mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+ mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+ mkdir -p $(PACK_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h b/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h
new file mode 100755
index 0000000..bbac100
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/include/lynq_shm.h
@@ -0,0 +1,26 @@
+/**
+ * @file shm.h
+ * @author hq
+ * @brief
+ * @version 1.0
+ * @date 2022-12-16
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
+#ifndef __LYNQ_SHM_H__
+#define __LYNQ_SHM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int ril_init_mem();
+void ril_deinit_mem();
+bool get_cur_shem_buffer_index(int size, int* level, int* index);
+bool get_shem_buffer_level(int size, int* level);
+char* get_shem_buffer(int level,int index);
+int get_max_shem_buffer_size();
+#ifdef __cplusplus
+}
+#endif
+#endif //#ifndef __TEST_SHARED_MEMORY_INCLUDE__
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp
new file mode 100755
index 0000000..bc1b25a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/lynq_shm.cpp
@@ -0,0 +1,195 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <binder/Parcel.h>
+//#include <sys/socket.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/shm.h>
+#include <liblog/lynq_deflog.h>
+#include <pthread.h>
+#include "lynq_shm.h"
+
+#undef LOG_TAG
+#define LOG_TAG "SHM"
+
+#define shm_key "shm_key"
+
+int shmid=-1;
+
+static int s_use_count=0;
+
+typedef struct{
+ int num_of_buffer;
+ int size_of_buffer;
+ int cur_index;
+}lynq_shm_type_config;
+
+typedef enum{
+ shm_buf_type_256,
+ shm_buf_type_1k,
+ shm_buf_type_max,
+}lynq_shm_buf_type;
+
+lynq_shm_type_config s_lynq_shm_config[shm_buf_type_max]={
+ {10,256,0},
+ {5,1024,0}
+};
+
+static void * s_ril_shm_buf=(void*) -1L;
+
+static pthread_mutex_t s_shm_mtx = PTHREAD_MUTEX_INITIALIZER;
+
+bool get_cur_shem_buffer_index(int size, int* level, int* index)
+{
+ pthread_mutex_lock(&s_shm_mtx);
+ for(int i=0;i<shm_buf_type_max;i++)
+ {
+ if(size<=s_lynq_shm_config[i].size_of_buffer)
+ {
+ (*level)=i;
+ (*index)=(s_lynq_shm_config[i].cur_index)%s_lynq_shm_config[i].num_of_buffer;
+ s_lynq_shm_config[i].cur_index++;
+ pthread_mutex_unlock(&s_shm_mtx);
+ return true;
+ }
+ }
+ pthread_mutex_unlock(&s_shm_mtx);
+ return false;
+}
+
+bool get_shem_buffer_level(int size, int* level)
+{
+ for(int i=0;i<shm_buf_type_max;i++)
+ {
+ if(size<=s_lynq_shm_config[i].size_of_buffer)
+ {
+ (*level)=i;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+char* get_shem_buffer(int level,int index)
+{
+ int offset=0;
+ for(int i=0;i<level;i++)
+ {
+ offset+=s_lynq_shm_config[i].num_of_buffer*s_lynq_shm_config[i].size_of_buffer;
+ }
+ offset+=s_lynq_shm_config[level].size_of_buffer*index;
+ return ((char*) s_ril_shm_buf)+offset;
+}
+
+int get_max_shem_buffer_size()
+{
+ return s_lynq_shm_config[shm_buf_type_max-1].size_of_buffer;
+}
+
+int get_total_shem_buffer_size()
+{
+ int total_size=0;
+ for(int i=0;i<shm_buf_type_max;i++)
+ {
+ total_size+=s_lynq_shm_config[i].num_of_buffer*s_lynq_shm_config[i].size_of_buffer;
+ }
+ return total_size;
+}
+
+static int create_shm_common(int size,int flags)
+{
+ LYDBGLOG("create shared memory\n");
+
+// key_t key = ftok(shm_key, 's');
+ key_t key=0x123456;
+ if (key == -1)
+ {
+ LYERRLOG("ftok error.\n");
+ return -1;
+ }
+ LYDBGLOG("key is 0x%x\n", key);
+
+ int shmid = shmget(key,size , flags);
+ if (shmid == -1)
+ {
+ LYERRLOG("shmget error.\n");
+ return -1;
+ }
+ LYDBGLOG("shmid is %d\n", shmid);
+
+ return shmid;
+}
+
+int create_shm()
+{
+ shmid = create_shm_common(get_total_shem_buffer_size(),IPC_CREAT|0644);
+
+ if(shmid==-1)
+ {
+ return -1;
+ }
+ s_ril_shm_buf = shmat(shmid, NULL, 0);
+ if (s_ril_shm_buf == (void*) -1L)
+ {
+ LYERRLOG("shmat error.\n");
+ return -1;
+ }
+ return 0;
+}
+
+void remove_shm()
+{
+ if(shmid!=-1)
+ {
+ if (shmdt(s_ril_shm_buf) != 0)
+ {
+ LYERRLOG("shmdt error.\n");
+ }
+ shmid = -1;
+ }
+ s_ril_shm_buf = (void*) -1L;
+ return ;
+}
+
+int ril_init_mem()
+{
+ pthread_mutex_lock(&s_shm_mtx);
+ LYERRLOG("init begin, use count is %d.\n",s_use_count);
+ if(s_use_count==0)
+ {
+ if(create_shm()!=0)
+ {
+ LYERRLOG("init end, use count is %d.\n",s_use_count);
+ pthread_mutex_unlock(&s_shm_mtx);
+ return -1;
+ }
+ }
+ s_use_count++;
+ LYERRLOG("init end, use count is %d.\n",s_use_count);
+ pthread_mutex_unlock(&s_shm_mtx);
+ return 0;
+}
+
+void ril_deinit_mem()
+{
+ pthread_mutex_lock(&s_shm_mtx);
+
+ LYERRLOG("de-init begin, use count is %d.\n",s_use_count);
+ if(s_use_count==1)
+ {
+ remove_shm();
+ }
+
+ if(s_use_count>0)
+ {
+ s_use_count--;
+ }
+ LYERRLOG("de-init end, use count is %d.\n",s_use_count);
+ pthread_mutex_unlock(&s_shm_mtx);
+ return ;
+}
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile
new file mode 100755
index 0000000..115eb9f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-shm/makefile
@@ -0,0 +1,65 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC
+
+PWD := $(shell pwd)
+
+$(warning ################# lynq shm ROOT: $(ROOT),includedir:$(includedir), PWD :$(PWD))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+ -I$(ROOT)$(includedir) \
+ -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -llynq-log \
+ -lpthread \
+
+
+# -lbinder \
+# -lutils \
+# -lcutils \
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-shm.so
+
+OBJECTS=$(SOURCES:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+
+install:
+ $(warning ################# lynq shm EXECUTABLE: $(EXECUTABLE),base:$(base_libdir))
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+
+pack_rootfs:
+ $(warning ################# lynq shm PACK: $(PACK_INITRAMFS_TO),base:$(base_libdir))
+ mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+ mkdir -p $(PACK_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)
+
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-uci/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h b/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h
new file mode 100755
index 0000000..0e9ec37
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/include/lynq_uci.h
@@ -0,0 +1,35 @@
+#ifndef _LYNQ_UCI_H_
+#define _LYNQ_UCI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <uci.h>
+
+#define LYNQ_UCI_MAX_LEN 128
+#define LYNQ_UCI_SUCCESS 0
+#define LYNQ_UCI_ERROR 1
+#define LYNQ_UCI_FILE "lynq_uci"
+#define LYNQ_UCI_RO_FILE "lynq_uci_ro"
+
+//static struct uci_context * ctx = NULL;
+
+int lynq_del(char *option);
+#if UCI_SUPPORT
+ static int uci_get_value(struct uci_option *o, char *out_buf);
+#endif //uci_support
+int lynq_uci_get(const char *arg, char *out_buf);
+
+int lynq_uci_set(const char *arg);
+
+int lynq_add_section(char *section_type, char *section);
+
+int lynq_set_value(char *section, char *key, char *value);
+
+int lynq_get_value(char *file, char *section, char *key, char *tmp);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
new file mode 100755
index 0000000..3ac501d
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci.config
@@ -0,0 +1,28 @@
+config lynq_ril_rw 'lynq_ril'
+ option serverport '8000'
+
+config lynq_log_rw 'lynq_log'
+ option thhandle_level '0'
+ option function_test_level '0'
+
+config lynq_wifi_rw 'lynq_wifi'
+ option gateway '192.168.11.1'
+
+config lynq_sync_time_rw 'lynq_sync_time'
+
+config lynq_autosuspend 'lynq_autosuspend'
+ option auto_enable '0'
+ option debug '1'
+
+config lynq_fota_rw 'lynq_fota'
+
+config service 'adb'
+
+config adb 'tcp'
+ option port '5555'
+
+config lynq_apn 'lynq_apn_info'
+ option insertId '0'
+
+config rndis_status 'rndis'
+ option status '0'
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config
new file mode 100755
index 0000000..4aa92ac
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/lynq_uci_ro.config
@@ -0,0 +1,4 @@
+config lynq_version_ro 'lynq_version'
+
+config lynq_wifi_ro 'lynq_wifi'
+ option serverport '8000'
\ No newline at end of file
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile
new file mode 100755
index 0000000..209bf03
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/makefile
@@ -0,0 +1,85 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC \
+
+$(warning ################# C2K support: $(RAT_CONFIG_C2K_SUPPORT))
+ifeq ($(strip $(RAT_CONFIG_C2K_SUPPORT)), yes)
+ LOCAL_CFLAGS += -DC2K_SUPPORT
+
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsds)
+ LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 \
+ -DANDROID_MULTI_SIM \
+ -DMODE_DSDS
+endif
+
+ifeq ($(strip $(MTK_MULTI_SIM_SUPPORT)), dsss)
+ LOCAL_CFLAGS += -DMODE_DSSS
+endif
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(warning ################# TARGET_PLATFORM_MT2731)
+ LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+ -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+ LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+ -DMD_90_SUPPORT
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lpthread \
+ -luci \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-uci.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+ $(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+ mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+ mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+ mkdir -p $(PACK_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c b/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c
new file mode 100755
index 0000000..b557c08
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-uci/src/lynq_uci.c
@@ -0,0 +1,223 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lynq_uci.h>
+#define UCI_SUPPORT 1
+int lynq_del(char *option)
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ int ret;
+ char buf[LYNQ_UCI_MAX_LEN];
+ struct uci_context *ctx = uci_alloc_context();
+ struct uci_ptr ptr;
+
+ sprintf(buf, "%s", option);
+ if(uci_lookup_ptr(ctx, &ptr, buf, true) == UCI_OK)
+ {
+ uci_delete(ctx, &ptr);
+ uci_save(ctx, ptr.p);
+ ret = LYNQ_UCI_SUCCESS;
+ }
+ else
+ ret = LYNQ_UCI_ERROR;
+
+ uci_free_context(ctx);
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+#if UCI_SUPPORT
+static int uci_get_value(struct uci_option *o, char *out_buf)
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ struct uci_element *e;
+ const char *delimiter = " ";
+ int lynq_uci_flag = 0;
+
+ switch(o->type) {
+ case UCI_TYPE_STRING:
+ strcpy(out_buf, o->v.string);
+ break;
+ case UCI_TYPE_LIST:
+ uci_foreach_element(&o->v.list, e)
+ {
+ if(lynq_uci_flag)
+ strcat(out_buf, delimiter);
+
+ strcat(out_buf, e->name);
+ lynq_uci_flag = 1;
+ }
+ break;
+ default:
+ return UCI_ERR_INVAL;
+ break;
+ }
+ return UCI_OK;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+#endif //#if UCI_SUPPORT
+int lynq_uci_get(const char *arg, char *out_buf)
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ struct uci_context *ctx;
+ struct uci_element *e;
+ struct uci_ptr ptr;
+
+ int ret = UCI_OK;
+ char *para_name = NULL;
+
+ if(arg == NULL || out_buf == NULL) return UCI_ERR_INVAL;
+
+ para_name = strdup(arg);
+ if(para_name == NULL) return UCI_ERR_INVAL;
+
+ ctx = uci_alloc_context();
+ if (!ctx) {
+ free(para_name);
+ return UCI_ERR_MEM;
+ }
+
+ if (uci_lookup_ptr(ctx, &ptr, para_name, true) != UCI_OK) {
+ uci_free_context(ctx);
+ free(para_name);
+ return UCI_ERR_NOTFOUND;
+ }
+
+ if(UCI_LOOKUP_COMPLETE & ptr.flags)
+ {
+ e = ptr.last;
+ switch(e->type)
+ {
+ case UCI_TYPE_SECTION:
+ ret = UCI_ERR_INVAL;
+ break;
+ case UCI_TYPE_OPTION:
+ ret = uci_get_value(ptr.o, out_buf);
+ break;
+ default:
+ ret = UCI_ERR_NOTFOUND;
+ break;
+ }
+ }
+ else
+ ret = UCI_ERR_NOTFOUND;
+
+ uci_free_context(ctx);
+ free(para_name);
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+
+int lynq_uci_set(const char *arg)
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ struct uci_context *ctx;
+ struct uci_element *e;
+ struct uci_ptr ptr;
+ int ret = UCI_OK;
+ char *name = NULL;
+
+ if(arg == NULL) return UCI_ERR_INVAL;
+
+ name = strdup(arg);
+ if(name == NULL) return UCI_ERR_MEM;
+
+ ctx = uci_alloc_context();
+ if (!ctx) {
+ free(name);
+ return UCI_ERR_MEM;
+ }
+
+ if (uci_lookup_ptr(ctx, &ptr, name, true) != UCI_OK) {
+ uci_free_context(ctx);
+ free(name);
+ return UCI_ERR_NOTFOUND;
+ }
+
+ ret = uci_set(ctx, &ptr);
+ if(ret != UCI_OK)
+ {
+ uci_free_context(ctx);
+ free(name);
+ return ret;
+ }
+
+ ret = uci_save(ctx, ptr.p);
+ if(ret != UCI_OK)
+ {
+ uci_free_context(ctx);
+ free(name);
+ return ret;
+ }
+
+ ret = uci_commit(ctx, &ptr.p, false);
+ if(ret != UCI_OK)
+ {
+ uci_free_context(ctx);
+ free(name);
+ return ret;
+ }
+
+ uci_free_context(ctx);
+ free(name);
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+
+int lynq_add_section(char *section_type, char *section)//rita add @2021.7.30 for adding section
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ char buf[128] = "";
+ sprintf(buf,"lynq_uci.%s=%s", section, section_type);
+ //printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);
+ int ret = lynq_uci_set(buf);
+
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+
+int lynq_set_value(char *section, char *key, char *value)//rita add @2021.7.30 for setting value
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ char buf[LYNQ_UCI_MAX_LEN] = "";
+
+ sprintf(buf,"%s.%s.%s=%s", LYNQ_UCI_FILE, section, key, value);
+ //printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);
+ int ret = lynq_uci_set(buf);
+
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
+
+int lynq_get_value(char *file, char *section, char *key, char *tmp)//rita add @2021.7.30 for getting value
+{
+ printf("this is lynq uci module,fun:%s,line:%d\n",__FUNCTION__,__LINE__);
+ #if UCI_SUPPORT
+ char buf[LYNQ_UCI_MAX_LEN] = "";
+ int ret = 0;
+
+ if(strcmp(file, LYNQ_UCI_RO_FILE) && strcmp(file, LYNQ_UCI_FILE))
+ {
+ printf("[%s-%d] invalid file %s!!!\n", __FUNCTION__, __LINE__, file);
+ return LYNQ_UCI_ERROR;
+ }
+
+ sprintf(buf,"%s.%s.%s", file, section, key);
+ //printf("[%s-%d] buf = %s\n", __FUNCTION__, __LINE__, buf);
+
+ ret = lynq_uci_get(buf, tmp);
+ return ret;
+ #endif //#if UCI_SUPPORT
+ return 0;//#if UCI_SUPPORT add
+}
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/LICENSE b/cap/zx297520v3/src/lynq/lib/libpal/LICENSE
new file mode 100755
index 0000000..77f59ed
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/Makefile b/cap/zx297520v3/src/lynq/lib/libpal/Makefile
new file mode 100755
index 0000000..b0ce89a
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/Makefile
@@ -0,0 +1,67 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+ -I$(LOCAL_PATH)/include/liblog \
+ -I$(LIB_DIR)/binder/include/log \
+ -I$(LIB_DIR)/binder/include \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -L$(zte_lib_path)/binder/liblog \
+ -L$(zte_lib_path)/binder/libcutils \
+ -ldl \
+ -lstdc++ \
+ -llog \
+ -lcutils \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = libpal.so
+
+OBJECTS=$(SOURCES:.c=.o)
+H_FILE = ${wildcard *.h}
+CUR_SOURCE=$(wildcard ./src/*.c)
+CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
+
+.PHONY: build clean install pack_rootfs
+
+all: build
+$(EXECUTABLE): $(CUR_OBJS)
+ $(CXX) -shared -Wl,--no-undefined $(CUR_OBJS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+
+romfs:
+ $(ROMFSINST) $(EXECUTABLE) /lib/$(EXECUTABLE)
+
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+ mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+ mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+ mkdir -p $(PACK_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735 b/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735
new file mode 100755
index 0000000..0ff7ca8
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/Makefile.mt2735
@@ -0,0 +1,29 @@
+CANLIB=libpal
+VERSION=1
+TARGET= $(CANLIB).so
+
+
+SO_CFLAGS= -shared
+CFLAGS?= -O2
+H_FILE = ${wildcard *.h}
+CUR_SOURCE=${wildcard *.c}
+CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}
+
+
+all: $(TARGET)
+
+install:
+ @mkdir -p $(DEST_DIR)/lib64
+ install -m 0644 $(CANLIB).so $(DEST_DIR)/lib64/
+
+%.o: %.c
+ $(CC) -Wall -fPIC $(CFLAGS) -c $^ -o $@
+$(TARGET).$(VERSION) : $(CUR_OBJS)
+ $(CC) -shared -nostartfiles -Wl,-soname,$@ $^ -o $@ $(LDFLAGS)
+
+$(TARGET): $(CANLIB).so.$(VERSION)
+ ln -s $< $@
+
+.PHONY: clean
+clean:
+ rm -f $(CANLIB).* $(CUR_OBJS)
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h b/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h
new file mode 100755
index 0000000..844fb1f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/include/pal_nm.h
@@ -0,0 +1,132 @@
+//SPDX-License-Identifier: MediaTekProprietary
+#ifndef __PAL_NM_H__
+#define __PAL_NM_H__
+
+/**
+ * @file pal_nm.h
+ * @brief
+ * @author MediaTek
+ * @version v0.1
+ * @date 2016-07-11
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define NM_INTERFACE_FLAG_UP (0x1<<0) //IFF_UP
+#define NM_INTERFACE_FLAG_LOOPBACK (0x1<<2) //IPP_LOOPBACK
+
+typedef enum {
+ NM_IP_TYPE_UNKNOWN = 0,
+ NM_IP_TYPE_V6_UNSPEC = 0x1,
+ NM_IP_TYPE_V6_LOOPBACK = 0x2,
+ NM_IP_TYPE_V6_MULTICAST = 0x4,
+ NM_IP_TYPE_V6_LINKLOCAL = 0x8,
+ NM_IP_TYPE_V6_SITELOCAL = 0x10,
+
+ NM_IP_TYPE_V6_GLOBAL_PERNAMENT = 0x20,
+ NM_IP_TYPE_V6_GLOBAL_TEMP = 0x40,
+ NM_IP_TYPE_V6_GLOBAL_DYNAMIC =0x80,
+ NM_IP_TYPE_V6_GLOBAL = NM_IP_TYPE_V6_GLOBAL_PERNAMENT | NM_IP_TYPE_V6_GLOBAL_TEMP | NM_IP_TYPE_V6_GLOBAL_DYNAMIC,
+ NM_IP_TYPE_V6_UNIQUE = 0x100,
+
+ NM_IP_TYPE_V6_ALLCONFIG = NM_IP_TYPE_V6_GLOBAL | NM_IP_TYPE_V6_UNIQUE,
+ NM_IP_TYPE_V6_VALIDIP = NM_IP_TYPE_V6_GLOBAL_PERNAMENT | NM_IP_TYPE_V6_GLOBAL_DYNAMIC | NM_IP_TYPE_V6_UNIQUE, /*For App use*/
+
+} NM_IP_TYPE_V6;
+
+typedef enum {
+ NM_NETWORK_TYPE_UNKNOW = 0,
+ NM_NETWORK_TYPE_IMS = 1,
+ NM_NETWORK_TYPE_INTERNET = 2
+} NM_NETWORK_TYPE;
+
+/*interface ipv4 related APIs*/
+int nm_interface_ipv4_set(const char *intf_name, const char* addr, int prefix_len);
+int nm_interface_ipv4_up(const char *intf_name);
+int nm_interface_ipv4_down(const char *intf_name);
+int nm_interface_ipv4_mtu_set(const char *intf_name, int mtu);
+int nm_interface_ipv4_info_get(const char *intf_name, unsigned long *addr,
+ int *prefix_len, int *mtu, unsigned int*flags);
+int nm_interface_ipv4_hwaddr_get(const char *intf_name, unsigned char *hw_addr);
+int nm_interface_ipv4_addr_clear(const char *intf_name);
+
+
+/*interface ipv6 related APIs*/
+int nm_interface_ipv6_mtu_set(const char *intf_name, int mtu);
+int nm_interface_ipv6_addr_clear(const char *intf_name);
+int nm_interface_ipv6_set(const char *intf_name, int on);
+int nm_interface_ipv6_privacyextenstion_enable_set(const char *intf_name, int on);
+int nm_interface_ipv6_ndoffload_enable_set(const char *intf_name, int on);
+int nm_interface_ipv6_addr_set(const char *intf_name, const char *addr, int prefix_len);
+int nm_interface_ipv6_addr_get(const char *intf_name, int addr_type, char *addr, int *prefix_len);
+
+
+/*network related APIs*/
+int nm_network_create(unsigned net_id, const char *permission);
+int nm_network_destroy(unsigned net_id);
+int nm_network_default_set(unsigned net_id);
+int nm_network_default_clear();
+int nm_network_interface_add(unsigned net_id, const char* intf_name);
+int nm_network_interface_remove(unsigned net_id, const char* intf_name);
+int nm_network_route_add(unsigned net_id, const char* intf_name,
+ const char *destination, const char *nexthop,
+ int legacy, unsigned int uid);
+int nm_network_route_remove( unsigned net_id, const char* intf_name,
+ const char *destination, const char *nexthop,
+ int legacy, unsigned int uid);
+
+
+
+/*ipfwd related APIs*/
+int nm_fwd_ipv4_set(int enable, const char *requestor);
+int nm_fwd_ipv4_get(int *enable);
+int nm_fwd_ipv6_set(int enable, const char *requestor);
+int nm_fwd_ipv6_get(int *enable);
+
+
+/*DNS related APIs*/
+//set ipv6 dns name server
+int nm_resolver_ipv6_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type);
+
+//set ipv4 dns name server
+int nm_resolver_ipv4_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type);
+
+//set ipv4 && ipv6 dns name server
+int nm_resolver_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type);
+
+
+//clear name server for both ipv4/ipv6
+int nm_resolver_dns_clear(unsigned net_id);
+
+//flush dns cache
+int nm_resolver_dns_cache_flush(unsigned net_id);
+
+int nm_command_test(char *intf);
+
+int nm_interface_get_netid(const char *intf_name,unsigned int *netid);
+
+
+void nm_network_policy_route_init();
+int nm_network_ipv6_policy_route_modify(uint16_t action, uint32_t table, const char* interface);
+int nm_network_ipv6_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif);
+int nm_network_ipv4_policy_route_modify(uint16_t action, uint32_t table, const char* interface);
+int nm_network_ipv4_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif);
+struct Stats {
+ uint64_t rxBytes;
+ uint64_t rxPackets;
+ uint64_t txBytes;
+ uint64_t txPackets;
+ uint64_t tcpRxPackets;
+ uint64_t tcpTxPackets;
+};
+
+int parseIfaceStats(const char* iface, struct Stats* stats);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PAL_NM_H__*/
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script b/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script
new file mode 100755
index 0000000..fa4c1e6
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/script/dns.script
@@ -0,0 +1,107 @@
+#!/bin/sh
+# dns event handling script
+#
+
+RESOLV_CONF="/etc/resolv.conf"
+
+usage() {
+ echo "Usage: $0 {set/clean} dns..."
+ exit 1
+}
+
+clean() {
+ # clean /etc/resolv.conf
+ cat /dev/null > $RESOLV_CONF
+}
+
+show() {
+ cat $RESOLV_CONF
+}
+
+takelock()
+{
+ while [ -f "/tmp/dns_lock_fd" ]; do
+ :
+ echo "lock dns file now!"
+ sleep 1;
+ done
+ echo 1 > "/tmp/dns_lock_fd"
+}
+
+givelock()
+{
+ rm /tmp/dns_lock_fd
+}
+
+
+rmV4DNS(){
+ cat /etc/resolv.conf | grep : > /var/dns6
+ cat /var/dns6 > /etc/resolv.conf
+}
+
+rmV6DNS(){
+ cat /etc/resolv.conf | grep -v : > /var/dns4
+ cat /var/dns4 > /etc/resolv.conf
+}
+
+
+count=1
+if [ $# \< $count ] ; then
+ usage
+fi
+
+
+
+ takelock;
+case "$1" in
+
+ set)
+
+ rmV4DNS;
+ i=2
+ total=$#
+ while [ $i -le $total ];
+ do
+ shift
+ dns=$1
+ echo "adding dns " $dns
+ echo nameserver "$dns" >> $RESOLV_CONF
+ i=`expr $i + 1`
+ done
+ show
+ ;;
+
+ setv6)
+
+ rmV6DNS;
+ i=2
+ total=$#
+ while [ $i -le $total ];
+ do
+ shift
+ dns=$1
+ echo "adding dns " $dns
+ echo nameserver "$dns" >> $RESOLV_CONF
+ i=`expr $i + 1`
+ done
+ show
+ ;;
+
+
+ rmv4)
+ rmV4DNS
+ ;;
+ rmv6)
+ rmV6DNS
+ ;;
+
+
+ clean)
+ clean
+ ;;
+
+ *)
+ usage
+ ;;
+esac
+ givelock;
diff --git a/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c b/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c
new file mode 100755
index 0000000..d958efe
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/libpal/src/pal_nm.c
@@ -0,0 +1,1812 @@
+//SPDX-License-Identifier: MediaTekProprietary
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_addr.h>
+#include <../include/pal_nm.h>
+#include <syslog.h>
+
+#include <cutils/sockets.h>
+
+#include <linux/fib_rules.h>
+#include <asm/types.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <inttypes.h>
+
+
+#define PAL_NM_CMD_BUF_SIZE 256
+#define PAL_NM_DIGTAL_STRING_SIZE 10
+#define ETH_ALEN 6
+#define IPV6_PTRADDR_LEN 46
+#define MAX_DNS_NUMS 2
+
+const char sys_net_path[] = "/sys/class/net";
+static const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
+static const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
+
+static const char* QTAGUID_IFACE_STATS = "/proc/net/xt_qtaguid/iface_stat_fmt";
+//static const char* QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats";
+
+const uint16_t FRA_UID_START = 18;
+const uint16_t FRA_UID_END = 19;
+
+struct rtattr FRATTR_PRIORITY;
+struct rtattr FRATTR_TABLE;
+struct rtattr FRATTR_FWMARK;
+struct rtattr FRATTR_FWMASK;
+struct rtattr FRATTR_UID_START;
+struct rtattr FRATTR_UID_END;
+
+struct rtattr RTATTR_TABLE;
+struct rtattr RTATTR_OIF;
+
+const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
+const uint16_t NETLINK_CREATE_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
+
+uint8_t PADDING_BUFFER[RTA_ALIGNTO] = {0, 0, 0, 0};
+
+
+struct in6_ifreq{
+ struct in6_addr ifr6_addr;
+ int ifr6_prefixlen;
+ int ifr6_ifindex;
+};
+
+#define PAL_DEBUG_TRACE 5
+int pal_nm_debug = PAL_DEBUG_TRACE;
+
+#if 0
+#define PAL_DEBUG_PRINT(level, str, args...) \
+ do { \
+ if(level<=pal_nm_debug) \
+ { \
+ printf("\n\r[PAL-NM] %s - ", __FUNCTION__); \
+ printf(str, ##args); \
+ } \
+ } while(0)
+#else
+
+#define PAL_DEBUG_PRINT(level, str, args...) \
+ do { \
+ if(level<=pal_nm_debug) \
+ { \
+ syslog(LOG_DEBUG, "[PAL-NM][%s:%d:]--- " str "\n", __FUNCTION__, __LINE__, ## args);\
+ } \
+ } while(0)
+
+
+#endif
+static int get_ifindex(const char *dev, int *index)
+{
+ int fd;
+ struct ifreq req={{{0}}};
+ int ret;
+
+ strncpy(req.ifr_name, dev, strlen(dev));
+
+ if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail:%s", strerror(errno));
+ return -1;
+ }
+
+ ret = ioctl(fd, SIOCGIFINDEX, &req);
+
+ if(ret == -1)
+ {
+ *index = 0;
+ close(fd);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ioctl fail:%s", strerror(errno));
+ return ret;
+ }
+ *index = req.ifr_ifindex;
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "req.ifr_ifindex[%d]", req.ifr_ifindex);
+ close(fd);
+ return 0;
+}
+static int ipv4NetmaskToPrefixLength(in_addr_t mask)
+{
+ int prefixLength = 0;
+ uint32_t m = (uint32_t)ntohl(mask);
+ while (m & 0x80000000) {
+ prefixLength++;
+ m = m << 1;
+ }
+ return prefixLength;
+}
+
+static NM_IP_TYPE_V6 _net_ip_scope_v6(const char* ip_in)
+{
+ if (ip_in == NULL) return NM_IP_TYPE_UNKNOWN;
+ if (strchr(ip_in, ':') == NULL) return NM_IP_TYPE_UNKNOWN;
+ if (strcmp(ip_in, "::") == 0) return NM_IP_TYPE_V6_UNSPEC;
+ if (strcmp(ip_in, "::1") == 0) return NM_IP_TYPE_V6_LOOPBACK;
+ if (!strncmp(ip_in, "2", 1) || !strncmp(ip_in, "3", 1)) return NM_IP_TYPE_V6_GLOBAL;
+
+ if (strncmp(ip_in, "ff00", 4) == 0) return NM_IP_TYPE_V6_MULTICAST;
+ if (strncmp(ip_in, "fe80", 4) == 0) return NM_IP_TYPE_V6_LINKLOCAL;
+ if (strncmp(ip_in, "fec0", 4) == 0) return NM_IP_TYPE_V6_SITELOCAL;
+ if (!strncmp(ip_in, "fc", 2) || !strncmp(ip_in, "fd", 2)) return NM_IP_TYPE_V6_UNIQUE;
+
+ return NM_IP_TYPE_UNKNOWN;
+}
+
+static NM_IP_TYPE_V6 _net_ip_type_v6(int scope, int ifa_flags)
+{
+ if(NM_IP_TYPE_V6_GLOBAL != scope)
+ return scope;
+
+ if(ifa_flags & IFA_F_PERMANENT)
+ return NM_IP_TYPE_V6_GLOBAL_PERNAMENT;
+
+ if(ifa_flags & IFA_F_SECONDARY)
+ return NM_IP_TYPE_V6_GLOBAL_TEMP;
+
+ return NM_IP_TYPE_V6_GLOBAL_DYNAMIC;
+}
+int nm_interface_ipv4_set(const char *intf_name, const char* addr, int prefix_len)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name || !addr)
+ return -1;
+ if(strlen(intf_name)==0 || strlen(addr)==0)
+ return -1;
+ //interface setcfg <interface> [addr | prefixLength] [up | down]
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s %s %d", intf_name, addr, prefix_len);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+
+
+int nm_interface_ipv4_up(const char *intf_name)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name)
+ return -1;
+
+ //interface setcfg <interface> [addr | prefixLength] [up | down]
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s up", intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv4_down(const char *intf_name)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name)
+ return -1;
+
+ //interface setcfg <interface> [addr | prefixLength] [up | down]
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setcfg %s down", intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int nm_interface_ipv4_mtu_set(const char *intf_name, int mtu)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name)
+ return -1;
+
+ //interface setmtu <interface> <mtu>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setmtu %s %d", intf_name, mtu);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv4_info_get(const char *intf_name, unsigned long *addr,
+ int *prefix_len, int *mtu, unsigned int*flags)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ int sockfd;
+ struct ifreq ifr;
+ char mtuPath[30] = {0};
+ char chmtu[11] = {0};
+ FILE *fp = NULL;
+ if (!intf_name || !addr ||
+ !intf_name || !mtu || !flags)
+ {
+ return -1;
+ }
+
+ if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail");
+ return -1;
+ }
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "IFNAMSIZ[%d]", IFNAMSIZ);
+ strncpy(ifr.ifr_name, intf_name, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+ if (addr != NULL) {
+ if(ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "SIOCGIFADDR fail");
+ *addr = 0;
+ } else {
+ *addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*addr[%lu]", *addr);
+ }
+ }
+
+ if (prefix_len != NULL) {
+ if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "SIOCGIFNETMASK fail");
+ *prefix_len = 0;
+ } else {
+ *prefix_len = ipv4NetmaskToPrefixLength(
+ ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*prefix_len[%u]", *prefix_len);
+ }
+ }
+
+ if (flags != NULL) {
+ if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
+ *flags = 0;
+ } else {
+ *flags = ifr.ifr_flags;
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*flags[%u]", *flags);
+ }
+ }
+
+ snprintf(mtuPath, 29, "%s/%s/mtu", sys_net_path, intf_name);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "mtuPath[%s]", mtuPath);
+
+ fp = fopen(mtuPath , "r");
+ if (NULL == fp)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "open %s fail", mtuPath);
+ *mtu = 0;
+ }else
+ {
+ fread(chmtu, 1, 10, fp);
+ chmtu[10] = '\0';
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "chmtu[%s]", chmtu);
+ *mtu = atoi(chmtu);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*mtu[%u]", *mtu);
+ fclose(fp);
+ }
+ close(sockfd);
+
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv4_hwaddr_get(const char *intf_name, unsigned char *hw_addr)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ int ret;
+ int sockfd;
+ struct ifreq ifr;
+ if (!intf_name || !hw_addr)
+ {
+ return -1;
+ }
+
+ if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "create socket fail");
+ return -1;
+ }
+
+ bzero(&ifr, sizeof(ifr));
+ ifr.ifr_name[IFNAMSIZ -1] = '\0';
+ strncpy(ifr.ifr_name, intf_name, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ -1] = '\0';
+
+ ret = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
+ if(ret < 0) {
+ close(sockfd);
+ return -1;
+ }
+
+ memcpy(hw_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+
+ close(sockfd);
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv4_addr_clear(const char *intf_name)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ // interface clearaddrs <interface>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface clearaddrs %s", intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+/*interface ipv6 related APIs*/
+int nm_interface_ipv6_mtu_set(const char *intf_name, int mtu)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ //interface setmtu <interface> <mtu>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface setmtu %s %d", intf_name, mtu);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_addr_clear(const char *intf_name)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ // interface clearaddrs <interface>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface clearaddrs %s", intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ // interface ipv6 <interface> <enable | disable>
+
+ if (on)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6 %s enable", intf_name);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6 %s disable", intf_name);
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_privacyextenstion_enable_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ // interface ipv6privacyextensions <interface> <enable | disable>
+
+ if (on)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6privacyextensions %s enable", intf_name);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6privacyextensions %s disable", intf_name);
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_ndoffload_enable_set(const char *intf_name, int on)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ if (!intf_name)
+ return -1;
+
+ // interface ipv6ndoffload <interface> <enable | disable>
+
+ if (on)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6ndoffload %s enable", intf_name);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc interface ipv6ndoffload %s disable", intf_name);
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_interface_ipv6_addr_set(const char *intf_name, const char *addr, int prefix_len)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ int fd;
+ int ret;
+ int index = 0;
+ struct in6_ifreq v6_ifreq = {0};
+ if (!intf_name || !addr)
+ {
+ return -1;
+ }
+
+ ret = get_ifindex(intf_name, &index);
+ if (ret)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex");
+ return ret;
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex index[%d]", index);
+
+ fd = socket(AF_INET6, SOCK_DGRAM,0);
+ if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "open socket fail:%s", strerror(errno));
+
+ }
+
+ ret = inet_pton(AF_INET6, addr, &v6_ifreq.ifr6_addr.s6_addr);
+ if(ret != 1)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "inet_pton fail:%s", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ v6_ifreq.ifr6_ifindex = index;
+ v6_ifreq.ifr6_prefixlen = prefix_len;
+
+ ret = ioctl(fd, SIOCSIFADDR, &v6_ifreq);
+ if(ret == -1)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ioctl SIOCSIFADDR fail:%s", strerror(errno));
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_interface_ipv6_addr_get(const char *intf_name, int addr_type, char *addr, int *prefix_len)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ int status;
+ char *buf = NULL;
+ struct nlmsghdr *nlmp;
+ int nlmsgLen;
+ struct ifaddrmsg *rt_ifmsg;
+ struct rtattr *rta;
+ int rtattrlen;
+ struct in6_addr *in6p;
+ int ifidx;
+ int ip_scope, ip_type=0;
+ struct{
+ struct nlmsghdr n;
+ struct ifaddrmsg r;
+ }req;
+ if (!intf_name || !addr || !prefix_len)
+ {
+ return -1;
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "intf_name[%s], addr[%s], prefix[%d], addr_type[%u]", intf_name, addr, *prefix_len, addr_type);
+ status = get_ifindex(intf_name, &ifidx);
+ if (status)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "get_ifindex fail");
+ return -1;
+ }
+
+ buf = (char *)malloc(16384);
+ if (NULL == buf)
+ {
+ return -1;
+ }
+
+ memset(buf, 0, 16384);
+
+ int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+ req.n.nlmsg_type = RTM_GETADDR;
+ req.r.ifa_family = AF_INET6;
+
+
+ /* Time to send and recv the message from kernel */
+ status = send(fd, &req, req.n.nlmsg_len, 0);
+ if (status < 0) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "send fail:%s", strerror(errno));
+ close(fd);
+ if (buf)
+ {
+ free(buf);
+ buf = NULL;
+ }
+ return -1;
+ }
+
+
+
+ status = recv(fd, buf, 16384, 0);
+ if (status <= 0) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "send fail:%s", strerror(errno));
+ close(fd);
+ if (buf)
+ {
+ free(buf);
+ buf = NULL;
+ }
+ return -1;
+ }
+
+ /* Typically the message is stored in buf, so we need to parse the message to get the required data*/
+ for(nlmp = (struct nlmsghdr *)buf; status > sizeof(struct nlmsghdr);)
+ {
+ nlmsgLen = nlmp->nlmsg_len;
+ if (!NLMSG_OK(nlmp, status))
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "NLMSG not OK");
+ if (buf)
+ {
+ free(buf);
+ buf = NULL;
+ }
+ close(fd);
+ return 1;
+ }
+ rt_ifmsg = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
+ rta = (struct rtattr *)IFA_RTA(rt_ifmsg);
+ rtattrlen = IFA_PAYLOAD(nlmp);
+
+ status -= NLMSG_ALIGN(nlmsgLen);
+ nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(nlmsgLen));
+ /*Device not match, to next*/
+ if(ifidx != rt_ifmsg->ifa_index)
+ continue;
+
+ for (; RTA_OK(rta, rtattrlen); rta = RTA_NEXT(rta, rtattrlen))
+ {
+ if(rta->rta_type == IFA_CACHEINFO)
+ continue;
+ if(rta->rta_type == IFA_LOCAL||rta->rta_type == IFA_BROADCAST||rta->rta_type == IFA_ANYCAST)
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Find curious ipv6-address!\n");
+ if(rta->rta_type == IFA_ADDRESS)
+ {
+ in6p = (struct in6_addr *)RTA_DATA(rta);
+ inet_ntop(AF_INET6, in6p, addr, IPV6_PTRADDR_LEN);
+ /*Get type match address*/
+ ip_scope = _net_ip_scope_v6(addr);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip:ip_scope[%d]\n", ip_scope);
+ ip_type = _net_ip_type_v6(ip_scope, rt_ifmsg->ifa_flags);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip:ip_type[%d]\n", ip_type);
+ *prefix_len = rt_ifmsg->ifa_prefixlen;
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "ip: %s, prefix: %d, type: %d==\n", addr, *prefix_len, ip_type);
+ if(ip_type & addr_type)/*addr type is we need, and may have a fix of several. Just return the first valid*/
+ {
+ close(fd);
+ if (buf)
+ {
+ free(buf);
+ buf = NULL;
+ }
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "return success\n");
+ return 0;
+ }
+ }
+ }
+ }
+
+ close(fd);
+ if (buf)
+ {
+ free(buf);
+ buf = NULL;
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "return fail\n");
+ return -1;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+/*network related APIs*/
+int nm_network_create(unsigned net_id, const char *permission)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ /*
+ * network create <netId> [permission]
+ * permisstion: NETWORK / SYSTEM
+ */
+ if (permission)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network create %d %s", net_id, permission);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network create %d", net_id);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_destroy(unsigned net_id)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //network destroy <netId>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network destroy %d", net_id);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_default_set(unsigned net_id)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //network default set <netId>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network default set %d", net_id);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_default_clear()
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //network default clear
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network default clear");
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_interface_add(unsigned net_id, const char* intf_name)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //network interface add <netId> <interface>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network interface add %d %s", net_id, intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_interface_remove(unsigned net_id, const char* intf_name)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //network interface remove <netId> <interface>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network interface remove %d %s", net_id, intf_name);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_route_add(unsigned net_id, const char* intf_name,
+ const char *destination, const char *nexthop,
+ int legacy, unsigned int uid)
+{
+
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name || !destination)
+ {
+ return -1;
+ }
+
+ /* network route [legacy <uid>] add <netId> <interface> <dst> [nexthop] */
+ if (legacy && nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d add %d %s %s %s",
+ uid, net_id, intf_name, destination, nexthop);
+ }
+ else if (!legacy && nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route add %d %s %s %s",
+ net_id, intf_name, destination, nexthop);
+
+ }
+ else if (legacy && !nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d add %d %s %s",
+ uid, net_id, intf_name, destination);
+
+ }
+ else
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route add %d %s %s",
+ net_id, intf_name, destination);
+
+ }
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_network_route_remove( unsigned net_id, const char* intf_name,
+ const char *destination, const char *nexthop,
+ int legacy, unsigned int uid)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ if (!intf_name || !destination)
+ {
+ return -1;
+ }
+
+ /*network route [legacy <uid>] remove <netId> <interface> <dst> [nexthop]*/
+ if (legacy && nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d remove %d %s %s %s",
+ uid, net_id, intf_name, destination, nexthop);
+ }
+ else if (!legacy && nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route remove %d %s %s %s",
+ net_id, intf_name, destination, nexthop);
+
+ }
+ else if (legacy && !nexthop)
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route legacy %d remove %d %s %s",
+ uid, net_id, intf_name, destination);
+
+ }
+ else
+ {
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc network route remove %d %s %s",
+ net_id, intf_name, destination);
+
+ }
+
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+
+/*ipfwd related APIs*/
+int nm_fwd_ipv4_set(int enable, const char *requestor)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ // ipfwd <status | enable | disable> <requestor>
+
+ if (enable)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipfwd enable %s", requestor);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipfwd disable %s", requestor);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv4_get(int *enable)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ FILE *fp = NULL;
+ char fwd[11] = {0};
+ if (!enable)
+ {
+ return -1;
+ }
+
+ fp = fopen(IPV4_FORWARDING_PROC_FILE, "r");
+
+ if (NULL == fp) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Failed to open ipv6_forward (%s)", strerror(errno));
+ *enable = 0;
+ return -1;
+ }
+
+ fread(fwd, 1, 10, fp);
+
+ *enable = atoi(fwd);
+
+ fclose(fp);
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv6_set(int enable, const char *requestor)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ // ipv6fwd <status | enable | disable> <requestor>
+
+ if (enable)
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipv6fwd enable %s", requestor);
+ else
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc ipv6fwd disable %s", requestor);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_fwd_ipv6_get(int *enable)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ FILE *fp = NULL;
+ char fwd[11] = {0};
+ if (!enable)
+ {
+ return -1;
+ }
+
+ fp = fopen(IPV6_FORWARDING_PROC_FILE, "r");
+
+ if (NULL == fp) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "Failed to open ipv6_forward (%s)", strerror(errno));
+ *enable = 0;
+ return -1;
+ }
+
+ fread(fwd, 1, 10, fp);
+
+ *enable = atoi(fwd);
+
+ fclose(fp);
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+/*DNS related APIs*/
+int nm_resolver_ipv6_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len, total_len;
+ int index;
+ char *temp_ptr = cmd_buf;
+ char dns[200] = "/usr/bin/dns.script setv6";
+
+ if (!domains)
+ return -1;
+
+ if (numservers > MAX_DNS_NUMS)
+ {
+ numservers = MAX_DNS_NUMS;
+ }
+
+ //resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+ len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ total_len = len;
+
+ for (index=0; index<numservers; index++)
+ {
+ if (NM_NETWORK_TYPE_INTERNET == type)
+ snprintf(&(dns[strlen(dns)]), 200-strlen(servers[index]), " %s", servers[index]);
+
+ len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+ if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ total_len += len;
+
+ }
+
+ if (NM_NETWORK_TYPE_INTERNET == type)
+ {
+ if (system(dns) == -1)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "dns:%s:%s", dns, strerror(errno));
+ }
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_ipv4_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len, total_len;
+ int index;
+ char *temp_ptr = cmd_buf;
+ char dns[201] = "/usr/bin/dns.script set";
+
+ if (!domains)
+ return -1;
+
+ if (numservers > MAX_DNS_NUMS)
+ {
+ numservers = MAX_DNS_NUMS;
+ }
+
+ //resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+ len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ total_len = len;
+
+ for (index=0; index<numservers; index++)
+ {
+ if (NM_NETWORK_TYPE_INTERNET == type)
+ snprintf(&(dns[strlen(dns)]), 200-strlen(servers[index]), " %s", servers[index]);
+
+ len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+ if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+
+ total_len += len;
+
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+ if (NM_NETWORK_TYPE_INTERNET == type)
+ {
+ if (system(dns) == -1)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "dns:%s:%s", dns, strerror(errno));
+ }
+ }
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_dns_set(unsigned net_id, const char *domains, const char* const* servers, int numservers, NM_NETWORK_TYPE type)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len, total_len = 0;
+ int index;
+ char *temp_ptr = cmd_buf;
+
+ if (!domains)
+ return -1;
+ //resolver setnetdns <netId> <domains> <dns1> <dns2>
+
+ len = snprintf(temp_ptr, PAL_NM_CMD_BUF_SIZE, "ndc resolver setnetdns %d %s", net_id, domains);
+
+ total_len = len;
+
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ for (index=0; index<numservers; index++)
+ {
+ len = snprintf(temp_ptr+total_len, PAL_NM_CMD_BUF_SIZE-total_len, " %s", servers[index]);
+ if ((total_len+len) >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+
+ total_len += len;
+ }
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int nm_resolver_dns_clear(unsigned net_id)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+
+ //resolver clearnetdns <netId>
+
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc resolver clearnetdns %d", net_id);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_resolver_dns_cache_flush(unsigned net_id)
+{
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ //resolver flushnet <netId>
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "ndc resolver flushnet %d", net_id);
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "command:%s", cmd_buf);
+
+ return system(cmd_buf);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+
+int nm_command_test(char *intf)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char *dns_servier[] =
+ {"192.168.0.1",
+ "192.168.0.2",
+ "192.168.0.3",
+ "192.168.0.4",
+ "192.168.0.5",
+ " "};
+ char **dns_ptr = &(dns_servier[0]);
+ pal_nm_debug = 6;
+
+ /*interface command*/
+ nm_interface_ipv4_up(intf);
+ nm_interface_ipv4_down(intf);
+ nm_interface_ipv4_mtu_set(intf, 512);
+ nm_interface_ipv4_addr_clear(intf);
+ nm_interface_ipv6_mtu_set(intf, 512);
+ nm_interface_ipv6_set(intf, 1);
+ nm_interface_ipv6_set(intf, 0);
+ nm_interface_ipv6_privacyextenstion_enable_set(intf, 1);
+ nm_interface_ipv6_privacyextenstion_enable_set(intf, 0);
+ nm_interface_ipv6_ndoffload_enable_set(intf, 1);
+ nm_interface_ipv6_ndoffload_enable_set(intf, 0);
+
+ /*net_id network*/
+ nm_network_create(3, "enable");
+ nm_network_destroy(3);
+ nm_network_default_set(3);
+ nm_network_interface_add(3, intf);
+ nm_network_interface_remove(3, intf);
+ nm_network_route_add(3, intf, "192.168.0.11", NULL, 0, 1);
+ nm_network_route_add(3, intf, "192.168.0.11", "192.168.0.22", 0, 1);
+ nm_network_route_add(3, intf, "192.168.0.11", NULL, 1, 1);
+ nm_network_route_add(3, intf, "192.168.0.11", "192.168.0.22", 1, 1);
+ nm_network_route_remove(3, intf, "192.168.0.11", NULL, 0, 1);
+ nm_network_route_remove(3, intf, "192.168.0.11", "192.168.0.22", 0, 1);
+ nm_network_route_remove(3, intf, "192.168.0.11", NULL, 1, 1);
+ nm_network_route_remove(3, intf, "192.168.0.11", "192.168.0.22", 1, 1);
+
+ /*ipfwd*/
+ nm_fwd_ipv4_set(1, "abc");
+ nm_fwd_ipv4_set(0, "abc");
+ nm_fwd_ipv6_set(1, "abc");
+ nm_fwd_ipv6_set(0, "abc");
+
+ /*dns*/
+ nm_resolver_ipv4_dns_set(1, "my_domains", (const char* const*)dns_ptr, 5, NM_NETWORK_TYPE_INTERNET);
+ nm_resolver_dns_clear(1);
+
+
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+
+}
+int do_cmd(char *cmd_buf,char *ret_buf)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ int sock;
+ char buffer[1024];
+ int offset = 0;
+ char tmp[4];
+ int i = 0;
+ int code=0;
+ if ((sock = socket_local_client("netd",
+ ANDROID_SOCKET_NAMESPACE_RESERVED,
+ SOCK_STREAM)) < 0) {
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error connecting (%s)\n",strerror(errno));
+ return -1;
+ }
+ if (write(sock, cmd_buf, strlen(cmd_buf) + 1) < 0) {
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"write error\n");
+ return -1;
+ }
+
+ fd_set read_fds;
+ struct timeval to;
+ int rc = 0;
+
+ to.tv_sec = 10;
+ to.tv_usec = 0;
+
+ FD_ZERO(&read_fds);
+ FD_SET(sock, &read_fds);
+
+ if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error in select (%s)\n", strerror(errno));
+ return -1;
+ } else if (!rc) {
+
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"TIMEDOUT (%s)\n", strerror(errno));
+ return ETIMEDOUT;
+ } else if (FD_ISSET(sock, &read_fds)) {
+ memset(buffer, 0, 1024);
+ while ((rc = read(sock, buffer, 1024)) ) {
+ if (rc == 0)
+ {
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Lost connection to Netd - did it crash?\n");
+ return -1;
+ }
+ else if(rc<0)
+ {
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"Error reading data (%s)\n", strerror(errno));
+ return -1;
+ }
+ else
+ {
+ offset=0;
+ for (i = 0; i < rc; i++) {
+ if (buffer[i] == '\0') {
+ strncpy(tmp, buffer + offset, 3);
+ tmp[3] = '\0';
+ code = atoi(tmp);
+ offset = i + 1;
+ if (code >= 200 && code < 600)
+ {
+ strncpy(ret_buf, buffer + 4, offset);
+ close(sock);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"code (%d)\n", code);
+ return code;
+ }
+ }
+ }
+ }
+ }
+ }
+ close(sock);
+ return -1;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+int nm_interface_get_netid(const char *intf_name,unsigned int *netid)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char cmd_buf[PAL_NM_CMD_BUF_SIZE];
+ int len;
+ char ret_buf[1024];
+ len = snprintf(cmd_buf, PAL_NM_CMD_BUF_SIZE, "0 network interface get %s", intf_name);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"nm_interface_get start \n");
+ if (len >= PAL_NM_CMD_BUF_SIZE)
+ return -1;
+
+ if(do_cmd(cmd_buf,ret_buf)!=200)
+ {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"nm_interface_get return error \n");
+ return -1;
+ }
+
+ *netid=atoi(ret_buf);
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "*netid:%d", *netid);
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+void nm_network_policy_route_init()
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ FRATTR_PRIORITY.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ FRATTR_PRIORITY.rta_type = FRA_PRIORITY;
+
+ FRATTR_TABLE.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ FRATTR_TABLE.rta_type = FRA_TABLE;
+
+ FRATTR_FWMARK.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ FRATTR_FWMARK.rta_type = FRA_FWMARK;
+
+ FRATTR_FWMASK.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ FRATTR_FWMASK.rta_type = FRA_FWMASK;
+
+ FRATTR_UID_START.rta_len = RTA_LENGTH(sizeof(uid_t));
+ FRATTR_UID_START.rta_type = FRA_UID_START;
+
+ FRATTR_UID_END.rta_len = RTA_LENGTH(sizeof(uid_t));
+ FRATTR_UID_END.rta_type = FRA_UID_END;
+
+ RTATTR_TABLE.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ RTATTR_TABLE.rta_type = RTA_TABLE;
+
+ RTATTR_OIF.rta_len = RTA_LENGTH(sizeof(uint32_t));
+ RTATTR_OIF.rta_type = RTA_OIF;
+#endif //LYNQ_MAY_SUPPORT
+return NULL;//LYNQ_MAY_SUPPORT add
+}
+
+const struct sockaddr_nl NETLINK_ADDRESS = {AF_NETLINK, 0, 0, 0};
+
+int sendNetlinkRequest(uint16_t action, uint16_t flags, struct iovec* iov, int iovlen) {
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ struct nlmsghdr nlmsg = {
+ .nlmsg_type = action,
+ .nlmsg_flags = flags,
+ };
+ iov[0].iov_base = &nlmsg;
+ iov[0].iov_len = sizeof(nlmsg);
+ for (int i = 0; i < iovlen; ++i) {
+ nlmsg.nlmsg_len += iov[i].iov_len;
+ }
+
+ int ret;
+ struct {
+ struct nlmsghdr msg;
+ struct nlmsgerr err;
+ } response;
+
+ int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+ if (sock == -1) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "socket error");
+ ret=-1;
+ goto fail;
+ }
+
+ if (connect(sock, (struct sockaddr *)&NETLINK_ADDRESS, sizeof(NETLINK_ADDRESS)) == -1) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "connect error");
+ ret=-1;
+ goto fail;
+ }
+
+ if (writev(sock, iov, iovlen) == -1) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "writev error");
+ ret=-1;
+ goto fail;
+ }
+
+ if ((ret = recv(sock, &response, sizeof(response), 0)) == -1) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE, "recv error");
+ ret=-1;
+ goto fail;
+ }
+
+
+ if (ret == sizeof(response)) {
+ ret = response.err.error; // Netlink errors are negative errno.
+ if (ret) {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"netlink response contains error (%s)", strerror(-ret));
+ }
+ } else {
+ PAL_DEBUG_PRINT(PAL_DEBUG_TRACE,"bad netlink response message size (%d != %zu)", ret, sizeof(response));
+ ret = -999;
+ }
+fail:
+ if (sock != -1) {
+ close(sock);
+ }
+
+ return ret;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+int nm_network_ipv6_policy_route_modify(uint16_t action, uint32_t table, const char* interface)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ uint8_t rawAddress[sizeof(struct in6_addr)];
+ uint8_t rawNexthop[sizeof(struct in6_addr)];
+ int rawLength = sizeof(rawAddress);
+
+ if (!interface) return -1;
+
+ memset(rawAddress, 0, rawLength);
+
+ struct rtmsg route = {
+ .rtm_protocol = RTPROT_STATIC,
+ .rtm_type = RTN_UNICAST,
+ .rtm_family = AF_INET6,
+ .rtm_dst_len = 0,
+ .rtm_scope = RT_SCOPE_UNIVERSE,
+ .rtm_flags = 0,
+ };
+
+ struct rtattr rtaDst;;
+ struct rtattr rtaGateway;
+
+ rtaDst.rta_len = RTA_LENGTH(rawLength);
+ rtaDst.rta_type = RTA_DST;
+
+ rtaGateway.rta_len = RTA_LENGTH(rawLength);
+ rtaGateway.rta_type = RTA_GATEWAY;
+
+ uint32_t ifindex = if_nametoindex(interface);
+
+ struct iovec iov[] = {
+ { NULL, 0 },
+ { &route, sizeof(route) },
+ { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
+ { &table, sizeof(table) },
+#if 0
+ { &rtaDst, sizeof(rtaDst) },
+ { rawAddress, 16 },
+#else
+ { &rtaDst, 0 },
+ { rawAddress, 0 },
+#endif
+ { &RTATTR_OIF, sizeof(RTATTR_OIF)},
+ { &ifindex, sizeof(ifindex)},
+ { &rtaGateway, 0 },
+ { rawNexthop, 0},
+ };
+
+ uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+ return sendNetlinkRequest(action, flags, iov, 10);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv4_policy_route_modify(uint16_t action, uint32_t table, const char* interface)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ uint8_t rawAddress[sizeof(struct in_addr)];
+ uint8_t rawNexthop[sizeof(struct in_addr)];
+ int rawLength = sizeof(rawAddress);
+
+ if (!interface) return -1;
+
+ memset(rawAddress, 0, rawLength);
+
+ struct rtmsg route = {
+ .rtm_protocol = RTPROT_STATIC,
+ .rtm_type = RTN_UNICAST,
+ .rtm_family = AF_INET,
+ .rtm_dst_len = 0,
+ .rtm_scope = RT_SCOPE_UNIVERSE,
+ .rtm_flags = 0,
+ };
+
+ struct rtattr rtaDst;;
+ struct rtattr rtaGateway;
+
+ rtaDst.rta_len = RTA_LENGTH(rawLength);
+ rtaDst.rta_type = RTA_DST;
+
+ rtaGateway.rta_len = RTA_LENGTH(rawLength);
+ rtaGateway.rta_type = RTA_GATEWAY;
+
+ uint32_t ifindex = if_nametoindex(interface);
+
+ struct iovec iov[] = {
+ { NULL, 0 },
+ { &route, sizeof(route) },
+ { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
+ { &table, sizeof(table) },
+#if 0
+ { &rtaDst, sizeof(rtaDst) },
+ { rawAddress, 16 },
+#else
+ { &rtaDst, 0 },
+ { rawAddress, 0 },
+#endif
+ { &RTATTR_OIF, sizeof(RTATTR_OIF)},
+ { &ifindex, sizeof(ifindex)},
+ { &rtaGateway, 0 },
+ { rawNexthop, 0},
+ };
+
+ uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+ return sendNetlinkRequest(action, flags, iov, 10);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv6_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char iif_name[16], oif_name[16];
+ int iif_name_len, iif_name_padding;
+ int oif_name_len, oif_name_padding;
+ struct rtattr FRATTR_IIFNAME;
+ struct rtattr FRATTR_OIFNAME;
+ uid_t uidStart = 0, uidEnd = 0;
+
+ if (iif) {
+ snprintf(iif_name, sizeof(iif_name), "%s", iif);
+ iif_name_len = strlen(iif_name) + 1;
+ iif_name_padding = RTA_SPACE(iif_name_len) - RTA_LENGTH(iif_name_len);
+ } else {
+ iif_name_len = 0;
+ iif_name_padding = 0;
+ }
+ FRATTR_IIFNAME.rta_len = RTA_LENGTH(iif_name_len);
+ FRATTR_IIFNAME.rta_type = FRA_IIFNAME;
+
+ if (oif) {
+ snprintf(oif_name, sizeof(oif_name), "%s", oif);
+ oif_name_len = strlen(oif_name) + 1;
+ oif_name_padding = RTA_SPACE(oif_name_len) - RTA_LENGTH(oif_name_len);
+ } else {
+ oif_name_len = 0;
+ oif_name_padding = 0;
+ }
+ FRATTR_OIFNAME.rta_len = RTA_LENGTH(oif_name_len);
+ FRATTR_OIFNAME.rta_type = FRA_OIFNAME;
+
+ struct fib_rule_hdr rule = {
+ .action = FR_ACT_TO_TBL,
+ };
+
+ struct iovec iov[] = {
+ { NULL, 0 },
+ { &rule, sizeof(rule) },
+ { &FRATTR_PRIORITY, sizeof(FRATTR_PRIORITY) },
+ { &priority, sizeof(priority) },
+ { &FRATTR_TABLE, table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 },
+ { &table, table != RT_TABLE_UNSPEC ? sizeof(table) : 0 },
+ { &FRATTR_FWMARK, mask ? sizeof(FRATTR_FWMARK) : 0 },
+ { &fwmark, mask ? sizeof(fwmark) : 0 },
+ { &FRATTR_FWMASK, mask ? sizeof(FRATTR_FWMASK) : 0 },
+ { &mask, mask ? sizeof(mask) : 0 },
+ { &FRATTR_UID_START, 0 },
+ { &uidStart, 0 },
+ { &FRATTR_UID_END, 0 },
+ { &uidEnd, 0 },
+ { &FRATTR_IIFNAME, iif != NULL ? sizeof(FRATTR_IIFNAME) : 0 },
+ { iif_name, iif_name_len },
+ { PADDING_BUFFER, iif_name_padding },
+ { &FRATTR_OIFNAME, oif != NULL ? sizeof(FRATTR_OIFNAME) : 0 },
+ { oif_name, oif_name_len },
+ { PADDING_BUFFER, oif_name_padding },
+ };
+
+ uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+
+ rule.family = AF_INET6;
+ return sendNetlinkRequest(action, flags, iov, 20);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+int nm_network_ipv4_policy_rule_modify(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, const char* oif)
+{
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ char iif_name[16], oif_name[16];
+ int iif_name_len, iif_name_padding;
+ int oif_name_len, oif_name_padding;
+ struct rtattr FRATTR_IIFNAME;
+ struct rtattr FRATTR_OIFNAME;
+ uid_t uidStart = 0, uidEnd = 0;
+
+ if (iif) {
+ snprintf(iif_name, sizeof(iif_name), "%s", iif);
+ iif_name_len = strlen(iif_name) + 1;
+ iif_name_padding = RTA_SPACE(iif_name_len) - RTA_LENGTH(iif_name_len);
+ } else {
+ iif_name_len = 0;
+ iif_name_padding = 0;
+ }
+ FRATTR_IIFNAME.rta_len = RTA_LENGTH(iif_name_len);
+ FRATTR_IIFNAME.rta_type = FRA_IIFNAME;
+
+ if (oif) {
+ snprintf(oif_name, sizeof(oif_name), "%s", oif);
+ oif_name_len = strlen(oif_name) + 1;
+ oif_name_padding = RTA_SPACE(oif_name_len) - RTA_LENGTH(oif_name_len);
+ } else {
+ oif_name_len = 0;
+ oif_name_padding = 0;
+ }
+ FRATTR_OIFNAME.rta_len = RTA_LENGTH(oif_name_len);
+ FRATTR_OIFNAME.rta_type = FRA_OIFNAME;
+
+ struct fib_rule_hdr rule = {
+ .action = FR_ACT_TO_TBL,
+ };
+
+ struct iovec iov[] = {
+ { NULL, 0 },
+ { &rule, sizeof(rule) },
+ { &FRATTR_PRIORITY, sizeof(FRATTR_PRIORITY) },
+ { &priority, sizeof(priority) },
+ { &FRATTR_TABLE, table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 },
+ { &table, table != RT_TABLE_UNSPEC ? sizeof(table) : 0 },
+ { &FRATTR_FWMARK, mask ? sizeof(FRATTR_FWMARK) : 0 },
+ { &fwmark, mask ? sizeof(fwmark) : 0 },
+ { &FRATTR_FWMASK, mask ? sizeof(FRATTR_FWMASK) : 0 },
+ { &mask, mask ? sizeof(mask) : 0 },
+ { &FRATTR_UID_START, 0 },
+ { &uidStart, 0 },
+ { &FRATTR_UID_END, 0 },
+ { &uidEnd, 0 },
+ { &FRATTR_IIFNAME, iif != NULL ? sizeof(FRATTR_IIFNAME) : 0 },
+ { iif_name, iif_name_len },
+ { PADDING_BUFFER, iif_name_padding },
+ { &FRATTR_OIFNAME, oif != NULL ? sizeof(FRATTR_OIFNAME) : 0 },
+ { oif_name, oif_name_len },
+ { PADDING_BUFFER, oif_name_padding },
+ };
+
+ uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+
+ rule.family = AF_INET;
+ return sendNetlinkRequest(action, flags, iov, 20);
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+static const uint64_t UNKNOWN = -1;
+
+int parseIfaceStats(const char* iface, struct Stats* stats) {
+printf("this pal_nm api fun:%s,line:%s",__FUNCTION__,__LINE__);
+#ifdef LYNQ_MAY_SUPPORT
+ FILE *fp = fopen(QTAGUID_IFACE_STATS, "r");
+ if (fp == NULL) {
+ return -1;
+ }
+
+ char buffer[384];
+ char cur_iface[32];
+ bool foundTcp = false;
+ uint64_t rxBytes, rxPackets, txBytes, txPackets, tcpRxPackets, tcpTxPackets;
+
+ while (fgets(buffer, sizeof(buffer), fp) != NULL) {
+ int matched = sscanf(buffer, "%31s %" SCNu64 " %" SCNu64 " %" SCNu64
+ " %" SCNu64 " " "%*u %" SCNu64 " %*u %*u %*u %*u "
+ "%*u %" SCNu64 " %*u %*u %*u %*u", cur_iface, &rxBytes,
+ &rxPackets, &txBytes, &txPackets, &tcpRxPackets, &tcpTxPackets);
+ if (matched >= 5) {
+ if (matched == 7) {
+ foundTcp = true;
+ }
+ if (!iface || !strcmp(iface, cur_iface)) {
+ stats->rxBytes += rxBytes;
+ stats->rxPackets += rxPackets;
+ stats->txBytes += txBytes;
+ stats->txPackets += txPackets;
+ if (matched == 7) {
+ stats->tcpRxPackets += tcpRxPackets;
+ stats->tcpTxPackets += tcpTxPackets;
+ }
+ }
+ }
+ }
+
+ if (!foundTcp) {
+ stats->tcpRxPackets = UNKNOWN;
+ stats->tcpTxPackets = UNKNOWN;
+ }
+
+ if (fclose(fp) != 0) {
+ return -1;
+ }
+ return 0;
+#endif //LYNQ_MAY_SUPPORT
+return 0;//LYNQ_MAY_SUPPORT add
+}
+
+
+