Squashed 'LYNQ_PUBLIC/' content from commit 79d8f932f
git-subtree-dir: LYNQ_PUBLIC
git-subtree-split: 79d8f932fb4ebc4b5aec6c5ace97634912394272
Change-Id: If2527ba937f56fe989487bf71e996f7cfd9fbe61
diff --git a/IC_src/mtk/lib/liblynq-codec/LICENSE b/IC_src/mtk/lib/liblynq-codec/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/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/IC_src/mtk/lib/liblynq-codec/Makefile b/IC_src/mtk/lib/liblynq-codec/Makefile
new file mode 100644
index 0000000..b24b4e8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/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 ########## libvendor_ril BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+
+
+SUBDIRS += liblynq-codec
+
+
+
+
+
+$(warning ########## lynq-rilcmd 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/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h b/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h
new file mode 100755
index 0000000..2e3cf37
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/include/lynq_codec.h
@@ -0,0 +1,29 @@
+#ifndef __LYNQ_CODEC_H__
+#define __LYNQ_CODEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ LYNQ_CALL = 1,
+ LYNQ_RTP,
+ LYNQ_MEDIA,
+}media_src_t;
+
+typedef enum {
+ CODEC_CLOSE = 0,
+ CODEC_OPEN,
+}codec_op;
+
+void set_codec(media_src_t src, codec_op open_close);
+const char * get_customer_tone_path();
+int get_customer_tone_sample_rate();
+int customer_set_pa_volume(const int volume);
+int customer_get_pa_volume(int* volume);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__LYNQ_CODEC_H__
diff --git a/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c
new file mode 100755
index 0000000..9cd770d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/lynq_codec.c
@@ -0,0 +1,486 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "lynq_codec.h"
+#include <syslog.h>
+#include <log/log.h>
+
+#define LOG_TAG "CODEC_API"
+
+static void write_codec_reg(const char * val)
+{
+ if (val == NULL)
+ {
+ RLOGE("Invalid input\n");
+ return;
+ }
+
+ FILE* fp=fopen("/sys/kernel/debug/regmap/0-0018/registers", "w");
+ if (fp == NULL)
+ {
+ RLOGE("Failed to open file\n");
+ return;
+ }
+ fwrite(val, strlen(val), 1, fp);
+ fclose(fp);
+}
+
+void set_zk_3104_codec(int open)
+{
+ RLOGD("set_codec %d",open);
+
+ if(open==0)
+ {
+ system("echo out 201 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo out 113 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo out 29 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ /*dongyu@2023.7.12 ZK ADC/DAC power supply default off state, turn on during call, turn off after hang up start*/
+ write_codec_reg("0x13 0x00");
+ write_codec_reg("0x16 0x00");
+ write_codec_reg("0x25 0x00");
+ /*dongyu@2023.7.12 ZK ADC/DAC power supply default off state, turn on during call, turn off after hang up end*/
+ }
+ else
+ {
+ system("echo out 201 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ usleep(10);//just open need usleep 10us
+ system("echo out 113 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ usleep(10);//just open need usleep 10us
+ system("echo out 29 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ write_codec_reg("0x00 0x00");
+ write_codec_reg("0x01 0x00");
+ write_codec_reg("0x02 0x00");
+ write_codec_reg("0x03 0x80");
+ write_codec_reg("0x04 0x04");
+ write_codec_reg("0x05 0x00");
+ write_codec_reg("0x06 0x00");
+ write_codec_reg("0x07 0xa0");
+ write_codec_reg("0x08 0x20");
+ write_codec_reg("0x09 0x00");
+ write_codec_reg("0x0a 0x00");
+ write_codec_reg("0x0b 0x32");
+ write_codec_reg("0x0c 0x00");
+ write_codec_reg("0x0d 0x00");
+ write_codec_reg("0x0f 0x10");
+ write_codec_reg("0x10 0x20");
+ write_codec_reg("0x11 0xf8");
+ write_codec_reg("0x12 0xff");
+ /*dongyu@2023.7.12 ZK ADC/DAC 0x13 power supply default off state, turn on during call, turn off after hang up*/
+ write_codec_reg("0x13 0x7a");
+ write_codec_reg("0x14 0x78");
+ write_codec_reg("0x15 0x00");
+ /*dongyu@2023.7.12 ZK ADC/DAC 0x16 power supply default off state, turn on during call, turn off after hang up*/
+ write_codec_reg("0x16 0x78");
+ write_codec_reg("0x17 0x78");
+ write_codec_reg("0x18 0x78");
+ write_codec_reg("0x19 0x80");
+ write_codec_reg("0x1a 0x00");
+ write_codec_reg("0x1b 0xfe");
+ write_codec_reg("0x1c 0x00");
+ write_codec_reg("0x1d 0x00");
+ write_codec_reg("0x1e 0xfe");
+ write_codec_reg("0x1f 0x00");
+ write_codec_reg("0x20 0x18");
+ write_codec_reg("0x21 0x18");
+ write_codec_reg("0x22 0x00");
+ write_codec_reg("0x23 0x00");
+ write_codec_reg("0x24 0xc0");
+ /*dongyu@2023.7.12 ZK ADC/DAC 0x25 power supply default off state, turn on during call, turn off after hang up*/
+ write_codec_reg("0x25 0xc0");
+ write_codec_reg("0x26 0x00");
+ write_codec_reg("0x27 0x00");
+ write_codec_reg("0x28 0x00");
+ write_codec_reg("0x29 0x00");
+ write_codec_reg("0x2a 0x00");
+ write_codec_reg("0x2b 0x02");
+ write_codec_reg("0x2c 0x02");
+ write_codec_reg("0x2d 0x00");
+ write_codec_reg("0x2e 0x02");
+ write_codec_reg("0x2f 0x85");
+ write_codec_reg("0x30 0x00");
+ write_codec_reg("0x31 0x80");
+ write_codec_reg("0x32 0x85");
+ write_codec_reg("0x33 0x9f");
+ write_codec_reg("0x34 0x00");
+ write_codec_reg("0x35 0x80");
+ write_codec_reg("0x36 0x82");
+ write_codec_reg("0x37 0x00");
+ write_codec_reg("0x38 0x00");
+ write_codec_reg("0x39 0x82");
+ write_codec_reg("0x3a 0x9f");
+ write_codec_reg("0x3b 0x00");
+ write_codec_reg("0x3c 0x00");
+ write_codec_reg("0x3d 0x00");
+ write_codec_reg("0x3e 0x00");
+ write_codec_reg("0x3f 0x80");
+ write_codec_reg("0x40 0xaf");
+ write_codec_reg("0x41 0x0d");
+ write_codec_reg("0x42 0x00");
+ write_codec_reg("0x43 0x80");
+ write_codec_reg("0x44 0x00");
+ write_codec_reg("0x45 0x00");
+ write_codec_reg("0x46 0x02");
+ write_codec_reg("0x47 0xaf");
+ write_codec_reg("0x48 0x0d");
+ write_codec_reg("0x49 0x00");
+ write_codec_reg("0x4a 0x00");
+ write_codec_reg("0x4b 0x00");
+ write_codec_reg("0x4c 0x00");
+ write_codec_reg("0x4d 0x00");
+ write_codec_reg("0x4e 0x00");
+ write_codec_reg("0x4f 0x00");
+ write_codec_reg("0x50 0x00");
+ write_codec_reg("0x51 0x00");
+ write_codec_reg("0x52 0x00");
+ write_codec_reg("0x53 0x00");
+ write_codec_reg("0x54 0x02");
+ write_codec_reg("0x55 0xbf");
+ write_codec_reg("0x56 0x9b");
+ write_codec_reg("0x57 0x00");
+ write_codec_reg("0x58 0x02");
+ write_codec_reg("0x59 0xbf");
+ write_codec_reg("0x5a 0x00");
+ write_codec_reg("0x5b 0x00");
+ write_codec_reg("0x5c 0xbf");
+ write_codec_reg("0x5d 0x08");
+ write_codec_reg("0x5e 0xde");
+ write_codec_reg("0x5f 0x0c");
+ write_codec_reg("0x60 0x00");
+ write_codec_reg("0x61 0x00");
+ write_codec_reg("0x62 0x00");
+ write_codec_reg("0x63 0x00");
+ write_codec_reg("0x64 0x00");
+ write_codec_reg("0x65 0x01");
+ write_codec_reg("0x66 0xa2");
+ write_codec_reg("0x67 0x00");
+ write_codec_reg("0x68 0x00");
+ write_codec_reg("0x69 0x00");
+ write_codec_reg("0x6a 0x00");
+ write_codec_reg("0x6b 0x00");
+ write_codec_reg("0x6c 0x40");
+ write_codec_reg("0x6d 0x00");
+ }
+}
+
+/*hqing add for Geely demand on 11/07/2022, after playing audio, codec should sleep*/
+static void set_gsw_3104_codec(codec_op open)
+{
+ if(open==0)
+ {
+ system("echo out 201 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo out 181 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ }
+ else
+ {
+ system("echo out 181 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+ usleep(10);//just open need usleep 10us
+
+ write_codec_reg("0x00 0x00");
+ write_codec_reg("0x01 0x00");
+ write_codec_reg("0x02 0x00");
+ write_codec_reg("0x03 0x80");
+ write_codec_reg("0x04 0x04");
+ write_codec_reg("0x05 0x00");
+ write_codec_reg("0x06 0x00");
+ write_codec_reg("0x07 0xa0");
+ write_codec_reg("0x08 0x20");
+ write_codec_reg("0x09 0x00");
+ write_codec_reg("0x0a 0x00");
+ write_codec_reg("0x0b 0x32");
+ write_codec_reg("0x0c 0x00");
+ write_codec_reg("0x0d 0x00");
+ write_codec_reg("0x0f 0x10");
+ write_codec_reg("0x10 0x20");
+ write_codec_reg("0x11 0xf8");
+ write_codec_reg("0x12 0xff");
+ write_codec_reg("0x13 0x04");
+ write_codec_reg("0x14 0x78");
+ write_codec_reg("0x15 0x78");
+ write_codec_reg("0x16 0x04");
+ write_codec_reg("0x17 0x78");
+ write_codec_reg("0x18 0x78");
+ write_codec_reg("0x19 0x80");
+ write_codec_reg("0x1a 0x00");
+ write_codec_reg("0x1b 0xfe");
+ write_codec_reg("0x1c 0x00");
+ write_codec_reg("0x1d 0x00");
+ write_codec_reg("0x1e 0xfe");
+ write_codec_reg("0x1f 0x00");
+ write_codec_reg("0x20 0x18");
+ write_codec_reg("0x21 0x18");
+ write_codec_reg("0x22 0x00");
+ write_codec_reg("0x23 0x00");
+ write_codec_reg("0x24 0xc0");
+ write_codec_reg("0x25 0xc0");
+ write_codec_reg("0x26 0x00");
+ write_codec_reg("0x27 0x00");
+ write_codec_reg("0x28 0x00");
+ write_codec_reg("0x29 0x00");
+ write_codec_reg("0x2a 0x00");
+ write_codec_reg("0x2b 0x02");
+ write_codec_reg("0x2c 0x02");
+ write_codec_reg("0x2d 0x00");
+ write_codec_reg("0x2e 0x02");
+ write_codec_reg("0x2f 0x85");
+ write_codec_reg("0x30 0x00");
+ write_codec_reg("0x31 0x80");
+ write_codec_reg("0x32 0x85");
+ write_codec_reg("0x33 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default
+ write_codec_reg("0x34 0x00");
+ write_codec_reg("0x35 0x80");
+ write_codec_reg("0x36 0x82");
+ write_codec_reg("0x37 0x00");
+ write_codec_reg("0x38 0x00");
+ write_codec_reg("0x39 0x82");
+ write_codec_reg("0x3a 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default
+ write_codec_reg("0x3b 0x00");
+ write_codec_reg("0x3c 0x00");
+ write_codec_reg("0x3d 0x00");
+ write_codec_reg("0x3e 0x00");
+ write_codec_reg("0x3f 0x80");
+ write_codec_reg("0x40 0xaf");
+ write_codec_reg("0x41 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default
+ write_codec_reg("0x42 0x00");
+ write_codec_reg("0x43 0x80");
+ write_codec_reg("0x44 0x00");
+ write_codec_reg("0x45 0x00");
+ write_codec_reg("0x46 0x02");
+ write_codec_reg("0x47 0xaf");
+ write_codec_reg("0x48 0x00"); //dongyu@2023.9.18 Disables CODEC lineout output by default
+ write_codec_reg("0x49 0x00");
+ write_codec_reg("0x4a 0x00");
+ write_codec_reg("0x4b 0x00");
+ write_codec_reg("0x4c 0x00");
+ write_codec_reg("0x4d 0x00");
+ write_codec_reg("0x4e 0x00");
+ write_codec_reg("0x4f 0x00");
+ write_codec_reg("0x50 0x00");
+ write_codec_reg("0x51 0x02");
+ write_codec_reg("0x52 0xbf");
+ write_codec_reg("0x53 0x00");
+ write_codec_reg("0x54 0x00");
+ write_codec_reg("0x55 0x00");
+ write_codec_reg("0x56 0x9b");
+ write_codec_reg("0x57 0x00");
+ write_codec_reg("0x58 0x00");
+ write_codec_reg("0x59 0x00");
+ write_codec_reg("0x5a 0x00");
+ write_codec_reg("0x5b 0x02");
+ write_codec_reg("0x5c 0xbf");
+ write_codec_reg("0x5d 0x08");
+ write_codec_reg("0x5e 0xde");
+ write_codec_reg("0x5f 0x0c");
+ write_codec_reg("0x60 0x00");
+ write_codec_reg("0x61 0x00");
+ write_codec_reg("0x62 0x00");
+ write_codec_reg("0x63 0x00");
+ write_codec_reg("0x64 0x00");
+ write_codec_reg("0x65 0x01");
+ write_codec_reg("0x66 0xa2");
+ write_codec_reg("0x67 0x00");
+ write_codec_reg("0x68 0x00");
+ write_codec_reg("0x69 0x00");
+ write_codec_reg("0x6a 0x00");
+ write_codec_reg("0x6b 0x00");
+ write_codec_reg("0x6c 0x40");
+ write_codec_reg("0x6d 0x00");
+ }
+}
+
+
+#ifdef ZK_CODEC_CFG
+
+/*dongyu@2023.5.31 Add ZK set codec tlv320aic3x API register start*/
+
+void set_codec(media_src_t src, codec_op open_close)
+{
+ RLOGD("set_zk_3104_codec src=[%d] op=[%d]", src, open);
+ set_zk_3104_codec(open_close);
+}
+
+const char * get_customer_tone_path()
+{
+ return "/tmp/tone.wav";
+}
+
+int get_customer_tone_sample_rate()
+{
+ return 44100;
+}
+
+int customer_set_pa_volume(const int volume)
+{
+ int file;
+ char *filename = "/dev/i2c-0";
+ int addr = 0x6c;
+ char buf[2];
+
+ if (volume < 1 || volume > 4)
+ {
+ RLOGE("Invalid volume specified\n");
+ return -1;
+ }
+
+ if ((file = open(filename, O_RDWR)) < 0)
+ {
+ RLOGE("Failed to open i2c bus\n");
+ return -1;
+ }
+
+ if (ioctl(file, I2C_SLAVE, addr) < 0)
+ {
+ RLOGE("Failed to acquire bus access and/or talk to slave\n");
+ close(file);
+ return -1;
+ }
+
+ switch (volume) {
+ case 1:
+ buf[0] = 0x03;
+ buf[1] = 0x00; //Gain set to 20 dB
+ break;
+ case 2:
+ buf[0] = 0x03;
+ buf[1] = 0x78; //Gain set to 26 dB
+ break;
+ case 3:
+ buf[0] = 0x03;
+ buf[1] = 0x80; //Gain set to 32 dB
+ break;
+ case 4:
+ buf[0] = 0x03;
+ buf[1] = 0xc0; //Gain set to 36 dB
+ break;
+ }
+
+ if (write(file, buf, 2) != 2)
+ {
+ RLOGE("Failed to write to the i2c bus\n");
+ close(file);
+ return -1;
+ }
+
+ RLOGE("Set the 0x%02x register value to 0x%02x\n", buf[0], buf[1]);
+
+ close(file);
+
+ return 0;
+}
+
+int customer_get_pa_volume(int* volume)
+{
+ int file;
+ char *filename = "/dev/i2c-0";
+ int addr = 0x6c;
+ char buf[2];
+
+ if (volume < 1 || volume > 4)
+ {
+ RLOGE("Invalid volume specified\n");
+ return -1;
+ }
+
+ if ((file = open(filename, O_RDWR)) < 0)
+ {
+ RLOGE("Failed to open i2c bus\n");
+ return -1;
+ }
+
+ if (ioctl(file, I2C_SLAVE, addr) < 0)
+ {
+ RLOGE("Failed to acquire bus access and/or talk to slave\n");
+ close(file);
+ return -1;
+ }
+
+ switch (volume) {
+ case 1:
+ buf[0] = 0x03;
+ buf[1] = 0x00; //Gain set to 20 dB
+ break;
+ case 2:
+ buf[0] = 0x03;
+ buf[1] = 0x78; //Gain set to 26 dB
+ break;
+ case 3:
+ buf[0] = 0x03;
+ buf[1] = 0x80; //Gain set to 32 dB
+ break;
+ case 4:
+ buf[0] = 0x03;
+ buf[1] = 0xc0; //Gain set to 36 dB
+ break;
+ }
+
+ if (write(file, buf, 2) != 2)
+ {
+ RLOGE("Failed to write to the i2c bus\n");
+ close(file);
+ return -1;
+ }
+
+ RLOGE("Set the 0x%02x register value to 0x%02x\n", buf[0], buf[1]);
+
+ close(file);
+
+ return 0;
+}
+
+#elif defined(GSW_CODEC_CFG)
+
+void set_codec(media_src_t src, codec_op open_close)
+{
+ RLOGD("set_gsw_3104_codec src=[%d] op=[%d]", src, open);
+ set_gsw_3104_codec(open_close);
+}
+
+const char * get_customer_tone_path()
+{
+ return "/tmp/tone.wav";
+}
+
+int get_customer_tone_sample_rate()
+{
+ return 44100;
+}
+
+int customer_set_pa_volume(const int volume)
+{
+ RLOGE("not implement\n");
+ return -1;
+}
+
+int customer_get_pa_volume(int* volume)
+{
+ RLOGE("not implement\n");
+ return -1;
+}
+
+#else
+const char * get_customer_tone_path()
+{
+ return "/tmp/tone.wav";
+}
+
+int get_customer_tone_sample_rate()
+{
+ return 44100;
+}
+
+int customer_set_pa_volume(const int volume)
+{
+ RLOGE("not implement\n");
+ return -1;
+}
+
+int customer_get_pa_volume(int* volume)
+{
+ RLOGE("not implement\n");
+ return -1;
+}
+
+void set_codec(media_src_t src, codec_op open_close)
+{
+ RLOGE("not implement\n");
+}
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile
new file mode 100755
index 0000000..b0fe68a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-codec/liblynq-codec/makefile
@@ -0,0 +1,78 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -DKEEP_ALIVE \
+ -DECALL_SUPPORT \
+
+
+ifeq ($(strip $(MOBILETEK_CODEC_CFG)), GSW)
+ LOCAL_CFLAGS += -DGSW_CODEC_CFG
+
+endif
+
+ifeq ($(strip $(MOBILETEK_CODEC_CFG)), ZK)
+ LOCAL_CFLAGS += -DZK_CODEC_CFG
+endif
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(LOCAL_PATH)/../include \
+ -I$(ROOT)$(includedir)/glib-2.0 \
+ -I$(ROOT)$(libdir)/glib-2.0/include \
+ -I$(ROOT)$(includedir)/gstreamer-1.0 \
+ -I$(ROOT)$(libdir)/gstreamer-1.0/include\
+
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lstdc++ \
+ -llog \
+
+
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-codec.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/IC_src/mtk/lib/liblynq-driver/LICENSE b/IC_src/mtk/lib/liblynq-driver/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/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/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2 b/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/MODULE_LICENSE_APACHE2
diff --git a/IC_src/mtk/lib/liblynq-driver/Makefile b/IC_src/mtk/lib/liblynq-driver/Makefile
new file mode 100644
index 0000000..b74de2c
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/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 ########## libvendor_ril BB_TELEFWK_OPTION $(BB_TELEFWK_OPTION) ##########)
+
+
+
+SUBDIRS += liblynq-driver
+
+
+
+
+
+$(warning ########## lynq-rilcmd 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/IC_src/mtk/lib/liblynq-driver/NOTICE b/IC_src/mtk/lib/liblynq-driver/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/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/IC_src/mtk/lib/liblynq-driver/README b/IC_src/mtk/lib/liblynq-driver/README
new file mode 100644
index 0000000..9a7e82f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/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/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h b/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h
new file mode 100755
index 0000000..348385d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/include/liblynq-driver/libdriver.h
@@ -0,0 +1,17 @@
+#ifndef __LYNQ_DRIVER_CONTROL_H__
+#define __LYNQ_DRIVER_CONTROL_H__
+typedef int BOOL;
+typedef void (*triggerCallback)(const char*, int);
+void disconnect_key();
+void register_key_info();
+int trigger_loop();
+//BOOL ServiceIsReady(void);
+void registerTriggerCallback(triggerCallback callback);
+int lynq_set_gpio (char * mode,int gpio_numb,int param);
+void lynq_get_gpio (int gpio_numb,char *response);
+
+int lynq_i2c_write(char *dev_node, int addr, char reg, char data);
+int lynq_i2c_read(char *dev_node, int addr, char reg, char *read_value);
+int lynq_setGpio_values(const char *state, int gpio_numb, int param);
+int lynq_getGpio_values(int gpio_numb, char* mode, char* dir, char* dout, char* drive);
+#endif //__LOG_H__
diff --git a/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c
new file mode 100755
index 0000000..837e841
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/driver_control.c
@@ -0,0 +1,466 @@
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gio/gio.h>
+#include <log/log.h>
+#include <glib.h>
+/*dongyu@2023.7.11 Add I2C read/write interface start*/
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/i2c-dev.h>
+/*dongyu@2023.7.11 Add I2C read/write interface end*/
+#include "libdriver.h"
+#define GPIO_SERVICE "gpio.lynq" /*well-known bus name */
+#define GPIO_DATA_INTERFACE "gpio.lynq.Data" /*interface name*/
+#define GPIO_DATA_PATH "/gpio/lynq/data" /*object name*/
+#define LOG_TAG "GPIO_CONTROL"
+static GMainLoop *loop = NULL;
+static GDBusProxy *pProxy = NULL;
+triggerCallback mtriggerCallback = NULL;;
+
+void proxy_signals_on_signal (GDBusProxy *proxy,
+ const gchar *sender_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ gint32 status;
+ RLOGD("signal_name: %s\n", signal_name);
+ g_variant_get (parameters,"(i)",&status);
+ //RLOGD("listen singal ok,%d",status);
+ if(mtriggerCallback){
+ mtriggerCallback(signal_name,status);
+ }
+ else
+ {
+ RLOGE("mbroadcastcallback NULL");
+ }
+ printf("trigger status is %d\n",status);
+}
+
+BOOL registerClientSignalHandler(GDBusProxy *proxy)
+{
+ gulong signal_handler_id;
+ signal_handler_id = g_signal_connect(proxy, "g-signal",
+ G_CALLBACK (proxy_signals_on_signal), NULL);
+ RLOGD("proxy is ready");
+ if (signal_handler_id == 0) {
+ RLOGD("listen singal fail!");
+ return FALSE;
+ }
+ return TRUE;
+}
+void registerTriggerCallback(triggerCallback callback)
+{
+ if (NULL != callback){
+ //memcpy(&mbroadcastcallback, callback, sizeof(broadcastCallback));
+ mtriggerCallback = callback;
+ }
+ else{
+ RLOGD("registerSignalCallback: parameter point is NULL");
+ }
+}
+void *run(void* arg)
+{
+
+ /** start the main event loop which manages all available sources of events */
+ g_main_loop_run(loop);
+ return ((void*)0);
+}
+
+void disconnect_key(void)
+{
+ if(pProxy != NULL) {
+ g_object_unref (pProxy);
+ }
+ if(loop != NULL) {
+ g_main_loop_unref(loop);
+ }
+}
+int thread_create(void)
+{
+ int err;
+ pthread_t thr;
+
+ err = pthread_create(&thr, NULL, run, NULL);
+ if(0 != err){
+ RLOGD("Can't create thread: %s\n", strerror(err));
+ }
+ else{
+ RLOGD("New thread created: %s\n", strerror(err));
+ }
+
+ return err;
+}
+int trigger_loop()
+{
+ g_main_loop_run(loop);
+}
+
+BOOL service_ready(void)
+{
+ gchar *owner_name = NULL;
+ owner_name = g_dbus_proxy_get_name_owner((GDBusProxy*)pProxy);
+ if(NULL != owner_name)
+ {
+ RLOGD("Owner Name: %s\n", owner_name);
+ g_free(owner_name);
+ return TRUE;
+ }
+ else
+ {
+ g_print("Owner Name is NULL.");
+ return FALSE;
+ }
+}
+
+void register_key_info(void){
+ GError *error = NULL;
+ RLOGD("go!\n");
+ loop = g_main_loop_new(NULL, FALSE);
+
+ pProxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo */
+ GPIO_SERVICE,
+ GPIO_DATA_PATH,
+ GPIO_DATA_INTERFACE,
+ NULL, /* GCancellable */
+ &error);
+ if (pProxy == NULL)
+ {
+ RLOGD ("Error creating proxy: %s\n", error->message);
+ disconnect_key();
+ }
+ if (registerClientSignalHandler(pProxy)== FALSE){
+ RLOGD ("register Error");
+ disconnect_key();
+ }
+ while(service_ready() != TRUE);
+ thread_create();
+}
+
+int lynq_set_gpio (char * mode,int gpio_numb,int param)
+{
+ GDBusConnection *c1;
+ GVariant *result;
+ GError *error;
+ GMainLoop *loop;
+ gint32 set_result = -1;
+ g_type_init();
+ loop = g_main_loop_new(NULL, FALSE); /** create main loop, but do not start it.*/
+ error = NULL;
+ c1 = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ g_assert_no_error (error);
+ error = NULL;
+ g_assert (c1 != NULL);
+ g_assert (!g_dbus_connection_is_closed (c1));
+ result = g_dbus_connection_call_sync (c1,
+ GPIO_SERVICE, /* bus name */
+ GPIO_DATA_PATH, /* object path */
+ GPIO_DATA_INTERFACE, /* interface name */
+ "setGpio", /* method name */
+ g_variant_new ("(sii)", mode,gpio_numb,param), /* parameters */
+ G_VARIANT_TYPE ("(i)"), /* return type */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (result != NULL);
+ g_variant_get(result, "(i)", &(set_result));
+ // RLOGD("%s, %s, %d,result:%d", __FILE__, __FUNCTION__, __LINE__,set_result);
+ g_variant_unref (result);
+ //g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+ return set_result;
+}
+/*
+int set_gpio143(){
+ int result;
+ result = set_gpio (GPIO_MODE,WIFI_LED_CONTROL,1);
+ return result;
+ // sprintf(output, "gpio set stauts %d\n",result);
+ // printf("%s",output);
+ // emResultNotify(output);
+}*/
+void lynq_get_gpio (int gpio_numb,char *response)
+{
+ GDBusConnection *c1;
+ GError *error;
+ GMainLoop *loop;
+ //char output[2048] = {0};
+ //gchar *response;
+ GVariant *get;
+ gsize n_elts=0;
+ GVariantIter *iter;
+ //guchar *response;
+ gchar *get_res;
+// const char *p;
+ g_type_init();
+ loop = g_main_loop_new(NULL, FALSE); /** create main loop, but do not start it.*/
+ error = NULL;
+ c1 = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ g_assert_no_error (error);
+ error = NULL;
+ g_assert (c1 != NULL);
+ g_assert (!g_dbus_connection_is_closed (c1));
+ error = NULL;
+ get = g_dbus_connection_call_sync (c1,
+ GPIO_SERVICE,
+ GPIO_DATA_PATH,
+ GPIO_DATA_INTERFACE,
+ "getGpio",
+ g_variant_new ("(i)",gpio_numb),
+ G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (get != NULL);
+ g_variant_get (get, "(s)",&get_res);
+ strcpy(response, get_res);
+ g_variant_unref (get);
+ RLOGD("get_gpio,%s",response);
+ g_main_loop_unref (loop);
+}
+/*
+void get_gpio143(){
+ char output[1024] = {0};
+ char output1[2048] = {0};
+ get_gpio (WIFI_LED_CONTROL,output);
+ printf("get_gpio143,%s\n",output);
+
+}
+*/
+
+/*dongyu@2023.7.12 Add I2C read/write interface start*/
+/*****************************************************************************************************
+@file driver_control.c
+@brief The lynq_i2c_read function is used to read data from an I2C device. It accepts four parameters:
+ - dev_node¡êoPath to the I2C device node
+ - addr¡êoI2C device address
+ - reg¡êoRegister address to be read
+ - read_value¡êoRegister address data read
+ - return: If successful, return 0; if unsuccessful, return -1
+@author dongyu
+@date 2023-7-12
+@version V1.0
+@copyright MobileTek
+*****************************************************************************************************/
+int lynq_i2c_read(char *dev_node, int addr, char reg, char *read_value)
+{
+ int file;
+ char buf[1];
+
+ if (dev_node == NULL)
+ {
+ RLOGD("lynq_i2c_read Invalid dev_node\n");
+ return -1;
+ }
+
+ if ((file = open(dev_node, O_RDWR)) < 0)
+ {
+ RLOGD("Failed to open i2c bus\n");
+ return -1;
+ }
+
+ if (ioctl(file, I2C_SLAVE, addr) < 0)
+ {
+ RLOGD("Failed to acquire bus access and/or talk to slave\n");
+ close(file);
+ return -1;
+ }
+
+ buf[0] = reg;
+ if (write(file, buf, 1) != 1)
+ {
+ RLOGD("Failed to write to the i2c bus\n");
+ close(file);
+ return -1;
+ }
+
+ if (read(file, read_value, 1) != 1)
+ {
+ RLOGD("Failed to read from the i2c bus\n");
+ close(file);
+ return -1;
+ }
+
+ RLOGD("Read value: %02x\n", *read_value);
+
+ close(file);
+
+ return 0;
+}
+
+/*****************************************************************************************************
+@file driver_control.c
+@brief The lynq_i2c_write function is used to write data to an I2C device. It accepts four parameters:
+ - dev_node¡êoPath to the I2C device node
+ - addr¡êoI2C device address
+ - reg¡êoRegister address to be written
+ - data¡êoData to be written
+ - return: If successful, return 0; if unsuccessful, return -1
+@author dongyu
+@date 2023-7-12
+@version V1.0
+@copyright MobileTek
+*****************************************************************************************************/
+int lynq_i2c_write(char *dev_node, int addr, char reg, char data)
+{
+ int file;
+ char buf[2];
+
+ if (dev_node == NULL)
+ {
+ RLOGD("lynq_i2c_write Invalid dev_node\n");
+ return -1;
+ }
+
+ if ((file = open(dev_node, O_RDWR)) < 0)
+ {
+ RLOGD("Failed to open i2c bus\n");
+ return -1;
+ }
+
+ if (ioctl(file, I2C_SLAVE, addr) < 0)
+ {
+ RLOGD("Failed to acquire bus access and/or talk to slave\n");
+ close(file);
+ return -1;
+ }
+
+ buf[0] = reg;
+ buf[1] = data;
+ if (write(file, buf, 2) != 2)
+ {
+ RLOGD("Failed to write to the i2c bus\n");
+ close(file);
+ return -1;
+ }
+
+ RLOGD("Write value: %02x\n", data);
+
+ close(file);
+
+ return 0;
+}
+/*dongyu@2023.7.12 Add I2C read/write interface end*/
+
+/*dongyu@2023.7.11 Configurable General Purpose Interface for GPIO Packages start*/
+int lynq_getGpio_values(int gpio_numb, char* mode, char* dir, char* dout, char* drive)
+{
+ char command[100];
+ char response[100] = {0};
+
+ if (mode == NULL || dir == NULL || dout == NULL || drive == NULL)
+ {
+ RLOGD("lynq_getGpio_values pointers are NULL, returning -1\n");
+ return -1;
+ }
+
+ if (gpio_numb >= 0 && gpio_numb <= 180)
+ {
+ sprintf(command, "echo start 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ if(system(command) != 0)
+ {
+ RLOGD("0~180 Range command execution failure!\n");
+ return -1;
+ }
+ }
+ else if (gpio_numb > 180 && gpio_numb <= 234)
+ {
+ sprintf(command, "echo start 180 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ if(system(command) != 0)
+ {
+ RLOGD("180~234 Range command execution failure!\n");
+ return -1;
+ }
+ }
+ else
+ {
+ RLOGD("The gpio_numb parameter takes values in the range 0 ~ 234!\n");
+ return -1;
+ }
+
+ sprintf(command, "cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep -E \"^%03d\"", gpio_numb);
+ FILE* fp = popen(command, "r");
+ if (fp == NULL)
+ {
+ RLOGD("Failed to open pipe!\n");
+ return -1;
+ }
+ fgets(response, 100, fp);
+ pclose(fp);
+
+ if (strlen(response) < 10)
+ {
+ RLOGD("Response is either empty or shorter than expected!\n");
+ return -1;
+ }
+ *mode = response[4];
+ *dir = response[5];
+ *dout = response[6];
+ *drive = response[9];
+
+ return 0;
+}
+
+static int lynq_setGpio_execution(const char *state, int gpio_numb, int param)
+{
+ char command[100];
+ sprintf(command, "echo %s %d %d >/sys/devices/platform/10005000.pinctrl/mt_gpio", state, gpio_numb, param);
+ int result = system(command);
+ if (result != 0)
+ {
+ RLOGD("Failed to execute command: %s\n", command);
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_setGpio_values(const char *state, int gpio_numb, int param)
+{
+ int result;
+ char mode, dir, dout, drive;
+ if (state == NULL)
+ {
+ RLOGD("lynq_setGpio_values pointers are NULL, returning -1\n");
+ return -1;
+ }
+
+ lynq_getGpio_values(gpio_numb, &mode, &dir, &dout, &drive);
+
+ if ((strcmp(state, "mode") == 0 || strcmp(state, "driving") == 0) && \
+ (gpio_numb >= 0 && gpio_numb <= 234) && (param >= 0 && param <= 7))
+ {
+ result = lynq_setGpio_execution(state, gpio_numb, param);
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ else if ((strcmp(state, "dir") == 0 || strcmp(state, "out") == 0) && \
+ (gpio_numb >= 0 && gpio_numb <= 234) && (param >= 0 && param <= 1) && mode == '0')
+ {
+ result = lynq_setGpio_execution(state, gpio_numb, param);
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ else
+ {
+ RLOGD("The parameter you entered is invalid!\n");
+ return -1;
+ }
+
+ return 0;
+}
+/*dongyu@2023.7.11 Configurable General Purpose Interface for GPIO Packages end*/
diff --git a/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile
new file mode 100644
index 0000000..6439920
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-driver/liblynq-driver/makefile
@@ -0,0 +1,109 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -DKEEP_ALIVE \
+ -DECALL_SUPPORT \
+
+$(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/liblynq-driver \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/gstreamer-1.0 \
+ -I$(ROOT)$(includedir)/glib-2.0 \
+ -I$(ROOT)$(libdir)/glib-2.0/include \
+ -I$(ROOT)$(libdir)/gstreamer-1.0/include\
+ -I$(ROOT)$(includedir)/dbus-1.0 \
+ -I$(ROOT)$(libdir)/dbus-1.0/include \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lstdc++ \
+ -llog \
+ -lcutils \
+ -lutils \
+ -lpower \
+ -lbinder \
+ -lpthread \
+ -lpal \
+ -lgstreamer-1.0 \
+ -lglib-2.0 \
+ -lgstbase-1.0 \
+ -lgstreamer-1.0 \
+ -lgobject-2.0 \
+ -lgio-2.0 \
+ -ldtmf \
+ -ldbus-1 \
+
+SOURCES = $(wildcard *.c wildcard *.h)
+
+EXECUTABLE = liblynq-driver.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/IC_src/mtk/lib/liblynq-fota/MD5/md5.c b/IC_src/mtk/lib/liblynq-fota/MD5/md5.c
new file mode 100755
index 0000000..5dd9ff3
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5.c
@@ -0,0 +1,161 @@
+#include "string.h"
+#include "md5.h"
+
+unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+void MD5Init(MD5_CTX *context)
+{
+ context->count[0] = 0;
+ context->count[1] = 0;
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+}
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
+{
+ unsigned int i = 0,index = 0,partlen = 0;
+ index = (context->count[0] >> 3) & 0x3F;
+ partlen = 64 - index;
+ context->count[0] += inputlen << 3;
+ if(context->count[0] < (inputlen << 3))
+ context->count[1]++;
+ context->count[1] += inputlen >> 29;
+
+ if(inputlen >= partlen)
+ {
+ memcpy(&context->buffer[index],input,partlen);
+ MD5Transform(context->state,context->buffer);
+ for(i = partlen;i+64 <= inputlen;i+=64)
+ MD5Transform(context->state,&input[i]);
+ index = 0;
+ }
+ else
+ {
+ i = 0;
+ }
+ memcpy(&context->buffer[index],&input[i],inputlen-i);
+}
+void MD5Final(MD5_CTX *context,unsigned char digest[16])
+{
+ unsigned int index = 0,padlen = 0;
+ unsigned char bits[8];
+ index = (context->count[0] >> 3) & 0x3F;
+ padlen = (index < 56)?(56-index):(120-index);
+ MD5Encode(bits,context->count,8);
+ MD5Update(context,PADDING,padlen);
+ MD5Update(context,bits,8);
+ MD5Encode(digest,context->state,16);
+}
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
+{
+ unsigned int i = 0,j = 0;
+ while(j < len)
+ {
+ output[j] = input[i] & 0xFF;
+ output[j+1] = (input[i] >> 8) & 0xFF;
+ output[j+2] = (input[i] >> 16) & 0xFF;
+ output[j+3] = (input[i] >> 24) & 0xFF;
+ i++;
+ j+=4;
+ }
+}
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
+{
+ unsigned int i = 0,j = 0;
+ while(j < len)
+ {
+ output[i] = (input[j]) |
+ (input[j+1] << 8) |
+ (input[j+2] << 16) |
+ (input[j+3] << 24);
+ i++;
+ j+=4;
+ }
+}
+void MD5Transform(unsigned int state[4],unsigned char block[64])
+{
+ unsigned int a = state[0];
+ unsigned int b = state[1];
+ unsigned int c = state[2];
+ unsigned int d = state[3];
+ unsigned int x[64];
+ MD5Decode(x,block,64);
+ FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
\ No newline at end of file
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c"
new file mode 100755
index 0000000..2d0b84b
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/main\0507919\051.c"
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#incldue "md5_encode.h"
+
+int main()
+{
+ int ret;
+ ret=md5_file_verfy("111","222");
+ printf("ret:%d\n",ret);
+
+ return 0;
+
+}
\ No newline at end of file
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h"
new file mode 100755
index 0000000..89939b0
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0502203\051.h"
@@ -0,0 +1,15 @@
+
+int ota_file_open(char* path, char* flag);
+
+int ota_file_seek(int handle, int offset, int flag);
+
+int ota_file_read(char* buffer, size_t count, int file);
+
+void ota_file_close(int handle);
+
+int md5_file_verfy(char* filePath, char* file_md5);
+
+
+
+
+
diff --git "a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c" "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c"
new file mode 100755
index 0000000..106cee1
--- /dev/null
+++ "b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/Backup/md5_encode\0505411\051.c"
@@ -0,0 +1,82 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include "md5.h"
+
+
+
+
+int ota_file_open(char* path, char* flag)
+{
+#if 0
+ if(strcmp(flag, "r") == 0 || strcmp(flag, "rb") == 0)
+ return mtk_device_wrap_open(path, O_RDONLY);
+ else if(strcmp(flag, "r+") == 0 || strcmp(flag, "rb+") == 0)
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT);
+ else if(strcmp(flag, "w+") == 0 ||strcmp(flag, "wb+") == 0 || strcmp(flag, "w") == 0 || strcmp(flag, "wb") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_TRUNC);
+ else if(strcmp(flag, "a+") == 0 ||strcmp(flag, "ab+") == 0 || strcmp(flag, "a") == 0 || strcmp(flag, "ab") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_APPEND);
+#endif
+}
+
+
+int ota_file_seek(int handle, int offset, int flag)
+{
+// return mtk_device_wrap_seek(handle,offset,flag);
+}
+
+
+
+int ota_file_read(char* buffer, size_t count, int file)
+{
+// return mtk_device_wrap_read(file,buffer,count);
+}
+
+
+
+void ota_file_close(int handle)
+{
+// mtk_device_wrap_close(handle);
+}
+
+
+int md5_file_verfy(char* filePath, char* file_md5)
+{
+ int ret = FALSE;
+ int handle;
+
+ printf("calc file md5: %s\n", filePath);
+ handle = ota_file_open(filePath, "rb",0);
+ if(handle >= 0){
+ ota_file_seek(handle, 0, SEEK_END,0);
+
+ {
+ int read_len = 0;
+ unsigned char buffer[1024] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ while ((read_len = ota_file_read(buffer, 1, 1024, handle,0))){
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, 1024);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ printf("md5:%s\n", buffer);
+ printf("md5:%s\n", file_md5);
+
+ ret = strcmp((const char*)buffer, (const char*)file_md5) == 0;
+ }
+ ota_file_close(handle,0);
+ }
+ return ret;
+}
+
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc
new file mode 100755
index 0000000..70e9321
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/main.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc
new file mode 100755
index 0000000..934a8b0
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc
new file mode 100755
index 0000000..5ecf4aa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5.h.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc
new file mode 100755
index 0000000..913feaa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.c.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc
new file mode 100755
index 0000000..09ce7a0
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/cache/parse/md5_encode.h.sisc
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml
new file mode 100755
index 0000000..2e78352
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.bookmarks.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SourceInsightBookmarks
+ AppVer="4.00.0096"
+ AppVerMinReader="4.00.0009"
+ >
+ <Bookmarks/>
+</SourceInsightBookmarks>
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml
new file mode 100755
index 0000000..53541bc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siproj_settings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ProjectSettings
+ AppVer="4.00.0096"
+ AppVerMinReader="4.00.0034"
+ GlobalConfiguration="1"
+ GlobalWorkspace="0"
+ LocalsInDb="0"
+ IndexMembers="1"
+ IndexFragments="1"
+ UseMasterFileList="0"
+ SourceDir="..\"
+ BackupDir="%PROJECT_DATA_DIR%\Backup"
+ MasterFileList="%PROJECT_SOURCE_DIR%\%PROJECT_NAME%_filelist.txt"
+ IsImportProject="0"
+ >
+ <Imports>
+ <ImportedLibs/>
+ </Imports>
+ <ParseConditions>
+ <Defines/>
+ </ParseConditions>
+</ProjectSettings>
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork
new file mode 100755
index 0000000..bcd4a37
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_0628.si4project/md5_0628.siwork
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c b/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c
new file mode 100755
index 0000000..918d634
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/MD5/md5_encode.c
@@ -0,0 +1,264 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <log/log.h>
+//xf.li@20230822 add for ab recover start
+#include <errno.h>
+//xf.li@20230822 add for ab recover end
+#include "md5.h"
+#include "mtk_device_wrap.h"
+#include "liblog/lynq_deflog.h"
+#define LOG_TAG "LYNQ_FOTA"
+
+int ota_file_open(char* path, char* flag)
+{
+#if 1
+ if(strcmp(flag, "r") == 0 || strcmp(flag, "rb") == 0)
+ return mtk_device_wrap_open(path, O_RDONLY);
+ else if(strcmp(flag, "r+") == 0 || strcmp(flag, "rb+") == 0)
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT);
+ else if(strcmp(flag, "w+") == 0 ||strcmp(flag, "wb+") == 0 || strcmp(flag, "w") == 0 || strcmp(flag, "wb") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_TRUNC);
+ else if(strcmp(flag, "a+") == 0 ||strcmp(flag, "ab+") == 0 || strcmp(flag, "a") == 0 || strcmp(flag, "ab") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_APPEND);
+#endif
+}
+
+
+int ota_file_seek(int handle, int offset, int flag)
+{
+ return mtk_device_wrap_seek(handle,offset,flag);
+}
+
+
+
+int ota_file_read(char* buffer, size_t count, int file)
+{
+ return mtk_device_wrap_read(file,buffer,count);
+}
+
+
+
+void ota_file_close(int handle)
+{
+ mtk_device_wrap_close(handle);
+}
+
+#define MD5_READ_BUFFER_LEN 4*1024
+int lynq_md5_file_verfy(char* filePath, char* file_md5)
+{
+ int ret = -1;
+ int handle;
+
+ LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ LYVERBLOG("[+MD5]:handle:%d\n",handle);
+ if(handle >= 0){
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ //strcpy(buffer,"12345");
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ //printf("readlen:%d\n",read_len);
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+ LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ LYVERBLOG("[+MD5]:ret:%d\n", ret);
+ }
+ close(handle);
+ }
+ return ret;
+}
+//xf.li@20230822 add for ab recover start
+#define MD5_VERFY_ERROR 5
+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5)
+{
+ int ret = -1;
+ int handle;
+
+ RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ RLOGD("[+MD5]:handle:%d\n",handle);
+ if(handle == -1)
+ {
+ RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+ }
+ if(handle >= 0)
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ usleep(1000);
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ RLOGD("[+MD5]:buffer md5:%s\n", buffer);
+ RLOGD("[+MD5]:file_md5 md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ RLOGD("[+MD5]:ret:%d\n", ret);
+ close(handle);
+ }
+ if(ret != 0)
+ {
+ return MD5_VERFY_ERROR;
+ }
+ return ret;
+}
+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[])
+{
+ //int ret = -1;
+ int handle;
+
+ RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ RLOGD("[+MD5]:handle:%d\n",handle);
+ if(handle == -1)
+ {
+ RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+ }
+ if(handle >= 0)
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ usleep(1000);
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ RLOGD("[+MD5]: md5 of %s : %s\n", filePath, buffer);
+ memcpy(buffer_out, buffer, MD5_READ_BUFFER_LEN);
+ close(handle);
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2)
+{
+ int ret = -1;
+ int handle_1, handle_2;
+ unsigned char buffer_1[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char buffer_2[MD5_READ_BUFFER_LEN] = {0};
+
+ ret = calculate_file_md5_value(filePath_1, buffer_1);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate file1 md5 value ERROE!!!\n");
+ return ret;
+ }
+ ret = calculate_file_md5_value(filePath_2, buffer_2);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate file2 md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("buffer_1 is %s, buffer_2 is %s\n", buffer_1, buffer_2);
+ ret = strncmp((const char*)buffer_1, (const char*)buffer_2, 32);
+ RLOGD("[+MD5]:strncmp ret:%d\n", ret);
+
+ if(ret != 0)
+ {
+ return MD5_VERFY_ERROR;
+ }
+ return 0;
+}
+//xf.li@20230822 add for ab recover end
+#if 0
+int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len)
+{
+ int ret = -1;
+ int handle;
+ int tatal_packe_len = 0;
+
+ LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+ handle = mtk_device_wrap_open(filePath, O_RDONLY);
+ LYVERBLOG("[+MD5]:handle:%d\n",handle);
+ if(handle >= 0){
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ //strcpy(buffer,"12345");
+ tatal_packe_len = packe_len;
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ while ((read_len = mtk_device_wrap_read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ //printf("readlen:%d\n",read_len);
+ if(tatal_packe_len >= read_len)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ tatal_packe_len -= read_len;
+ }
+ else if(tatal_packe_len > 0)
+ {
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ MD5Update(&md5, (unsigned char*)buffer, tatal_packe_len);
+ tatal_packe_len -= read_len;
+ }
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ memset(buffer,0,sizeof(buffer));
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+ LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ LYVERBLOG("[+MD5]:ret:%d\n", ret);
+ }
+ mtk_device_wrap_close(handle);
+ }
+ return ret;
+}
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h b/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h
new file mode 100755
index 0000000..a6e6821
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/iot_rock.h
@@ -0,0 +1,166 @@
+#ifndef _IOT_ROCK_H_
+#define _IOT_ROCK_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* public */
+
+#define E_ROCK_SUCCESS (0)
+#define E_ROCK_INVALID_DELTA (-1)
+#define E_ROCK_DELTA_MISMATCH (-2)
+#define E_ROCK_DELTA_CHUNK_MISMATCH (-3)
+#define E_ROCK_READ_DELTA_ERROR (-4)
+#define E_ROCK_READ_BLOCK_ERROR (-11)
+#define E_ROCK_WRITE_BLOCK_ERROR (-12)
+#define E_ROCK_RAM_NOT_ENOUGH (-20)
+#define E_ROCK_INVALID_CTX (-30)
+#define E_ROCK_FOTA_ADDR (-50)
+
+
+#define PATCH_SYSTEM (1)
+#define PATCH_BOOT (2)
+#define PATCH_TEE (3)
+#define PATCH_MD1IMG (4)
+#define PATCH_MD1DSP (5)
+#define PATCH_VBMETA (6)
+#define PATCH_OEMAPP (7)
+#define PATCH_OEMAPP2 (8)
+#define PATCH_MEDMCU (9)
+#define PATCH_SPM (10)
+#define PATCH_PROTECT (11)
+#define PATCH_MCF1 (12)
+#define PATCH_MCF2 (13)
+#define PATCH_MCUPM (14)
+#define PATCH_SSPM (15)
+#define PATCH_DPM (16)
+#define PATCH_PIIMG (17)
+#define PATCH_HSMOS (18)
+#define PATCH_BL2 (19)
+#define PATCH_BL33 (20)
+
+#define FULL_SYSTEM (65)
+#define FULL_BOOT (66)
+#define FULL_TEE (67)
+#define FULL_MD1IMG (68)
+#define FULL_MD1DSP (69)
+#define FULL_VBMETA (70)
+#define FULL_OEMAPP (71)
+#define FULL_OEMAPP2 (72)
+#define FULL_MEDMCU (73)
+#define FULL_SPM (74)
+#define FULL_PROTECT (75)
+#define FULL_MCF1 (76)
+#define FULL_MCF2 (77)
+#define FULL_MCUPM (78)
+#define FULL_SSPM (79)
+#define FULL_DPM (80)
+#define FULL_PIIMG (81)
+#define FULL_HSMOS (82)
+#define FULL_BL2 (83)
+#define FULL_BL33 (84)
+
+
+
+
+
+
+
+
+#define MAX_OTA_ROLE (128)
+#define REAL_OTA_ROLE (20)
+
+
+
+#define MODE_NORMAL 0
+#define MODE_A2B 1
+#define MODE_B2A 2
+
+#define WAIT 0xff
+#define PASS 0
+#define ERROR -1
+
+typedef struct {
+ void* user_context;
+ unsigned int rom_base; // old rom start
+ unsigned char* ram_base; // ram working buffer start
+ unsigned int ram_len; // ram working buffer len
+
+ unsigned int backup_base; // ram backup storage start
+ unsigned int backup_len; // ram backup storage len
+
+ unsigned int update_nvram; // nvram update flag
+
+ int read_rom_directly;
+ int first_run;
+} IOT_UPDATA_CONTEXT;
+
+
+
+
+typedef struct {
+
+ char fota_flag[32]; //fota 标志保留
+ int update_result; //升级结果
+ int ota_run; //
+ char cid[32];
+ char did[32];
+} UPDATE_INFO;
+
+
+typedef struct {
+ int need_update;
+ int check_delta;
+ int check_rom;
+ int update_result;
+
+} UPDATE_STATUS;
+
+
+typedef struct {
+ int ota_run;
+ UPDATE_STATUS update_status[MAX_OTA_ROLE];
+ int update_result;
+ int switch_slot;
+
+} OTA_STATUS;
+
+
+
+
+
+//#define DELTA_HEARD_SIZE (4*5)
+
+//#define DELTA_HEARD_SIZE (4*11 + 4*11)
+#define DELTA_HEARD_SIZE 512
+#define DELTA_FULL_HEARD_SIZE 8
+
+
+
+int iot_patch(IOT_UPDATA_CONTEXT* update_ctx);
+
+unsigned int iot_hash(unsigned char *buf,unsigned int len, unsigned int* value);
+int lynq_md5_file_verfy(char* filePath, char* file_md5);
+//xf.li@20230822 add for ab recover start
+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5);
+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[]);
+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2);
+//xf.li@20230822 add for ab recover end
+//int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len);
+int lynq_rock_main(int first_run);
+int lynq_fota_func(void);
+int lynq_nand_open(const char *pathname, int flags);
+ssize_t lynq_nand_read(int fd, void *buf, size_t count);
+ssize_t lynq_nand_write(int fd, void *buf, size_t count);
+int lynq_nand_close(int fd);
+int lynq_get_upgrade_status(void);
+void lynq_reboot_device(void);
+int lynq_fota_nrestart(void);
+int lynq_fota_set_addr_value(char *value,int size);
+int lynq_fota_get_addr_value(char *tmp);
+#endif
+
+
+
diff --git a/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h b/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h
new file mode 100755
index 0000000..77c7c2a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/iot_rock_ipl.h
@@ -0,0 +1,22 @@
+#ifndef _IOT_ROCK_IPL_H_
+#define _IOT_ROCK_IPL_H_
+
+void rock_trace(void* ctx, const char* fmt, ...);
+void rock_progress(void* ctx, int percent);
+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size);
+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size);
+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size);
+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size);
+int rock_get_blocksize(void* ctx);
+
+int rock_read_file(void* ctx, void* name, unsigned char* dest, unsigned int offset, unsigned int size);
+int rock_write_file(void* ctx, void* name, unsigned char* src, unsigned int offset, unsigned int size);
+
+int rock_delete_file(void* ctx, void* name);
+
+int rock_fatal(void* ctx, int error_code);
+
+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size,
+ unsigned int source_hash,unsigned int target_hash);
+#endif
+
diff --git a/IC_src/mtk/lib/liblynq-fota/include/md5.h b/IC_src/mtk/lib/liblynq-fota/include/md5.h
new file mode 100755
index 0000000..f0e3a1b
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/md5.h
@@ -0,0 +1,48 @@
+#ifndef MD5_H
+#define MD5_H
+
+typedef struct
+{
+ unsigned int count[2];
+ unsigned int state[4];
+ unsigned char buffer[64];
+}MD5_CTX;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+{ \
+ a += F(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define GG(a,b,c,d,x,s,ac) \
+{ \
+ a += G(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define HH(a,b,c,d,x,s,ac) \
+{ \
+ a += H(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define II(a,b,c,d,x,s,ac) \
+{ \
+ a += I(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
+void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+void MD5Transform(unsigned int state[4],unsigned char block[64]);
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h b/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h
new file mode 100755
index 0000000..c3e5d38
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/md5_encode.h
@@ -0,0 +1,33 @@
+#ifndef MD5_ENCODE_H_
+#define MD5_ENCODE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//打开文件
+int ota_file_open(char* path, char* flag);
+//文件偏移位置
+int ota_file_seek(int handle, int offset, int flag);
+//读文件内容
+int ota_file_read(char* buffer, size_t count, int file);
+//关闭文件
+void ota_file_close(int handle);
+
+
+/***
+ * @description: 校验文件的MD5
+ * @param filePath 文件路径
+ * @param file_md5 待校验MD5值
+ * @return 0:校验成功; 其他:校验失败
+ */
+int md5_file_verfy(char* filePath, char* file_md5);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-fota/include/sha.h b/IC_src/mtk/lib/liblynq-fota/include/sha.h
new file mode 100755
index 0000000..05f9941
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/include/sha.h
@@ -0,0 +1,75 @@
+/* sha.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Google Inc. nor the names of its contributors may
+** be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _EMBEDDED_SHA_H_
+#define _EMBEDDED_SHA_H_
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SHA_CTX {
+ uint64_t count;
+ uint32_t state[5];
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+ union {
+ uint8_t b[64];
+ uint32_t w[16];
+ } buf;
+#else
+ uint8_t buf[64];
+#endif
+} SHA_CTX;
+
+void SHA_init(SHA_CTX* ctx);
+void SHA_update(SHA_CTX* ctx, const void* data, int len);
+const uint8_t* SHA_final(SHA_CTX* ctx);
+
+/* Convenience method. Returns digest parameter value. */
+const uint8_t* SHA(const void* data, int len, uint8_t* digest);
+
+#define SHA_DIGEST_SIZE 20
+
+typedef enum check_status_t{
+ ERROR_SHA = -3, // sha1输入参数错误
+ PATCH_ERR = -2, // 检测hash既不等于source_hash也不等于target_hash, 一般错误情况
+ NOT_EXIST_FILE = -1, // 检测文件不存在
+ SOURCE_SUCC = 0, // 检测hash等于目标source_hash, 一般正常情况
+ PATCH_SUCC = 1, // 检测hash等于目标target_hash, up to data
+}Check_status;
+
+int ParseSha1(const char* str, uint8_t* digest);
+
+const uint8_t* ROCK_SHA(const char *file_name, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a b/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a
new file mode 100755
index 0000000..023c16e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/lib/libiotpatch.a
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a b/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a
new file mode 100755
index 0000000..1cebf1f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/lib/libmd5.a
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-fota/makefile b/IC_src/mtk/lib/liblynq-fota/makefile
new file mode 100755
index 0000000..4fe83ea
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/makefile
@@ -0,0 +1,79 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fpermissive \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -DKEEP_ALIVE \
+ -D__LINUX_OS__ \
+ -DECALL_SUPPORT
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I./include \
+ -I$(LOCAL_PATH)/../include \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/liblog \
+ -I$(ROOT)$(includedir)/ftp \
+ -I$(ROOT)$(includedir)/glib-2.0 \
+ -I$(ROOT)$(libdir)/glib-2.0/include \
+
+
+
+LOCAL_LIBS := \
+ -L. \
+ -L./lib \
+ -ldl \
+ -lpthread \
+ -llog \
+ -lstdc++ \
+ -liotpatch \
+ -lmd5 \
+ -lnandapi \
+ -lbootctrl \
+ -llynq-log \
+ -llynq-protcl \
+ -llynq-uci \
+
+SOURCES = $(wildcard *.c wildcard *.h rock_ua/*.c MD5/*c)
+
+EXECUTABLE = liblynq-fota.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)
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c b/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
new file mode 100755
index 0000000..c970ce1
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
@@ -0,0 +1,2079 @@
+// 2017-07-31 carota Rock FOTA ua porting file
+
+
+#define ROCK_FOTA_SUPPORT
+
+#ifdef ROCK_FOTA_SUPPORT
+
+
+#include "iot_rock.h"
+#include "iot_rock_ipl.h"
+#include "sha.h"
+#include <log/log.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdint.h>
+
+
+#include <hardware/boot_control.h>
+#include <hardware/hardware.h>
+#include <sys/reboot.h>
+
+
+
+#include "liblog/lynq_deflog.h"
+#include "mtk_device_wrap.h"
+#include <include/lynq_uci.h>
+
+#define ROCK_DEFAULT_BLOCK_SIZE 0x40000
+#define ROCK_RAM_LEN (1024*1024)
+
+#define LOG_TAG "LYNQ_FOTA"
+#define ROCK_BACKUP_LEN ROCK_DEFAULT_BLOCK_SIZE
+
+
+
+#define FILENAME_SIZE 50
+
+
+
+//#define DEV_DELTA "/dev/disk/by-partlabel/delta"
+#if 0
+#define DEV_DELTA "/dev/disk/by-partlabel/delta"
+#else
+#define DEV_DELTA "/dev/mtd41"
+#endif
+
+
+
+char partition_filename_a[][FILENAME_SIZE] = {
+ {"/dev/disk/by-partlabel/system_a"},
+ {"/dev/disk/by-partlabel/boot_a"},
+ {"/dev/disk/by-partlabel/tee_a"},
+ {"/dev/disk/by-partlabel/md1img_a"},
+ {"/dev/disk/by-partlabel/md1dsp_a"},
+ {"/dev/disk/by-partlabel/vbmeta_a"},
+ {"/dev/disk/by-partlabel/oemapp_a"},
+ {"/dev/disk/by-partlabel/oemapp2_a"},
+ {"/dev/disk/by-partlabel/medmcu_a"},
+ {"/dev/disk/by-partlabel/spm_a"},
+ {"/dev/disk/by-partlabel/protect_a"},
+ {"/dev/disk/by-partlabel/mcf1_a"},
+ {"/dev/disk/by-partlabel/mcf2_a"},
+ {"/dev/disk/by-partlabel/mcupm_a"},
+ {"/dev/disk/by-partlabel/sspm_a"},
+ {"/dev/disk/by-partlabel/dpm_a"},
+ {"/dev/disk/by-partlabel/pi_img_a"},
+ {"/dev/disk/by-partlabel/hsm_os_a"},
+ {"/dev/disk/by-partlabel/bl2_a"},
+ {"/dev/disk/by-partlabel/bl33_a"}
+};
+
+
+char partition_filename_b[][FILENAME_SIZE] = {
+ {"/dev/disk/by-partlabel/system_b"},
+ {"/dev/disk/by-partlabel/boot_b"},
+ {"/dev/disk/by-partlabel/tee_b"},
+ {"/dev/disk/by-partlabel/md1img_b"},
+ {"/dev/disk/by-partlabel/md1dsp_b"},
+ {"/dev/disk/by-partlabel/vbmeta_b"},
+ {"/dev/disk/by-partlabel/oemapp_b"},
+ {"/dev/disk/by-partlabel/oemapp2_b"},
+ {"/dev/disk/by-partlabel/medmcu_b"},
+ {"/dev/disk/by-partlabel/spm_b"},
+ {"/dev/disk/by-partlabel/protect_b"},
+ {"/dev/disk/by-partlabel/mcf1_b"},
+ {"/dev/disk/by-partlabel/mcf2_b"},
+ {"/dev/disk/by-partlabel/mcupm_b"},
+ {"/dev/disk/by-partlabel/sspm_b"},
+ {"/dev/disk/by-partlabel/dpm_b"},
+ {"/dev/disk/by-partlabel/pi_img_b"},
+ {"/dev/disk/by-partlabel/hsm_os_b"},
+ {"/dev/disk/by-partlabel/bl2_b"},
+ {"/dev/disk/by-partlabel/bl33_b"}
+};
+
+
+
+
+char partition_filename[][FILENAME_SIZE] = {
+ {"system"},
+ {"boot"},
+ {"tee"},
+ {"md1img"},
+ {"md1dsp"},
+ {"vbmeta"},
+ {"oemapp"},
+ {"oemapp2"},
+ {"medmcu"},
+ {"spm"},
+ {"protect"},
+ {"mcf1"},
+ {"mcf2"},
+ {"mcupm"},
+ {"sspm"},
+ {"dpm"},
+ {"pi_img"},
+ {"hsm_os"},
+ {"bl2"},
+ {"bl33"}
+};
+//+10
+
+unsigned int delta_head[128]={0}; //512/4 128/2=64
+
+
+
+#define FOTA_UCI_MODULE "lynq_fota"
+#define FOTA_UCI_FILE "lynq_uci"
+#define FOTA_UCI_ADDR "lynq_fota_addr"
+#define FOTA_UCI_STATE "lynq_fota_state"
+
+#define FILE_UPDATE_STATE "/data/.update_status"
+#define FILE_UPDATE_FLAG "/tmp/update_flag"
+#define FILE_FOTA_STATE "/data/.fota_status"
+
+#define NAND_PAGE_SIZE 4096
+
+
+#define BOOTDEV_TYPE_NAND 1
+
+#define BACKUP_ADDR_FLAG 0xffffffff
+#define FILE_BACKUP "/data/.backup"
+
+#define SLOT_A 0
+#define SLOT_B 1
+
+#define FULL_HEAD "full-ota"
+
+//xf.li@20230822 add for ab rollback start
+#define DEV_SYSTEM_A "/dev/disk/by-partlabel/system_a"
+#define DEV_SYSTEM_B "/dev/disk/by-partlabel/system_b"
+
+#define DEV_BOOT_A "/dev/disk/by-partlabel/boot_a"
+#define DEV_BOOT_B "/dev/disk/by-partlabel/boot_b"
+
+#define DEV_SPM_A "/dev/disk/by-partlabel/spm_a"
+#define DEV_SPM_B "/dev/disk/by-partlabel/spm_b"
+
+#define DEV_MD1IMG_A "/dev/disk/by-partlabel/md1img_a"
+#define DEV_MD1IMG_B "/dev/disk/by-partlabel/md1img_b"
+
+#define DEV_TEE_A "/dev/disk/by-partlabel/tee_a"
+#define DEV_TEE_B "/dev/disk/by-partlabel/tee_b"
+
+#define DEV_VBMETA_A "/dev/disk/by-partlabel/vbmeta_a"
+#define DEV_VBMETA_B "/dev/disk/by-partlabel/vbmeta_b"
+
+#define DEV_BL2_A "/dev/disk/by-partlabel/bl2_a"
+#define DEV_BL2_B "/dev/disk/by-partlabel/bl2_b"
+
+#define DEV_BL33_A "/dev/disk/by-partlabel/bl33_a"
+#define DEV_BL33_B "/dev/disk/by-partlabel/bl33_b"
+
+#define DEV_MEDMCU_A "/dev/disk/by-partlabel/medmcu_a"
+#define DEV_MEDMCU_B "/dev/disk/by-partlabel/medmcu_b"
+
+#define DEV_OEMAPP_A "/dev/disk/by-partlabel/oemapp_a"
+#define DEV_OEMAPP_B "/dev/disk/by-partlabel/oemapp_b"
+
+#define DEV_OEMAPP2_A "/dev/disk/by-partlabel/oemapp2_a"
+#define DEV_OEMAPP2_B "/dev/disk/by-partlabel/oemapp2_b"
+
+
+#define DEV_MISC "/dev/disk/by-partlabel/misc"
+
+#define BACKUP_UBI_NUM 31 //max ubi number
+#define MTD_SYSTEM_A 14
+#define MTD_SYSTEM_B 15
+#define MD5_RETRY_TIME 3
+#define MD5_VERFY_ERROR 5
+#define MD5_READ_BUFFER_LEN 4*1024
+#define FOTA_FIRST 0
+#define RECOVER_FIRST 1
+int fota_interrupt = 1;
+//xf.li@20230822 add for ab rollback end
+
+
+//int fd_system_a,fd_system_b,fd_boot_a,fd_boot_b,fd_tee_a,fd_tee_b,fd_bl2,fd_bl33,fd_delta,fd_curr,fd_log,fd_update_status,fd_md1img_a,fd_md1img_b,fd_fota_status,fd_md1dsp_a,fd_md1dsp_b,fd_vbmeta_a,fd_vbmeta_b,fd_oemapp_a,fd_oemapp_b,fd_oemapp2_a,fd_oemapp2_b,fd_medmcu_a,fd_medmcu_b,fd_bl33_a,fd_bl33_b;
+int fd_delta,fd_curr,fd_log,fd_update_status,fd_fota_status;
+int fd_write,fd_read;
+
+static unsigned int delta_offset = 0;
+static unsigned int now_patch = 0;
+unsigned int current_slot = 0;
+unsigned char rock_debug_buffer[512];
+
+
+
+OTA_STATUS fota_status;
+UPDATE_INFO up_info;
+
+
+extern const hw_module_t HAL_MODULE_INFO_SYM;
+boot_control_module_t* module;
+
+static void lynq_init_wake_lock_func(void);
+static void lynq_fota_grab_artial_wake_lock(void);
+static void lynq_fota_release_wake_lock(void);
+int check(int sys_size);
+int check_cpu();
+
+static const char hex_chars[] = "0123456789abcdef";
+
+/**
+ * @brief The following is the wake up
+ * start
+ */
+
+#define ANDROID_WAKE_LOCK_NAME "fota-interface"
+
+void *dlHandle_wakelock;
+
+enum {
+ PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
+ FULL_WAKE_LOCK = 2 // the screen is also on
+};
+
+// while you have a lock held, the device will stay on at least at the
+// level you request.
+
+int (*acquire_wake_lock)(int lock, const char* id);
+int (*release_wake_lock)(const char* id);
+
+void convert_hex(unsigned char *sha, unsigned char *shastr)
+{
+ int i;
+ int j = 0;
+ unsigned int c;
+
+ for (i = 0; i < 20; i++) {
+ c = (sha[i] >> 4) & 0x0f;
+ shastr[j++] = hex_chars[c];
+ shastr[j++] = hex_chars[sha[i] & 0x0f];
+ }
+ shastr[40] = '\0';
+}
+
+
+
+
+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size,
+ unsigned int source_hash,unsigned int target_hash) {
+
+ return 0;
+}
+
+int rock_fatal(void* ctx, int error_code) {
+ return 0;
+}
+
+void rock_trace(void* ctx, const char* fmt, ...) {
+
+ va_list ap;
+ memset(rock_debug_buffer,0x0,sizeof(rock_debug_buffer));
+ va_start (ap, fmt);
+
+
+ vsnprintf(rock_debug_buffer,sizeof(rock_debug_buffer),fmt,ap);
+ LYDBGLOG("+[UA]: %s",rock_debug_buffer);
+
+
+ va_end (ap);
+
+}
+
+static int save_fota_status()
+{
+ int err;
+ fd_fota_status = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+ if (fd_fota_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+
+ write(fd_fota_status, &fota_status,sizeof(fota_status));
+ sync();
+
+ close(fd_fota_status);
+}
+
+static int save_fota_info()
+{
+ int err;
+ fd_update_status = open(FILE_UPDATE_STATE,O_RDWR);
+
+ if (fd_update_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+
+ write(fd_update_status, &up_info, sizeof(fota_status));
+ sync();
+ close(fd_update_status);
+}
+
+
+
+void rock_progress(void* ctx, int percent) {
+ int i = 0;
+ static int tmp_percent = -1;
+ rock_trace(ctx, "rock update progress %d\n", percent);
+
+ if (tmp_percent != percent) {
+ tmp_percent = percent;
+ if (percent > 20) {
+ i = fota_status.ota_run;
+ if (fota_status.update_status[i-1].check_delta != PASS) {
+ fota_status.update_status[i-1].check_delta = PASS;
+ fota_status.update_status[i-1].check_rom= PASS;
+ save_fota_status();
+ }
+ }
+ }
+}
+
+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size){
+ //rock_trace(ctx, "rock update progress block %d\n", size);
+
+ int writen = 0;
+ int ret,err;
+
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+ while (writen < size) {
+ write(fd_backup,data,ROCK_DEFAULT_BLOCK_SIZE);
+ sync();
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+ close(fd_backup);
+ return size;
+ }
+
+
+
+ writen = 0;
+
+ if (mtk_device_wrap_seek(fd_write, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek write\n");
+ return err;
+ }
+
+ while (writen < size) {
+ ret = mtk_device_wrap_write(fd_write,data+writen, ROCK_DEFAULT_BLOCK_SIZE);
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+
+
+ return size;
+}
+
+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size){
+
+#if 0
+
+ int writen = 0;
+ int ret,err;
+
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+ while (writen < size) {
+ write(fd_backup,src,ROCK_DEFAULT_BLOCK_SIZE);
+ sync();
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+ close(fd_backup);
+ return size;
+ }
+
+ writen = 0;
+
+ if (mtk_device_wrap_seek(fd_curr, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek write\n");
+ return err;
+ }
+
+ while (writen < size) {
+ ret = mtk_device_wrap_write(fd_curr,src+writen, ROCK_DEFAULT_BLOCK_SIZE);
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+
+
+#endif
+
+ return size;
+
+}
+
+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size){
+
+
+ int ret,err;
+
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDONLY);
+ read(fd_backup,dest,size);
+ sync();
+ close(fd_backup);
+ return size;
+ }
+
+
+
+ if (mtk_device_wrap_seek(fd_read, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek read block err\n");
+ }
+
+ do {
+
+ ret = mtk_device_wrap_read(fd_read, dest, size);
+
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ err = -errno;
+ rock_trace(ctx,"%s Error reading metadata file\n");
+
+ mtk_device_wrap_close(fd_read);
+
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+
+
+ return ret;
+
+
+}
+
+
+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size){
+
+ int ret = 0,err = 0;
+
+
+ if (lseek(fd_delta, offset + delta_offset, SEEK_SET) < 0) {
+ err = -errno;
+ rock_trace(ctx, "mtk_device_wrap_seek df_delta err\n");
+ return err;
+ }
+
+ do {
+
+ ret = read(fd_delta, dest, size);
+
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ err = -errno;
+ rock_trace(ctx," Error reading metadata file\n");
+
+ close(fd_delta);
+
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+
+ return ret;
+
+}
+
+int rock_get_blocksize(void* ctx) {
+ return ROCK_DEFAULT_BLOCK_SIZE;
+}
+
+int rock_read_file(void* ctx, void* name, unsigned char* dest, unsigned int offset, unsigned int size){return 0;}
+int rock_write_file(void* ctx, void* name, unsigned char* src, unsigned int offset, unsigned int size){return 0;}
+int rock_delete_file(void* ctx, void* name){return 0;}
+/* ROCK IPL end */
+
+
+
+static int init_dev_fd()
+{
+
+ int err;
+ char lynq_fota_addr[64] = {0};
+ char fota_name[]= "fota.delta";
+ int n;
+ if(0 != lynq_fota_get_addr_value(lynq_fota_addr))
+ {
+ return E_ROCK_FOTA_ADDR;
+ }
+ RLOGD("+[UA]: get fota pack addr: %s\n",lynq_fota_addr);
+ fd_delta = open(lynq_fota_addr,O_RDWR);
+
+ if (fd_delta < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+
+ fd_update_status = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+ if (fd_update_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+ memset(&up_info, 0, sizeof(up_info));
+ lseek(fd_update_status,0,SEEK_SET);
+ read(fd_update_status,(unsigned char *)&up_info,sizeof(up_info));
+ close(fd_update_status);
+ return 0;
+}
+
+
+
+
+
+static int close_dev_fd(int fd)
+{
+ close(fd);
+}
+
+
+
+static int reboot_device() {
+
+ reboot(RB_AUTOBOOT);
+
+ while (1) pause();
+}
+
+
+
+int test_write_delta(char *source, char *target)
+{
+ int fd_source,fd_target,size;
+
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+
+ fd_source = open(source,O_RDONLY);
+
+ if (fd_source < 0) {
+ RLOGD("+[UA]: open source error\n");
+ return 1;
+ }
+
+ fd_target = mtk_device_wrap_open(target,O_RDWR);
+
+ if (fd_target < 0) {
+ mtk_device_wrap_close(fd_target);
+ close(fd_source);
+ RLOGD("+[UA]: open target error\n");
+ return 1;
+ }
+
+ while(( size = read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ }
+
+ mtk_device_wrap_close(fd_target);
+ close(fd_source);
+ return 0;
+}
+
+
+int nand_copyto_nand(char *source, char *target)
+{
+ int fd_source,fd_target,size;
+
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+
+ fd_source = mtk_device_wrap_open(source,O_RDONLY);
+
+ if (fd_source < 0) {
+ RLOGD("+[UA]: open source error\n");
+ return 1;
+ }
+
+ fd_target = mtk_device_wrap_open(target,O_RDWR);
+
+ if (fd_target < 0) {
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ RLOGD("+[UA]: open target error\n");
+ return 1;
+ }
+
+ while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ }
+
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ return 0;
+}
+
+int delta_copyto_nand(unsigned int start,int size)
+{
+
+ char delta_data[NAND_PAGE_SIZE];
+ unsigned int ret = 0;
+ int err;
+
+
+ if (lseek(fd_delta, start, SEEK_SET) < 0) {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+ if (mtk_device_wrap_seek(fd_curr, 0, SEEK_SET) < 0) {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+
+ do {
+ memset(delta_data,0,NAND_PAGE_SIZE);
+ ret = read(fd_delta, delta_data, NAND_PAGE_SIZE);
+
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ err = -errno;
+
+ return err;
+ }
+
+ size -= NAND_PAGE_SIZE;
+ mtk_device_wrap_write(fd_curr,delta_data,NAND_PAGE_SIZE);
+ //mtk_device_wrap_write(fd_curr,delta_data,ret);
+
+ } while(size > 0);
+
+
+ return 0;
+
+}
+
+
+unsigned char ram_buffer[ROCK_RAM_LEN];
+
+int check(int sys_size)
+{
+ int fd;
+ int i=0;
+ int j=0;
+ int num=i;
+ int n = 0;
+ const uint8_t data[] = { 0x74, 0x77, 0x6f, 0x63, 0x6f, 0x72, 0x65};
+ const char * core_flag="twocore\n";
+
+ uint8_t buffer[16];
+
+ if(sys_size == 0)//for only upgrade oemapp and oemapp2
+ {
+ return 0;
+ }
+ n = strlen(core_flag);
+ lseek(fd_delta,520,SEEK_SET);
+ lseek(fd_delta,sys_size,SEEK_CUR);
+ lseek(fd_delta, -1*n, SEEK_CUR);
+ read(fd_delta, buffer, n);
+ lseek(fd_delta,0,SEEK_SET);//file reset
+ if (memcmp(buffer, core_flag, n) == 0)
+ {
+ return 0;
+ }
+ return -1;
+
+}
+
+int check_cpu(void)
+{
+ int i=0;
+ int ret;
+ char buffer[3][64];
+ FILE *fp;
+ char num;
+ fp = popen("od -x /proc/device-tree/chosen/atag,devinfo","r");
+
+ for(i=0;i<3;i++)
+ {
+ fgets(buffer[i], 64, fp);
+ }
+
+ for(i=0;i<3;i++)
+ {
+ RLOGD("buffer[i] = %s\n",buffer[i]);
+ }
+ RLOGD("%c\n", buffer[2][14]);
+
+ num = buffer[2][14];
+
+
+ RLOGD("num=%c\n", num);
+ if(num == '0' || num == '1')
+ {
+ printf("this is four core\n");
+ return 4;
+ }
+ else if(num == '2' || num == '3')
+ {
+ printf("this is two core\n");
+ return 2;
+ }
+ else
+ {
+ RLOGD("this char is error\n");
+ return -1;
+ }
+ pclose(fp);
+
+ return -1;
+}
+
+
+
+static int rock_update_main(unsigned int rom_base, unsigned int backup_base, unsigned int backup_len, int read_rom_directly, int first_run, int switch_slot_flag, int
+reboot_flag, int backup_mode) {
+ int status,err,start,fd;
+ int ret = 0;
+ int i = 0;
+ int retry_cnt = 0;
+ int cpu_flag;
+ IOT_UPDATA_CONTEXT ctx;
+
+ //OTA_STATUS fota_status;
+
+
+ const hw_module_t* hw_module;
+ unsigned int slot;
+
+ unsigned int update_mode = MODE_NORMAL;
+ unsigned int delta_size;
+ unsigned char full_header[9];
+
+ char digest_s[SHA_DIGEST_SIZE];
+ char digest_t[SHA_DIGEST_SIZE];
+ char str_sha[40];
+ char cmd_sys[100];
+ int core_num;
+ int sha_size = 0;
+ int is_need_fullupdate = 0;
+ int fd_partition_a,fd_partition_b;
+//xf.li@20230830 add for ab_recover start
+ fd = open(FILE_UPDATE_FLAG,O_RDWR | O_CREAT,0777);
+ if (fd < 0)
+ {
+ RLOGD("+[UA]: can't open file /tmp/update_flag.\n");
+ return -1;
+ }
+ close(fd);
+//xf.li@20230830 add for ab_recover end
+ hw_module = &HAL_MODULE_INFO_SYM;
+
+ if (!hw_module ||
+ strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+ ret = -EINVAL;
+ }
+ if (ret != 0) {
+ RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+
+
+ if (module == NULL) {
+ RLOGD("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+
+ lynq_init_wake_lock_func();
+ lynq_fota_grab_artial_wake_lock();
+ /************* Bootctrl Init End *************/
+
+ current_slot = module->getCurrentSlot(module);
+
+ int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+
+ RLOGD("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+
+
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.rom_base = 0;
+ ctx.ram_base =(unsigned char *)&ram_buffer[0];
+ ctx.ram_len = ROCK_RAM_LEN;
+ ctx.backup_base = BACKUP_ADDR_FLAG;
+ //ctx.backup_len = ROCK_DEFAULT_BLOCK_SIZE;
+ ctx.backup_len = 0;
+ ctx.update_nvram = 0;
+ ctx.read_rom_directly = read_rom_directly;
+ //ctx.first_run = first_run;
+ ctx.first_run = 1;
+
+ if(0 != init_dev_fd())
+ {
+ RLOGD("+[UA]: get fota addr error\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return E_ROCK_FOTA_ADDR;
+ }
+
+
+ memset(&fota_status,0,sizeof(fota_status));
+ RLOGD("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
+
+#if 0
+ if ((up_info.ota_run>PATCH_BL33)||(up_info.ota_run<PATCH_SYSTEM))
+ {
+ up_info.ota_run = 0;
+ }
+#endif
+
+ up_info.ota_run = 0;
+ if(backup_mode == 1)
+ {
+ if(current_slot == 0)
+ {
+ update_mode = MODE_A2B;
+ }else
+ {
+ update_mode = MODE_B2A;
+ }
+ }
+ else
+ {
+ update_mode = MODE_NORMAL;
+ }
+
+ RLOGD("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
+ RLOGD("+[UA]: update_mode = %d\n",update_mode);
+
+ //memset(&da_head, 0, sizeof(da_head));
+
+ //read(fd_delta, (unsigned char*)&da_head, sizeof(da_head));
+
+ memset(&delta_head, 0, sizeof(delta_head));
+ read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+
+
+ delta_size = 0;
+ sha_size = 0;
+ for (i = 0;i<REAL_OTA_ROLE; i++) {
+ if (delta_head[i] > 0) {
+ fota_status.update_status[i].need_update = 1;
+ delta_size+=delta_head[i];
+
+ }
+ RLOGD("+[UA]: %s,delta size = %d\n",partition_filename[i],delta_head[i]);
+ }
+
+
+ for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE); i++) {
+ if (delta_head[i] > 0) {
+ fota_status.update_status[i].need_update = 1;
+ sha_size+=delta_head[i];
+ }
+ RLOGD("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
+ }
+
+ core_num= check_cpu();
+ if(core_num == 2)
+ {
+ cpu_flag = check(delta_head[64]);
+ if(cpu_flag < 0)
+ {
+ RLOGD("cpu core is error\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ else
+ {
+ RLOGD("cpu core match\n");
+ }
+ }
+ else if(core_num == 4)
+ {
+ RLOGD("the cpu core is four!!!\n");
+ }
+ else
+ {
+ RLOGD("read the cpu core fail");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+
+ fota_status.switch_slot = WAIT;
+ save_fota_status();
+
+ //delta_size = da_head.sys + da_head.boot + da_head.tee + da_head.md1img + da_head.md1dsp + da_head.vbmeta + da_head.oemapp + da_head.oemapp2 + da_head.medmcu+da_head.bl33;
+
+ //sha_size = da_head.full_sys + da_head.full_boot + da_head.full_tee + da_head.full_md1img + da_head.full_md1dsp + da_head.full_vbmeta + da_head.full_oemapp + da_head.full_oemapp2 + da_head.full_medmcu+da_head.full_bl33
+
+
+
+
+ is_need_fullupdate = 0;
+ if(sha_size>0) {
+ is_need_fullupdate = 1;
+ sha_size+=8;
+ }
+
+ sha_size+=delta_size;
+
+ memset(digest_s,0,SHA_DIGEST_SIZE);
+ memset(digest_t,0,SHA_DIGEST_SIZE);
+ memset(str_sha,0,40);
+
+ lseek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
+ read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+ convert_hex(digest_s,str_sha);
+ RLOGD("+[UA]: delta save sha = %s\n",str_sha);
+
+ ROCK_SHA_FILE_COMMON(fd_delta,sizeof(delta_head),sha_size,digest_t);
+ memset(str_sha,0,40);
+ convert_hex(digest_t,str_sha);
+ RLOGD("+[UA]: delta calc sha = %s\n",str_sha);
+
+ if(memcmp(digest_s,digest_t,SHA_DIGEST_SIZE)==0) {
+
+ RLOGD("sha verify pass\n");
+
+ }else{
+ RLOGD("delta sha verify fial!\n");
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+
+ }
+
+ memset(digest_s,0,SHA_DIGEST_SIZE);
+ memset(digest_t,0,SHA_DIGEST_SIZE);
+
+
+ //delta_offset = DELTA_HEARD_SIZE;
+ delta_offset = sizeof(delta_head);
+
+ for(i = 0;i<REAL_OTA_ROLE; i++){ //diff
+ //now_patch = i+1;
+ if (i>0) {
+ delta_offset+=delta_head[i-1];
+ }
+ if((delta_head[i]>0) && (up_info.ota_run<=(i+1))){
+ now_patch = i + 1;
+#if 0
+ if (up_info.ota_run == now_patch) //升级ps断电?
+ {
+ ctx.first_run = 0;
+
+ }else{
+ ctx.first_run = 1;
+ }
+#endif
+ ctx.first_run = 1; //always
+ RLOGD("+[UA]: PATCH %s,ctx.first_run = %d\n", partition_filename[i] ,ctx.first_run);
+ up_info.ota_run = now_patch;
+
+ if(current_slot==SLOT_B) {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i]);
+ }else{
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i]);
+ }
+ system(cmd_sys);
+
+
+ fd_partition_a = mtk_device_wrap_open(partition_filename_a[i],O_RDWR);
+ if (fd_partition_a < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+
+ fd_partition_b = mtk_device_wrap_open(partition_filename_b[i],O_RDWR);
+ if (fd_partition_b < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ if(current_slot==SLOT_B){
+ fd_read = fd_partition_b;
+ fd_write = fd_partition_a;
+ } else {
+ fd_read = fd_partition_a;
+ fd_write = fd_partition_b;
+ }
+
+ fota_status.ota_run = i;
+ fota_status.update_status[i].check_delta = WAIT;
+ fota_status.update_status[i].check_rom = WAIT;
+ fota_status.update_status[i].update_result= WAIT;
+
+ save_fota_status();
+
+
+ up_info.ota_run = i+1;
+ save_fota_info();
+
+ RLOGD("+[UA]: Start upgrading %s.\n",partition_filename[i]);
+ status = iot_patch(&ctx);
+ RLOGD("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
+
+ //up_info.ota_run = 0;
+
+ //fota_status.ota_run = 0;
+ fota_status.update_status[i].update_result= status;
+ fota_status.update_result= status;
+
+ if((status == 0)||(status ==1))
+ {
+
+ fota_status.update_status[i].check_delta = PASS;
+ fota_status.update_status[i].check_rom = PASS;
+ RLOGD("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
+
+ }else if(status == E_ROCK_INVALID_DELTA) {
+ fota_status.update_status[i].check_delta = ERROR;
+ fota_status.update_status[i].check_rom = WAIT;
+ }else if((status == E_ROCK_DELTA_MISMATCH)||(status == E_ROCK_DELTA_CHUNK_MISMATCH)) {
+ fota_status.update_status[i].check_delta = PASS;
+ fota_status.update_status[i].check_rom = ERROR;
+
+ }else{
+
+ //fota_status.update_status[PATCH_SYSTEM -1].check_delta = PASS;
+ //fota_status.update_status[PATCH_SYSTEM -1].check_rom = WAIT;
+ }
+
+ save_fota_status();
+
+
+ if ((status != 0) &&(status != 1))
+ {
+
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ mtk_device_wrap_close(fd_read);
+ mtk_device_wrap_close(fd_write);
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return status;
+ }
+ mtk_device_wrap_close(fd_read);
+ mtk_device_wrap_close(fd_write);
+
+ }
+
+ }
+
+
+
+ if (is_need_fullupdate == 1)
+ {
+
+ now_patch = 0;
+ up_info.ota_run = 0;
+
+ memset(&fota_status,0,sizeof(fota_status));
+ fota_status.switch_slot = WAIT;
+ save_fota_status();
+
+ if (lseek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0) {
+ err = errno;
+ RLOGD("+[UA]: mtk_device_wrap_seek df_delta err\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+
+ read(fd_delta, full_header, DELTA_FULL_HEARD_SIZE);
+
+
+ if (memcmp(full_header, "full-ota", DELTA_FULL_HEARD_SIZE) != 0) {
+ RLOGD("+[UA]: invalid full delta header\r\n");
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = -1;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ //for (i = FULL_SYSTEM;i<=FULL_BL33;i++){
+
+ for (i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++){
+ if (fota_status.update_status[i].need_update ==1) {
+ fota_status.ota_run = i;
+ fota_status.update_status[i].check_delta = ERROR;
+ fota_status.update_status[i].check_rom= WAIT;
+ fota_status.update_status[i].update_result= ERROR;
+ }
+ }
+ fota_status.update_result = ERROR;
+ save_fota_status();
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ }
+
+
+
+ delta_offset = DELTA_HEARD_SIZE + delta_size + DELTA_FULL_HEARD_SIZE;
+
+ for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++) {
+
+ if (i>MAX_OTA_ROLE/2) {
+ delta_offset+=delta_head[i-1];
+ }
+ if(delta_head[i]>0) {
+
+ if(current_slot==SLOT_B) {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i-MAX_OTA_ROLE/2]);
+ } else {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i-MAX_OTA_ROLE/2]);
+ }
+ system(cmd_sys);
+
+ if(current_slot==SLOT_B) {
+ fd_partition_a = mtk_device_wrap_open(partition_filename_a[i-MAX_OTA_ROLE/2],O_RDWR);
+ if (fd_partition_a < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ fd_curr = fd_partition_a;
+ }else{
+ fd_partition_b = mtk_device_wrap_open(partition_filename_b[i-MAX_OTA_ROLE/2],O_RDWR);
+ if (fd_partition_b < 0) {
+ err = errno;
+ RLOGD("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ fd_curr = fd_partition_b;
+ }
+ fota_status.ota_run = i+1;
+ save_fota_status();
+ up_info.ota_run = i+1;
+ save_fota_info();
+ retry_cnt = 0;
+ RLOGD("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
+ do{
+ status = delta_copyto_nand(delta_offset,delta_head[i]);
+
+ ROCK_SHA_FILE_COMMON(fd_delta,delta_offset,delta_head[i],digest_s);
+ ROCK_SHA_FILE(fd_curr,0,delta_head[i],digest_t);
+ retry_cnt++;
+ }while((strncmp(digest_s,digest_t,SHA_DIGEST_SIZE)!=0)&&(retry_cnt <= 3));
+
+ mtk_device_wrap_close(fd_curr);
+
+ RLOGD("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
+
+ if (retry_cnt>3) {
+ if (status == 0) {
+ status = retry_cnt;
+ }
+ if(current_slot==SLOT_B) {
+ nand_copyto_nand(partition_filename_b[i-MAX_OTA_ROLE/2],partition_filename_a[i-MAX_OTA_ROLE/2]);
+ }
+ else{
+ nand_copyto_nand(partition_filename_a[i-MAX_OTA_ROLE/2],partition_filename_b[i-MAX_OTA_ROLE/2]);
+ }
+ }
+
+ RLOGD("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
+
+ fota_status.update_result = status;
+ fota_status.update_status[i].update_result = status;
+ save_fota_status();
+
+ if (status != 0)
+ {
+
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return status;
+ }
+
+ }
+
+ }
+
+
+
+
+ if(update_mode != MODE_NORMAL){ //need backup
+ if(current_slot == SLOT_A) {
+ up_info.fota_flag[0] = 'B';
+ up_info.fota_flag[1] = '-';
+ up_info.fota_flag[2] = 'A';
+
+ }else{
+ up_info.fota_flag[0] = 'A';
+ up_info.fota_flag[1] = '-';
+ up_info.fota_flag[2] = 'B';
+
+ }
+
+ }else{
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+
+ }
+
+
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ //close_dev_fd(fd_curr);
+
+
+
+ close(fd_update_status);
+ sync();
+
+
+ slot = (current_slot == 0) ? 1 : 0;
+
+ RLOGD("+[UA]: slot SLOT = %d\n",slot);
+
+ if(switch_slot_flag==1)
+ {
+ module->setActiveBootSlot(module,slot);
+ RLOGD("+[UA]: upgrade is success!!!!\n");
+ }
+
+ fota_status.ota_run = 0;
+ fota_status.switch_slot = PASS;
+ fota_status.update_result = status;
+ save_fota_status();
+
+ sleep(5);
+ sync();
+ sleep(5);
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+
+ if(reboot_flag==1){
+ reboot_device();
+ }
+
+ return status;
+}
+
+
+
+static void rock_fail_handler()
+{
+ int ret = 0;
+ RLOGD("rock_fail_handler start\n");
+ //ret = rock_update_main(0, 0, 0, 0, 1, 1);
+ if(ret)
+ {
+ RLOGD("fota update fail again!\n");
+ }
+}
+
+/* main entrpoint */
+int lynq_rock_main(int first_run)
+{
+
+ int ret = 0;
+
+#if 0
+
+ printf("-********copy delta ***-\n");
+ test_write_delta("/data/delta",DEV_DELTA);
+
+#endif
+
+ ret = rock_update_main(0, 0, 0, 0, first_run, 1, 1, 1);
+ RLOGD("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ return ret;
+}
+
+#endif
+
+//xf.li@20230403 add for verfy start
+int lynq_file_md5_verfy(char *source, unsigned char *source_md5, char *target)
+{
+ int fd, size, ret, is_system = 0;
+ int need_copy = 1;
+ int system_mtd_num = 0;
+ int system_ubi_num = BACKUP_UBI_NUM;//max ubi number
+ char cmd_ubi_attach[128] = {0};
+ char cmd_ubi_detach[128] = {0};
+ char md5_target_file_patch[128] = {0};
+
+ RLOGD("in lynq_file_md5_verfy, source:%s, target:%s\n", source, target);
+ if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ RLOGD("verfy system.img\n");
+ is_system = 1;
+ if(strcmp(source, DEV_SYSTEM_A) == 0)
+ {
+ system_mtd_num = MTD_SYSTEM_B;
+ }
+ else if(strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ system_mtd_num = MTD_SYSTEM_A;
+ }
+ else
+ {
+ RLOGD("source:%s, target:%s\n", source, target);
+ }
+ for( ; system_ubi_num >= 10; system_ubi_num--)//try from ubi31 to ubi10
+ {
+ sprintf(md5_target_file_patch, "/dev/ubi%d", system_ubi_num);
+ RLOGD("ubi_num = %d\n", system_ubi_num);
+ if((access(md5_target_file_patch, F_OK)) == -1)
+ {
+ RLOGD("no the ubi file, can use this ubi.\n");
+ break;
+ }
+ }
+ if(system_ubi_num < 10)
+ {
+ RLOGE("no the ubi file, can use this ubi.\n");
+ return -1;
+ }
+ }
+ //=========================caculate md5sum start=====================
+ if(is_system == 1)
+ {
+ RLOGD("in system caculate\n");
+ RLOGD("system_mtd_num = %d, ubi_num = %d\n", system_mtd_num, system_ubi_num);
+ sprintf(cmd_ubi_attach, "ubiattach /dev/ubi_ctrl -m %d -d %d", system_mtd_num, system_ubi_num);
+ RLOGD("cmd_ubi_attach:%s", cmd_ubi_attach);
+ ret = system(cmd_ubi_attach);
+ if(ret != 0)
+ {
+ RLOGE("ubi attach error!!!\n");
+ return need_copy;
+ }
+ RLOGD("attach over\n");
+ //attach success
+ sprintf(md5_target_file_patch, "/dev/ubi%d_0", system_ubi_num);
+ RLOGD("md5_target_file_patch:%s", md5_target_file_patch);
+ //make sure the ubi volume is exist
+ if((access(md5_target_file_patch, F_OK)) == -1)
+ {
+ RLOGD("no the ubi file.\n");
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+
+ return need_copy;
+ }
+ //calculate md5sum
+ //ret = lynq_md5_two_file_verfy("/dev/ubi0_0", md5_target_file_patch);
+ ret = lynq_md5_file_verfy_ab(md5_target_file_patch, source_md5);
+ if(ret == MD5_VERFY_ERROR)
+ {
+ //ubidetach
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+ return need_copy;
+ }
+ if(ret != 0)
+ {
+ //ubidetach
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+ RLOGD("calculate system error!!!\n");
+ return -1;
+ }
+
+ RLOGD("verfy system.img over\n");
+ }
+ else
+ {
+ RLOGD("verfy else img\n");
+ //calculate md5sum
+ //ret = lynq_md5_two_file_verfy(source, target);
+ ret = lynq_md5_file_verfy_ab(target, source_md5);
+ if(ret == MD5_VERFY_ERROR)
+ {
+ return need_copy;
+ }
+ if(ret != 0)
+ {
+ RLOGD("calculate %s and %s error!!!\n", source, target);
+ return -1;
+ }
+ }
+ //====================caculate md5sum end======================
+ return 0;
+}
+//xf.li@20230403 add for verfy end
+
+
+//xf.li@20230401 add for ab rollback start
+
+int backup_nand_copyto_nand(char *source, char *target)
+{
+ int fd_source, fd_target, size;
+ int ret = -1;
+ int sleep_count = 0;
+ char cmd_erase_target[128] = {0};
+ int retry = MD5_RETRY_TIME;
+ unsigned char source_md5[MD5_READ_BUFFER_LEN] = {0};
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+ //caclculate source md5 start
+ if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ RLOGD("backup_nand_copyto_nand: verfy system.img\n");
+
+ ret = calculate_file_md5_value("/dev/ubi0_0", source_md5);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("source_md5 is %s\n", source_md5);
+ }
+ else
+ {
+ ret = calculate_file_md5_value(source, source_md5);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("source_md5 is %s\n", source_md5);
+ }
+ //caclculate source md5 end
+ //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+ ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+ RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+ if(ret == 0)
+ {
+ RLOGD("+[UA]: nand_copyto_nand don't neet copy\n");
+ }
+ for(; ret > 0 && retry > 0; retry--)
+ {
+ //erase nand-target start
+ if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+ {
+ RLOGD("+[UA]: fota runing\n");
+ return -1;
+ }
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+ RLOGD("+[UA]: ready to flash_erase\n");
+ sprintf(cmd_erase_target, "flash_erase %s 0 0", target);
+ ret = system(cmd_erase_target);
+ release_wake_lock("ab_recover");//unlock
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: erase %s fail\n", target);
+ return -1;
+ }
+ sleep(1);//sleep 1s
+
+ //erase nand-target end
+ RLOGD("+[UA]: ready to copy\n");
+ fd_source = mtk_device_wrap_open(source, O_RDONLY);
+ if (fd_source < 0) {
+ RLOGD("+[UA]: open source error\n");
+ return -1;
+ }
+
+ fd_target = mtk_device_wrap_open(target, O_RDWR);
+ if (fd_target < 0) {
+ RLOGD("+[UA]: open target error\n");
+ return -1;
+ }
+ ret = 0;//init ret
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+ while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0)
+ {
+ if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+ {
+ RLOGD("+[UA]: fota runing\n");
+ ret = -1;
+ break;
+ }
+ usleep(40000);//sleep 40ms
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ usleep(60000);//sleep 60ms
+ sleep_count++;
+ if(sleep_count >= 20)
+ {
+ //unlock
+ release_wake_lock("ab_recover");
+ sleep(1);//sleep 1s
+ //lock
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");
+ sleep_count = 0;
+ RLOGD("+[UA]: try sleep one time");
+ }
+ }
+ release_wake_lock("ab_recover");//unlock
+ RLOGD("+[UA]: copy end\n");
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ if(ret < 0)
+ {
+ RLOGD("+[UA]: ret < 0\n");
+ return -1;
+ }
+ RLOGD("+[UA]: ready to md5_verfy\n");
+ //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+ ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+ RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+ if(ret == 0)
+ {
+ RLOGD("+[UA]: nand_copyto_nand copy success\n");
+ break;
+ }
+ }
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: md5_file_verfy FAIL!!!\n");
+ }
+ return ret;
+}
+//xf.li@20230401 add for ab rollback end
+
+//xf.li@20230822 add for ab rollback start
+
+int lynq_backup_main()
+{
+ const hw_module_t* hw_module;
+ hw_module = &HAL_MODULE_INFO_SYM;
+ int is_successful;
+ int ret = 0;
+ if (!hw_module || strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0)
+ {
+ ret = -1;
+ }
+ RLOGD("ret = %d\n", ret);
+ if (ret != 0)
+ {
+ RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+ if (module == NULL)
+ {
+ RLOGD("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+ lynq_init_wake_lock_func();
+ current_slot = module->getCurrentSlot(module);
+ is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+ RLOGD("+[UA]: Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+ fota_interrupt = RECOVER_FIRST;
+ if(current_slot==SLOT_B)
+ {
+ ret = backup_nand_copyto_nand(DEV_SPM_B,DEV_SPM_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup spm_a fail\n");
+ return 1;
+ }
+ fota_interrupt = FOTA_FIRST;
+ ret = backup_nand_copyto_nand(DEV_SYSTEM_B,DEV_SYSTEM_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup system_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BOOT_B,DEV_BOOT_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup boot_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_TEE_B,DEV_TEE_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup tee_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MD1IMG_B,DEV_MD1IMG_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup md1img_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_VBMETA_B,DEV_VBMETA_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup vbmeta_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MEDMCU_B,DEV_MEDMCU_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup medmcu_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL2_B,DEV_BL2_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl2_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL33_B,DEV_BL33_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl33_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP_B,DEV_OEMAPP_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP2_B,DEV_OEMAPP2_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp2_a fail\n");
+ return 1;
+ }
+ }
+ else
+ {
+ ret = backup_nand_copyto_nand(DEV_SPM_A,DEV_SPM_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup spm_a fail\n");
+ return 1;
+ }
+ fota_interrupt = FOTA_FIRST;
+ ret = backup_nand_copyto_nand(DEV_SYSTEM_A,DEV_SYSTEM_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup system_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BOOT_A,DEV_BOOT_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup boot_b fail\n");
+ return 1;
+ }
+
+ ret = backup_nand_copyto_nand(DEV_TEE_A,DEV_TEE_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup tee_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MD1IMG_A,DEV_MD1IMG_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup md1img_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_VBMETA_A,DEV_VBMETA_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup vbmeta_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MEDMCU_A,DEV_MEDMCU_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup medmcu_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL2_A,DEV_BL2_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl2_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL33_A,DEV_BL33_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl33_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP_A,DEV_OEMAPP_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP2_A,DEV_OEMAPP2_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp2_b fail\n");
+ return 1;
+ }
+ }
+ RLOGD("+[UA]: lynq_backup_main success \n");
+ return 0;
+}
+//xf.li@20230822 add for ab rollback end
+
+
+int lynq_check_oemapp(char* name)
+{
+ FILE *fp;
+ char check_result[64];
+ if(strcmp(name, "oemapp") == 0)
+ {
+ RLOGD("lynq_check_oemapp oemapp");
+ if(system("df -lh|grep oemapp |grep -v oemapp2") != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if(strcmp(name, "oemapp2") == 0)
+ {
+ RLOGD("lynq_check_oemapp oemapp2");
+ if(system("df -lh|grep oemapp2") != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+}
+
+//lt add @2021.9.23 for deal with power down \ backup or upgrade.
+int lynq_fota_func(void)
+{
+ int fd;
+ int first_run = 1;
+ int ret = 0;
+ UPDATE_INFO lynq_up_info;
+ //xf.li@20230822 add for ab backup start
+ unsigned int current_slot, other_slot;
+ int is_other_slot_bootable;
+ const hw_module_t* hw_module;
+ //xf.li@20230822 add for ab backup end
+ RLOGD("[+UP]: ******lynq_fota_func start******\n");
+ //xf.li@20230822 add for ab backup start
+ //----------get current slot and whether other slot is bootable
+ hw_module = &HAL_MODULE_INFO_SYM;
+ if (!hw_module ||
+ strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+ ret = -EINVAL;
+ }
+ if (ret != 0) {
+ RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+ if (module == NULL) {
+ RLOGD("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+ current_slot = module->getCurrentSlot(module);
+ other_slot = (current_slot == 0) ? 1 : 0;
+ is_other_slot_bootable = module->isSlotBootable(module, other_slot);
+ //-----------end
+ RLOGD("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
+ //xf.li@20230822 add for ab backup end
+
+ memset(&lynq_up_info, 0, sizeof(lynq_up_info));
+ fd = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+ if (fd < 0)
+ {
+ return -1;
+ }
+ read(fd,(unsigned char *)&lynq_up_info,sizeof(lynq_up_info));
+ close(fd);
+
+ RLOGD("[+UP]: lynq_up_info.ota_run=%d\n",lynq_up_info.ota_run);
+ if((lynq_check_oemapp("oemapp") == 0) || (lynq_check_oemapp("oemapp2") == 0))
+ {
+ RLOGD("ENTER LYNQ_CHECK_OEMAPP\n");
+ system("echo mode 001 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo dir 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo out 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ RLOGD("need setUnbootable.\n");
+ module->setSlotAsUnbootable(module,current_slot);
+ RLOGD("+[UA]: setSlotAsUnbootable!!!!\n");
+ sync();
+ if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+ ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+ {
+ RLOGD("mark oemapp mount fail\n");
+ lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_STATE, "1");
+ }
+ sleep(5);
+ reboot_device();
+ }
+
+
+ if(lynq_up_info.ota_run != 0)
+ {
+ //Power off, call UA
+ RLOGD("[+UP]: ***Power off, call UA***\n");
+ ret = rock_update_main(0, 0, 0, 0, first_run, 1, 0, 1);
+ RLOGD("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ }
+
+ if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+ ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+ {
+ //Upgrade the other side and call UA
+ RLOGD("[+UP]: ***Upgrade the other side and call UA***\n");
+ ret = rock_update_main(0, 0, 0, 0, first_run, 0, 0, 0);
+ RLOGD("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ }
+ //xf.li@20230822 add for ab backup start
+ else if(is_other_slot_bootable == 0)
+ {
+ RLOGD("need backup\n");
+ ret = lynq_backup_main();
+ if(ret != 0)
+ {
+ RLOGD("ERROE: backup fail!!!\n");
+ }
+ else
+ {
+ RLOGD("backup success!!!\n");
+ module->setCompleteBackup(module, current_slot);
+ }
+ }
+ else
+ {
+ RLOGD("Don't need backup\n");
+ }
+ //xf.li@20230822 add for ab backup end
+
+ return 0;
+}
+
+int lynq_nand_open(const char *pathname, int flags)
+{
+// printf("pathname:%s---flags:%d",pathname,flags);
+ return open(pathname,flags);
+}
+
+ssize_t lynq_nand_read(int fd, void *buf, size_t count)
+{
+// printf("rfd:%d---buf:%s---count:%d",fd,buf,count);
+ return read(fd,buf,count);
+}
+
+ssize_t lynq_nand_write(int fd, void *buf, size_t count)
+{
+ // printf("wfd:%d---buf:%s---count:%d",fd,buf,count);
+ return write(fd,buf,count);
+}
+
+int lynq_nand_close(int fd)
+{
+ return close(fd);
+}
+
+/**
+ * @brief Obtain the upgrade result
+ *
+ * @param void
+ * @return 0xff:open file fail,0:upgrade success,1,upgrade wait
+ */
+ int lynq_get_upgrade_status(void)
+{
+ int lynq_state_fd;
+ int lynq_upgrade_wait = 1;
+ OTA_STATUS lynq_ota_status;
+
+ memset(&lynq_ota_status, 0, sizeof(lynq_ota_status));
+
+ lynq_state_fd = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+ if (lynq_state_fd < 0)
+ {
+ return 0xff;
+ }
+ read(lynq_state_fd,(unsigned char *)&lynq_ota_status,sizeof(lynq_ota_status));
+ close(lynq_state_fd);
+ if((lynq_ota_status.ota_run != 0) && (lynq_ota_status.update_result == 0))
+ {
+ return lynq_upgrade_wait;
+ }
+ return lynq_ota_status.update_result;
+}
+
+/**
+ * @brief reboot device
+ *
+ * @param void
+ * @return void
+ */
+ void lynq_reboot_device(void)
+{
+ reboot_device();
+ return ;
+}
+
+/**
+ * @brief fota no resatrt
+ *
+ * @param void
+ * @return 0:fota success -Other values:fota fail
+ */
+
+int lynq_fota_nrestart(void)
+{
+
+ int ret = 0;
+#if 0
+ printf("-********copy delta ***-\n");
+ test_write_delta("/data/delta",DEV_DELTA);
+#endif
+
+ ret = rock_update_main(0, 0, 0, 0, 1, 1, 0, 1);
+ RLOGD("rock_update_nrestart ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ return ret;
+}
+
+/**
+ * @brief Set the upgrade package address
+ *
+ * @param1 value:fota addr
+ * @param1 szie:fota addr length
+ * @return 0:set success other:set fail
+ */
+int lynq_fota_set_addr_value(char *value,int size)
+{
+ if(size < 64)
+ {
+ return lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_ADDR, value);
+ }
+ return -1;
+}
+/**
+ * @brief get the upgrade package address
+ *
+ * @param1 value:fota addr
+ * @return 0:get success other:set fail
+ */
+int lynq_fota_get_addr_value(char *tmp)
+{
+ return lynq_get_value(FOTA_UCI_FILE, FOTA_UCI_MODULE,FOTA_UCI_ADDR, tmp);
+}
+
+/**
+ * @brief Porting wakes up the demo content
+ */
+static void lynq_init_wake_lock_func(void)
+{
+ const char *lynqLibPath_WakeLock = "/usr/lib64/libpower.so";
+
+ dlHandle_wakelock = dlopen(lynqLibPath_WakeLock, RTLD_NOW);
+ if (dlHandle_wakelock == NULL)
+ {
+ printf("dlopen lynqLibPath_WakeLock failed: %s", dlerror());
+ exit(EXIT_FAILURE);
+ }
+
+ acquire_wake_lock = (int(*)(int,const char*))dlsym(dlHandle_wakelock, "acquire_wake_lock");
+ if (acquire_wake_lock == NULL) {
+ printf("acquire_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+ exit(EXIT_FAILURE);
+ }
+ release_wake_lock = (int(*)( const char*))dlsym(dlHandle_wakelock, "release_wake_lock");
+ if (release_wake_lock == NULL) {
+ printf("release_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+ exit(EXIT_FAILURE);
+ }
+ dlerror(); // Clear any previous dlerror
+
+ return;
+}
+
+/**
+ * @brief fota wake lock
+ *
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_grab_artial_wake_lock(void)
+{
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+}
+
+/**
+ * @brief get the upgrade package address
+ *
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_release_wake_lock(void)
+{
+ release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+}
+/**
+ * @brief This is the wake up call
+ * end
+ */
diff --git a/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c b/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c
new file mode 100755
index 0000000..5ac6b53
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-fota/rock_ua/sha.c
@@ -0,0 +1,428 @@
+/* sha.c
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Google Inc. nor the names of its contributors may
+** be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "sha.h"
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mtk_device_wrap.h"
+
+// Some machines lack byteswap.h and endian.h. These have to use the
+// slower code, even if they're little-endian.
+
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#include <byteswap.h>
+#include <memory.h>
+
+
+
+// This version is about 28% faster than the generic version below,
+// but assumes little-endianness.
+
+static inline uint32_t ror27(uint32_t val) {
+ return (val >> 27) | (val << 5);
+}
+static inline uint32_t ror2(uint32_t val) {
+ return (val >> 2) | (val << 30);
+}
+static inline uint32_t ror31(uint32_t val) {
+ return (val >> 31) | (val << 1);
+}
+
+static void SHA1_Transform(SHA_CTX* ctx) {
+ uint32_t W[80];
+ register uint32_t A, B, C, D, E;
+ int t;
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+#define SHA_F1(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = bswap_32(ctx->buf.w[t])) + \
+ (D^(B&(C^D))) + 0x5A827999; \
+ B = ror2(B);
+
+ for (t = 0; t < 15; t += 5) {
+ SHA_F1(A,B,C,D,E,t + 0);
+ SHA_F1(E,A,B,C,D,t + 1);
+ SHA_F1(D,E,A,B,C,t + 2);
+ SHA_F1(C,D,E,A,B,t + 3);
+ SHA_F1(B,C,D,E,A,t + 4);
+ }
+ SHA_F1(A,B,C,D,E,t + 0); // 16th one, t == 15
+
+#undef SHA_F1
+
+#define SHA_F1(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (D^(B&(C^D))) + 0x5A827999; \
+ B = ror2(B);
+
+ SHA_F1(E,A,B,C,D,t + 1);
+ SHA_F1(D,E,A,B,C,t + 2);
+ SHA_F1(C,D,E,A,B,t + 3);
+ SHA_F1(B,C,D,E,A,t + 4);
+
+#undef SHA_F1
+
+#define SHA_F2(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (B^C^D) + 0x6ED9EBA1; \
+ B = ror2(B);
+
+ for (t = 20; t < 40; t += 5) {
+ SHA_F2(A,B,C,D,E,t + 0);
+ SHA_F2(E,A,B,C,D,t + 1);
+ SHA_F2(D,E,A,B,C,t + 2);
+ SHA_F2(C,D,E,A,B,t + 3);
+ SHA_F2(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F2
+
+#define SHA_F3(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \
+ B = ror2(B);
+
+ for (; t < 60; t += 5) {
+ SHA_F3(A,B,C,D,E,t + 0);
+ SHA_F3(E,A,B,C,D,t + 1);
+ SHA_F3(D,E,A,B,C,t + 2);
+ SHA_F3(C,D,E,A,B,t + 3);
+ SHA_F3(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F3
+
+#define SHA_F4(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (B^C^D) + 0xCA62C1D6; \
+ B = ror2(B);
+
+ for (; t < 80; t += 5) {
+ SHA_F4(A,B,C,D,E,t + 0);
+ SHA_F4(E,A,B,C,D,t + 1);
+ SHA_F4(D,E,A,B,C,t + 2);
+ SHA_F4(C,D,E,A,B,t + 3);
+ SHA_F4(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F4
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX* ctx, const void* data, int len) {
+ int i = ctx->count % sizeof(ctx->buf);
+ const uint8_t* p = (const uint8_t*)data;
+
+ ctx->count += len;
+
+ while (len > sizeof(ctx->buf) - i) {
+ memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
+ len -= sizeof(ctx->buf) - i;
+ p += sizeof(ctx->buf) - i;
+ SHA1_Transform(ctx);
+ i = 0;
+ }
+
+ while (len--) {
+ ctx->buf.b[i++] = *p++;
+ if (i == sizeof(ctx->buf)) {
+ SHA1_Transform(ctx);
+ i = 0;
+ }
+ }
+}
+
+
+const uint8_t* SHA_final(SHA_CTX* ctx) {
+ uint64_t cnt = ctx->count * 8;
+ int i;
+
+ SHA_update(ctx, (uint8_t*)"\x80", 1);
+ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+ SHA_update(ctx, (uint8_t*)"\0", 1);
+ }
+ for (i = 0; i < 8; ++i) {
+ uint8_t tmp = cnt >> ((7 - i) * 8);
+ SHA_update(ctx, &tmp, 1);
+ }
+
+ for (i = 0; i < 5; i++) {
+ ctx->buf.w[i] = bswap_32(ctx->state[i]);
+ }
+
+ return ctx->buf.b;
+}
+
+#else // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+static void SHA1_transform(SHA_CTX *ctx) {
+ uint32_t W[80];
+ uint32_t A, B, C, D, E;
+ uint8_t *p = ctx->buf;
+ int t;
+
+ for(t = 0; t < 16; ++t) {
+ uint32_t tmp = *p++ << 24;
+ tmp |= *p++ << 16;
+ tmp |= *p++ << 8;
+ tmp |= *p++;
+ W[t] = tmp;
+ }
+
+ for(; t < 80; t++) {
+ W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+ for(t = 0; t < 80; t++) {
+ uint32_t tmp = rol(5,A) + E + W[t];
+
+ if (t < 20)
+ tmp += (D^(B&(C^D))) + 0x5A827999;
+ else if ( t < 40)
+ tmp += (B^C^D) + 0x6ED9EBA1;
+ else if ( t < 60)
+ tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
+ else
+ tmp += (B^C^D) + 0xCA62C1D6;
+
+ E = D;
+ D = C;
+ C = rol(30,B);
+ B = A;
+ A = tmp;
+ }
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX *ctx, const void *data, int len) {
+ int i = ctx->count % sizeof(ctx->buf);
+ const uint8_t* p = (const uint8_t*)data;
+
+ ctx->count += len;
+
+ while (len--) {
+ ctx->buf[i++] = *p++;
+ if (i == sizeof(ctx->buf)) {
+ SHA1_transform(ctx);
+ i = 0;
+ }
+ }
+}
+const uint8_t *SHA_final(SHA_CTX *ctx) {
+ uint8_t *p = ctx->buf;
+ uint64_t cnt = ctx->count * 8;
+ int i;
+
+ SHA_update(ctx, (uint8_t*)"\x80", 1);
+ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+ SHA_update(ctx, (uint8_t*)"\0", 1);
+ }
+ for (i = 0; i < 8; ++i) {
+ uint8_t tmp = cnt >> ((7 - i) * 8);
+ SHA_update(ctx, &tmp, 1);
+ }
+
+ for (i = 0; i < 5; i++) {
+ uint32_t tmp = ctx->state[i];
+ *p++ = tmp >> 24;
+ *p++ = tmp >> 16;
+ *p++ = tmp >> 8;
+ *p++ = tmp >> 0;
+ }
+
+ return ctx->buf;
+}
+
+#endif // endianness
+
+void SHA_init(SHA_CTX* ctx) {
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+ ctx->state[4] = 0xC3D2E1F0;
+ ctx->count = 0;
+}
+
+/* Convenience function */
+const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
+ const uint8_t *p;
+ int i;
+
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+ SHA_update(&ctx, data, len);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+#define NAND_PAGE_SIZE_SHA 4096
+
+const uint8_t* ROCK_SHA_FILE_COMMON(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+ const uint8_t *p;
+ int i = 0;
+ //int fd_sha;
+ int size = 0;
+ int totale_size_common = totle_size;
+ char data[NAND_PAGE_SIZE_SHA];
+
+
+ lseek(fd_sha, offset, SEEK_SET);
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+
+ do{
+ if(totale_size_common >= NAND_PAGE_SIZE_SHA)
+ {
+ size = read(fd_sha,data,NAND_PAGE_SIZE_SHA);
+ }
+ else
+ {
+ size = read(fd_sha,data,totale_size_common);
+ }
+ if (size == 0){
+ break;
+ }
+ SHA_update(&ctx, data, size);
+ totale_size_common -= size;
+
+ }while(totale_size_common>0);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i)
+ {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+const uint8_t* ROCK_SHA_FILE(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+ const uint8_t *p;
+ int i = 0;
+ //int fd_sha;
+ int size = 0;
+ int totale_size_file = totle_size;
+ char data[NAND_PAGE_SIZE_SHA];
+
+
+ mtk_device_wrap_seek(fd_sha, offset, SEEK_SET);
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+
+ do{
+ if(totale_size_file >= NAND_PAGE_SIZE_SHA)
+ {
+ size = mtk_device_wrap_read(fd_sha,data,NAND_PAGE_SIZE_SHA);
+ }
+ else
+ {
+ size = mtk_device_wrap_read(fd_sha,data,totale_size_file);
+ }
+ if (size == 0){
+ break;
+ }
+ SHA_update(&ctx, data, size);
+ totale_size_file -= size;
+
+ }while(totale_size_file>0);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i)
+ {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+
+
+// Take a string 'str' of 40 hex digits and parse it into the 20
+// byte array 'digest'. 'str' may contain only the digest or be of
+// the form "<digest>:<anything>". Return 0 on success, -1 on any
+// error.
+int ParseSha1(const char* str, uint8_t* digest) {
+ int i;
+ const char* ps = str;
+ uint8_t* pd = digest;
+ for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
+ int digit;
+ if (*ps >= '0' && *ps <= '9') {
+ digit = *ps - '0';
+ } else if (*ps >= 'a' && *ps <= 'f') {
+ digit = *ps - 'a' + 10;
+ } else if (*ps >= 'A' && *ps <= 'F') {
+ digit = *ps - 'A' + 10;
+ } else {
+ return -1;
+ }
+ if (i % 2 == 0) {
+ *pd = digit << 4;
+ } else {
+ *pd |= digit;
+ ++pd;
+ }
+ }
+ if (*ps != '\0') return -1;
+ return 0;
+}
diff --git a/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h b/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h
new file mode 100755
index 0000000..362baaf
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/include/lynq_gnss.h
@@ -0,0 +1,122 @@
+#ifndef LYNQ_GNSS_H
+#define LYNQ_GNSS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gpshal.h"
+#include "hal2mnl_interface.h"
+
+typedef enum{
+ LYNQ_MODE_GPS_GLONASS = 0,
+ LYNQ_MODE_GPS_BEIDOU,
+ LYNQ_MODE_GPS_GLONASS_BEIDOU,
+ LYNQ_MODE_GPS,
+ LYNQ_MODE_BEIDOU,
+ LYNQ_MODE_GLONASS,
+ LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO,
+ LYNQ_MODE_GPS_GALILEO,
+ LYNQ_MODE_GPS_GLONASS_GALILEO,
+ LYNQ_MODE_GPS_GALILEO_ONLY,
+ LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC,
+ LYNQ_MODE_GNSS_END
+}LYNQ_GNSS_MODE_CONFIGURATION;
+
+typedef enum{
+ LYNQ_SWITCH_DISABLE = 0,
+ LYNQ_SWITCH_ENABLE
+}LYNQ_CONF_SWITCH;
+
+typedef struct {
+ GpsLocation legacyLocation;
+
+ float horizontalAccuracyMeters;
+
+ /**
+ * Represents expected vertical position accuracy in meters
+ * (68% confidence).
+ */
+ float verticalAccuracyMeters;
+
+ /**
+ * Represents expected speed accuracy in meter per seconds
+ * (68% confidence).
+ */
+ float speedAccuracyMetersPerSecond;
+
+ /**
+ * Represents expected bearing accuracy in degrees
+ * (68% confidence).
+ */
+ float bearingAccuracyDegrees;
+} lynq_GpsLocation_ext;
+
+typedef void (*gps_location_callback_ext)(lynq_GpsLocation_ext* location);
+
+// typedef void (* gps_status_callback)(GpsStatus* status);
+
+// typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
+
+// typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg);
+
+//typedef void (*gnss_measurement_ext_callback) (GnssData_ext* data);
+
+
+typedef struct
+{
+ size_t size;
+ gps_location_callback_ext lynq_location_cb;
+ gps_status_callback lynq_status_cb;
+ gps_nmea_callback lynq_nmea_cb;
+ gps_create_thread lynq_create_thread_cb;
+}lynq_gnss_cb;
+
+typedef struct
+{
+ size_t size;
+ gnss_measurement_ext_callback lynq_measurement_callback;
+}lynq_raw_gnss_cbs;
+
+typedef void ( *lynq_atsvc_incb )(const char *input,const int length);
+typedef void ( *lynq_atsvc_outcb )(char *output,int out_size,int type);
+lynq_atsvc_incb lynq_register_gnss(lynq_atsvc_outcb out_cb);
+lynq_atsvc_outcb atsvc_gnss_outcb;
+
+int lynq_gnss_init(void);
+
+int lynq_gnss_deinit(void);
+
+int lynq_gnss_callback_reg(lynq_gnss_cb* callbacks);
+
+int lynq_gnss_start(void);
+
+int lynq_gnss_stop(void);
+
+int lynq_gnss_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty);
+
+int lynq_gnss_inject_location(double latitude,double longitude,float accuracy);
+
+int lynq_gnss_delete_aiding_data(GpsAidingData flags);
+
+int lynq_gnss_inject_fused_location(double latitude,double longitude,float accuracy);
+
+int lynq_gnss_start_raw_meas_mode(lynq_raw_gnss_cbs* raw_gnss_cbs);
+
+int lynq_gnss_stop_raw_meas_mode();
+
+int lynq_gnss_set_start_mode(LYNQ_GNSS_MODE_CONFIGURATION start_mode);
+
+int lynq_gnss_epo_switch(LYNQ_CONF_SWITCH switch_op);
+
+int lynq_gnss_output_frequency_set(int frequency);
+
+int lynq_agps_set_enabled(LYNQ_CONF_SWITCH agps_status);
+
+int lynq_agps_get_enabled_status(int *status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/makefile b/IC_src/mtk/lib/liblynq-gnss/makefile
new file mode 100755
index 0000000..f1ca7fc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/makefile
@@ -0,0 +1,62 @@
+SHELL = /bin/sh
+RM = rm -f
+
+
+LOCAL_CFLAGS := \
+ -Wall \
+ -g \
+ -Wall \
+ -fPIC \
+ -shared \
+ -D__COMPILE_OPTION__ \
+ -D__LINUX_OS__ \
+
+CPPFLAGS=\
+ -std=c++11 \
+
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I$(LOCAL_PATH)/include \
+ -I$(ROOT)$(includedir)/gps_hal \
+ -I$(ROOT)$(includedir)/gps_hal/inc \
+ -I$(ROOT)$(includedir)/gps_hal/hardware \
+ -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lrt \
+ -llog \
+ -lutils \
+ -lcutils \
+ -lgnsshal \
+ -lpthread \
+# -llynq-log \
+
+$(warning libs=$(LOCAL_LIBS))
+
+CXXSRC=\
+
+SOURCES = $(wildcard *.c wildcard src/*.c)
+
+EXECUTABLE = liblynq-gnss.so
+
+COBJS=$(SOURCES:.c=.o)
+$(warning test)
+all: $(EXECUTABLE)
+$(EXECUTABLE): $(COBJS)
+ $(CXX) -shared -Wl,--no-undefined $(COBJS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o: %.c
+ $(warning ----->build $<)
+ $(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: install clean
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+
+clean:
+ rm -f $(EXECUTABLE) rm -rf *.o
+ find ./ -name *.o | xargs rm -rf
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c
new file mode 100644
index 0000000..b457941
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.c
@@ -0,0 +1,510 @@
+#include <stdio.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <log/log.h>
+
+
+#include "lynq_gnss.h"
+#include "lynq_agps.h"
+
+#define LOG_TAG "LYNQ_AGPS"
+
+
+// -1 means failure
+int do_socket_connect(const char* path)
+{
+ struct sockaddr_un addr;
+ int fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if(fd < 0) {
+ RLOGD("socket() failed fd=%d\n", fd);
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path + 1, path, strlen(path));
+ addr.sun_family = AF_UNIX;
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ RLOGD("connect failed reason=[%s] path=[%s]\n", strerror(errno), path);
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+//get
+char get_byte(char* buff, int* offset)
+{
+ char ret = buff[*offset];
+ *offset += 1;
+ return ret;
+}
+
+short get_short(char* buff, int* offset)
+{
+ short ret = 0;
+ ret |= get_byte(buff, offset) & 0xff;
+ ret |= (get_byte(buff, offset) << 8);
+ return ret;
+}
+
+int get_int(char* buff, int* offset)
+{
+ int ret = 0;
+ ret |= get_short(buff, offset) & 0xffff;
+ ret |= (get_short(buff, offset) << 16);
+ return ret;
+}
+
+int socket_connect() {
+ return do_socket_connect("agpsd2");
+}
+
+//-1 means failure
+static int safe_write(int fd, void* buf, int len)
+{
+ int n, retry = 10;
+
+ if(fd < 0 || buf == NULL || len < 0) {
+ RLOGD("safe_write fd=%d buf=%p len=%d\n", fd, buf, len);
+ return -1;
+ }
+
+ while((n = write(fd, buf, len)) != len) {
+ if(errno == EINTR) continue;
+ if(errno == EAGAIN) {
+ if(retry-- > 0) {
+ usleep(100 * 1000);
+ continue;
+ }
+ goto exit;
+ }
+ goto exit;
+ }
+ return n;
+exit:
+ RLOGD("safe_write reason=[%s]%d\n", strerror(errno), errno);
+ return -1;
+}
+
+//-1 means failure
+static int safe_read(int fd, void* buf, int len)
+{
+ int n, retry = 10;
+
+ if(fd < 0 || buf == NULL || len < 0)
+ {
+ RLOGD("safe_read fd=%d buf=%p len=%d\n", fd, buf, len);
+ return -1;
+ }
+
+ if(len == 0)
+ {
+ return 0;
+ }
+
+ while((n = read(fd, buf, len)) < 0)
+ {
+ if(errno == EINTR)
+ {
+ RLOGD("safe read interrupt");
+ continue;
+ }
+ if(errno == EAGAIN)
+ {
+ if(retry-- > 0)
+ {
+ usleep(100 * 1000);
+ continue;
+ }
+ goto exit;
+ }
+ goto exit;
+ }
+ return n;
+
+exit:
+ if(errno != EAGAIN)
+ {
+ RLOGD("safe_read reason=[%s] fd=%d len=%d buf=%p\n",
+ strerror(errno), fd, len, buf);
+ }
+ return -1;
+}
+
+static char socket_get_byte(int fd)
+{
+ int read_len = 0;
+ char buff[1] = {0};
+ int offset = 0;
+
+ read_len = safe_read(fd, buff, sizeof(buff));
+ if(read_len != sizeof(buff))
+ {
+ RLOGD("socket_get_byte read_len=%d\n", read_len);
+ }
+ return get_byte(buff, &offset);
+}
+
+static int socket_get_int(int fd)
+{
+ int read_len = 0;
+ char buff[4] = {0};
+ int offset = 0;
+
+ read_len = safe_read(fd, buff, sizeof(buff));
+ if(read_len != sizeof(buff))
+ {
+ RLOGD("socket_get_int read_len=%d\n", read_len);
+ }
+ return get_int(buff, &offset);
+}
+
+static char* socket_get_string(int fd, char* buff, int buff_len)
+{
+ int read_len = 0;
+
+ char ret = socket_get_byte(fd);
+ if(ret == 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ int len = socket_get_int(fd);
+ if(len > buff_len)
+ {
+ RLOGD("socket_get_string your buff len=%d is too small, need len=%d\n",
+ buff_len, len);
+ return NULL;
+ }
+
+ read_len = safe_read(fd, buff, len);
+ if(read_len != len)
+ {
+ RLOGD("socket_get_string read_len=%d len=%d\n", read_len, len);
+ return NULL;
+ }
+
+ return buff;
+ }
+}
+
+
+static int socket_get_binary(int fd, char* buff)
+{
+ int read_len = 0;
+
+ int len = socket_get_int(fd);
+ if(len > 0)
+ {
+ read_len = safe_read(fd, buff, len);
+ if(read_len != len)
+ {
+ RLOGD("socket_get_binary read_len=%d len=%d\n", read_len, len);
+ return 0;
+ }
+ }
+ return len;
+}
+
+void put_byte(char* buff, int* offset, const char input)
+{
+ *((char*)&buff[*offset]) = input;
+ *offset += 1;
+}
+
+void put_short(char* buff, int* offset, const short input)
+{
+ put_byte(buff, offset, input & 0xff);
+ put_byte(buff, offset, (input >> 8) & 0xff);
+}
+
+void put_int(char* buff, int* offset, const int input)
+{
+ put_short(buff, offset, input & 0xffff);
+ put_short(buff, offset, (input >> 16) & 0xffff);
+}
+
+int set_template_1(app_mgr_cmd_enum cmd,char data)
+{
+ char buff[MAX_BUFF_SIZE] = {0};
+ int offset = 0;
+ int fd = 0;
+
+ fd = socket_connect();
+ if(fd < 0)
+ {
+ RLOGD("Socket connect fail");
+ return -1;
+ }
+ RLOGD("Set template start fd:%d cmd:%d data:%d",fd,cmd,data);
+ // write
+ put_int(buff, &offset, cmd);
+ put_byte(buff, &offset, data);
+ if(safe_write(fd, buff, offset) == -1)
+ {
+ RLOGD("set_template_1 Safe write fail");
+ close(fd);
+ return -1;
+ }
+
+ // read ACK
+ socket_get_byte(fd);
+
+ close(fd);
+ return 0;
+}
+
+int get_template_agps_config(app_mgr_cmd_enum cmd,agps_intf_agps_config *config)
+{
+ char buff[MAX_BUFF_SIZE] = {0};
+ int offset = 0;
+ int fd = 0;
+
+ fd = socket_connect();
+ if(fd < 0)
+ {
+ RLOGD("Socket connect fail");
+ return -1;
+ }
+ RLOGD("get_template_agps_config start fd:%d cmd:%d",fd,cmd);
+
+ // write
+ put_int(buff, &offset, cmd);
+ if(safe_write(fd, buff, offset) == -1)
+ {
+ RLOGD("get_template_agps_config Safe write fail");
+ close(fd);
+ return -1;
+ }
+
+ // read
+ config->agps_setting.agps_enable = socket_get_byte(fd);
+ config->agps_setting.agps_protocol = socket_get_int(fd);
+ config->agps_setting.gpevt = socket_get_byte(fd);
+
+ config->cp_setting.molr_pos_method = socket_get_int(fd);
+ config->cp_setting.external_addr_enable = socket_get_byte(fd);
+ socket_get_string(fd, config->cp_setting.external_addr, sizeof(config->cp_setting.external_addr));
+ config->cp_setting.mlc_number_enable = socket_get_byte(fd);
+ socket_get_string(fd, config->cp_setting.mlc_number, sizeof(config->cp_setting.mlc_number));
+ config->cp_setting.cp_auto_reset = socket_get_byte(fd);
+ config->cp_setting.epc_molr_lpp_payload_enable = socket_get_byte(fd);
+ config->cp_setting.epc_molr_lpp_payload_len =
+ socket_get_binary(fd, config->cp_setting.epc_molr_lpp_payload);
+
+ config->up_setting.ca_enable = socket_get_byte(fd);
+ config->up_setting.ni_request = socket_get_byte(fd);
+ config->up_setting.roaming = socket_get_byte(fd);
+ config->up_setting.cdma_preferred = socket_get_int(fd);
+ config->up_setting.pref_method = socket_get_int(fd);
+ config->up_setting.supl_version = socket_get_int(fd);
+ config->up_setting.tls_version = socket_get_int(fd);
+ config->up_setting.supl_log = socket_get_byte(fd);
+ config->up_setting.msa_enable = socket_get_byte(fd);
+ config->up_setting.msb_enable = socket_get_byte(fd);
+ config->up_setting.ecid_enable = socket_get_byte(fd);
+ config->up_setting.otdoa_enable = socket_get_byte(fd);
+ config->up_setting.qop_hacc = socket_get_int(fd);
+ config->up_setting.qop_vacc = socket_get_int(fd);
+ config->up_setting.qop_loc_age = socket_get_int(fd);
+ config->up_setting.qop_delay = socket_get_int(fd);
+ config->up_setting.lpp_enable = socket_get_byte(fd);
+ config->up_setting.cert_from_sdcard = socket_get_byte(fd);
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V14)
+ {
+ config->up_setting.auto_profile_enable = socket_get_byte(fd);
+ config->up_setting.ut2 = socket_get_byte(fd);
+ config->up_setting.ut3 = socket_get_byte(fd);
+ config->up_setting.apn_enable = socket_get_byte(fd);
+ config->up_setting.sync_to_slp = socket_get_byte(fd);
+ config->up_setting.udp_enable = socket_get_byte(fd);
+ config->up_setting.autonomous_enable = socket_get_byte(fd);
+ config->up_setting.aflt_enable = socket_get_byte(fd);
+ config->up_setting.imsi_enable = socket_get_byte(fd);
+
+ config->gnss_setting.sib8_sib16_enable = socket_get_byte(fd);
+ config->gnss_setting.gps_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.glonass_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.beidou_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.galileo_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.gps_satellite_support = socket_get_byte(fd);
+ config->gnss_setting.glonass_satellite_support = socket_get_byte(fd);
+ config->gnss_setting.beidou_satellite_support = socket_get_byte(fd);
+ config->gnss_setting.galileo_satellite_support = socket_get_byte(fd);
+
+ config->up_setting.supl_ver_minor = socket_get_byte(fd);
+ config->up_setting.supl_ver_ser_ind = socket_get_byte(fd);
+
+ config->gnss_setting.a_glonass_satellite_enable = socket_get_byte(fd);
+ }
+
+ socket_get_string(fd, config->cur_supl_profile.name, sizeof(config->cur_supl_profile.name));
+ socket_get_string(fd, config->cur_supl_profile.addr, sizeof(config->cur_supl_profile.addr));
+ config->cur_supl_profile.port = socket_get_int(fd);
+ config->cur_supl_profile.tls = socket_get_byte(fd);
+ socket_get_string(fd, config->cur_supl_profile.mcc_mnc, sizeof(config->cur_supl_profile.mcc_mnc));
+ socket_get_string(fd, config->cur_supl_profile.app_id, sizeof(config->cur_supl_profile.app_id));
+ socket_get_string(fd, config->cur_supl_profile.provider_id, sizeof(config->cur_supl_profile.provider_id));
+ socket_get_string(fd, config->cur_supl_profile.default_apn, sizeof(config->cur_supl_profile.default_apn));
+ socket_get_string(fd, config->cur_supl_profile.optional_apn, sizeof(config->cur_supl_profile.optional_apn));
+ socket_get_string(fd, config->cur_supl_profile.optional_apn_2, sizeof(config->cur_supl_profile.optional_apn_2));
+ socket_get_string(fd, config->cur_supl_profile.address_type, sizeof(config->cur_supl_profile.address_type));
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V14)
+ {
+ socket_get_string(fd, config->cdma_profile.name, sizeof(config->cdma_profile.name));
+ config->cdma_profile.mcp_enable = socket_get_byte(fd);;
+ socket_get_string(fd, config->cdma_profile.mcp_addr, sizeof(config->cdma_profile.mcp_addr));
+ config->cdma_profile.mcp_port = socket_get_int(fd);;
+ config->cdma_profile.pde_addr_valid = socket_get_byte(fd);;
+ config->cdma_profile.pde_ip_type = socket_get_int(fd);;
+ socket_get_string(fd, config->cdma_profile.pde_addr, sizeof(config->cdma_profile.pde_addr));
+ config->cdma_profile.pde_port = socket_get_int(fd);;
+ config->cdma_profile.pde_url_valid = socket_get_byte(fd);;
+ socket_get_string(fd, config->cdma_profile.pde_url_addr, sizeof(config->cdma_profile.pde_url_addr));
+ }
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V20)
+ {
+ //V15
+ config->agps_setting.e911_gps_icon_enable = socket_get_byte(fd);
+ //V16
+ config->agps_setting.e911_open_gps = socket_get_byte(fd);
+ //V17
+ config->gnss_setting.a_gps_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.a_beidou_satellite_enable = socket_get_byte(fd);
+ config->gnss_setting.a_galileo_satellite_enable = socket_get_byte(fd);
+ //V18
+ config->up_setting.sha_version = socket_get_int(fd);
+ config->up_setting.preferred_2g3g_cell_age = socket_get_int(fd);
+ config->up_setting.ut1 = socket_get_byte(fd);
+ config->up_setting.no_sensitive_log = socket_get_byte(fd);
+ config->up_setting.tls_reuse_enable = socket_get_byte(fd);
+ config->up_setting.imsi_cache_enable = socket_get_byte(fd);
+ config->up_setting.supl_raw_data_enable = socket_get_byte(fd);
+ config->up_setting.tc10_enable = socket_get_byte(fd);
+ config->up_setting.tc10_use_apn = socket_get_byte(fd);
+ config->up_setting.tc10_use_fw_dns = socket_get_byte(fd);
+ config->up_setting.allow_ni_for_gps_off = socket_get_byte(fd);
+ config->up_setting.force_otdoa_assist_req = socket_get_byte(fd);
+ config->cp_setting.reject_non911_nilr_enable = socket_get_byte(fd);
+ config->cp_setting.cp_2g_disable = socket_get_byte(fd);
+ config->cp_setting.cp_3g_disable = socket_get_byte(fd);
+ config->cp_setting.cp_4g_disable = socket_get_byte(fd);
+ config->agps_setting.tc10_ignore_fw_config = socket_get_byte(fd);
+ config->agps_setting.lppe_hide_wifi_bt_status = socket_get_byte(fd);
+ //V19
+ config->agps_setting.lppe_network_location_disable = socket_get_byte(fd);
+ config->cp_setting.cp_lppe_enable = socket_get_byte(fd);
+ config->up_setting.up_lppe_enable = socket_get_byte(fd);
+ //V20
+ config->cp_setting.support_cp_lppe = socket_get_byte(fd);
+ config->gnss_setting.mnl_support_lppe = socket_get_byte(fd);
+ }
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V21)
+ {
+ config->agps_setting.agps_nvram_enable = socket_get_byte(fd);
+ config->agps_setting.lbs_log_enable = socket_get_byte(fd);
+ config->agps_setting.lppe_crowd_source_confident = socket_get_int(fd);
+
+ config->up_setting.esupl_apn_mode = socket_get_int(fd);
+ config->up_setting.tcp_keepalive = socket_get_int(fd);
+ config->up_setting.aosp_profile_enable = socket_get_byte(fd);
+ config->up_setting.bind_nlp_setting_to_supl = socket_get_byte(fd);
+ }
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V22)
+ {
+ config->agps_setting.ignore_si_for_e911 = socket_get_byte(fd);
+ config->cp_setting.cp_lppe_wlan_enable = socket_get_byte(fd);
+ config->cp_setting.cp_lppe_srn_enable = socket_get_byte(fd);
+ config->cp_setting.cp_lppe_sensor_enable = socket_get_byte(fd);
+ config->cp_setting.cp_lppe_dbh_enable = socket_get_byte(fd);
+
+ config->up_setting.up_lppe_wlan_enable = socket_get_byte(fd);
+ config->up_setting.up_lppe_srn_enable = socket_get_byte(fd);
+ config->up_setting.up_lppe_sensor_enable = socket_get_byte(fd);
+ config->up_setting.up_lppe_dbh_enable = socket_get_byte(fd);
+ config->up_setting.ip_version_prefer = socket_get_int(fd);
+ config->up_setting.up_lppe_in_2g3g_disable = socket_get_byte(fd);
+ config->up_setting.up_rrlp_in_4g_disable = socket_get_byte(fd);
+ config->up_setting.up_si_disable = socket_get_byte(fd);
+ }
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V23)
+ {
+ config->up_setting.use_ni_slp = socket_get_byte(fd);
+ config->agps_setting.use_tc10_config = socket_get_byte(fd);
+ config->agps_setting.lppe_def_nlp_enable = socket_get_byte(fd);
+ }
+
+ if(cmd >= APP_MGR_CMD_GET_CONFIG_V24)
+ {
+ config->agps_setting.emergency_ext_secs = socket_get_int(fd);
+ config->up_setting.aosp_pos_mode_enable = socket_get_byte(fd);
+ config->up_setting.privacy_override_mode = socket_get_int(fd);
+ }
+
+ config->valid = 1;
+ // read ACK
+ socket_get_byte(fd);
+ RLOGD("Socket read ACK sucess, close fd");
+ close(fd);
+ return 0;
+}
+
+int agps_get_total_status(agps_intf_agps_config *config)
+{
+ if (NULL == config)
+ {
+ RLOGD("agps_get_total_status incoming paramter error");
+ }
+ int res = 0;
+ res = get_template_agps_config(APP_MGR_CMD_GET_CONFIG_V24,config);
+ return res;
+}
+
+
+int lynq_agps_set_enabled(LYNQ_CONF_SWITCH agps_status)
+{
+ int ret = -1;
+ RLOGD("[LYNQ_GNSS]set agps:%d",agps_status);
+ ret = set_template_1(APP_MGR_CMD_SET_AGPS_ENABLE,agps_status);
+ if (ret != 0)
+ {
+ RLOGD("set AGPS error ret = %d",ret);
+ return ret;
+ }
+ return ret;
+}
+
+int lynq_agps_get_enabled_status(int *status)
+{
+ int ret = 0;
+ if (NULL == status)
+ {
+ RLOGD("incoming paramter error");
+ return -1;
+ }
+
+ agps_intf_agps_config config;
+ memset(&config, 0, sizeof(config));
+ ret = agps_get_total_status(&config);
+ if (ret != 0)
+ {
+ RLOGD("agps get status fail");
+ return ret;
+ }
+ *status = config.agps_setting.agps_enable;
+ RLOGD("[LYNQ_GNSS]agps status:%d",*status);
+ return ret;
+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h
new file mode 100644
index 0000000..f3da3d3
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_agps.h
@@ -0,0 +1,393 @@
+#ifndef LYNQ_AGPS_H
+#define LYNQ_AGPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*Copy for agps_interface.h*/
+#define agps_bool char
+
+#define MAX_BUFF_SIZE 8192
+#define SUPL_PROFILES_NUM 30
+
+#define AGPS_INTF_STRING_LEN 64
+#define AGPS_SUPL_ADDR_LEN 128
+#define MNL_MCC_STRING_LEN 16
+#define EXTERNAL_ADD_LEN 20
+#define MLC_NUMBER_LEN 20
+#define EPC_MOLR_LPP_PAYLOAD_LEN 300
+#define SUPL_PROFILES_NUM 30
+#define PROFILING_MESSAGE_LEN 64
+#define PROFILING_ELEMENT_NUM 20
+
+typedef enum {
+ // Command Enum APP -> AGPSD
+ APP_MGR_CMD_CODER_TEST = 0,
+ APP_MGR_CMD_VERSION = 1,
+
+ APP_MGR_CMD_GET_CONFIG = 100, //AgpsConfig
+ APP_MGR_CMD_GET_OMA_CP_SUPL_PROFILE = 101,
+ APP_MGR_CMD_GET_SYSTEM_PROPERTY = 102,
+ APP_MGR_CMD_GET_AGPS_PROFILING = 103,
+ APP_MGR_CMD_GET_EMULATOR_MODE = 104,
+ APP_MGR_CMD_GET_CONFIG_V2 = 105,
+ APP_MGR_CMD_GET_CONFIG_V3 = 106, // add cert_from_sdcard
+ APP_MGR_CMD_GET_CONFIG_V14 = 117,
+ APP_MGR_CMD_GET_CONFIG_V20 = 123,
+ APP_MGR_CMD_GET_CONFIG_V21 = 124,
+ APP_MGR_CMD_GET_CONFIG_V22 = 125,
+ APP_MGR_CMD_GET_CONFIG_V23 = 126,
+ APP_MGR_CMD_GET_CONFIG_V24 = 127,
+
+ APP_MGR_CMD_SET_AGPS_ENABLE = 200,
+ APP_MGR_CMD_SET_PROTOCOL,
+ APP_MGR_CMD_SET_CDMA_PREF,
+ APP_MGR_CMD_SET_UP_PREF_METHOD,
+ APP_MGR_CMD_SET_POS_TECHNOLOGY_MSA,
+ APP_MGR_CMD_SET_POS_TECHNOLOGY_MSB,
+ APP_MGR_CMD_SET_POS_TECHNOLOGY_ECID,
+ APP_MGR_CMD_SET_POS_TECHNOLOGY_OTDOA,
+ APP_MGR_CMD_SET_SUPL_VERSION,
+ APP_MGR_CMD_SET_SUPL_PROFILE, //AgpsProfil
+ APP_MGR_CMD_SET_QOP = 210, //AgpsQoP
+ APP_MGR_CMD_SET_MOLR_POS_METHDO,
+ APP_MGR_CMD_SET_EXTERNAL_ADDR,
+ APP_MGR_CMD_SET_MLC_NUMBER,
+ APP_MGR_CMD_SET_CP_AUTO_RESET,
+ APP_MGR_CMD_SET_ALLOW_NI,
+ APP_MGR_CMD_SET_ALLOW_ROAMING,
+ APP_MGR_CMD_SET_SUPL_2_FILE,
+ APP_MGR_CMD_SET_RESET_TO_DEFAULT,
+ APP_MGR_CMD_SET_OMA_CP_SUPL_PROFILE,
+ APP_MGR_CMD_SET_NI_REQ = 220, //un-implemented for test
+ APP_MGR_CMD_SET_EPC_MOLR_PDU_ENABLE,
+ APP_MGR_CMD_SET_EPC_MOLR_PDU,
+ APP_MGR_CMD_SET_TLS_VERSION,
+ APP_MGR_CMD_SET_CA_ENABLE,
+ APP_MGR_CMD_SET_UDP_ENABLE,
+ APP_MGR_CMD_SET_LPP_ENABLE,
+ APP_MGR_CMD_SET_CERT_FROM_SDCARD_ENABLE,
+ APP_MGR_CMD_SET_AUTO_PROFILE_ENABLE,
+ APP_MGR_CMD_SET_UT2,
+ APP_MGR_CMD_SET_UT3 = 230,
+ APP_MGR_CMD_SET_SUPL_APN_ENABLE,
+ APP_MGR_CMD_SET_SYNC_TO_SLP,
+ APP_MGR_CMD_SET_UDP_ENABLE_V2,
+ APP_MGR_CMD_SET_AUTONOMOUS_ENABLE,
+ APP_MGR_CMD_SET_AFLT_ENABLE,
+ APP_MGR_CMD_SET_IMSI_ENABLE,
+ APP_MGR_CMD_SET_SIB8_16_ENABLE,
+ APP_MGR_CMD_SET_GPS_ENABLE,
+ APP_MGR_CMD_SET_GLONASS_ENABLE,
+ APP_MGR_CMD_SET_BEIDOU_ENABLE = 240,
+ APP_MGR_CMD_SET_GALILEO_ENABLE,
+ APP_MGR_CMD_SET_SUPL_SHA_VERSION,
+ APP_MGR_CMD_SET_SUPL_TLS_VERSION,
+ APP_MGR_CMD_SET_SUPL_VER_MINOR,
+ APP_MGR_CMD_SET_SUPL_VER_SER_IND,
+ APP_MGR_CMD_SET_A_GLONASS_ENABLE,
+ APP_MGR_CMD_SET_PDE_PROFILE,
+ APP_MGR_CMD_SET_E911_GPS_ICON_ENABLE,
+ APP_MGR_CMD_SET_E911_OPEN_GPS_ENABLE,
+ APP_MGR_CMD_SET_A_GPS_ENABLE = 250,
+ APP_MGR_CMD_SET_A_BEIDOU_ENABLE,
+ APP_MGR_CMD_SET_A_GALILEO_ENABLE,
+ APP_MGR_CMD_SET_PREF_2G3G_CELL_AGE,
+ APP_MGR_CMD_SET_UT1,
+ APP_MGR_CMD_SET_NO_SENSITIVE_LOG,
+ APP_MGR_CMD_SET_TLS_REUSE_ENABLE,
+ APP_MGR_CMD_SET_IMSI_CACHE_ENABLE,
+ APP_MGR_CMD_SET_SUPL_RAW_DATA_ENABLE,
+ APP_MGR_CMD_SET_TC10_ENABLE,
+ APP_MGR_CMD_SET_TC10_USE_APN = 260,
+ APP_MGR_CMD_SET_TC10_USE_FW_DNS,
+ APP_MGR_CMD_SET_ALLOW_NI_FOR_GPS_OFF,
+ APP_MGR_CMD_SET_FORCE_OTDOA_ASSIST_REQ,
+ APP_MGR_CMD_SET_REJECT_NON911_NILR_ENABLE,
+ APP_MGR_CMD_SET_CP_2G_DISABLE,
+ APP_MGR_CMD_SET_CP_3G_DISABLE,
+ APP_MGR_CMD_SET_CP_4G_DISABLE,
+ APP_MGR_CMD_SET_TC10_IGNORE_FW_CONFIG,
+ APP_MGR_CMD_SET_LPPE_HIDE_WIFI_BT_STATUS,
+ APP_MGR_CMD_SET_LPPE_NETWORK_LOCATION_DISABLE = 270,
+ APP_MGR_CMD_SET_LPPE_CP_ENABLE,
+ APP_MGR_CMD_SET_LPPE_UP_ENABLE,
+ APP_MGR_CMD_SET_VZW_DEBUG_SCREEN_ENABLE,
+ APP_MGR_CMD_SET_AOSP_PROFILE_ENABLE,
+ APP_MGR_CMD_SET_BIND_NLP_SETTING_TO_SUPL,
+ APP_MGR_CMD_SET_ESUPL_APN_MODE,
+ APP_MGR_CMD_SET_TCP_KEEPALIVE,
+ APP_MGR_CMD_SET_AGPS_NVRAM_ENABLE,
+ APP_MGR_CMD_SET_LBS_LOG_ENABLE,
+ APP_MGR_CMD_SET_LPPE_CROWD_SOURCE_CONFIDENT = 280,
+ APP_MGR_CMD_SET_IGNORE_SI_FOR_E911,
+ APP_MGR_CMD_SET_LPPE_CP_WLAN_ENABLE,
+ APP_MGR_CMD_SET_LPPE_CP_SRN_ENABLE,
+ APP_MGR_CMD_SET_LPPE_CP_SENSOR_ENABLE,
+ APP_MGR_CMD_SET_LPPE_CP_DBH_ENABLE,
+ APP_MGR_CMD_SET_LPPE_UP_WLAN_ENABLE,
+ APP_MGR_CMD_SET_LPPE_UP_SRN_ENABLE,
+ APP_MGR_CMD_SET_LPPE_UP_SENSOR_ENABLE,
+ APP_MGR_CMD_SET_LPPE_UP_DBH_ENABLE,
+ APP_MGR_CMD_SET_IP_VERSION_PREFER = 290,
+ APP_MGR_CMD_SET_UP_LPP_IN_2G3G_DISABLE,
+ APP_MGR_CMD_SET_UP_RRLP_IN_4G_DISABLE,
+ APP_MGR_CMD_UP_SI_DISABLE,
+
+ // To implement
+ APP_MGR_CMD_SET_USE_NI_SLP,
+ APP_MGR_CMD_SET_USE_TC10_CONFIG,
+ APP_MGR_CMD_SET_LPPE_DEF_NLP_ENABLE,
+ APP_MGR_CMD_SET_AOSP_POS_MODE_ENABLE,
+ APP_MGR_CMD_SET_PRIVACY_OVERRIDE_MODE,
+ APP_MGR_CMD_SET_EMERGENCY_EXT_SECS, // 299
+
+
+ APP_MGR_CMD_START_PERIODIC = 300,
+ APP_MGR_CMD_ABORT_PERIODIC,
+ APP_MGR_CMD_START_AREA_EVENT,
+ APP_MGR_CMD_ABORT_AREA_EVENT,
+
+ APP_MGR_CMD_START_TEST_CASE = 400,
+ APP_MGR_CMD_START_TEST_BUTTON,
+ APP_MGR_CMD_START_RESET_AGPSD,
+ APP_MGR_CMD_START_EMULATOR_MODE,
+
+
+ // To implement
+ APP_MGR_CMD_SET_TC10_SUPL_SSL_METHOD = 500,
+ APP_MGR_CMD_SET_TC10_AUTO_SUPL_VER_FOR_NI,
+ APP_MGR_CMD_SET_TC10_SUPL_VER_SKT_NI,
+ APP_MGR_CMD_SET_TC10_USE_APN_NI,
+ APP_MGR_CMD_SET_TC10_USE_APN_SI,
+ APP_MGR_CMD_SET_CP_PRIVACY_OVERRIDE,
+ APP_MGR_CMD_SET_SUPL_ADDR_NI,
+ APP_MGR_CMD_SET_RRLP_GOOGLE_SUPL,
+ APP_MGR_CMD_SET_SUPL2_CAP_EXT_DISABLE,
+ APP_MGR_CMD_SET_NI_STATISTIC_ENABLE,
+ APP_MGR_CMD_SET_UP_OPERATION_MODE, // 510
+ APP_MGR_CMD_SET_GLONASS_MSA_ENABLE,
+ APP_MGR_CMD_SET_GLONASS_MSB_ENABLE,
+ APP_MGR_CMD_SET_BEIDOU_MSA_ENABLE,
+ APP_MGR_CMD_SET_BEIDOU_MSB_ENABLE,
+ APP_MGR_CMD_SET_GALILEO_MSA_ENABLE,
+ APP_MGR_CMD_SET_GALILEO_MSB_ENABLE,
+ APP_MGR_CMD_SET_TC10_AUTO_SUPL_VER_FOR_ENI,
+ APP_MGR_CMD_SET_TC10_CP_LPP_GUARD_TIME_SEC,
+ APP_MGR_CMD_SET_TC10_CP_CAPABILITY_VALID_ENABLE,
+ APP_MGR_CMD_SET_TC10_CP_CAPABILITY_ENABLE, // 520
+ APP_MGR_CMD_SET_IGNORE_EMERGENCY_EXT_SECS_FROM_FRAMEWORK,
+ APP_MGR_CMD_GET_AGPSD_VERSION,
+ APP_MGR_CMD_GET_IMSI,
+} app_mgr_cmd_enum;
+
+typedef enum {
+ AGPS_INTF_PDE_IP_TYPE_IPV4 = 0,
+ AGPS_INTF_PDE_IP_TYPE_IPV6 = 1,
+} agps_intf_pde_ip_type;
+
+typedef enum {
+ AGPS_INTF_CDMA_PREFERRED_WCDMA = 0,
+ AGPS_INTF_CDMA_PREFERRED_CDMA = 1,
+ AGPS_INTF_CDMA_PREFERRED_CDMA_FORCE = 2,
+} agps_intf_cdma_preferred;
+
+typedef enum {
+ AGPS_INTF_PREF_METHOD_MSA = 0,
+ AGPS_INTF_PREF_METHOD_MSB = 1,
+ AGPS_INTF_PREF_METHOD_NO_PREF = 2,
+} agps_intf_pref_method;
+
+typedef enum {
+ AGPS_INTF_AGPS_PROTOCOL_UP = 0,
+ AGPS_INTF_AGPS_PROTOCOL_CP = 1,
+} agps_intf_agps_protocol;
+
+typedef enum {
+ AGPS_INTF_SUPL_VERSION_1 = 1,
+ AGPS_INTF_SUPL_VERSION_2 = 2,
+} agps_intf_supl_version;
+
+typedef enum {
+ AGPS_INTF_TLS_VERSION_1_0 = 0,
+ AGPS_INTF_TLS_VERSION_1_1 = 1,
+ AGPS_INTF_TLS_VERSION_1_2 = 2,
+} agps_intf_tls_version;
+
+typedef enum {
+ AGPS_INTF_ESUPL_APN_EIMS_IMS = 0,
+ AGPS_INTF_ESUPL_APN_EIMS = 1,
+ AGPS_INTF_ESUPL_APN_IMS = 2,
+ AGPS_INTF_ESUPL_APN_AS_NORMAL = 3,
+} agps_intf_esupl_apn;
+
+typedef enum {
+ AGPS_INTF_MOLR_POS_METHOD_LOC_EST = 0,
+ AGPS_INTF_MOLR_POS_METHOD_ASSIST_DATA = 1,
+} agps_intf_molr_pos_method;
+
+typedef struct {
+ char name[AGPS_INTF_STRING_LEN];
+ char addr[AGPS_SUPL_ADDR_LEN];
+ int port;
+ agps_bool tls;
+ char mcc_mnc[MNL_MCC_STRING_LEN];
+ char app_id[AGPS_INTF_STRING_LEN];
+ char provider_id[AGPS_INTF_STRING_LEN];
+ char default_apn[AGPS_INTF_STRING_LEN];
+ char optional_apn[AGPS_INTF_STRING_LEN];
+ char optional_apn_2[AGPS_INTF_STRING_LEN];
+ char address_type[AGPS_INTF_STRING_LEN];
+} agps_intf_supl_profile;
+
+typedef struct {
+ char name[AGPS_INTF_STRING_LEN];
+ agps_bool mcp_enable;
+ char mcp_addr[AGPS_INTF_STRING_LEN];
+ int mcp_port;
+ agps_bool pde_addr_valid;
+ agps_intf_pde_ip_type pde_ip_type; //0=IPV4 1=IPV6
+ char pde_addr[AGPS_INTF_STRING_LEN];
+ int pde_port;
+ agps_bool pde_url_valid;
+ char pde_url_addr[AGPS_INTF_STRING_LEN];
+} agps_intf_cdma_profile;
+
+typedef struct {
+ agps_bool agps_enable;
+ agps_intf_agps_protocol agps_protocol;
+ agps_bool gpevt;
+ agps_bool e911_gps_icon_enable;
+ agps_bool e911_open_gps;
+ agps_bool tc10_ignore_fw_config;
+ agps_bool lppe_hide_wifi_bt_status;
+ agps_bool lppe_network_location_disable;
+ agps_bool agps_nvram_enable;
+ agps_bool lbs_log_enable;
+ int lppe_crowd_source_confident;
+ agps_bool ignore_si_for_e911; // North America operator 'V' asks us to ignore SI triggered by GMS
+ agps_bool use_tc10_config;
+ agps_bool lppe_def_nlp_enable;
+ int emergency_ext_secs;
+} agps_intf_agps_setting;
+
+typedef struct {
+ agps_intf_molr_pos_method molr_pos_method;
+ agps_bool external_addr_enable;
+ char external_addr[EXTERNAL_ADD_LEN];
+ agps_bool mlc_number_enable;
+ char mlc_number[MLC_NUMBER_LEN];
+ agps_bool cp_auto_reset;
+ agps_bool epc_molr_lpp_payload_enable;
+ int epc_molr_lpp_payload_len;
+ char epc_molr_lpp_payload[EPC_MOLR_LPP_PAYLOAD_LEN];
+ agps_bool cp_lppe_enable;
+ agps_bool support_cp_lppe;
+ agps_bool reject_non911_nilr_enable;
+ agps_bool cp_2g_disable;
+ agps_bool cp_3g_disable;
+ agps_bool cp_4g_disable;
+ agps_bool cp_lppe_wlan_enable;
+ agps_bool cp_lppe_srn_enable;
+ agps_bool cp_lppe_sensor_enable;
+ agps_bool cp_lppe_dbh_enable;
+} agps_intf_cp_setting;
+
+typedef struct {
+ agps_bool ca_enable;
+ agps_bool ni_request;
+ agps_bool roaming;
+ agps_intf_cdma_preferred cdma_preferred;
+ agps_intf_pref_method pref_method;
+ agps_intf_supl_version supl_version;
+ agps_intf_tls_version tls_version;
+ agps_bool supl_log;
+ agps_bool msa_enable;
+ agps_bool msb_enable;
+ agps_bool ecid_enable;
+ agps_bool otdoa_enable;
+ int qop_hacc;
+ int qop_vacc;
+ int qop_loc_age;
+ int qop_delay;
+ agps_bool lpp_enable;
+ agps_bool cert_from_sdcard;
+ agps_bool auto_profile_enable;
+ char ut2;
+ char ut3;
+ agps_bool apn_enable;
+ agps_bool sync_to_slp;
+ agps_bool udp_enable;
+ agps_bool autonomous_enable;
+ agps_bool aflt_enable;
+ agps_bool imsi_enable;
+ char supl_ver_minor;
+ char supl_ver_ser_ind;
+ int sha_version; // 0: SHA1 for SUPL1.0 and SHA256 for SUPL2.0, 1: SHA1 for SUPL1.0 and SUPL2.0, 2: SHA256 for SUPL1.0 and SUPL2.0
+ int preferred_2g3g_cell_age;
+ char ut1;
+ agps_bool no_sensitive_log;
+ agps_bool tls_reuse_enable;
+ agps_bool imsi_cache_enable;
+ agps_bool supl_raw_data_enable;
+ agps_bool tc10_enable;
+ agps_bool tc10_use_apn;
+ agps_bool tc10_use_fw_dns;
+ agps_bool allow_ni_for_gps_off;
+ agps_bool force_otdoa_assist_req;
+ agps_bool up_lppe_enable;
+ agps_intf_esupl_apn esupl_apn_mode;
+ int tcp_keepalive;
+ agps_bool aosp_profile_enable;
+ agps_bool bind_nlp_setting_to_supl;
+ agps_bool up_lppe_wlan_enable;
+ agps_bool up_lppe_srn_enable;
+ agps_bool up_lppe_sensor_enable;
+ agps_bool up_lppe_dbh_enable;
+ int ip_version_prefer; //0=IPv6 prefer 1=IPv4 prefer
+ agps_bool up_lppe_in_2g3g_disable; // For ATT SUPL server
+ agps_bool up_rrlp_in_4g_disable; // For ATT SUPL server
+ agps_bool up_si_disable; // For Sprint
+ agps_bool use_ni_slp; // tc10 (ALPS04423530)
+ agps_bool aosp_pos_mode_enable;
+ int privacy_override_mode;
+} agps_intf_up_setting;
+
+typedef struct {
+ agps_bool sib8_sib16_enable;
+ agps_bool gps_satellite_enable;
+ agps_bool glonass_satellite_enable;
+ agps_bool beidou_satellite_enable;
+ agps_bool galileo_satellite_enable;
+ agps_bool a_glonass_satellite_enable;
+
+ agps_bool gps_satellite_support;
+ agps_bool glonass_satellite_support;
+ agps_bool beidou_satellite_support;
+ agps_bool galileo_satellite_support;
+
+ agps_bool a_gps_satellite_enable;
+ agps_bool a_beidou_satellite_enable;
+ agps_bool a_galileo_satellite_enable;
+
+ agps_bool mnl_support_lppe;
+} agps_intf_gnss_setting;
+
+typedef struct {
+ int supl_profiles_num;
+ agps_intf_supl_profile supl_profiles[SUPL_PROFILES_NUM];
+ agps_intf_supl_profile cur_supl_profile;
+ agps_intf_cdma_profile cdma_profile;
+ agps_intf_agps_setting agps_setting;
+ agps_intf_cp_setting cp_setting;
+ agps_intf_up_setting up_setting;
+ agps_intf_gnss_setting gnss_setting;
+ agps_bool valid;
+} agps_intf_agps_config;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c
new file mode 100755
index 0000000..b8a402f
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_callback.c
@@ -0,0 +1,209 @@
+#include<pthread.h>
+#include<stdio.h>
+#include<unistd.h>
+#include<errno.h>
+#include<string.h>
+
+#include"lynq_gnsshal.h"
+#include"mtk_lbs_utility.h"
+#include"lynq_gnss.h"
+
+extern lynq_gnss_cb* lynq_callbacks;
+extern lynq_raw_gnss_cbs *lynq_meas_callbacks;
+
+void lynq_gps_location_callback(GpsLocation_ext* location)
+{
+ GpsLocation_ext* loc = (GpsLocation_ext *)location;
+ lynq_GpsLocation_ext lynq_loc;
+ //lynq_loc.legacyLocation.size = loc->legacyLocation.size;
+ lynq_loc.legacyLocation.size = sizeof(lynq_GpsLocation_ext);
+ lynq_loc.legacyLocation.flags = loc->legacyLocation.flags;
+ lynq_loc.legacyLocation.latitude = loc->legacyLocation.latitude;
+ lynq_loc.legacyLocation.longitude = loc->legacyLocation.longitude;
+ lynq_loc.legacyLocation.altitude = loc->legacyLocation.altitude;
+ lynq_loc.legacyLocation.speed = loc->legacyLocation.speed;
+ lynq_loc.legacyLocation.bearing = loc->legacyLocation.bearing;
+ lynq_loc.legacyLocation.accuracy = loc->legacyLocation.accuracy;
+ lynq_loc.legacyLocation.timestamp = loc->legacyLocation.timestamp;
+ lynq_loc.horizontalAccuracyMeters = loc->horizontalAccuracyMeters;
+ lynq_loc.verticalAccuracyMeters = loc->speedAccuracyMetersPerSecond;
+ lynq_loc.bearingAccuracyDegrees = loc->bearingAccuracyDegrees;
+ lynq_callbacks->lynq_location_cb(&lynq_loc);
+}
+
+void lynq_gps_status_callback(GpsStatus* status)
+{
+ lynq_callbacks->lynq_status_cb(status);
+}
+
+void lynq_gps_sv_status_callback(GpsSvStatus* sv_info)
+{
+
+}
+
+void lynq_gps_nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)
+{
+ lynq_callbacks->lynq_nmea_cb(timestamp,nmea,length);
+
+}
+
+void lynq_gps_set_capabilities(uint32_t capabilities)
+{
+
+}
+
+void lynq_gps_acquire_wakelock(void)
+{
+
+}
+
+void lynq_gps_release_wakelock(void)
+{
+
+}
+
+void lynq_gps_request_utc_time(void)
+{
+
+}
+
+void lynq_set_system_info_cb(const GnssSystemInfo* info)
+{
+
+}
+
+void lynq_gnss_sv_status_cb(GnssSvStatus_ext* sv_info)
+{
+
+}
+
+pthread_t lynq_gps_create_thread(const char* name, void (*start)(void *), void* arg)
+{
+ lynq_callbacks->lynq_create_thread_cb(name,(void *(*)(void *))start,arg);
+}
+
+void lynq_gnss_set_name_cb(const char* name, int length)
+{
+
+}
+
+void lynq_gnss_request_location_cb(bool independentFromGnss, bool isUserEmergency)
+{
+
+}
+
+void lynq_agnss_location_callback(GpsLocation_ext* location) {
+
+}
+
+
+GpsCallbacks_ext lynq_gps_callbacks_gnss = {
+ .size = sizeof(GpsCallbacks_ext),
+ .location_cb = lynq_gps_location_callback,
+ .status_cb = lynq_gps_status_callback,
+ .sv_status_cb = lynq_gps_sv_status_callback,
+ .nmea_cb = lynq_gps_nmea_callback,
+ .set_capabilities_cb = lynq_gps_set_capabilities,
+ .acquire_wakelock_cb = lynq_gps_acquire_wakelock,
+ .release_wakelock_cb = lynq_gps_release_wakelock,
+ .create_thread_cb = lynq_gps_create_thread,
+ .request_utc_time_cb = lynq_gps_request_utc_time,
+ .set_system_info_cb = lynq_set_system_info_cb,
+ .gnss_sv_status_cb = lynq_gnss_sv_status_cb,
+ .set_name_cb = lynq_gnss_set_name_cb,
+ .request_location_cb = lynq_gnss_request_location_cb,
+ .agps_location_cb = lynq_agnss_location_callback,
+};
+
+GpsCallbacks_ext* lynq__get_gps_callbacks(void)
+{
+ return &lynq_gps_callbacks_gnss;
+}
+
+void lynq_measurement_callback(GpsData *data)
+{
+
+}
+
+void lynq_gnss_measurement_callback(GnssData_ext* data)
+{
+ lynq_meas_callbacks->lynq_measurement_callback(data);
+ return;
+}
+
+GpsMeasurementCallbacks_ext lynq_test_raw_callbacks = {
+ .size = sizeof(GpsMeasurementCallbacks_ext),
+ .measurement_callback = lynq_measurement_callback,
+ .gnss_measurement_callback = lynq_gnss_measurement_callback,
+};
+
+GpsMeasurementCallbacks_ext* lynq_gnss_get_raw_callbacks(void)
+{
+ return &lynq_test_raw_callbacks;
+}
+
+
+void lynq_at_gps_location_callback(lynq_GpsLocation_ext* location)
+{
+
+}
+
+void lynq_at_gps_status_callback(GpsStatus* status)
+{
+
+}
+
+#define NMEA_ACC "ACCURACY"
+#define NMEA_GSA "GSA"
+#define NMEA_RMC "RMC"
+#define NMEA_GGA "GGA"
+#define NMEA_VTG "VTG"
+#define NMEA_GSV "GSV"
+
+void lynq_at_gps_nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)
+{
+ if (at_gpsnmea_status == 1)
+ {
+ if(strncmp(nmea+3,NMEA_GSA,strlen(NMEA_GSA))==0 || strncmp(nmea+3,NMEA_RMC,strlen(NMEA_RMC)) == 0 || \
+ strncmp(nmea+3,NMEA_GGA,strlen(NMEA_GGA)) == 0 || strncmp(nmea+3,NMEA_VTG,strlen(NMEA_VTG)) == 0|| \
+ strncmp(nmea+3,NMEA_GSV,strlen(NMEA_GSV)) == 0)
+ {
+ atsvc_gnss_outcb(nmea,strlen(nmea),1);
+ }
+ }
+}
+
+
+
+pthread_t lynq_at_gps_create_thread(const char* name, void (*start)(void *), void* arg)
+{
+ pthread_t at_ntid = 0;
+ int ret = 0;
+
+ ret = pthread_create(&at_ntid, NULL, (void *(*)(void *))start, arg);
+
+ if(ret != 0)
+ {
+ printf("thread %s create fail(%s)!\r\n", name, strerror(errno));
+ at_ntid = 0;
+ }
+ else
+ {
+ printf("tread %s create success!\r\n", name);
+ }
+
+ return at_ntid;
+}
+
+lynq_gnss_cb lynq_at_gnss_callbacks = {
+ .size = sizeof(lynq_gnss_cb),
+ .lynq_location_cb =lynq_at_gps_location_callback,
+ .lynq_status_cb = lynq_at_gps_status_callback,
+ .lynq_nmea_cb = lynq_at_gps_nmea_callback,
+ .lynq_create_thread_cb = lynq_at_gps_create_thread,
+};
+
+lynq_gnss_cb* lynq_at_get__gnss_callbacks(void)
+{
+ return &lynq_at_gnss_callbacks;
+}
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c
new file mode 100755
index 0000000..a812738
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnss.c
@@ -0,0 +1,620 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <log/log.h>
+#include <stdlib.h>
+
+#include "lynq_gnss.h"
+#include "gpshal.h"
+#include "hal2mnl_interface.h"
+#include "lynq_gnsshal.h"
+#include "mtk_lbs_utility.h"
+#include "lynq_prop.h"
+#include "mnldinf_utility.h"
+
+#define LOG_TAG "LYNQ_GNSS"
+
+
+lynq_gnss_cb* lynq_callbacks =NULL ;
+lynq_raw_gnss_cbs* lynq_meas_callbacks = NULL;
+
+GpsCallbacks_ext* turn_cbs = NULL;
+GpsMeasurementCallbacks_ext* raw_cbs = NULL;
+
+lynq_gnss_cb* lynq_at_callbacks = NULL ;
+/**
+ * @brief mark gnss initialization state
+ * 0: deinit state
+ * 1: init state
+ */
+static int g_lynq_gnss_init_flag = 0;
+
+static int g_lynq_gnss_calback_flag = 0;
+
+/**
+ * @brief mark gnss raw meas state
+ * 0: deinit state
+ * 1: init state
+ */
+static int g_lynq_gnss_raw_meas_flag = 0;
+
+int lynq_gnss_init(void)
+{
+ if (g_lynq_gnss_init_flag == 1)
+ {
+ RLOGD("init twice is not allowed");
+ return -1;
+ }
+ if (g_lynq_gnss_calback_flag == 0)
+ {
+ RLOGD("Plz Reg callback before init");
+ return -1;
+ }
+ g_lynq_gnss_init_flag = 1;
+ gpshal_set_gps_state_intent(GPSHAL_STATE_INIT);
+ gpshal2mnl_gps_init();
+ g_gpshal_ctx.mnl_retry_timer = mnldinf_init_timer(gpshal_mnl_retry_routine);
+ return 0;
+}
+
+int lynq_gnss_callback_reg(lynq_gnss_cb* callbacks)
+{
+ int i=0;
+ if (NULL == callbacks)
+ {
+ RLOGD("illegal callbacks!!!");
+ return -1;
+ }
+ mnldinf_wake_lock_init();
+ lynq_callbacks = callbacks;
+ turn_cbs = lynq__get_gps_callbacks();
+ if(turn_cbs == NULL)
+ {
+ RLOGD("callbacks error");
+ return -1;
+ }
+ for(i=0;i<5;i++)
+ {
+ RLOGD("The callback_gps_state:%s",gpshal_state_to_string(g_gpshal_ctx.gps_state));
+ if(gpshal_gpscbs_save(turn_cbs) != 0)
+ {
+ RLOGD("For cbs save error\r\n");
+ }
+ RLOGD("The callback_gps_state:%s",gpshal_state_to_string(g_gpshal_ctx.gps_state));
+ if(g_gpshal_ctx.gps_state != GPSHAL_STATE_UNKNOWN)
+ {
+ break;
+ }
+ sleep(1);
+ }
+ if(i>=5)
+ {
+ RLOGD("For cbs save error2\r\n");
+ return -1;
+ }
+ g_lynq_gnss_calback_flag = 1;
+ return 0;
+}
+
+int lynq_gnss_deinit(void)
+{
+ if (g_lynq_gnss_init_flag == 0)
+ {
+ RLOGD("deinit twice is not allowed");
+ return -1;
+ }
+ timer_t retry_timer;
+ gpshal_set_gps_state_intent(GPSHAL_STATE_CLEANUP);
+ gpshal2mnl_gps_cleanup();
+ RLOGD("WAKE_LOCK_Begin");
+ mnldinf_wake_lock_deinit();
+ RLOGD("WAKE_LOCK_END");
+ retry_timer = g_gpshal_ctx.mnl_retry_timer;
+ g_gpshal_ctx.mnl_retry_timer = INVALID_TIMERID;
+ RLOGD("timer deinit start");
+ if(mnldinf_deinit_timer(retry_timer) == -1) {
+ RLOGD("retry_timer deinit fail:%s", strerror(errno));
+ return -1;
+ }
+ RLOGD("timer de init end");
+ g_lynq_gnss_calback_flag = 0;
+ g_lynq_gnss_init_flag = 0;
+ return 0;
+}
+
+int lynq_gnss_start(void)
+{
+ if (g_lynq_gnss_init_flag == 0)
+ {
+ RLOGD("start is not allowed");
+ return -1;
+ }
+ //memset(&lynq_debug_data, 0, sizeof(DebugData));
+ gpshal_set_gps_state_intent(GPSHAL_STATE_START);
+ gpshal2mnl_gps_start();
+ return 0;
+}
+
+int lynq_gnss_stop(void)
+{
+ if (g_lynq_gnss_init_flag == 0)
+ {
+ RLOGD("stop is not allowed");
+ return -1;
+ }
+ gpshal_set_gps_state_intent(GPSHAL_STATE_STOP);
+ gpshal2mnl_gps_stop();
+ return 0;
+}
+
+int lynq_gnss_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
+{
+ if (hal2mnl_gps_inject_time(time, timeReference, uncertainty) == -1) {
+ RLOGD("hal2mnl_gps_inject_time failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_gnss_inject_location(
+ double latitude,
+ double longitude,
+ float accuracy) {
+ if (hal2mnl_gps_inject_location(latitude, longitude, accuracy) == -1) {
+ RLOGD("hal2mnl_gps_inject_location failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_gnss_delete_aiding_data(GpsAidingData flags) {
+ if (hal2mnl_gps_delete_aiding_data(flags) == -1) {
+ RLOGD("hal2mnl_gps_delete_aiding_data failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_gnss_inject_fused_location(
+ double latitude,
+ double longitude,
+ float accuracy) {
+ // TODO: hal2mnl_gps_inject_fused_location(latitude, longitude, accuracy);
+ UNUSED(latitude);
+ UNUSED(longitude);
+ UNUSED(accuracy);
+ return 0; // 0:ok, non-zero: error; but GPS JNI will ignore it
+}
+/*get extension*/
+int lynq_gnss_start_raw_meas_mode(lynq_raw_gnss_cbs* raw_gnss_cbs)
+{
+ if (g_lynq_gnss_raw_meas_flag == 1)
+ {
+ RLOGD("start twice is not allowed");
+ return -1;
+ }
+ g_lynq_gnss_raw_meas_flag = 1;
+
+ lynq_meas_callbacks = raw_gnss_cbs;
+ raw_cbs = lynq_gnss_get_raw_callbacks();
+ if (NULL == raw_cbs)
+ {
+ RLOGD("callbacks error");
+ return -2;
+ }
+ g_gpshal_ctx.meas_cbs = raw_cbs;
+ RLOGD("liblynq-gnss:Test for adress %p",g_gpshal_ctx.meas_cbs);
+ int ret = hal2mnl_set_gps_measurement(true, true);
+ return (ret > 0)?
+ GPS_GEOFENCE_OPERATION_SUCCESS :
+ GPS_GEOFENCE_ERROR_GENERIC;
+}
+
+int lynq_gnss_stop_raw_meas_mode()
+{
+ if (g_lynq_gnss_raw_meas_flag == 0)
+ {
+ RLOGD("must start raw meas first");
+ return -1;
+ }
+ if (hal2mnl_set_gps_measurement(false, false) == -1) {
+ LOGE("hal2mnl_set_gps_measurement failed because of safe_sendto fail ,strerror:%s \n", strerror(errno));
+ }
+ RLOGD("typethree test: stop gps raw measurement");
+ return 0;
+}
+
+int lynq_gnss_set_start_mode(LYNQ_GNSS_MODE_CONFIGURATION start_mode)
+{
+ int ret = 0;
+ switch (start_mode)
+ {
+ case LYNQ_MODE_GPS_GLONASS:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS);
+ break;
+
+ case LYNQ_MODE_GPS_BEIDOU:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_BEIDOU);
+ break;
+
+ case LYNQ_MODE_GPS_GLONASS_BEIDOU:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU);
+ break;
+
+ case LYNQ_MODE_GPS:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS);
+ break;
+
+ case LYNQ_MODE_BEIDOU:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_BEIDOU);
+ break;
+
+ case LYNQ_MODE_GLONASS:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GLONASS);
+ break;
+
+ case LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO);
+
+ break;
+
+ case LYNQ_MODE_GPS_GALILEO:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GALILEO);
+
+ break;
+
+ case LYNQ_MODE_GPS_GLONASS_GALILEO:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_GALILEO);
+
+ break;
+
+ case LYNQ_MODE_GPS_GALILEO_ONLY:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GALILEO_ONLY);
+
+ break;
+
+ case LYNQ_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
+ mnld_write_cfg(LYNQ_GNSS_MODE , LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO_NAVIC);
+
+ break;
+ default:
+ RLOGD("unknown type of GNSS MODE");
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int lynq_gnss_debug_switch(LYNQ_CONF_SWITCH switch_op)
+{
+ int ret = 0;
+ switch (switch_op)
+ {
+ case LYNQ_SWITCH_DISABLE:
+ mnld_write_cfg(LYNQ_DEBUG_STATUS,LYNQ_CONFIG_DISABLE);
+ break;
+ case LYNQ_SWITCH_ENABLE:
+ mnld_write_cfg(LYNQ_DEBUG_STATUS,LYNQ_CONFIG_ENABLE);
+ break;
+ default:
+ RLOGD("unknown op");
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+int lynq_gnss_epo_switch(LYNQ_CONF_SWITCH switch_op)
+{
+ int ret = 0;
+ switch (switch_op)
+ {
+ case LYNQ_SWITCH_DISABLE:
+ mnld_write_cfg(LYNQ_EPO_STATUS,LYNQ_CONFIG_DISABLE);
+ break;
+ case LYNQ_SWITCH_ENABLE:
+ mnld_write_cfg(LYNQ_EPO_STATUS,LYNQ_CONFIG_ENABLE);
+ break;
+ default:
+ RLOGD("unknown op");
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+int lynq_gnss_output_frequency_set(int frequency)
+{
+ int frequency_turn = frequency;
+
+ int freq_num = 1000/frequency_turn;
+ char freq[LYNQ_MAX_FRREQUENCY];
+ sprintf(freq, "%d", freq_num);
+ mnld_write_cfg(LYNQ_OUTPUT_FREQUENCY,freq);
+ return 0;
+}
+
+lynq_atsvc_outcb atsvc_gnss_outcb;
+void atsvc_incb_entity(const char *input,const int length);
+int lynq_at_cgps(int at_type,char *at_paramter);
+int lynq_at_cgpsnmea(int at_type,char *at_paramter);
+
+int at_gps_status = 0;
+int at_gpsnmea_status = 0;
+
+int strUpper(char * str)
+{
+ int i=0;
+ while(1)
+ {
+ if(str[i]=='\0')
+ {
+ break;
+ }
+ if(str[i]>='a'&&str[i]<='z')
+ {
+ str[i]=str[i]-32;
+ }
+ i++;
+ }
+ return 0;
+}
+
+int gnss_at_cmd_parse(char *cmd,char *parse_cmd[],int* at_type)
+{
+ if (NULL == cmd || NULL == parse_cmd || NULL == at_type)
+ {
+ return -1;
+ }
+ int ret = 0;
+ int at_type_jug = 0;
+ int cmd_size;
+ char cmd_buf[128] = {0};
+ char buffer1[128] = {0};
+ char buffer2[128] = {0};
+ bzero(cmd_buf,128);
+ bzero(buffer1,128);
+ bzero(buffer2,128);
+ cmd_size = strlen(cmd);
+ memcpy(cmd_buf,cmd,cmd_size);
+ strUpper(cmd_buf);
+ ret = sscanf(cmd_buf, "%[^=]=%[^=]", buffer1,buffer2);
+ if (ret == 1)
+ {
+ *at_type = 1;
+ sscanf(buffer1, "%[^?]", buffer2);
+ strcpy(parse_cmd[0],buffer2);
+ return 0;
+ }
+ else if (ret == 2)
+ {
+ at_type_jug = strcmp(buffer2,"?");
+ RLOGD("at_type_jug :%d",at_type_jug);
+ if (at_type_jug == 0)
+ {
+ *at_type = 0;
+ strcpy(parse_cmd[0],buffer1);
+ return 0;
+ }
+ else
+ {
+ *at_type = 2;
+ RLOGD("Buffertest1:buffer1 :%s buffer2 :%s",buffer1,buffer2);
+ strcpy(parse_cmd[0],buffer1);
+ strcpy(parse_cmd[1],buffer2);
+ RLOGD("buffer1 :%s buffer2 :%s",parse_cmd[0],parse_cmd[1]);
+ return 0;
+ }
+ }
+ else
+ {
+ RLOGD("unknown paramters");
+ return -1;
+ }
+}
+
+lynq_atsvc_incb lynq_register_gnss(lynq_atsvc_outcb out_cb)
+{
+ char reg_return[100] = {0};
+ if(NULL == out_cb)
+ {
+ RLOGD("out cb is null");
+ return NULL;
+ }
+ atsvc_gnss_outcb=out_cb;
+ memcpy(reg_return,"gnss register success\r\n",24);
+ atsvc_gnss_outcb(reg_return,24,0);
+ return atsvc_incb_entity;
+}
+
+
+void atsvc_incb_entity(const char *input,const int length)
+{
+ int res = 0;
+ int income_at_type = 0;
+ char at_cmd[512]={0};
+ char gnss_at_cmd[100] = {0};
+ char *parse_atcmd[128]; //argv[0]:at cmd,argv[2]:at paramter
+ if(NULL == input)
+ {
+ RLOGD("input is null");
+ memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));
+ atsvc_gnss_outcb(gnss_at_cmd,strlen("+CME ERROR: 100\r\n"),0);
+ return -1;
+ }
+ if (strlen(input) >= 128)
+ {
+ RLOGD("input size more than 128");
+ memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));
+ atsvc_gnss_outcb(gnss_at_cmd,strlen("+CME ERROR: 100\r\n"),0);
+ return -1;
+ }
+ bzero(at_cmd,512);
+ memcpy(at_cmd,input,strlen(input));
+ res = gnss_at_cmd_parse(at_cmd,parse_atcmd,&income_at_type);
+ if (res != 0)
+ {
+ RLOGD("parse at cmd error");
+ return -1;
+ }
+
+ if (!strcmp(parse_atcmd[0], "AT+CGPS"))
+ {
+ res = lynq_at_cgps(income_at_type,parse_atcmd[1]);
+ if (res != 0)
+ {
+ RLOGD("cgps unknown error");
+ }
+ }
+ else if (!strcmp(parse_atcmd[0], "AT+CGPSNMEA"))
+ {
+ lynq_at_cgpsnmea(income_at_type,parse_atcmd[1]);
+ }
+ else
+ {
+ memcpy(gnss_at_cmd,"+CME ERROR: 100\r\n",strlen("+CME ERROR: 100\r\n"));
+ }
+ memcpy(gnss_at_cmd,"OK\r\n",4);
+ atsvc_gnss_outcb(gnss_at_cmd,4,0);
+}
+
+
+int lynq_at_cgps(int at_type,char *at_paramter)
+{
+ int ret = 0;
+ char cgps_at_res[512]={};
+
+ if (at_type == LYNQ_ATCMD_TEST)
+ {
+ bzero(cgps_at_res,512);
+ memcpy(cgps_at_res,"+CGPS:(0,1)\r\n",strlen("+CGPS:(0,1)"));
+ atsvc_gnss_outcb(cgps_at_res,strlen("+CGPS:(0,1)\r\n"),0);
+ return 0;
+ }
+ else if(at_type == LYNQ_ATCMD_READ)
+ {
+ bzero(cgps_at_res,512);
+ sprintf(cgps_at_res,"+CGPS:<%d>",at_gps_status);
+ atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);
+ return 0;
+ }
+ else if(at_type == LYNQ_ATCMD_WRITE)
+ {
+ if (at_gps_status != atoi(at_paramter))
+ {
+ at_gps_status = atoi(at_paramter);
+ }
+ else
+ {
+ bzero(cgps_at_res,512);
+ memcpy(cgps_at_res,"+CGPS ERROR: same status\r\n",strlen("+CGPS ERROR: same status\r\n"));
+ atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);
+ return -1;
+ }
+ if (at_gps_status == 0)
+ {
+ ret = lynq_gnss_stop();
+ if (ret != 0)
+ {
+ RLOGD("lynq gnss stop fail");
+ return -1;
+ }
+ ret = lynq_gnss_deinit();
+ if (ret != 0)
+ {
+ RLOGD("lynq gnss deinit fail");
+ return -1;
+ }
+ bzero(cgps_at_res,512);
+ memcpy(cgps_at_res,"+CGPS OK\r\n",strlen("+CGPS OK\r\n"));
+ atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);
+ }
+ else if(at_gps_status == 1)
+ {
+ lynq_at_callbacks = lynq_at_get__gnss_callbacks();
+ ret = lynq_gnss_callback_reg(lynq_at_callbacks);
+ if (ret != 0)
+ {
+ RLOGD("lynq gnss callback reg fail");
+ return -1;
+ }
+ ret = lynq_gnss_init();
+ if (ret != 0)
+ {
+ RLOGD("lynq gnss init fail");
+ return -1;
+ }
+ ret = lynq_gnss_start();
+ if (ret != 0)
+ {
+ RLOGD("lynq gnss init fail");
+ return -1;
+ }
+ bzero(cgps_at_res,512);
+ memcpy(cgps_at_res,"+CGPS OK\r\n",strlen("+CGPS OK\r\n"));
+ atsvc_gnss_outcb(cgps_at_res,strlen(cgps_at_res),0);
+ }
+ else
+ {
+ RLOGD("unknown at paramters");
+ bzero(cgps_at_res,512);
+ memcpy(cgps_at_res,"+CGPS ERROR: 100\r\n",strlen("+CGPS ERROR: 100\r\n"));
+ atsvc_gnss_outcb(cgps_at_res,strlen("+CGPS ERROR: 100\r\n"),0);
+ }
+ return 0;
+ }
+}
+
+
+int lynq_at_cgpsnmea(int at_type,char *at_paramter)
+{
+ int ret = 0;
+ char cgpsnmea_at_res[512]={};
+
+ if (at_type == LYNQ_ATCMD_TEST)
+ {
+ bzero(cgpsnmea_at_res,512);
+ memcpy(cgpsnmea_at_res,"+CGPSNMEA:(0,1)\r\n",strlen("+CGPSNMEA:(0,1)"));
+ atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);
+ return 0;
+ }
+ else if(at_type == LYNQ_ATCMD_READ)
+ {
+ bzero(cgpsnmea_at_res,512);
+ sprintf(cgpsnmea_at_res,"+CGPSNMEA:<%d>",at_gpsnmea_status);
+ atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);
+ return 0;
+ }
+ else if(at_type == LYNQ_ATCMD_WRITE)
+ {
+ if (at_gpsnmea_status != atoi(at_paramter))
+ {
+ at_gpsnmea_status = atoi(at_paramter);
+ bzero(cgpsnmea_at_res,512);
+ memcpy(cgpsnmea_at_res,"+CGPSNMEA OK\r\n",strlen("+CGPSNMEA OK\r\n"));
+ atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);
+ }
+ else
+ {
+ RLOGD("unknown at paramters");
+ bzero(cgpsnmea_at_res,512);
+ memcpy(cgpsnmea_at_res,"+CGPSNMEA ERROR: 100\r\n",strlen("+CGPSNMEA ERROR: 100\r\n"));
+ atsvc_gnss_outcb(cgpsnmea_at_res,strlen(cgpsnmea_at_res),0);
+ }
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h
new file mode 100755
index 0000000..04938c9
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_gnsshal.h
@@ -0,0 +1,56 @@
+#ifndef LYNQ_GNSSHAL_H
+#define LYNQ_GNSSHAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include<pthread.h>
+#include "lynq_gnss.h"
+#include "hardware/gps_mtk.h"
+#include "hal2mnl_interface.h"
+#include "gpshal.h"
+#include "gps_mtk.h"
+
+#define LYNQ_GNSS_MODE "GNSS_MODE"
+#define LYNQ_DEBUG_STATUS "debug.dbg2file"
+#define LYNQ_EPO_STATUS "EPO_enabled"
+#define LYNQ_OUTPUT_FREQUENCY "fix_interval"
+
+#define LYNQ_CONF_GPS_GLONASS "0"
+#define LYNQ_CONF_GPS_BEIDOU "1"
+#define LYNQ_CONF_GPS_GLONASS_BEIDOU "2"
+#define LYNQ_CONF_GPS "3"
+#define LYNQ_CONF_BEIDOU "4"
+#define LYNQ_CONF_GLONASS "5"
+#define LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO "6"
+#define LYNQ_CONF_GPS_GALILEO "7"
+#define LYNQ_CONF_GPS_GLONASS_GALILEO "8"
+#define LYNQ_CONF_GPS_GALILEO_ONLY "9"
+#define LYNQ_CONF_GPS_GLONASS_BEIDOU_GALILEO_NAVIC "10"
+
+#define LYNQ_CONFIG_DISABLE "0"
+#define LYNQ_CONFIG_ENABLE "1"
+
+#define LYNQ_MAX_FRREQUENCY 16
+
+GpsCallbacks_ext* lynq__get_gps_callbacks(void);
+
+GpsMeasurementCallbacks_ext* lynq_gnss_get_raw_callbacks(void);
+
+lynq_gnss_cb* lynq_at_get__gnss_callbacks(void);
+
+extern lynq_atsvc_outcb atsvc_gnss_outcb;
+extern int at_gpsnmea_status;
+
+typedef enum{
+ LYNQ_ATCMD_TEST = 0,
+ LYNQ_ATCMD_READ,
+ LYNQ_ATCMD_WRITE
+}LYNQ_ATCMD_TYPE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c
new file mode 100755
index 0000000..deaacc2
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.c
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <log/log.h>
+
+#include "lynq_prop.h"
+
+#define PROPBUF_SIZE 512
+
+
+const char *mnl_prop_path[] = {
+ "/etc/gnss/mnl.prop", /*mainly for target*/
+ "/sbin/mnl.prop", /*mainly for emulator*/
+};
+
+int write_prop(const char *file_name, char* key, char* val) {
+ if(NULL == file_name||NULL == key|| NULL == val)
+ {
+ RLOGD("incoming char error");
+ return -1;
+ }
+ char linebuffer[PROPBUF_SIZE] = {0};
+ char buffer1[PROPBUF_SIZE] = {0};
+ char buffer2[PROPBUF_SIZE] = {0};
+
+ int line_len = 0;
+ int len = 0;
+ int res;
+ int changed = 0;
+ FILE *fp = NULL;
+
+ if (0 != access(file_name, F_OK)) { // if file is not exit, create file
+ RLOGD("access file error(%s), Try to create file", file_name);
+
+ fp = fopen(file_name, "w"); //Create file
+ if (fp == NULL) {
+ RLOGD("create file %s fail(%s)", file_name, strerror(errno));
+ return -1;
+ }
+ } else {
+ fp = fopen(file_name, "r+"); //Read and write
+ if(fp == NULL)
+ {
+ RLOGD("open error, %s", strerror(errno));
+ return -1;
+ }
+ }
+
+ while(fgets(linebuffer, PROPBUF_SIZE, fp)) {
+ line_len = strlen(linebuffer);
+ len += line_len;
+ sscanf(linebuffer, "%[^=]=%[^=]", buffer1,buffer2);
+ RLOGD("buffer1:%s, buffer2:%s", buffer1, buffer2);
+ if(!strcmp(key, buffer1)) {
+ len -= strlen(linebuffer);
+ res = fseek(fp, len, SEEK_SET);
+ if(res < 0) {
+ RLOGD("fseek fail, %s", strerror(errno));
+ fclose(fp);
+ return -1;
+ }
+ RLOGD("Before modify [%s=%s] in file [%s]", buffer1, buffer2, file_name);
+ memset(buffer2, 0, PROPBUF_SIZE);
+ LYNQ_STRNCPY(buffer2, val, PROPBUF_SIZE);
+ strncat(buffer1, "=", PROPBUF_SIZE - strlen(buffer1) - 1);
+ strncat(buffer1, buffer2, PROPBUF_SIZE - strlen(buffer1) - 1);
+ strncat(buffer1, "\n", PROPBUF_SIZE - strlen(buffer1) - 1);
+ RLOGD("After modify [%s] in file [%s]", buffer1, file_name);
+ changed = 1;
+ fprintf(fp, "%s", buffer1);
+ fclose(fp);
+ return 0;
+ }
+ }
+ if(changed == 0) { //Not find key
+ memset(linebuffer, 0, PROPBUF_SIZE);
+ strncat(linebuffer, "\n", PROPBUF_SIZE - strlen(linebuffer) - 1);
+ strncat(linebuffer, key, PROPBUF_SIZE - strlen(linebuffer) - 1);
+ strncat(linebuffer, "=", PROPBUF_SIZE - strlen(linebuffer) - 1);
+ strncat(linebuffer, val, PROPBUF_SIZE - strlen(linebuffer) - 1);
+ strncat(linebuffer, "\n", PROPBUF_SIZE - strlen(buffer1) - 1);
+ RLOGD("Add config [%s] to file [%s]", linebuffer, file_name);
+ res = fseek(fp, 0, SEEK_END);
+ if(res < 0) {
+ RLOGD("fseek fail, %s", strerror(errno));
+ fclose(fp);
+ return -1;
+ }
+ fprintf(fp, "%s", linebuffer);
+
+ fclose(fp);
+ }
+ return 0;
+}
+
+void mnld_write_cfg(char* key, char* val) {
+ int idx;
+ int cnt = sizeof(mnl_prop_path)/sizeof(mnl_prop_path[0]);
+
+ for (idx = 0; idx < cnt; idx++) {
+ if (!write_prop(mnl_prop_path[idx], key, val))
+ break;
+ }
+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h
new file mode 100755
index 0000000..cad51bf
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-gnss/src/lynq_prop.h
@@ -0,0 +1,27 @@
+#ifndef LYNQ_PROP_H
+#define LYNQ_PROP_H
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#define MTK_GPS_DATA_PATH "\"/etc/gnss/\""
+
+#define LYNQ_STRNCPY(dst,src,size) do{\
+ strncpy((char *)(dst), (char *)(src), (size - 1));\
+ (dst)[size - 1] = '\0';\
+ }while(0)
+
+
+
+#define F_OK 0
+
+int write_prop(const char *file_name, char* key, char* val);
+
+void mnld_write_cfg(char* key, char* val);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-misc/LICENSE b/IC_src/mtk/lib/liblynq-misc/LICENSE
new file mode 100755
index 0000000..605b7ea
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/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/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h b/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h
new file mode 100755
index 0000000..4207191
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/include/lynq_misc.h
@@ -0,0 +1,28 @@
+/**
+ * @file misc.h
+ * @author you.chen
+ * @brief
+ * @version 1.0
+ * @date 2023-08-21
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+#ifndef __LYNQ_MISC_H__
+#define __LYNQ_MISC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief lynq_get_security_boot_flag get the flag in efuse
+ * @param enable_flag (output param, 1 for enabled)
+ * @return 0 success, -1 some error occur
+ */
+int lynq_get_security_boot_flag(int * enabled_flag);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //#ifndef __LYNQ_MISC_H__
diff --git a/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp b/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp
new file mode 100755
index 0000000..6e6fe8d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/lynq_misc.cpp
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "lynq_misc.h"
+#include "log/log.h"
+
+#undef LOG_TAG
+#define LOG_TAG "MISC"
+
+int lynq_get_security_boot_flag(int * enabled_flag)
+{
+ int value, ret;
+ if (enabled_flag == NULL)
+ {
+ RLOGE("input param is null ptr");
+ return -1;
+ }
+ *enabled_flag = 0;
+ FILE *pfile=fopen("/proc/device-tree/chosen/atag,devinfo", "r");
+ if (pfile == NULL)
+ {
+ RLOGE("open devinfo fail");
+ return -1;
+ }
+ ret = fseek(pfile, 0x428, 0);
+ if (ret != 0)
+ {
+ RLOGE("seek file fail");
+ fclose(pfile);
+ return -1;
+ }
+ ret = fread(&value, sizeof (value), 1, pfile);
+ if (ret != 1)
+ {
+ RLOGE("read file fail");
+ fclose(pfile);
+ return -1;
+ }
+ fclose(pfile);
+
+ // the third bit of 32bits at 0x428 (index start with 0?), 1 for enabled, 0 not enabled
+ *enabled_flag = (value & 0x8) == 0 ? 0 : 1;
+ return 0;
+}
diff --git a/IC_src/mtk/lib/liblynq-misc/makefile b/IC_src/mtk/lib/liblynq-misc/makefile
new file mode 100755
index 0000000..5864273
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-misc/makefile
@@ -0,0 +1,58 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fPIC
+
+PWD := $(shell pwd)
+
+$(warning ################# lynq misc ROOT: $(ROOT),includedir:$(includedir), PWD :$(PWD))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+ -I$(ROOT)$(includedir) \
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -llog \
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-misc.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 misc EXECUTABLE: $(EXECUTABLE),base:$(base_libdir))
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+
+pack_rootfs:
+ $(warning ################# lynq misc 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/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h b/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h
new file mode 100755
index 0000000..8144df4
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/include/liblynq-rtk.h
@@ -0,0 +1,108 @@
+#ifndef LIBLYNQ_RTK_H
+#define LIBLYNQ_RTK_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ lynq_rtk_log_info,
+ lynq_rtk_log_warn,
+ lynq_rtk_log_err
+} lynq_rtk_log_level;
+
+typedef struct
+{
+ unsigned char bPosFlag;
+ unsigned char bTrackNo;
+ unsigned char bSatNo;
+
+ unsigned char bRtkFlag;
+ double fDiffAge;
+ unsigned int uGpsWeek;
+ double fWeekSeconds;
+ double fUTC;
+ double fLeapSeconds;
+
+ double fPosX;
+ double fPosY;
+ double fPosZ;
+ float fPosXDelta;
+ float fPosYDelta;
+ float fPosZDelta;
+
+ double fLat;
+ double fLong;
+ double fAlt;
+ double fHeightOfGeoid;
+ float fLatStd;
+ float fLongStd;
+ float fAltStd;
+
+ double fVelX;
+ double fVelY;
+ double fVelZ;
+ float fVelXDelta;
+ float fVelYDelta;
+ float fVelZDelta;
+
+ float fVelN;
+ float fVelE;
+ float fVelU;
+ float fVelNDelta;
+ float fVelEDelta;
+ float fVelUDelta;
+
+ float fHorSpeed;
+ float fHorSpeedDelta;
+
+ float fTrueHeading;
+ float fTrueHeadingDelta;
+
+ float fHeading2Ant;
+ float fHeading2AntDelta;
+
+ float fRangeRms;
+ float fPhaseRms;
+
+ float fHDOP;
+ float fPDOP;
+ float fVDOP;
+ float fCN0;
+
+ double fClkTime;
+
+ int iBaseStatus;
+ int iRtkStatus;
+}lynq_rtk_result_info;
+
+typedef void (*lynq_rtk_out_debuginfo)(const char * pBuff, const int length, const int ilevel);
+typedef void (*lynq_rtk_out_postdata)(const unsigned char * pBuff, const int length);
+typedef void (*lynq_rtk_out_basesdkstatus)(const int status);
+typedef void (*lynq_rtk_out_status)(const int status);
+
+typedef void (*lynq_rtk_out_result)(const lynq_rtk_result_info * prtk);
+typedef void (*lynq_rtk_out_result_nmea)(const char * strnmea, const int length);
+
+extern void lynq_rtk_lib_version(char * version);
+extern void lynq_rtk_init();
+extern void lynq_rtk_set_userinfo(const char *username,const char *pwd);
+extern void lynq_rtk_set_deviceID(const char* device_id);
+extern void lynq_rtk_result_cb_reg(lynq_rtk_out_result result_cb);
+extern void lynq_rtk_result_nmea_cb_reg(lynq_rtk_out_result_nmea nmea_cb);
+extern void lynq_rtk_config_log_reg(lynq_rtk_out_debuginfo pdebuginfo);
+extern void lynq_rtk_config_post_reg(lynq_rtk_out_postdata ppostdata);
+extern void lynq_rtk_base_sdkstatus(lynq_rtk_out_basesdkstatus psdkstatus);
+extern void lynq_rtk_base_status(lynq_rtk_out_status pstatus);
+extern void lynq_rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen);
+extern void lynq_rtk_rove_addrawmess(GnssData_ext* data);
+extern void lynq_rtk_setserverIP(const char* server_ip);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so b/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so
new file mode 100755
index 0000000..b1a15aa
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/libRTKFUN.so
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so b/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so
new file mode 100755
index 0000000..b56dd84
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/libcmcc_sdk.so
Binary files differ
diff --git a/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c b/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c
new file mode 100755
index 0000000..460a1bb
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/liblynq-rtk.c
@@ -0,0 +1,192 @@
+#include <stdio.h>
+#include <string.h>
+#include <liblog/lynq_deflog.h>
+#include "rtk_fun.h"
+#include "liblynq-rtk.h"
+
+
+lynq_rtk_out_result lib_result_cb = NULL;
+lynq_rtk_out_result_nmea lib_nmea_cb = NULL;
+lynq_rtk_out_debuginfo lib_debuginfo = NULL;
+lynq_rtk_out_postdata lib_postdata = NULL;
+lynq_rtk_out_basesdkstatus lib_basesdkstatus = NULL;
+lynq_rtk_out_status lib_status = NULL;
+
+
+void librtk_out_result(const rtk_result_info * prtk)
+{
+ /*change rtk_result_info into lynq_result_info*/
+ if (NULL == prtk)
+ {
+ LYERRLOG("result info is NULL return : error");
+ return ;
+ }
+ lynq_rtk_result_info result_info;
+ memset(&result_info,0,sizeof(result_info));
+ memcpy(&result_info,prtk,sizeof(result_info));
+ lib_result_cb(&result_info);
+ return ;
+}
+
+void librtk_out_result_nmea(const char * strnmea, const int length)
+{
+ lib_nmea_cb(strnmea,length);
+ return ;
+}
+
+void librtk_out_debuginfo(const char * pBuff, const int length, const int ilevel)
+{
+ lib_debuginfo(pBuff,length,ilevel);
+ return ;
+}
+
+void librtk_out_postdata(const unsigned char * pBuff, const int length)
+{
+ lib_postdata(pBuff,length);
+ return ;
+}
+
+void librtk_out_basesdkstatus(const int status)
+{
+ lib_basesdkstatus(status);
+ return ;
+}
+
+void librtk_out_status(const int status)
+{
+ lib_status(status);
+ return;
+}
+
+
+
+void lynq_rtk_lib_version(char * version)
+{
+ if (NULL == version)
+ {
+ LYERRLOG("incoming version is NULL, error");
+ return ;
+ }
+ rtk_version(version);
+ return ;
+}
+
+void lynq_rtk_init()
+{
+ LYINFLOG("lib rtk init");
+ rtk_init();
+ return ;
+}
+
+void lynq_rtk_set_userinfo(const char *username,const char *pwd)
+{
+ if (NULL == username || NULL == pwd)
+ {
+ LYERRLOG("invalid username or pwd incoming ,error");
+ return ;
+ }
+ rtk_set_UserInfo(username,pwd);
+ return ;
+}
+
+void lynq_rtk_set_deviceID(const char* device_id)
+{
+ if (NULL == device_id)
+ {
+ LYERRLOG("invalid device_id incoming ,error");
+ return ;
+ }
+ rtk_set_DeviceID(device_id);
+ return ;
+}
+
+void lynq_rtk_result_cb_reg(lynq_rtk_out_result result_cb)
+{
+ if (NULL == result_cb)
+ {
+ LYERRLOG("invalid lynq_rtk_out_result incoming ,error");
+ return ;
+ }
+ lib_result_cb = result_cb;
+ rtk_result_cb(librtk_out_result);
+ return ;
+}
+
+void lynq_rtk_result_nmea_cb_reg(lynq_rtk_out_result_nmea nmea_cb)
+{
+ if (NULL == nmea_cb)
+ {
+ LYERRLOG("invalid lynq_rtk_out_result_nmea incoming ,error");
+ return ;
+ }
+ lib_nmea_cb = nmea_cb;
+ rtk_result_nmea_cb(librtk_out_result_nmea);
+ return ;
+}
+
+void lynq_rtk_config_log_reg(lynq_rtk_out_debuginfo pdebuginfo)
+{
+ if (NULL == pdebuginfo)
+ {
+ LYERRLOG("invalid lynq_rtk_out_debuginfo incoming ,error");
+ return ;
+ }
+ lib_debuginfo = pdebuginfo;
+ rtk_config_log(librtk_out_debuginfo);
+ return ;
+}
+
+void lynq_rtk_config_post_reg(lynq_rtk_out_postdata ppostdata)
+{
+ if (NULL == ppostdata)
+ {
+ LYERRLOG("invalid lynq_rtk_out_postdata incoming ,error");
+ return ;
+ }
+ lib_debuginfo = ppostdata;
+ rtk_config_post(librtk_out_debuginfo);
+ return ;
+}
+
+void lynq_rtk_base_sdkstatus(lynq_rtk_out_basesdkstatus psdkstatus)
+{
+ if (NULL == psdkstatus)
+ {
+ LYERRLOG("invalid lynq_rtk_out_basesdkstatus incoming ,error");
+ return ;
+ }
+ lib_basesdkstatus = psdkstatus;
+ rtk_base_sdkstatus(librtk_out_basesdkstatus);
+ return ;
+}
+
+void lynq_rtk_base_status(lynq_rtk_out_status pstatus)
+{
+ if (NULL == pstatus)
+ {
+ LYERRLOG("invalid lynq_rtk_out_status incoming ,error");
+ return ;
+ }
+ lib_status = pstatus;
+ rtk_status_update(librtk_out_status);
+ return ;
+}
+
+void lynq_rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen)
+{
+ rtk_rove_addnmea(pBuff,iBuffLen);
+ return ;
+}
+
+void lynq_rtk_rove_addrawmess(GnssData_ext* data)
+{
+ rtk_rove_addrawmess(data);
+ return ;
+}
+
+void lynq_rtk_setserverIP(const char* server_ip)
+{
+ rtk_setServerIP(server_ip);
+ return ;
+}
+
diff --git a/IC_src/mtk/lib/liblynq-rtk/makefile b/IC_src/mtk/lib/liblynq-rtk/makefile
new file mode 100755
index 0000000..6469254
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/makefile
@@ -0,0 +1,56 @@
+SHELL = /bin/bash
+RM =rm -f
+
+
+LOCAL_CFLAGS := \
+ -Wall \
+ -g \
+ -Wall \
+ -fPIC \
+ -shared \
+ -D__COMPILE_OPTION__ \
+ -D__LINUX_OS__ \
+
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include/ \
+ -I$(LOCAL_PATH)/ \
+ -I$(ROOT)$(includedir)/gps_hal \
+ -I$(ROOT)$(includedir)/gps_hal/inc \
+ -I$(ROOT)$(includedir)/gps_hal/hardware \
+ -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS := \
+ -L . \
+ -ldl \
+ -lcmcc_sdk\
+ -lRTKFUN \
+ -llynq-log \
+ -lpthread \
+
+
+SOURCES = $(wildcard *.c wildcard src/*.c)
+EXECUTABLE = liblynq-rtk.so
+
+COBJS=$(SOURCES:.c=.o)
+all : $(EXECUTABLE)
+$(EXECUTABLE): $(COBJS)
+ $(CXX) -shared -Wl,--no-undefined $(COBJS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o: %.c
+ $(warning ----->build $<)
+ $(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+%.o : %.cpp
+ $(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+.PHONY: install clean
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+.PHONY: clean
+clean:
+ $(RM) $(COBJS) $(EXECUTABLE)
diff --git a/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h b/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h
new file mode 100755
index 0000000..76cbcdc
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-rtk/rtk_fun.h
@@ -0,0 +1,179 @@
+#ifndef _RTK_FUN_H_
+#define _RTK_FUN_H_
+
+#define RTK_SUPPORT
+#define ENABLE_RTKFUN //RTK�ĺ����ӿ�
+#define ENABLE_RTKCHANGEFREQ //
+
+#include "hardware/gps_mtk.h"
+#include "hardware/gps.h"
+
+
+typedef enum
+{
+ rtk_log_info,
+ rtk_log_warn,
+ rtk_log_err
+} rtk_log_level;
+
+typedef struct
+{
+ unsigned char bPosFlag; //��ǰ��״̬��0����Ч�� 1�����㣻 2��RTD(SBAS)�� 4��RTK fix�� 5��RTK float�� 6��Dead Reckoing�� 7��Fix pos mode�� 8��Sim mode
+ unsigned char bTrackNo; //����������
+ unsigned char bSatNo; //����������
+
+ unsigned char bRtkFlag; //RTKԭʼ��״̬(0:ʧ�� 1:���� 3:����̶� 4:�̶� 5:���� 12:���� 13:����ƽ�� 14:�Ƶ�)
+ double fDiffAge; //�������
+ unsigned int uGpsWeek; //GPSʱ����
+ double fWeekSeconds;//GPSʱ��������
+ double fUTC; //UTCʱ�������1970-01-01 00:00:00��ʼ����
+ double fLeapSeconds;//����
+
+
+ double fPosX; //X����(m)(WGS84)
+ double fPosY; //Y����(m)(WGS84)
+ double fPosZ; //Z����(m)(WGS84)
+ float fPosXDelta; //X����ı����
+ float fPosYDelta; //Y����ı����
+ float fPosZDelta; //Z����ı����
+
+ double fLat; //γ�ȣ���λ�ȣ�
+ double fLong; //���ȣ���λ�ȣ�
+ double fAlt; //���θߣ���λm��
+ double fHeightOfGeoid;//�߳��쳣����λm��
+ float fLatStd; //γ�ȱ���
+ float fLongStd; //���ȱ���
+ float fAltStd; //���θ� ����
+
+ double fVelX; //X������ٶȣ�m/s��
+ double fVelY; //Y������ٶ�
+ double fVelZ; //Z������ٶ�
+ float fVelXDelta; //X�����ٶȱ���
+ float fVelYDelta; //Y�����ٶȱ���
+ float fVelZDelta; //Z�����ٶȱ���
+
+ float fVelN; //�������ٶȣ�m/s)
+ float fVelE; //�������ٶȣ�m/s)
+ float fVelU; //�췽���ٶȣ�m/s)
+ float fVelNDelta; //�������ٶȱ��m/s)
+ float fVelEDelta; //�������ٶȱ��m/s)
+ float fVelUDelta; //�췽���ٶȱ��m/s)
+
+ float fHorSpeed; //�Ե��ٶȣ�m/s)
+ float fHorSpeedDelta;//�Ե��ٶȱ��m/s)
+
+ float fTrueHeading;//���溽��,�켣����ǣ��ȣ����˶�����
+ float fTrueHeadingDelta;//�켣����DZ���ȣ�
+
+ float fHeading2Ant; //˫���ߺ����ݲ�֧�֣����켣����Ǹ�ֵ��
+ float fHeading2AntDelta; //˫���ߺ��ȣ��ݲ�֧�֣����켣����ǵı��ֵ��
+
+ float fRangeRms; //α�ྫ��
+ float fPhaseRms; //�ز�����
+
+ float fHDOP; //HDOP
+ float fPDOP; //PDOP
+ float fVDOP; //VDOP
+ float fCN0; //��ǰ���붨λ���ǵľ�ֵCN0(dBHz)
+
+ double fClkTime; //��ӦMTK���ڲ�gps_clock�е�time_ns�ֶ�
+
+ int iBaseStatus;//ͬrtk_base_sdkstatus��������״̬
+ //RTK����״̬
+ //0x00000001��ʾ��վ����
+ //0x00000002��ʾ��Ч���ǵ���10��
+ //0x00000004��ʾ��Ч��������Ⱦ�ֵ������ֵ��Ĭ��24��
+ //0x00000008��ʾRTK�������ʧ�ܣ�����ʧ�ܰ������ǹ��٣��۲������������ȵͣ���������ȣ�
+ //0x00000010��ʾRTKδ������㣨δ�������ԭ�������վ���ݡ��л�վ���ݵ��ӳٴ���200��PVT��λʧ�ܡ�ʱ���ж��쳣�ȣ�
+ int iRtkStatus;
+
+}rtk_result_info;
+
+typedef void (*rtk_out_debuginfo)(const char * pBuff, const int length, const int ilevel);
+typedef void (*rtk_out_postdata)(const unsigned char * pBuff, const int length);
+typedef void (*rtk_out_basesdkstatus)(const int status);
+typedef void (*rtk_out_status)(const int status);
+
+typedef void (*rtk_out_result)(const rtk_result_info * prtk);
+typedef void (*rtk_out_result_nmea)(const char * strnmea, const int length);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//rtk��ʼ��
+extern void rtk_init();
+
+//ͨ�������û����������½
+extern void rtk_set_UserInfo(const char* user, const char* pwd);
+
+//�����豸ID��½
+extern void rtk_set_DeviceID(const char* device_id);
+
+//�����ƶ�վMTK��NMEA����(GGA/RMC/VTG/GSA/GSV/GST)
+extern void rtk_rove_addnmea(const unsigned char * pBuff, const int iBuffLen);
+
+//�����ƶ�վMTK�Ĺ۲���
+extern void rtk_rove_addrawmess(GnssData_ext* data);
+
+//�����ƶ�վMTK��ԭʼ������֡
+extern int rtk_rove_addrawnav(GnssNavigationMessage * msg);
+
+//rtk��������Ϣ
+extern void rtk_result_cb(rtk_out_result pRtk);
+
+//rtk��Nmea���Ľ��(GGA/RMC/VTG/GSA/GSV/GST)
+extern void rtk_result_nmea_cb(rtk_out_result_nmea pNmea);
+
+//rtk�Ĵ�ӡ��Ϣ,������Ϊ��
+extern void rtk_config_log(rtk_out_debuginfo pLog);
+
+//rtk��������,��������
+extern void rtk_config_post(rtk_out_postdata pOut);
+
+//��վ ��������ݣ�������״̬(�������SDK״̬��)
+extern void rtk_base_sdkstatus(rtk_out_basesdkstatus pBaseStatus);
+
+//rtk�����Ƿ�ر�ijϵͳ
+//bSys------1(GPS) 2(GLO) 3(GAL) 4(QZS) 5(BD2) 6(BD3)
+//bLock-----l(Lock) 0:(unLock)
+extern void rtk_config_lockout(const unsigned char bSys, const unsigned char bLock);
+
+//��ȡRTK�汾�����20�ֽڣ�
+extern void rtk_version(char * strVer);
+
+//rtk�Ƿ��������
+//0:����������Ĭ��״̬��
+//1:�������ߣ�rtk�ӿڲ��ٽ����������룬����sdk���������ͽ������ݣ�ֹͣ������
+//2:���뵥�㶨λ״̬��rtk�ӿڽ��������������������sdkֹͣ����
+extern void rtk_gotosleep(const unsigned char bMode);
+
+//��ȡ��ǰ���õ�DeviceID�����128�ֽڣ�
+extern void rtk_get_DeviceID(char* device_id);
+
+//���÷�����IP��ַ�ӿ�
+//server_ip:��������ַ
+extern void rtk_setServerIP(const char* server_ip);
+
+//����RTK�Ľ�����Ҫ��͵�����ȣ�Ĭ��24
+extern void rtk_setCN0(const unsigned char bCN0);
+
+//����RTK״̬��ӿڣ��������SDK��״̬��+RTK״̬�룬RTK״̬�����¶���)
+//���������ԭʼ�۲�����Ƶ�ʸ���RTK״̬�룬״̬��ύ����֣�����ԭʼ����������ÿ�����һ��״̬���������ߺ������
+//4001:��ԭʼ��������(����3�뼰����)
+//4002:��NMEA��������(����3�뼰����)
+//4003:���������������
+//4004:PVTδ��λ
+//4005:�����ź���(����Ⱦ�ֵ <30)
+//4006:�����ź�һ��(����Ⱦ�ֵ30~35)
+//4007:�����źź�(����Ⱦ�ֵ35~40)
+//4008:�����ź�ǿ(����Ⱦ�ֵ >40)
+extern void rtk_status_update(rtk_out_status pRtkStatus);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _RTK_FUN_H_ */
diff --git a/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h b/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h
new file mode 100644
index 0000000..0e5ff80
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/include/lynq-system-own.h
@@ -0,0 +1,17 @@
+#ifndef LYNQ_SYSTEM_OWN
+#define LYNQ_SYSTEM_OWN
+typedef void (*LYNQ_Lpm_Handler_T) ( int lpm_edge);
+int LYNQ_Lpm_Init(LYNQ_Lpm_Handler_T lynq_lpm_handler);
+int LYNQ_Lpm_Deinit();
+int LYNQ_Autosleep_Enable(int enable);
+int LYNQ_SLP_WakeLock_Lock(const char *name);
+int LYNQ_SLP_WakeLock_Unlock(const char *name);
+void LYNQ_Power_Mode(char *power_mode);
+void LYNQ_Power_Down(int mode);
+int LYNQ_Adc_Show(int adc_num);
+void lynq_lpm_handler(int lpm_edge);
+LYNQ_Lpm_Handler_T LYNQ_Lpm_Handler=NULL;
+int last_state=0;
+#endif
+
+
diff --git a/IC_src/mtk/lib/liblynq-system-own/makefile b/IC_src/mtk/lib/liblynq-system-own/makefile
new file mode 100644
index 0000000..97a234e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/makefile
@@ -0,0 +1,57 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -std=gnu++14 \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -fpermissive \
+
+$(warning ################# RITA ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-system-own.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/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh b/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh
new file mode 100644
index 0000000..188cc03
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/power_mode_own.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+case "$1" in
+ "flight")
+ echo "Sys flight mode" >/dev/console
+ killall -9 lynq-function-test
+ echo 11 | emdlogger_ctrl ##set log status
+ sleep 1
+ mdlogctlstop ##stop modem log
+ echo mem > /sys/power/autosleep ##set autosleep modem
+ /usr/bin/telephony & ##initialize Ril function.
+ sleep 5
+ sh/usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0 ##switch sim card 0
+ echo "RIL_REQUEST_RADIO_POWER 0" > dev/udp/127.0.0.1/8000 ##turn off radio off sim card 0
+ sh/usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1 ##switch sim card 1
+ echo "RIL_REQUEST_RADIO_POWER 0" >/dev/udp/127.0.0.1/8000 ##turn off radio off sim card 1
+ ;;
+
+ "standby")
+ echo "Sys standby mode" >/dev/console
+ killall -9 lynq-function-test
+ echo 7 | emdlogger_ctrl
+ /usr/bin/telephony &
+ sleep 5
+ sh /usr/bin/demoscript/Network_API/SetPrefferredNetworkType.sh 11
+ sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1
+ echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+ sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0
+ echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+ echo mem > /sys/power/autosleep
+ ;;
+
+ "talking")
+ echo "Sys standby mode" >/dev/console
+ killall -9 lynq-function-test
+ echo 7 | emdlogger_ctrl
+ /usr/bin/telephony &
+ sleep 5
+ sh /usr/bin/demoscript/Network_API/SetPrefferredNetworkType.sh 2
+ sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1
+ echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+ sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0
+ echo "RIL_REQUEST_SCREEN_STATE 0" > /dev/udp/127.0.0.1/8000
+ sh /usr/bin/demoscript/CC_API/dialACall.sh <number>
+ echo mem > /sys/power/autosleep
+ ;;
+
+ *)
+ echo $0 'power - start system'
+ ;;
+esac
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c b/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c
new file mode 100644
index 0000000..0c5334a
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-system-own/src/lynq-system-own.c
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+#include <lynq-system-own.h>
+
+void lynq_lpm_handler(int lpm_edge)
+{
+ FILE * fp = NULL;
+ char buft[32] = {0};
+ char * cmd="cat /sys/devices/platform/10005000.pinctrl/mt_gpio | grep 000: | cut -b 8";
+ //printf("[%s][%d]cmd=[%s]\n",__FUNCTION__,__LINE__,cmd);
+
+ fp = popen (cmd, "r");
+ if (fp) {
+ if (fgets(buft, sizeof(buft), fp) != NULL) {
+ //printf("[%s][%d]%s\n",__FUNCTION__,__LINE__,buft);
+ strtok(buft, "\n");
+
+ }
+ pclose(fp);
+ }
+ //printf("[%s][%d]last_state %d\n",__FUNCTION__,__LINE__,last_state);
+ if(atoi(buft)!=last_state){
+ last_state=atoi(buft);
+ lpm_edge=atoi(buft);
+ printf("[%s][%d]lpm_edge=%d\n",__FUNCTION__,__LINE__,lpm_edge);
+ }
+}
+
+int LYNQ_Lpm_Init (LYNQ_Lpm_Handler_T lynq_lpm_handler)
+{
+ LYNQ_Lpm_Handler=lynq_lpm_handler;
+ return 0;
+}
+int LYNQ_Lpm_Deinit (void)
+{
+ LYNQ_Lpm_Handler=NULL;
+ return 0;
+}
+
+void suspendOperatingSystem()
+{
+ system("killall -9 lynq-function-test");
+ system("echo 7 | emdlogger_ctrl");
+ system("/usr/bin/telephony &");
+ system("sleep 5");
+ system("sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 0");
+ system("sh /usr/bin/demoscript/Network_API/RadioOn.sh 0");
+ system("sh /usr/bin/demoscript/DSDS/set_default_sim_all_except_data.sh 1");
+ system("sh /usr/bin/demoscript/Network_API/RadioOn.sh 0");
+ system("echo mem > /sys/power/autosleep");
+}
+
+int LYNQ_Autosleep_Enable(int enable)
+{
+ if(enable){
+ suspendOperatingSystem();
+ }
+ return 0;
+}
+
+int LYNQ_SLP_WakeLock_Lock(const char *name)
+{
+ char gyCmd[64] = {0};
+ sprintf(gyCmd,"echo %s > /sys/power/wake_lock",name);
+ system(gyCmd);
+}
+
+int LYNQ_SLP_WakeLock_Unlock(const char *name)
+{
+ char gyCmd[64] = {0};
+ sprintf(gyCmd,"echo %s > /sys/power/wake_unlock",name);
+ system(gyCmd);
+}
+
+void LYNQ_Power_Mode(char *power_mode)
+{
+ char gyCmd[64] = {0};
+ sprintf(gyCmd,"sh /etc/powerscript/power_mode_own %s",power_mode);
+ system(gyCmd);
+}
+
+void LYNQ_Power_Down(int mode)
+{
+ if(mode){
+ system("reboot");
+ }else{
+ system("init 0");
+ }
+}
+
+int LYNQ_Adc_Show(int adc_num)
+{
+ FILE * fp = NULL;
+ char buft[32] = {0};
+ char * cmd="cat /sys/bus/iio/devices/iio:device0/in_voltage0_BATADC_input";
+ //printf("[%s][%d]cmd=[%s]\n",__FUNCTION__,__LINE__,cmd);
+
+ fp = popen (cmd, "r");
+ if (fp) {
+ if (fgets(buft, sizeof(buft), fp) != NULL) {
+ //printf("[%s][%d]%s\n",__FUNCTION__,__LINE__,buft);
+ strtok(buft, "\n");
+
+ }
+ pclose(fp);
+ }
+ return atoi(buft);
+}
+
+
diff --git a/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h b/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h
new file mode 100755
index 0000000..87bb23d
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/include/liblynq-thermal/lynq_get_thermal.h
@@ -0,0 +1,44 @@
+#ifndef __LYNQ_GET_THERMAL_H__
+#define __LYNQ_GET_THERMAL_H__
+
+#define LYNQ_THM_PATH 256
+
+#define TYPE_PATH_PRE "/sys/class/thermal"
+
+#define LYNQ_THM_OK 0
+#define LYNQ_THM_OPEN_ERROR -1
+#define LYNQ_THM_READ_ERROR -2
+#define LYNQ_THM_ACCESS_ERROR -3
+#define LYNQ_THM_ZONE_ERROR -4
+
+#define LYNQ_THM_ZONE_KEY "thermal_zone"
+#define LYNQ_THM_COOLER_KEY "cooling_device"
+
+typedef enum {
+ soc_max=0,
+ cpu0,
+ cpu1,
+ cpu2,
+ cpu3,
+ gpu0,
+ gpu1,
+ dramc,
+ mmsys,
+ md_5g,
+ md_4g,
+ md_3g,
+ soc_dram_ntc,
+ pa_5g,
+ pa_4g,
+ rf_ntc,
+ pmic,
+ pmic_vcore,
+ pmic_vpro,
+ pmic_vgpu=19,
+} ZONE_NUM;
+
+char* lynq_read_version();
+int read_sys_info(char *sys_path, char *out_buf, int out_buf_len);
+int lynq_get_zone_tmp(ZONE_NUM num, int *temp);
+
+#endif //__LYNQ_GET_THERMAL_H__
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq-thermal/makefile b/IC_src/mtk/lib/liblynq-thermal/makefile
new file mode 100755
index 0000000..bae164e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/makefile
@@ -0,0 +1,85 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -std=gnu++14 \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -fpermissive \
+
+$(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 ################# 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 \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-thermal.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/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c b/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c
new file mode 100755
index 0000000..dad9076
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-thermal/src/lynq_get_thermal.c
@@ -0,0 +1,74 @@
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "liblynq-thermal/lynq_get_thermal.h"
+
+
+char* lynq_read_version()
+{
+ return "THERMAL-V1.0";
+}
+
+int read_sys_info(char *sys_path, char *out_buf, int out_buf_len)
+{
+ int fd, ret;
+ char buf[LYNQ_THM_PATH] = "";
+
+ if (NULL == out_buf)
+ return LYNQ_THM_ZONE_ERROR;
+
+ if ((access(sys_path, F_OK)) == -1)
+ return LYNQ_THM_ACCESS_ERROR;
+
+ fd = open(sys_path, O_RDONLY);
+
+ if (fd < 0)
+ {
+ printf("[%s-%d] open error!!!\n", __FUNCTION__, __LINE__);
+ return LYNQ_THM_OPEN_ERROR;
+ }
+
+ ret = read(fd, buf, sizeof(buf));
+
+
+ if(ret<0){
+ close(fd);
+ printf("[%s-%d] read error!!!\n", __FUNCTION__, __LINE__);
+ return LYNQ_THM_READ_ERROR;
+ }
+ memcpy(out_buf, buf, out_buf_len);
+ close(fd);
+
+ return LYNQ_THM_OK;
+}
+
+int lynq_get_zone_tmp(ZONE_NUM num, int *temp)
+{
+ char tz_path[LYNQ_THM_PATH] = "";
+ char buf[LYNQ_THM_PATH] = "";
+
+ if(num < 0 || num > 19)
+ {
+ printf("[%s-%d] no such device,please reinput!!\n", __FUNCTION__, __LINE__);
+ return LYNQ_THM_ZONE_ERROR;
+ }
+
+ if(NULL == temp)
+ return LYNQ_THM_ZONE_ERROR;
+
+ sprintf(tz_path, "%s/%s%d/temp", TYPE_PATH_PRE, LYNQ_THM_ZONE_KEY, num);
+
+ int ret = read_sys_info(tz_path, buf, LYNQ_THM_PATH);
+ if(!ret)
+ {
+ if(strlen(buf))
+ *temp = atoi(buf);
+ }
+
+ return ret;
+}
diff --git a/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h b/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h
new file mode 100755
index 0000000..53006b8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/include/libwifi6.h
@@ -0,0 +1,272 @@
+/**@File libwifi6.h
+* @Brief :about function test
+* @details :
+* @Author : qs.xiong
+* @Date : 2022-3-14
+* @Version : V1.0
+* @copy ritght : Copyright (c) MobileTek
+*/
+#ifndef __LIBWIFI6_H__
+#define __LIBWIFI6_H__
+
+typedef enum {
+ LYNQ_WIFI_BANDWIDTH_HT10 = 0, // not support in ap mode
+ LYNQ_WIFI_BANDWIDTH_HT20,
+ LYNQ_WIFI_BANDWIDTH_HT40, // not support in ap mode
+ LYNQ_WIFI_BANDWIDTH_HT80,
+}lynq_wifi_bandwidth_type_m;
+
+typedef enum {
+ LYNQ_WIFI_AUTH_OPEN = 0,
+ LYNQ_WIFI_AUTH_WEP, // not support WEP
+ LYNQ_WIFI_AUTH_WPA_PSK,
+ LYNQ_WIFI_AUTH_WPA2_PSK,
+ LYNQ_WIFI_AUTH_WPA2_WPA3_PSK,
+ LYNQ_WIFI_AUTH_WPA3_PSK,
+}lynq_wifi_auth_s;
+
+typedef enum {
+ LYNQ_WIFI_2G_band = 1,
+ LYNQ_WIFI_5G_band,
+ LYNQ_WIFI_2_and_5G_band, //not support
+}lynq_wifi_band_m;
+
+typedef enum {
+ LYNQ_WIFI_AP_STATUS_DISABLE = 0,
+ LYNQ_WIFI_AP_STATUS_ENABLE, //ap is running status
+}lynq_wifi_ap_run_status_s;
+
+typedef enum {
+ LYNQ_WIFI_STA_STATUS_DISABLE = 0,
+ LYNQ_WIFI_STA_STATUS_ENABLE, //sta is running status
+}lynq_wifi_sta_run_status_s;
+
+typedef enum {
+ LYNQ_WIFI_INTERFACE_0 = 0, //sta
+ LYNQ_WIFI_INTERFACE_1, //ap
+}lynq_wifi_index_e;
+
+typedef enum {
+ LYNQ_WIFI_STATUS_DISCONNECT = 0,
+ LYNQ_WIFI_STATUS_CONNECT,
+ LYNQ_WIFI_SERVICE_ABNORMAL,
+}lynq_wifi_ap_status_s;
+
+typedef struct ap_info
+{
+ char ap_ip[32];
+ char ap_mac[32];
+ char ap_ssid[64];
+ char psw[64]; //password
+ lynq_wifi_auth_s auth;
+ lynq_wifi_band_m band;
+}ap_info_s;
+
+typedef struct device_info
+{
+ char sta_ip[32];
+ char sta_mac[32];
+ char hostname[32];
+ lynq_wifi_ap_status_s status;
+}device_info_s;
+
+typedef struct scan_info
+{
+ char mac[32];
+ char ssid[64];
+ lynq_wifi_band_m band;
+ lynq_wifi_auth_s auth;
+ int rssi;
+}scan_info_s;
+
+typedef struct ap_detail_info
+{
+ struct ap_info base_info; // base_info : base info of strcut ap_info
+ lynq_wifi_ap_run_status_s status; // status:is not running 1:is running
+ int rssi; //[0~199]
+}ap_detail_info_s;
+
+typedef struct saved_ap_info
+{
+ struct ap_info base_info;
+}saved_ap_info_s;
+
+
+// insmod drive and start service of wifi
+int lynq_wifi_enable(void);
+//rmmod drive
+int lynq_wifi_disable(void);
+//set ssid of ap
+int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid);
+//get ap of ssid
+int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx,char *ap_ssid);
+
+//set frquency for ap
+int lynq_wifi_ap_frequency_set(lynq_wifi_index_e idx,int lynq_wifi_frequency);
+//get freuency of ap
+int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency);
+
+//set bandwidth for ap
+int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth);
+//get thr bandwidth of ap
+int lynq_wifi_ap_bandwidth_get(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m *bandwidth);
+
+//set channel for ap
+int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel);
+//get channel of ap
+int lynq_wifi_ap_channel_get( lynq_wifi_index_e idx,int* channel);
+
+//set auth for ap
+int lynq_wifi_ap_auth_set(lynq_wifi_index_e idx, lynq_wifi_auth_s auth);
+//get ap auth
+int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth);
+
+//start ap
+int lynq_wifi_ap_start(lynq_wifi_index_e idx);
+//stop ap
+int lynq_wifi_ap_stop(lynq_wifi_index_e idx);
+//restart ap
+int lynq_wifi_ap_restart(lynq_wifi_index_e idx);
+
+//hide ssid
+int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx);
+//unhide ssid
+int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx);
+
+//set the password for ap
+int lynq_ap_password_set(lynq_wifi_index_e idx, char *password);
+//get the ap password
+int lynq_ap_password_get(lynq_wifi_index_e idx, char *password);
+
+//set the password to connet to dest_ap
+int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password);
+int lynq_sta_ssid_password_get(lynq_wifi_index_e idx, ap_info_s *ap, char *password);
+
+//get the ssid of sta
+int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx,char *sta_ssid);
+//get availble device info such as:ssid mac band rssi status auth
+int lynq_wifi_get_sta_available_ap(lynq_wifi_index_e idx,ap_detail_info_s *info);
+
+
+
+//get the sta connect ap auth
+int lynq_wifi_get_sta_auth(lynq_wifi_index_e idx, lynq_wifi_auth_s* auth); //auth 0:OPEN 1:WEP 2:WPA-PSK 3:WPA2-PSK
+
+//sta start connect to dest_ap
+int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw);
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout);
+//disconnect
+int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx,char *ssid);
+int lynq_wifi_sta_disconnect_ap(lynq_wifi_index_e idx,char *ssid);
+
+//start sta mode;enable sta
+int lynq_wifi_sta_start(lynq_wifi_index_e idx);
+int lynq_wifi_sta_start_auto(lynq_wifi_index_e idx);
+//stop sta:disable sta
+int lynq_wifi_sta_stop(lynq_wifi_index_e idx);
+
+//Get all device info linked ap
+int lynq_get_ap_device_list(lynq_wifi_index_e idx, ap_info_s **ap, device_info_s ** list,int * len); //list info:mac ip hostname status len:device len
+//Get scan_result info
+int lynq_get_scan_list(lynq_wifi_index_e idx, scan_info_s ** list,int * len); //list info:mac ssid band auth rssi len:scan_info len
+int lynq_sta_forget_ap(lynq_wifi_index_e idx, char *ssid,lynq_wifi_auth_s auth);
+int lynq_get_sta_saved_ap(lynq_wifi_index_e idx,saved_ap_info_s ** list,int * len); //len: length of saved_ap_info
+
+//start scan availbale ap active
+int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx);
+
+//add for STA auto connect
+int lynq_wifi_sta_stop_net(lynq_wifi_index_e idx,int networkid);
+/*
+ * event usage:
+ * first declare a funcion like AP_CALLBACK_FUNC_PTR to recv messge from wifi lib
+ * call lynq_reg_ap_event_callback to register whih private data pointer and the callback fuction pointer declared before
+ * when envent comes the last registered callback function will been called
+ */
+
+typedef void(*AP_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_ap_status_s status);
+int lynq_reg_ap_event_callback(void *priv, AP_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_ap_event_callback(void *priv);
+
+typedef enum {
+ LYNQ_WIFI_STA_STATUS_DISCONNECT = 0,
+ LYNQ_WIFI_STA_STATUS_CONNECT,
+ LYNQ_WIFI_STA_STATUS_SCAN_RESULT, //finish sta scan
+ LYNQ_WIFI_STA_STATUS_CONNECT_FAIL,
+ LYNQ_WIFI_STA_SERVICE_ABNORMAL,
+ LYNQ_WIFI_STATUS_EGNORE,
+}lynq_wifi_sta_status_s;
+typedef enum
+{
+ LYNQ_TIME_OUT = 0,
+ LYNQ_UNSPECIFIED_REASON,
+ LYNQ_AUTHENTICATION_NO_LONGER_VALID,
+ LYNQ_PSW_ERROR,
+ LYNQ_AUTH_ERROR,
+ LYNQ_AP_UNABLE_HANDLE,
+ LYNQ_NOT_FIND_AP,
+ LYNQ_WAIT_CONNECT_ACTIVE,
+}error_number_s;
+
+typedef void(*STA_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_sta_status_s status, error_number_s number);
+int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_sta_event_callback(void * priv);
+typedef void(*STA_AUTO_CALLBACK_FUNC_PTR)(void *priv, lynq_wifi_sta_status_s status, error_number_s number,int networkid);
+int lynq_reg_sta_auto_event_callback(void * priv, STA_AUTO_CALLBACK_FUNC_PTR cb);
+int lynq_unreg_sta_auto_event_callback(void * priv);
+
+//get current ap status
+int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status);
+//get curent sta status
+int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status);
+
+//set the country code
+int lynq_get_country_code(lynq_wifi_index_e idx, char *country_code);
+//get current country code
+int lynq_set_country_code(lynq_wifi_index_e idx, char *country_code);
+
+//get wlan0/ap0 ip or mac
+int lynq_get_interface_ip(lynq_wifi_index_e idx,char *ip);
+int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac);
+
+
+//get current connect ap mac rssi band
+int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac);
+int lynq_get_connect_ap_rssi(lynq_wifi_index_e idx,int * rssi);
+int lynq_get_connect_ap_band(lynq_wifi_index_e idx,lynq_wifi_band_m * band);
+int lynq_get_connect_ap_ip(lynq_wifi_index_e idx,char *ip);
+int lynq_get_sta_connected_dns(lynq_wifi_index_e idx,char *dns);
+/*****add limit of connected ap device number 2022.10.12 by qs.xiong
+ *
+ *sta_number:
+ * ap max be connected no more than 15
+ * so sta_number : [1-15]
+ */
+int lynq_ap_connect_num(int sta_number);
+
+/****add acs contrl api*****************
+ *
+ *idx:
+ * 1 is ap and only 1 is legal in this api
+ *acs_mode:
+ * 2 is open acs at 2.4GHz
+ * 5 is open acs at 5GHz
+ * didnt ssuport 2.4G&5G together
+ * add by qs.xiong 20221012*************/
+int lynq_enable_acs(lynq_wifi_index_e idx,int acs_mode);
+
+//you.chen add for tv-box start
+/**
+ * @brief enableGBW, repeat call will fail before disableGBW
+ * @param mac of tv-box
+ * @return
+ */
+int enableGBW(const char* mac);
+/**
+ * @brief disableGBW
+ * @return
+ */
+int disableGBW();
+//you.chen add for tv-box end
+
+#endif
diff --git a/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
new file mode 100755
index 0000000..60c4224
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
@@ -0,0 +1,5221 @@
+/**@File lib_wifi6.c
+* @Brief :about function test
+* @details :
+* @Author : you.chen
+* @Date : 2022-4-6
+* @Version : V1.0
+* @copy ritght : Copyright (c) MobileTek
+*/
+#include <log/log.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libwifi6.h"
+#include <wpa_ctrl.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include "log/log.h"
+#include <sys/time.h>
+#include <asm/errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_WIFI"
+#define MAX_CMD 128
+#define MAX_RET 4096
+#define MODE_LEN 10
+#define CTRL_STA 0
+#define CTRL_AP 1
+#define AP_NETWORK_0 0
+#define STA_MAX_SAVED_AP_NUM 50
+#define MAC_LEN 17
+
+pthread_t g_ap_watcher_pid = 0;
+volatile int g_ap_watcher_stop_flag = 0;
+volatile int g_ap_watcher_started_flag = 0;
+
+pthread_t g_ap_tmp_watcher_pid = 0;
+volatile int g_ap_tmp_watcher_stop_flag = 0;
+
+pthread_t g_sta_watcher_pid = 0;
+volatile int g_sta_watcher_stop_flag = 0;
+volatile int g_sta_scan_finish_flag = 1;
+volatile int g_sta_watcher_started_flag = 0;
+volatile int g_sta_conncet_status_flag = 0;
+volatile int g_sta_fake_scan_finish_flag = 0;
+
+pthread_t g_sta_auto_watcher_pid = 0;
+volatile int g_sta_auto_watcher_stop_flag = 0;
+volatile int g_sta_auto_scan_finish_flag = 1;
+volatile int g_sta_auto_watcher_started_flag = 0;
+void * g_ap_callback_priv = NULL;
+AP_CALLBACK_FUNC_PTR g_ap_callback_func = NULL;
+void * g_sta_callback_priv = NULL;
+STA_CALLBACK_FUNC_PTR g_sta_callback_func = NULL;
+void * g_sta_auto_callback_priv = NULL;
+STA_AUTO_CALLBACK_FUNC_PTR g_sta_auto_callback_func = NULL;
+
+
+//const char * CTRL_PATH="/var/run/wpa_supplicant";
+const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/ap0"};
+//const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/wlan0"};
+const char * cmd_list_networks = "LIST_NETWORKS";
+const char * cmd_save_config = "SAVE_CONFIG";
+const char * cmd_disconnect = "DISCONNECT";
+const char * cmd_remove_all = "REMOVE_NETWORK all";
+const char * state_scan_result = "CTRL-EVENT-SCAN-RESULTS";
+const char * STATE_COMPLETED = "COMPLETED";
+const char * STATE_SCANNING = "SCANNING";
+const char * STATE_DISCONNECTED = "DISCONNECTED";
+
+const char * cmd_ping = "PING";
+const char * rsp_pong = "PONG";
+const int SLEEP_TIME_ON_IDLE = 100 * 1000; // usecond
+const int MAX_IDLE_COUNT = 600; // 60s
+
+const char * start_wg870_service_script = "/etc/wg870/scripts/start_wg870_service.sh";
+const char * get_interface_name_script = "/etc/wg870/scripts/get_interface_name.sh";
+const char * start_stop_sta_script = "/etc/wg870/scripts/start_stop_sta.sh";
+const char * start_stop_ap_script = "/etc/wg870/scripts/start_stop_ap.sh";
+const char * sta_status_change_script = "/etc/wg870/scripts/sta_status_change.sh";
+
+static char s_ap_iterface_name[64] = {0};
+
+struct local_wpa_ctrl{
+ struct wpa_ctrl *ctrl;
+ pthread_mutex_t mutex;
+};
+
+volatile int g_history_disconnect_valid_num = 0;
+int g_history_disconnect_net[128];
+
+static pthread_mutex_t s_check_wpa_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_sta_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_ap_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+// add for auto connect
+static pthread_mutex_t s_sta_auto_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static struct local_wpa_ctrl * g_lynq_wpa_ctrl[2] = {0};
+
+//you.chen add for tv-box start
+volatile int g_gbw_enabled = 0;
+char * g_gbw_mac = NULL;
+pthread_t g_gbw_watcher_pid = 0;
+static int startGBW();
+static int stopGBW();
+//you.chen add for tv-box end
+
+typedef struct __curr_status_info {
+ ap_info_s *ap;
+ char * state;
+ int net_no;
+}curr_status_info;
+
+typedef enum {
+ INNER_STA_STATUS_INIT = 0,
+ INNER_STA_STATUS_CONNECTING,
+ INNER_STA_STATUS_ASSOCIATING,
+ INNER_STA_STATUS_ASSOCIATED,
+ INNER_STA_STATUS_CONNECTED,
+ INNER_STA_STATUS_DISCONNECTING,
+ INNER_STA_STATUS_DISCONNECTED,
+ INNER_STA_STATUS_CANCEL,
+}inner_sta_status_s;
+
+static pthread_cond_t s_global_check_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t s_global_check_mutex = PTHREAD_MUTEX_INITIALIZER;
+volatile inner_sta_status_s s_sta_status = INNER_STA_STATUS_INIT;
+static error_number_s s_sta_error_number = -1;
+static char s_sta_current_connecting_ssid[64] = {0};
+static struct timespec s_sta_connect_timeout;
+const int MAX_CONNNECT_TIME = 15; // second
+pthread_t g_global_watcher_pid = 0;
+static int s_service_invoke_timeout_cnt=0;
+const int FAKE_MAX_INT_VALUE = 99999;
+
+static void print_disconnect_list()
+{
+ int i;
+ for( i = 0; i < g_history_disconnect_valid_num; i++ )
+ {
+ RLOGD(" list of g_history_disconnect_valid_num is %d histroy_list[%d]:%d --------- %d",g_history_disconnect_valid_num,i,g_history_disconnect_net[i],__LINE__);
+ }
+
+ return;
+}
+
+// idex ----> history_disconnect_list[x] index
+static int removeElement(int idex)
+{
+ RLOGD("into removeElement");
+ if( index < 0 )
+ {
+ RLOGD("WIFI [removeElement] input idex < 0,idex is %d: ",idex);
+ return -1;
+ }
+ RLOGD("%s line: %d g_history_disconnect_net[%d]: %d end g_history_disconnect_net[%d]:%d",__func__,__LINE__,idex,g_history_disconnect_net[idex],g_history_disconnect_valid_num-1, g_history_disconnect_net[g_history_disconnect_valid_num-1]);
+ g_history_disconnect_net[idex] = g_history_disconnect_net[g_history_disconnect_valid_num-1]; //g_history_disconnect_vaild_num -1 for get last index
+ g_history_disconnect_valid_num --;
+ RLOGD("end removeElement");
+ return 0;
+}
+static int check_history_disconenct_ap_list(int val)
+{
+ print_disconnect_list();
+ RLOGD("WIFI[check_history_disconenct_ap_list]into check_history_disconenct_ap_list && input val is %d g_history_disconnect_valid_num is %d line",val,g_history_disconnect_valid_num,__LINE__);
+ int i;
+ for( i = 0; i < g_history_disconnect_valid_num; i++)
+ {
+ if( val == g_history_disconnect_net[i] )
+ {
+ RLOGD("[wifi]-----input val is %d,g_history_disconnect_net[%d]:%d",val,i,g_history_disconnect_net[i]);
+ RLOGD("end check_history_disconenct_ap_list && return network index");
+ return i;
+ }
+ }
+ RLOGD("end check_history_disconenct_ap_list && return fail,didn't need remove networkid %d from list g_history_disconnect_valid_num is %d line %d",val,g_history_disconnect_valid_num,__LINE__);
+ return -1;
+}
+
+
+static void lynq_sta_removeElement(int net_no)
+{
+ int ret;
+
+ ret = check_history_disconenct_ap_list(net_no);
+ if( ret == -1 )
+ {
+ RLOGD("curr_net_no not in history_disconenct_lsit,return 0 %s %d",__func__,__LINE__);
+ return;
+ }else
+ {
+ ret = removeElement(ret);
+ if( ret == 0 )
+ {
+ RLOGD("removeElement pass %s %d",__func__,__LINE__);
+ return;
+ }
+ }
+
+ return;
+}
+
+static void notify_service_invoke_fail(int error)
+{
+ struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+ pthread_mutex_lock(&s_global_check_mutex);
+ if (error == -2) //timeout
+ {
+ s_service_invoke_timeout_cnt++;
+ if (s_service_invoke_timeout_cnt > 10)
+ {
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ }
+ else if (error == -1)
+ {
+ // check if can connect wpa service
+ lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[0]);
+ if (lynq_wpa_ctrl == NULL)
+ {
+ s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ wpa_ctrl_close(lynq_wpa_ctrl);
+ lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[1]);
+ if (lynq_wpa_ctrl == NULL)
+ {
+ s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ wpa_ctrl_close(lynq_wpa_ctrl);
+ }
+
+ pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int system_call_v(const char * fmt, ...)
+{
+ char str_cmd[256] = {0};
+ va_list args;
+ va_start(args, fmt);
+ vsprintf(str_cmd, fmt, args);
+ va_end(args);
+ printf("system call----------%s\n", str_cmd);
+ return system(str_cmd);
+}
+
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len);
+
+static const char * inner_get_ap_interface_name()
+{
+ char * p;
+ char cmd[128]={0};
+
+ sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+ if (0 != exec_cmd(cmd, s_ap_iterface_name, sizeof(s_ap_iterface_name)) || s_ap_iterface_name[0] == '\0')
+ {
+ memset(s_ap_iterface_name, 0, sizeof (s_ap_iterface_name));
+ return NULL;
+ }
+ p = strchr(s_ap_iterface_name, ' ');
+ if (NULL != p)
+ {
+ *p = '\0';
+ }
+ p = strchr(s_ap_iterface_name, '\n');
+ if (NULL != p)
+ {
+ *p = '\0';
+ }
+ if (s_ap_iterface_name[0] == '\0')
+ {
+ return NULL;
+ }
+
+ return s_ap_iterface_name;
+}
+
+static void check_tether_and_notify()
+{
+ RLOGD("check_tether_and_notify called");
+ if (inner_get_ap_interface_name() == NULL || 0 == system_call_v("ifconfig | grep %s", s_ap_iterface_name))
+ {
+ return;
+ }
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+ pthread_cond_signal(&s_global_check_cond);
+ pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int local_wpa_ctrl_request(struct local_wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+ char *reply, size_t *reply_len,
+ void (*msg_cb)(char *msg, size_t len))
+{
+ int ret;
+ if (ctrl->ctrl == NULL) {
+ RLOGE("local_wpa_ctrl_request ctrl is null\n");
+ return -1;
+ }
+ pthread_mutex_lock(&ctrl->mutex);
+ ret = wpa_ctrl_request(ctrl->ctrl, cmd, cmd_len, reply, reply_len, msg_cb);
+ pthread_mutex_unlock(&ctrl->mutex);
+ if (ret != 0)
+ {
+ notify_service_invoke_fail(ret);
+ }
+ return ret;
+}
+
+static struct local_wpa_ctrl * inner_get_wpa_ctrl(int index) {
+ int repeat_cnt;
+ struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ RLOGD("inner_get_wpa_ctrl\n");
+ for (repeat_cnt = 0; repeat_cnt < 5 && NULL == g_lynq_wpa_ctrl[index]; repeat_cnt++) {
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+// printf("wait enable finish\n");
+ usleep(500 * 1000);
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ }
+ if (NULL == g_lynq_wpa_ctrl[index]) {
+ RLOGE("NULL == g_lynq_wpa_ctrl[index]");
+ goto out_addr;
+ }
+ if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+ g_lynq_wpa_ctrl[index]->ctrl = wpa_ctrl_open(CTRL_PATH[index]);
+ if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+ RLOGE("wpa_ctrl_open fail\n");
+ goto out_addr;
+ }
+ pthread_mutex_init(&g_lynq_wpa_ctrl[index]->mutex, NULL);
+ }
+ lynq_wpa_ctrl = g_lynq_wpa_ctrl[index];
+out_addr:
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ return lynq_wpa_ctrl;
+}
+
+#define PRINT_AND_RETURN_VALUE(str,value) \
+{\
+ perror((str));\
+ return (value);\
+}
+
+#define CHECK_IDX(idx, type) do { \
+ if ( (idx == LYNQ_WIFI_INTERFACE_0 && type != CTRL_STA) || (idx == LYNQ_WIFI_INTERFACE_1 && type != CTRL_AP) \
+ || idx < LYNQ_WIFI_INTERFACE_0 || idx > LYNQ_WIFI_INTERFACE_1 ) { \
+ RLOGE("not support create [%s] on interface [%d]\n", (type == CTRL_STA ? "station" : "ap"), idx); \
+ return -1; \
+ } \
+ }while (0)
+
+#define CHECK_WPA_CTRL(index) int ret = 0;\
+ size_t reply_len = MAX_RET; \
+ char cmd_reply[MAX_RET]={0}; \
+ struct local_wpa_ctrl *lynq_wpa_ctrl = NULL; \
+ do{ \
+ lynq_wpa_ctrl = inner_get_wpa_ctrl(index); \
+ if (NULL == lynq_wpa_ctrl) return -1; \
+ }while(0)
+
+#define DO_REQUEST(cmd_str) do { \
+ reply_len = MAX_RET;\
+ cmd_reply[0] = '\0'; \
+ RLOGD("to call [%s]\n", cmd_str); \
+ ret = local_wpa_ctrl_request(lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL); \
+ if (ret != 0) { \
+ RLOGE("call "#cmd_str" fail %d\n", ret); \
+ return ret; \
+ } \
+ cmd_reply[reply_len+1] = '\0'; \
+ RLOGD("cmd replay [ %s ]\n", cmd_reply); \
+ }while(0)
+
+#define DO_OK_FAIL_REQUEST(cmd_str) do { \
+ DO_REQUEST(cmd_str); \
+ if (reply_len >=4 && memcmp(cmd_reply, "FAIL", 4) == 0 ) {\
+ RLOGE("cmd "#cmd_str" return FAIL\n"); \
+ return -1; \
+ } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0) { \
+ RLOGE("cmd "#cmd_str" return not OK|FAIL\n"); \
+ return -1; \
+ } \
+ }while (0)
+
+
+static int check_connection(struct wpa_ctrl * wpa_ctrl)
+{
+ size_t reply_len = MAX_RET;
+ char cmd_reply[MAX_RET]={0};
+ int ret;
+
+ RLOGD("check_connection [%p]", wpa_ctrl);
+ ret = wpa_ctrl_request(wpa_ctrl, cmd_ping, strlen(cmd_ping), cmd_reply, &reply_len, NULL);
+
+ if (ret != 0 || reply_len < 4 || memcmp(cmd_reply, rsp_pong, 4) != 0)
+ {
+ RLOGE("check_connection error: ctrl [%p], ret [%d], reply_len [%d], rsp [%s]", wpa_ctrl, ret, reply_len, cmd_reply);
+ if (ret != 0)
+ {
+ notify_service_invoke_fail(ret);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief check_pending_msg
+ * @param lynq_wpa_ctrl
+ * @return 1 has msg, 0 no msg, -1 error
+ */
+static int check_pending_msg(struct wpa_ctrl ** pp_lynq_wpa_ctrl, int type, int* idle_count, int *started_flag)
+{
+ int ret;
+
+ if (*pp_lynq_wpa_ctrl == NULL) // need connect
+ {
+ *pp_lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[type]); //@todo temp change
+ if (*pp_lynq_wpa_ctrl == NULL)
+ {
+ usleep(SLEEP_TIME_ON_IDLE);
+ return -1;
+ }
+
+ ret = wpa_ctrl_attach(*pp_lynq_wpa_ctrl);
+ if (ret == 0) // attach success
+ {
+ *started_flag = 1;
+ }
+ else
+ {
+ RLOGE("[wifi error]sta watch thread wpa_ctrl_attach fail");
+ wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+ *pp_lynq_wpa_ctrl = NULL;
+ *idle_count = 0;
+ notify_service_invoke_fail(-2);
+ usleep(SLEEP_TIME_ON_IDLE);
+ return -1;
+ }
+ }
+
+ ret = wpa_ctrl_pending(*pp_lynq_wpa_ctrl);
+ if ( ret == 0) // no pending messages
+ {
+ usleep(SLEEP_TIME_ON_IDLE);
+ *idle_count += 1;
+ if (*idle_count > MAX_IDLE_COUNT)
+ {
+ if (check_connection(*pp_lynq_wpa_ctrl) != 0)
+ {
+ wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+ wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+ *pp_lynq_wpa_ctrl = NULL;
+ *idle_count = 0;
+ return -1;
+ }
+ *idle_count = 0;
+ }
+ return 0;
+ }
+ else if ( ret == -1) // on error
+ {
+ RLOGE("[wifi error]sta wpa_ctrl_pending");
+ wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+ wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+ *pp_lynq_wpa_ctrl = NULL;
+ *idle_count = 0;
+ notify_service_invoke_fail(ret);
+ return -1;
+ }
+
+ *idle_count = 0;
+ return 1;
+}
+
+static inline void inner_notify_ap_msg(lynq_wifi_ap_status_s status)
+{
+ pthread_mutex_lock(&s_ap_callback_mutex);
+ if (g_ap_callback_func != NULL)
+ g_ap_callback_func(g_ap_callback_priv, status);
+ pthread_mutex_unlock(&s_ap_callback_mutex);
+}
+
+static void APWatcherThreadProc() {
+ size_t len = MAX_RET;
+ char msg_notify[MAX_RET];
+ int idle_count = 0;
+ char *ptr = NULL;
+ char mac[32] = {0};
+ char cmd[256] = {0};
+
+ struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+ g_ap_watcher_stop_flag = 0;
+
+ while (g_ap_watcher_stop_flag == 0)
+ {
+ if (check_pending_msg(&lynq_wpa_ctrl, CTRL_AP, &idle_count, &g_ap_watcher_started_flag) != 1)
+ {
+ if (g_ap_callback_func != NULL && idle_count == MAX_IDLE_COUNT - 100 )
+ {
+ check_tether_and_notify();
+ }
+
+ continue;
+ }
+
+ memset(msg_notify, 0, MAX_RET);
+ len = MAX_RET;
+ if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+ {
+ msg_notify[len+1] = '\0';
+ RLOGD("APWatcherThreadProc ap------> %s\n", msg_notify);
+ //you.chen change for tv-box start
+ if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL)
+ {
+ inner_notify_ap_msg(LYNQ_WIFI_STATUS_DISCONNECT);
+ ptr = strstr(msg_notify, "AP-STA-DISCONNECTED");
+ if( ptr != NULL)
+ {
+ ptr += strlen("AP-STA-DISCONNECTED ");
+ memcpy(mac,ptr,17);
+ sprintf(cmd,"cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print \"dhcp_release ap0 \"$3\" \"$2\}' | sh",mac);
+ RLOGD("%s %d cmd is %s",__func__,__LINE__,cmd);
+ system(cmd);
+ }
+
+ if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+ {
+ RLOGD("disconect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+ if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+ {
+ stopGBW();
+ }
+ }
+ }
+ else if (strstr(msg_notify, "AP-STA-CONNECTED") != NULL)
+ {
+ inner_notify_ap_msg(LYNQ_WIFI_STATUS_CONNECT);
+ if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+ {
+ RLOGD("conect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+ if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+ {
+ startGBW();
+ }
+ }
+ }
+ else if ( strstr(msg_notify, "Failed to start AP functionality") != NULL )
+ {
+ RLOGD("APWatcherThreadProc ap------> service error");
+ inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+ }
+ else
+ {
+ RLOGD("APWatcherThreadProc ap------> going on check next msg");
+ }
+ //you.chen add for tv-box end
+ } // end if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+ } // end while (g_ap_watcher_stop_flag == 0)
+ if (lynq_wpa_ctrl != NULL)
+ {
+ wpa_ctrl_detach(lynq_wpa_ctrl);
+ wpa_ctrl_close(lynq_wpa_ctrl);
+ }
+}
+
+static void inner_check_connect_error(const char * event_msg, lynq_wifi_sta_status_s state, error_number_s error_num)
+{
+ char * p;
+ const char * try_associat_flag = "Trying to associate";
+ const char * associated_flag = "Associated with ";
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ if (s_sta_status < INNER_STA_STATUS_CONNECTING || s_sta_status >= INNER_STA_STATUS_CONNECTED) //not in connecting stage, egnore
+ {
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return;
+ }
+
+ // youchen@2023-10-17 add for "not notify connect fail directly" begin
+ if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+ {
+ s_sta_error_number = error_num;
+ s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+ RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+ pthread_cond_signal(&s_global_check_cond);
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return;
+ }
+ // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+ if (state == LYNQ_WIFI_STATUS_EGNORE)
+ {
+ if (strstr(event_msg, try_associat_flag) != NULL && strstr(event_msg, s_sta_current_connecting_ssid) != NULL) //associating request ssid
+ {
+ s_sta_status = INNER_STA_STATUS_ASSOCIATING;
+ }
+ else if (s_sta_status == INNER_STA_STATUS_ASSOCIATING && (p=strstr(event_msg, associated_flag)) != NULL)
+ {
+ s_sta_status = INNER_STA_STATUS_ASSOCIATED;
+ }
+ }
+ else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+ {
+ s_sta_error_number = error_num;
+ if (s_sta_status >= INNER_STA_STATUS_ASSOCIATING && strstr(event_msg, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL && error_num != LYNQ_WAIT_CONNECT_ACTIVE)
+ {
+ s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+ RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ }
+ else if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+ {
+ s_sta_status = INNER_STA_STATUS_CONNECTED;
+ RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]);
+static inline char inner_convert_char(char in);
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid, size_t out_ssid_len);
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid);
+
+
+
+/*
+just tmp add for fix sta connect ap fail check ap connect info
+return 0 --->Current no sta device connect this AP
+*/
+static int lynq_connected_ap_sta_status() {
+
+ FILE *fp;
+ size_t i = 0;
+ int ret;
+ char lynq_cmd_ret[MAX_RET]={0};
+
+ if((fp=popen("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 list_sta","r"))==NULL)
+ {
+ perror("popen error!");
+ return -1;
+ }
+ if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+ {
+ perror("fread fail!");
+ ret=pclose(fp);
+ if(ret == -1)
+ perror("close file faild");
+ return -1;
+ }
+ if( strlen(lynq_cmd_ret) < MAC_LEN)
+ {
+ RLOGD("---Current no sta device connect this AP %s %d\n", lynq_cmd_ret,strlen(lynq_cmd_ret));
+ ret=pclose(fp);
+ if(ret==-1)
+ {
+ perror("close file faild");
+ }
+ return 0;
+ }else{
+ ret=pclose(fp);
+ if(ret==-1)
+ {
+ perror("close file faild");
+ }
+ RLOGD("---Current has sta device connect this AP--- %s\n", lynq_cmd_ret);
+ return 1;
+ }
+}
+
+/*
+ just tmp add for fix sta connect ap fail; check fw status
+ return 1 ----> fw status error; need wl down/up
+*/
+static int check_current_fw_status() {
+
+ FILE *fp;
+ FILE *fp1;
+ size_t i = 0;
+ int ret;
+ char lynq_cmd_ret_2g[MAX_RET]={0};
+ char lynq_cmd_ret_5g[MAX_RET]={0};
+
+ const char * fw_status = "0x0096"; //0x0096 is normal fw status
+
+ if((fp=popen("wl shmem 0x15ee a","r"))==NULL)
+ {
+ perror("popen error!");
+ return -1;
+ }
+ if((fread(lynq_cmd_ret_5g,sizeof(lynq_cmd_ret_2g),1,fp))<0)
+ {
+ perror("fread fail!");
+ if(pclose(fp) == -1)
+ perror("close fp file faild");
+ return -1;
+ }
+
+ if((fp1=popen("wl shmem 0x15ee b","r"))==NULL)
+ {
+ perror("popen error!");
+ if(pclose(fp) == -1)
+ perror("clsoe fp file faild");
+ return -1;
+ }
+ if((fread(lynq_cmd_ret_2g,sizeof(lynq_cmd_ret_5g),1,fp1))<0)
+ {
+ perror("fread fail!");
+ if(pclose(fp1) == -1)
+ perror("clsoe fp1 file faild");
+ if(pclose(fp) == -1)
+ perror("clsoe fp file faild");
+ return -1;
+ }
+
+ if ( strncmp(fw_status,lynq_cmd_ret_2g,6) == 0 || strncmp(fw_status,lynq_cmd_ret_5g,6) == 0 )
+ {
+ ret=pclose(fp);
+ if(ret==-1)
+ {
+ perror("close fp file faild");
+ }
+ ret=pclose(fp1);
+ if(ret==-1)
+ {
+ perror("close fp1 file faild");
+ }
+ return 0;
+ }else
+ {
+ ret=pclose(fp);
+ if(ret==-1)
+ {
+ perror("close file faild");
+ }
+ if(pclose(fp1) == -1)
+ {
+ perror("clsoe file fp1 faild");
+ }
+ RLOGD("current fw status --error--");
+ return 1;
+ }
+}
+
+/*
+eg: wl counters info
+sh-3.2# wl counters
+counters_version 30
+datalen 1648
+Slice_index: 0
+reinitreason_counts: 0(0) 1(0) 2(3) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(2) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0)
+reinit 0 reset 2 pciereset 0 cfgrestore 0 dma_hang 0 ampdu_wds 0
+
+check reinit status
+return 0 ===> fw did wl reinit cmd
+*/
+static int check_current_reinit_info()
+{
+ FILE *fp;
+ int ret;
+ char lynq_cmd_ret[MAX_RET]={0};
+ char * dest;
+ char destid[3]={0};
+ if((fp=popen("wl counters","r"))==NULL)
+ {
+ perror("popen error!");
+ return -1;
+ }
+ if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+ {
+ perror("fread fail!");
+ if(pclose(fp) == -1)
+ {
+ perror("close fp file faild");
+ }
+ return -1;
+ }
+ dest = strstr(lynq_cmd_ret,"reinit ");
+ if(dest != NULL)
+ {
+ dest +=strlen("reinit ");
+ RLOGD("current get dest str is %s",dest);
+ memcpy(destid,dest,2);
+ ret = atoi(destid);
+ RLOGD("get current wl counters cmd return counts is %d",ret);
+ if( ret != 0 )
+ {
+ RLOGD("current fw did run cmd wl reinit");
+ if( pclose(fp) == -1 )
+ {
+ perror("close fp file faild");
+ }
+ return 0;
+ }
+ }
+ if( pclose(fp) == -1 )
+ {
+ perror("close fp file faild");
+ }
+ RLOGD("current fw didn't run cmd wl reinit,dest ptr is NULL");
+ return -1;
+}
+
+static void APTmpWatcherThreadProc() {
+
+ int i = 0;
+ int delytime = 300;
+ g_ap_tmp_watcher_stop_flag = 0;
+
+ RLOGD("APTmpWatcherThreadProc ----> ThreadProc start");
+ while(1)
+ {
+ sleep(1);
+ i++;
+ if ( (i % 30) == 0 )
+ {
+ if ( check_current_reinit_info() == 0 )
+ {
+ system("wl reset_cnts");
+ system("wl down");
+ system("wl up");
+ RLOGD("APTmpWatcherThreadProc:check fw did reinit cmd,do down/up reset");
+ }
+ }
+ if ( (i % 10) == 0 )
+ {
+ if( lynq_connected_ap_sta_status() == 0 ) //0 --->no sta device connect this ap
+ {
+ if(check_current_fw_status() == 1) //1 --->current fw status not 0x0096
+ {
+ system("wl down");
+ system("wl up");
+ }
+ }
+ }
+ if ( i == delytime )
+ {
+ i = 0;
+ }
+ if( g_ap_tmp_watcher_stop_flag == 1 ) //quit proc
+ {
+ RLOGD("APTmpWatcherThreadProc ----- > ap closed or wifi disabled");
+ return;
+ }
+
+ }
+
+}
+
+static int lynq_wifi_sta_stop_network(lynq_wifi_index_e idx,int networkid)
+{
+ char LYNQ_DISABLE_CMD[128]={0};
+
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+ RLOGD("LYNQ_DISABLE_CMD is:%s\n",LYNQ_DISABLE_CMD);
+ DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+
+ return 0;
+
+}
+
+static int lynq_wifi_sta_enable_network(lynq_wifi_index_e idx,int networkid)
+{
+ char LYNQ_ENABLE_CMD[128]={0};
+
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+
+
+ sprintf(LYNQ_ENABLE_CMD,"ENABLE_NETWORK %d",networkid);
+ RLOGD("LYNQ_ENABLE_CMD is:%s\n",LYNQ_ENABLE_CMD);
+ DO_OK_FAIL_REQUEST(LYNQ_ENABLE_CMD);
+
+ return 0;
+
+}
+
+static int lynq_tmp_enable_network(lynq_wifi_index_e idx,int net_no_list[],int len)
+{
+
+ int index,networkid;
+
+ for ( index = 0; index < len ;index++)
+ {
+ networkid = net_no_list[index];
+ if( lynq_wifi_sta_enable_network(idx,networkid) != 0 )
+ {
+ RLOGE("[wifi]lynq_tmp_enable_network id is %d fail",networkid);
+ }
+ RLOGD("[wifi]lynq_tmp_enable_network id is %d",networkid);
+ }
+ return 0;
+
+}
+
+
+/*
+ dis_net_list user disconnect list
+*/
+static void lynq_two_arr_merge(int dis_net_list[],int valid_num,int out[],int * outlen)
+{
+ RLOGD("enter %s %d",__func__,__LINE__);
+ print_disconnect_list();
+ int count,ncount,index;
+ int flag = 0;
+ int merge_index = 0;
+ int net_no_list[128];
+
+ for(ncount = 0;ncount < valid_num; ncount++ )
+ {
+ RLOGD("input history disconenct_list[%d] %d %d",ncount,dis_net_list[ncount],__LINE__);
+ }
+
+ index =lynq_get_network_number_list(0, 0, net_no_list,NULL);
+ for( count = 0; count < index; count++)
+ {
+ for(ncount = 0; ncount < valid_num; ncount++)
+ {
+ RLOGD(" %s dis_net_list[%d]->%d %d",__func__,ncount,dis_net_list[ncount],__LINE__);
+ if(net_no_list[count] == dis_net_list[ncount])
+ {
+ RLOGD("[wifi]this is history disconnect idx ----> %d %d",net_no_list[count],__LINE__);
+ flag = 1;
+ break;
+ }
+ }
+ if( flag != 1 )
+ {
+ out[merge_index] = net_no_list[count];
+ RLOGD("out[%d]: %d net_no_list[%d]: %d %d",merge_index,out[merge_index],count,net_no_list[count],__LINE__);
+ merge_index ++;
+ }
+ flag = 0;
+ }
+ * outlen =merge_index;
+ RLOGD("[wifi]lynq_two_arr_merge get len is -----> %d",* outlen);
+ return;
+}
+
+void get_state_error(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error)
+{
+ char *pReason;
+ char *wpanetid;
+ char destid[3] = {0};
+ int tmpdisid = -1;
+ *error = LYNQ_WAIT_CONNECT_ACTIVE;
+ if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+ {
+ *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+ RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d\n",*state,*error);
+ return;
+ }
+
+ if (strstr(modify, "Trying to associate") != NULL)
+ {
+ RLOGD("Current sta is Trying to associate");
+ *state = LYNQ_WIFI_STATUS_EGNORE;
+ g_sta_conncet_status_flag = 1;
+ return;
+ }
+
+ if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+ {
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+ RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d",*state,*error);
+ g_sta_conncet_status_flag = 0;
+ return;
+ }
+
+ if (strstr(modify,"CTRL-EVENT-AUTH-REJECT") != NULL)
+ {
+ *error = LYNQ_PSW_ERROR;
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+ RLOGD("CTRL-EVENT-AUTH-REJECT state:%d,error:%d\n",*state,*error);
+ g_sta_conncet_status_flag = 0;
+ return;
+ }
+ if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+ {
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ wpanetid = strstr(modify,"id=");
+ if ( wpanetid != NULL )
+ {
+ wpanetid +=strlen("id=");
+ memcpy(destid,wpanetid,2);
+ tmpdisid = atoi(destid);
+
+ }
+ pReason = strstr(modify, "reason=");
+ if (pReason != NULL)
+ {
+ pReason += strlen("reason=");
+ if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+ {
+ *error = LYNQ_TIME_OUT;
+ }
+ else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+ {
+ *error = LYNQ_PSW_ERROR;
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+ // tmp fix sta autoconnect connect and disconnect
+ // you.chen@2023-10-17 only disable network during autoconnect
+ if(tmpdisid != -1 && s_sta_status == INNER_STA_STATUS_INIT && lynq_wifi_sta_stop_network(0,tmpdisid) != 0)
+ {
+ RLOGE("stop wlan0 network %d fail",tmpdisid);
+ }
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,tmpnetid:%d",*state,*error,tmpdisid);
+ g_sta_conncet_status_flag = 0;
+ return;
+
+ }
+
+ if (strstr(modify, "CTRL-EVENT-NETWORK-NOT-FOUND") != NULL)
+ {
+ *error = LYNQ_NOT_FIND_AP;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-NETWORK-NOT-FOUND state:%d,error:%d\n",*state,*error);
+ g_sta_conncet_status_flag = 0;
+ return;
+ }
+
+
+ if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+ pReason = strstr(modify, "status_code=");
+ if (pReason != NULL)
+ {
+ pReason += strlen("status_code=");
+ if (memcmp(pReason, "17", 2) == 0)
+ {
+ *error = LYNQ_AP_UNABLE_HANDLE;
+ }
+ else if (memcmp(pReason, "1",1) == 0)
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d\n",*state,*error);
+ g_sta_conncet_status_flag = 0;
+ return;
+ }
+ else
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d\n",*state,*error);
+ return;
+ }
+ }
+
+ if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+ *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d\n",*state,*error);
+ return;
+ }
+
+ if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+ *error = LYNQ_WAIT_CONNECT_ACTIVE;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+ return;
+ }
+
+ // add by qs.xiong 20231026 tmp fix sta association request to the driver failed
+ if (strstr(modify, "Association request to the driver failed") != NULL)
+ {
+ RLOGD("Association request to the driver failed --- recover");
+ system("wl down");
+ system("wl up");
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+ return;
+ }
+ // add by qs.xiong 20231026 tmp fix sta association request to the driver failed end
+
+
+ RLOGD("EVENT : %s\n", modify);
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STATUS_EGNORE;
+ RLOGD("LAST : STA state:%d,error:%d\n",*state,*error);
+ return;
+
+}
+
+void get_state_error_networkid(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error,int *networkid)
+{
+ char *pReason;
+ char *wpanetid;
+ char destid[3];
+ *error = LYNQ_WAIT_CONNECT_ACTIVE;
+ *networkid = -1;
+ if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+ {
+ *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+ RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d,,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+ {
+ RLOGD("[xiong]:wpanetid = strstrmodify;\n");
+ wpanetid = strstr(modify,"id=");
+ if ( wpanetid != NULL )
+ {
+ wpanetid +=strlen("id=");
+ RLOGD("[xiong]:memcpy(destid,wpanetid,0\n");
+ if (memcpy(destid,wpanetid,2) != NULL)
+ {
+ RLOGD("[xiong]:memcpy(destid,wpanetid,1\n");
+ *networkid = atoi(destid);
+ RLOGD("get networkid is %d\n",*networkid);
+ }
+ RLOGD("[xiong]:memcpy(destid,wpanetid,2\n");
+ }
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+ RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+ {
+ wpanetid = strstr(modify,"id=");
+ if ( wpanetid != NULL )
+ {
+ wpanetid +=strlen("id=");
+ if (memcpy(destid,wpanetid,2) != NULL)
+ {
+ *networkid = atoi(destid);
+ RLOGD("get networkid is %d\n",*networkid);
+ }
+ }
+ pReason = strstr(modify, "reason=");
+ if (pReason != NULL)
+ {
+ pReason += strlen("reason=");
+ if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+ {
+ *error = LYNQ_TIME_OUT;
+ }
+ else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+ {
+ *error = LYNQ_PSW_ERROR;
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+ RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+ return;
+ }
+ }
+ if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+ {
+ wpanetid = strstr(modify,"id=");
+ if ( wpanetid != NULL )
+ {
+ wpanetid +=strlen("id=");
+ if (memcpy(destid,wpanetid,2) != NULL)
+ {
+ *networkid = atoi(destid);
+ RLOGD("get networkid is %d\n",*networkid);
+ }
+ }
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+ pReason = strstr(modify, "status_code=");
+ if (pReason != NULL)
+ {
+ pReason += strlen("status_code=");
+ if (memcmp(pReason, "17", 2) == 0)
+ {
+ *error = LYNQ_AP_UNABLE_HANDLE;
+ }
+ else if (memcmp(pReason, "1",1) == 0)
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ else
+ {
+ *error = LYNQ_UNSPECIFIED_REASON;
+ }
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ else
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ }
+ if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+ *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+ {
+ RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+ *error = LYNQ_WAIT_CONNECT_ACTIVE;
+ *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+ RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+ return;
+ }
+ RLOGD("EVENT : %s\n", modify);
+ *error = LYNQ_UNSPECIFIED_REASON;
+ *state = LYNQ_WIFI_STATUS_EGNORE;
+ RLOGD("LAST : STA state:%d,error:%d,network:%d\n",*state,*error,*networkid);
+ return;
+}
+static void notify_connect_status(lynq_wifi_sta_status_s state, error_number_s error)
+{
+ pthread_mutex_lock(&s_sta_callback_mutex);
+ if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+ {
+ RLOGD("STAWatcherThreadProc callback begin ------> %d %d\n", state, error);
+ g_sta_callback_func(g_sta_callback_priv, state, error);
+ RLOGD("STAWatcherThreadProc callback end ------> %d %d\n", state, error);
+ }
+ pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+static void notify_auto_connect_status(lynq_wifi_sta_status_s state, error_number_s error,int networkid)
+{
+ pthread_mutex_lock(&s_sta_callback_mutex);
+ if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+ {
+ RLOGD("STAWatcherThreadProc callback begin ------> %d %d %d\n", state, error,networkid);
+ g_sta_auto_callback_func(g_sta_auto_callback_priv, state, error,networkid);
+ RLOGD("STAAutoWatcherThreadProc callback end ------> %d %d %d\n", state, error,networkid);
+ }
+ pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+
+static void STAWatcherThreadProc() {
+ size_t len = MAX_RET;
+ char msg_notify[MAX_RET];
+ error_number_s error;
+ lynq_wifi_sta_status_s state, last_state = -1;
+ int idle_count = 0;
+
+ struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+ g_sta_watcher_stop_flag = 0;
+
+ RLOGD("STAWatcherThreadProc thread started ------");
+ while (g_sta_watcher_stop_flag == 0)
+ {
+ if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_watcher_started_flag) != 1)
+ {
+ continue;
+ }
+
+ memset(msg_notify, 0, MAX_RET);
+ len = MAX_RET;
+ if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+ {
+ msg_notify[len+1] = '\0';
+ RLOGD("STAWatcherThreadProc sta ------> %s\n", msg_notify);
+ if (strstr(msg_notify, state_scan_result) != NULL)
+ {
+ g_sta_scan_finish_flag = 1;
+ }
+
+ if (g_sta_callback_func == NULL)
+ {
+ continue;
+ }
+ get_state_error(msg_notify,&state,&error);
+ // youchen@2023-10-17 add for "not notify connect fail directly" begin
+ if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+ {
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_DISCONNECT, error);
+ }
+ else if (state == LYNQ_WIFI_STA_STATUS_SCAN_RESULT &&
+ s_sta_status != INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0)
+ {
+ RLOGD("donot report scan result during in call connect manual");
+ }
+ else
+ {
+ notify_connect_status(state, error);
+ }
+ // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+ if (state != LYNQ_WIFI_STA_STATUS_SCAN_RESULT)
+ {
+ inner_check_connect_error(msg_notify, state, error);
+ if (last_state != state)
+ {
+ if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+ {
+ system_call_v("%s %s", sta_status_change_script, "connect");
+ }
+ else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+ {
+ system_call_v("%s %s", sta_status_change_script, "disconnect");
+ }
+ }
+
+ last_state = state;
+ if (g_sta_fake_scan_finish_flag == 1)
+ {
+ g_sta_fake_scan_finish_flag = 0;
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_SCAN_RESULT, 0);
+ }
+ }
+ }
+ }
+ if (lynq_wpa_ctrl != NULL)
+ {
+ wpa_ctrl_detach(lynq_wpa_ctrl);
+ wpa_ctrl_close(lynq_wpa_ctrl);
+ }
+}
+static void STAAutoWatcherThreadProc() {
+ size_t len = MAX_RET;
+ char msg_notify[MAX_RET];
+ error_number_s error;
+ lynq_wifi_sta_status_s state;
+ int idle_count = 0;
+ int networkid;
+ struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+ g_sta_auto_watcher_stop_flag = 0;
+ RLOGD("STAAutoWatcherThreadProc thread started ------");
+ while (g_sta_auto_watcher_stop_flag == 0)
+ {
+ if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_auto_watcher_started_flag) != 1)
+ {
+ continue;
+ }
+ memset(msg_notify, 0, MAX_RET);
+ len = MAX_RET;
+ if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+ {
+ msg_notify[len+1] = '\0';
+ RLOGD("STAAutoWatcherThreadProc sta ------> %s\n", msg_notify);
+ if (strstr(msg_notify, state_scan_result) != NULL)
+ {
+ g_sta_auto_scan_finish_flag = 1;
+ }
+ if (g_sta_auto_callback_func == NULL)
+ {
+ continue;
+ }
+ get_state_error_networkid(msg_notify,&state,&error,&networkid); // add net state error network function
+ notify_auto_connect_status(state, error,networkid);
+ }
+ }
+ if (lynq_wpa_ctrl != NULL)
+ {
+ wpa_ctrl_detach(lynq_wpa_ctrl);
+ wpa_ctrl_close(lynq_wpa_ctrl);
+ }
+}
+
+// this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+static void GlobalWatcherThreadProc()
+{
+ int ret, connect_timeout, service_abnormal;
+ error_number_s error_num = -1;
+ inner_sta_status_s sta_status;
+ scan_info_s *scan_list = NULL;
+ int i, scan_len=0;
+ char connecting_ssid[64];
+ struct timeval now;
+
+ RLOGD("GlobalWatcherThreadProc start to run");
+
+ while (1)
+ {
+ pthread_mutex_lock(&s_global_check_mutex);
+ pthread_cond_wait(&s_global_check_cond,&s_global_check_mutex);
+ if (s_sta_status == INNER_STA_STATUS_CONNECTED)
+ {
+ pthread_mutex_unlock(&s_global_check_mutex);
+ usleep(50*1000);
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+ continue;
+ }
+
+ connect_timeout = 0;
+ service_abnormal = 0;
+ if (s_sta_status >= INNER_STA_STATUS_CONNECTING && s_sta_status < INNER_STA_STATUS_CONNECTED)
+ {
+ while (1)
+ {
+ ret = pthread_cond_timedwait(&s_global_check_cond, &s_global_check_mutex, &s_sta_connect_timeout);
+ if (ret == ETIME)
+ {
+ connect_timeout = 1;
+ }
+ else if (ret != 0)
+ {
+ gettimeofday(&now,NULL);
+ if (now.tv_sec < s_sta_connect_timeout.tv_sec) //time not arrive
+ {
+ usleep(SLEEP_TIME_ON_IDLE);
+ continue;
+ }
+ connect_timeout = 1;
+ }
+ sta_status = s_sta_status;
+ error_num = s_sta_error_number;
+ s_sta_status = INNER_STA_STATUS_INIT;
+ strcpy(connecting_ssid, s_sta_current_connecting_ssid);
+ memset(&s_sta_connect_timeout, 0, sizeof (s_sta_connect_timeout));
+ memset(&s_sta_current_connecting_ssid, 0, sizeof (s_sta_current_connecting_ssid));
+ break;
+ }
+ }
+ if (s_service_invoke_timeout_cnt > 10)
+ {
+ service_abnormal = 1;
+ s_service_invoke_timeout_cnt = 0;
+ }
+ pthread_mutex_unlock(&s_global_check_mutex);
+
+ if (service_abnormal == 1)
+ {
+ sleep(1);
+ RLOGE("wpa service is abnormal info app to exit");
+ notify_connect_status(LYNQ_WIFI_STA_SERVICE_ABNORMAL, -1);
+
+ inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+
+ sleep(FAKE_MAX_INT_VALUE); // wait process to exit
+ }
+
+ if (sta_status == INNER_STA_STATUS_CANCEL)
+ {
+ continue;
+ }
+ else if (sta_status == INNER_STA_STATUS_CONNECTED)
+ {
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+ }
+ else if (connect_timeout == 0 && error_num == LYNQ_NOT_FIND_AP) // not found ap maybe mismatch auth
+ {
+ if (0 == lynq_get_scan_list(0, &scan_list, &scan_len) && NULL != scan_list) // if not found, but scan result exist, maybe auth error
+ {
+ for(i=0; i < scan_len;i++)
+ {
+ if (strcmp(scan_list[i].ssid, connecting_ssid) == 0)
+ {
+ error_num = LYNQ_AUTH_ERROR;
+ break;
+ }
+ }
+ free(scan_list);
+ }
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+ }
+ else if (connect_timeout == 0)
+ {
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+ }
+ else // wait timeout
+ {
+ if (0 != lynq_get_sta_status(LYNQ_WIFI_INTERFACE_0, &sta_status)) // get status fail
+ {
+ ; // wpa service abnormal
+ }
+ else if (sta_status == LYNQ_WIFI_STA_STATUS_ENABLE) // connect ok
+ {
+ RLOGD("GlobalWatcherThreadProc notify connected");
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+ }
+ else
+ {
+ RLOGD("GlobalWatcherThreadProc notify timeout");
+ notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, LYNQ_TIME_OUT);
+ }
+ }
+ } // while (1)
+}
+
+int lynq_wifi_enable(void)
+{
+ int ret = 0;
+ int i;
+ RLOGD("enter lynq_wifi_enable");
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+
+ if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL)
+ {
+ goto out_enable;
+ }
+
+ ret = system(start_wg870_service_script);
+ if (ret != 0)
+ {
+ //printf("service state %d\n", ret);
+ RLOGE("[wifi error]service state %d",ret);
+ ret = -1;
+ goto out_enable;
+ }
+
+ if (g_global_watcher_pid == 0 ) // this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+ {
+ ret=pthread_create(&g_global_watcher_pid,NULL,GlobalWatcherThreadProc,NULL);
+ if(ret<0)
+ {
+ RLOGE("[wifi error]creat GlobalWatcherThreadProc fail");
+ ret = -1;
+ goto out_enable;
+ }
+ }
+
+ g_lynq_wpa_ctrl[0] = malloc(sizeof (struct local_wpa_ctrl));
+ g_lynq_wpa_ctrl[1] = malloc(sizeof (struct local_wpa_ctrl));
+ memset(g_lynq_wpa_ctrl[0], 0 , sizeof(struct local_wpa_ctrl));
+ memset(g_lynq_wpa_ctrl[1], 0 , sizeof(struct local_wpa_ctrl));
+out_enable:
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ return ret;
+}
+
+int lynq_wifi_disable(void)
+{
+ RLOGD("enter lynq_wifi_disable");
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ g_ap_watcher_stop_flag = 1;
+ g_sta_watcher_stop_flag = 1;
+ g_sta_auto_watcher_stop_flag = 1;
+/* g_ap_tmp_watcher_stop_flag = 1;
+ if (g_ap_watcher_pid != 0)
+ pthread_join(g_ap_watcher_pid, NULL);
+*/
+ if (g_sta_watcher_pid != 0)
+ pthread_join(g_sta_watcher_pid, NULL);
+ if (g_sta_auto_watcher_pid != 0)
+ pthread_join(g_sta_auto_watcher_pid, NULL);
+ if (g_lynq_wpa_ctrl[0] != NULL)
+ wpa_ctrl_close(g_lynq_wpa_ctrl[0]);
+ if (g_lynq_wpa_ctrl[1] != NULL)
+ wpa_ctrl_close(g_lynq_wpa_ctrl[1]);
+ if (g_ap_tmp_watcher_pid != 0)
+ pthread_join(g_ap_tmp_watcher_pid, NULL);
+ g_ap_watcher_pid = 0;
+ g_sta_watcher_pid = 0;
+ g_sta_auto_watcher_pid = 0;
+// g_ap_tmp_watcher_pid = 0;
+ g_lynq_wpa_ctrl[0] = NULL;
+ g_lynq_wpa_ctrl[1] = NULL;
+ g_history_disconnect_valid_num = 0; //clean history_disconenct_list info
+ system("systemctl stop wg870_drv_insmod.service");
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ return 0;
+}
+
+static inline char inner_convert_char(char in)
+{
+ if (in >= '0' && in <= '9')
+ {
+ return in - '0';
+ }
+ else if (in >= 'a' && in <= 'f')
+ {
+ return in - 'a' + 10;
+ }
+ else if (in >= 'A' && in <= 'F')
+ {
+ return in - 'A' + 10;
+ }
+ else
+ {
+ return '\xff';
+ }
+}
+
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid, size_t out_ssid_len)
+{
+ char *p;
+ size_t pos = 0;
+ if (NULL == out_ssid)
+ return;
+ //printf("input ssid=[%s]\n", ssid);
+ memset(out_ssid, 0, out_ssid_len);
+ if (NULL == ssid)
+ return;
+ p = strchr(ssid, '\\');
+ if (NULL == p)
+ {
+ strncpy(out_ssid, ssid, out_ssid_len);
+ //printf(" first %s\n", out_ssid);
+ }
+ else
+ {
+ pos = p - ssid;
+ memcpy(out_ssid, ssid, pos);
+ //printf("pos %lu -- %s\n", pos, out_ssid);
+ for(; pos < out_ssid_len; pos ++)
+ {
+ if (p[0] == '\0')
+ {
+ //printf(" out %s\n", out_ssid);
+ return;
+ }
+ else if (p[0] != '\\')
+ {
+ out_ssid[pos] = p[0];
+ p += 1;
+ }
+ else if (p[1] == 'x' || p[1] == 'X')
+ {
+ out_ssid[pos] = inner_convert_char(p[2]) << 4 | inner_convert_char(p[3]);
+ p += 4;
+ }
+ else if (p[1] == '\\')
+ {
+ out_ssid[pos] = '\\';
+ p += 2;
+ }
+ else if (p[1] == 't')
+ {
+ out_ssid[pos] = '\t';
+ p += 2;
+ }
+ else if (p[1] == 'r')
+ {
+ out_ssid[pos] = '\r';
+ p += 2;
+ }
+ else if (p[1] == 'n')
+ {
+ out_ssid[pos] = '\n';
+ p += 2;
+ }
+ else
+ {
+ out_ssid[pos] = p[1];
+ p += 2;
+ }//todo find a better way to convert?
+ }
+ }
+ //printf(" out %s\n", out_ssid);
+}
+
+static int inner_get_param(int interface, int net_no, char* param_name, char * out_put) {
+ int i, ssid_len;
+ char lynq_cmd_get[128]={0};
+ RLOGD("enter inner_get_param");
+ if (out_put == NULL)
+ {
+ RLOGE("output ptr is null");
+ return -1;
+ }
+ if (param_name == NULL)
+ {
+ RLOGE("param ptr is null");
+ return -1;
+ }
+ if (param_name[0] == '\0')
+ {
+ RLOGE("param is empty");
+ return -1;
+ }
+
+ sprintf(lynq_cmd_get, "GET_NETWORK %d %s", net_no, param_name);
+
+ CHECK_WPA_CTRL(interface);
+
+ DO_REQUEST(lynq_cmd_get);
+
+ if (memcmp(cmd_reply, "FAIL", 4) == 0)
+ {
+ RLOGE("wpa_supplicant return cmd_reply is FAIL");
+ return -1;
+ }
+
+// printf("reply len %d, %08x\n", reply_len, (int)out_put);
+ if (strcmp(param_name, "ssid") == 0)
+ {
+ if (cmd_reply[0] == '\"')
+ {
+ ssid_len = reply_len - 1;
+ memcpy(out_put, cmd_reply + 1, ssid_len);
+ if (out_put[ssid_len-1] == '\"')
+ {
+ out_put[ssid_len-1] = '\0';
+ }
+ else
+ {
+ out_put[ssid_len] = '\0';
+ }
+ }
+ else
+ {
+ ssid_len = reply_len / 2;
+ for(i=0; i<ssid_len; i++)
+ {
+ out_put[i] = inner_convert_char(cmd_reply[i*2]) << 4 | inner_convert_char(cmd_reply[i*2 + 1]);
+ }
+ out_put[ssid_len] = '\0';
+ }
+ }
+ else
+ {
+ memcpy(out_put, cmd_reply, reply_len + 1);
+ }
+ return 0;
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]) {
+ int ret = 0;
+ char * end = str + len - 1;
+ results[ret++] = str;
+ while(str < end)
+ {
+ if (*str == delimiter)
+ {
+ *str++ = '\0';
+ results[ret++] = str;
+ continue;
+ }
+ str++;
+ }
+ if (*str == delimiter)
+ {
+ *str = '\0';
+ }
+
+ results[ret] = NULL;
+
+ return ret;
+}
+/*
+ *add func to get conencted STA device ip from dnsmasq ap0.lease
+ *return 0 means get ip success
+ */
+static int inner_get_ip_by_mac_lease(const char * mac, char * ip,int ip_len)
+{
+ char * p;
+ int ret;
+ char cmd[256]={0};
+ if (NULL == mac || NULL == ip)
+ return -1;
+ memset(ip, 0, ip_len);
+ sprintf(cmd, "cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print $3}'", mac);
+ ret = exec_cmd(cmd, ip, ip_len);
+ if( ret == 0 )
+ {
+ p = strchr(ip, '\n');
+ if (NULL != p)
+ {
+ *p = '\0';
+ RLOGD("inner_get_ip_by_mac_lease %s function return is:%d", ip,ret);
+ return ret;
+ }else
+ {
+ ret = -1;
+ }
+ }
+ RLOGD("%s %d function return is:%d",__func__,__LINE__,ret);
+ return ret;
+
+}
+
+static int inner_get_ip_by_mac(const char * mac, char * ip, int ip_len)
+{
+ char * p;
+ int ret = 0;
+ char cmd[256]={0};
+ if (NULL == mac || NULL == ip)
+ return -1;
+ memset(ip, 0, ip_len);
+ sprintf(cmd, "ip n s | grep \"lladdr\" | grep \"%s\" | awk '{print $1}' | grep -v \":\" | head -1", mac);
+ ret = exec_cmd(cmd, ip, ip_len);
+ p = strchr(ip, '\n');
+ if (NULL != p)
+ {
+ *p = '\0';
+ }else
+ {
+ ret = inner_get_ip_by_mac_lease(mac,ip,ip_len);
+ }
+ RLOGD("inner_get_ip_by_mac %s\n", ip);
+ return ret;
+}
+
+static int inner_get_hostname_by_ip(char *ip, char *hostname) {
+ struct in_addr addr ={0};
+ struct hostent *ht;
+ char cmd[64] = {0};
+ char * p;
+ int ret;
+
+ if (ip == NULL || *ip == '\0' || hostname == NULL)
+ {
+ RLOGE("ip == NULL or hostname == NULL");
+ return -1;
+ }
+
+ *hostname = '\0';
+ if (inet_aton(ip, &addr) == 0)
+ {
+ printf("---inet_aton fail\n");
+ return -1;
+ }
+
+ ht = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET);
+
+ if (ht == NULL)
+ {
+ hostname[0] = '\0';
+ sprintf(cmd, "grep -F '%s' /run/wg870/ap0.lease | awk '{print $4}' | tail -1", ip);
+ ret = exec_cmd(cmd, hostname, 32);
+ if (ret == 0)
+ {
+ p = strchr(hostname, '\n');
+ if (p != NULL)
+ {
+ *p = '\0';
+ }
+ return 0;
+ }
+ hostname[0] = '\0';
+ RLOGE("---gethostbyaddr fail\n");
+ herror(NULL);
+ return -1;
+ }
+
+ strcpy(hostname, ht->h_name);
+
+ return 0;
+}
+
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid)
+{
+ int count, index, words_count;
+ char * split_lines[128]= {0};
+ char * split_words[128] = {0};
+ char local_ssid[128] = {0};
+ const char *lynq_wifi_list_networks = "LIST_NETWORKS";
+ RLOGD("[lynq_get_network_number_list] enter lynq_get_network_number_list api");
+
+ CHECK_WPA_CTRL(ap_sta);
+
+ DO_REQUEST(lynq_wifi_list_networks);
+
+ count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+ //@todo check ssid field to compatible
+
+ ret = 0;
+ for(index=1; index < count; index++)
+ {
+ words_count = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+ if (words_count > 2)
+ {
+ inner_copy_ssid(local_ssid, split_words[1], sizeof (local_ssid));
+ if (ssid == NULL || strcmp(local_ssid, ssid) == 0)
+ {
+ net_no_list[ret++] = atoi(split_words[0]);
+ }
+ }
+ }
+ RLOGD("[lynq_get_network_number_list] lynq_get_network_number_list return ok");
+ return ret;
+}
+
+static int lynq_add_network(int ap_sta) {
+ size_t i=0;
+ CHECK_WPA_CTRL(ap_sta);
+ const char *lynq_wifi_add_network = "ADD_NETWORK";
+
+ RLOGD("[lynq_add_network] enter lynq_add_network");
+ DO_REQUEST(lynq_wifi_add_network);
+ if (memcmp(cmd_reply, "FAIL", 4) == 0)
+ {
+ RLOGE("[wifi error]lynq_add_network cmd_reply FAIL");
+ return -1;
+ }
+
+ for(i=0;i<reply_len;i++)
+ {
+ if(cmd_reply[i] == '\n')
+ {
+ cmd_reply[i] = '\0';
+ break;
+ }
+ }
+ return atoi(cmd_reply);
+}
+
+static int lynq_check_network_number(lynq_wifi_index_e idx, int ap_sta, int net_no)
+{
+ int count, index;
+ int net_no_list[128];
+
+ RLOGD("[lynq_check_network_number] enter lynq_check_network_number api");
+ count = lynq_get_network_number_list(idx, ap_sta, net_no_list, NULL);
+ for (index=0; index < count; index++)
+ {
+ if (net_no_list[index] == net_no)
+ {
+ return 0;
+ }
+ }
+
+ if (count >= 1)
+ index = net_no_list[count - 1];
+ else
+ index = -1;
+
+ while (index < net_no )
+ {
+ index = lynq_add_network(ap_sta);
+ if (index >= net_no)
+ { // required network no created
+ RLOGD("required network no created\n");;
+ return 0;
+ }
+ else if( index < 0)
+ {
+ RLOGE("[lynq_check_network_number] add network fail");
+ return -1;
+ }
+ }
+
+ if (index < 0)
+ {
+ RLOGE("[lynq_check_network_number] network index < 0");
+ return -1;
+ }
+ RLOGD("[lynq_check_network_number] work finished &state is ok");
+ return 0;
+}
+
+static lynq_wifi_band_m convert_band_from_freq(int freq) { //@todo
+ if (freq > 5000 && freq < 6000)
+ {
+ return LYNQ_WIFI_5G_band;
+ }
+ else if (freq > 2000 && freq < 3000)
+ {
+ return LYNQ_WIFI_2G_band;
+ }
+ return LYNQ_WIFI_2_and_5G_band;
+}
+
+static lynq_wifi_auth_s convert_auth_from_key_mgmt(char * key_mgmt) {
+ if (key_mgmt != NULL)
+ {
+ if (memcmp( key_mgmt, "NONE", 4) == 0)
+ {
+ return LYNQ_WIFI_AUTH_OPEN;
+ }
+ else if (memcmp( key_mgmt, "WEP", 3) == 0)
+ {
+ return LYNQ_WIFI_AUTH_WEP;
+ }
+ else if (memcmp( key_mgmt, "WPA-PSK", 7) == 0)
+ {
+ return LYNQ_WIFI_AUTH_WPA_PSK;
+ }
+ else if (memcmp( key_mgmt, "WPA2-PSK", 8) == 0)
+ {
+ return LYNQ_WIFI_AUTH_WPA2_PSK;
+ }
+ }
+
+ return -1;
+}
+
+static lynq_wifi_auth_s convert_max_auth_from_flag(char * flag) {
+ if (flag != NULL)
+ {
+ if ( strstr(flag,"WPA2-PSK+SAE-CCMP") != NULL || strstr(flag, "SHA256") != NULL || strstr(flag,"WPA2-SAE") != NULL || ( strstr(flag,"SAE-H2E") != NULL && strstr(flag,"WPS") == NULL ) )
+ {
+ return LYNQ_WIFI_AUTH_WPA3_PSK;
+ }else if ( strstr( flag,"SAE-CCMP") != NULL || strstr(flag,"SAE-H2E") != NULL )
+ {
+ return LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+ }else if (strstr( flag, "WPA2-PSK") != NULL)
+ {
+ return LYNQ_WIFI_AUTH_WPA2_PSK;
+ }
+ else if (strstr( flag, "WPA-PSK") != NULL)
+ {
+ return LYNQ_WIFI_AUTH_WPA_PSK;
+ }
+ else if (strstr( flag, "WEP") != NULL)
+ {
+ return LYNQ_WIFI_AUTH_WEP;
+ }
+ else if (strstr( flag, "NONE") != NULL)
+ {
+ return LYNQ_WIFI_AUTH_OPEN;
+ }
+ else if (strcmp( flag, "[ESS]") == 0 || strcmp( flag,"[WPS][ESS]") == 0)
+ {
+ return LYNQ_WIFI_AUTH_OPEN;
+ }
+ else
+ {
+ RLOGD("convert_max_auth_from_flag not-found auth mode");
+ }
+ }
+
+ return -1;
+}
+
+static lynq_wifi_bandwidth_type_m convert_bandwidth_from_bw(int bw) {
+ switch (bw) {
+ case 10:
+ return LYNQ_WIFI_BANDWIDTH_HT10;
+ break;
+ case 20:
+ return LYNQ_WIFI_BANDWIDTH_HT20;
+ break;
+ case 40:
+ return LYNQ_WIFI_BANDWIDTH_HT40;
+ break;
+ case 80:
+ return LYNQ_WIFI_BANDWIDTH_HT80;
+ break;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth);
+static int inner_get_status_info(int interface, curr_status_info *curr_state) {
+ int i, count;
+ char *p;
+ const char *lynq_status_cmd = "STATUS";
+ const char * FLAG_SSID = "ssid=";
+ const char * FLAG_SBSID = "bssid=";
+ const char * FLAG_KEY_MGMT = "key_mgmt=";
+ const char * FLAG_FREQ = "freq=";
+ const char * FLAG_STATE = "wpa_state=";
+ const char * FLAG_ID = "id=";
+ const char * FLAG_IPADDR = "ip_address=";
+ char *split_lines[128] = {0};
+
+ CHECK_WPA_CTRL(interface);
+
+ if (curr_state == NULL)
+ {
+ RLOGE("[wifi error][inner_get_status_info]curr_state is NULL");
+ return -1;
+ }
+
+ DO_REQUEST(lynq_status_cmd);
+
+ count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+ curr_state->net_no = -1;
+ ret = -1;
+ for(i=0; i < count; i++)
+ {
+ if (curr_state->ap != NULL)
+ {
+ p = strstr(split_lines[i], FLAG_SBSID);
+ if (p != NULL)
+ {
+ strncpy(curr_state->ap->ap_mac, p + strlen(FLAG_SBSID), sizeof(curr_state->ap->ap_mac));
+ ret = 0;
+ continue;
+ }
+ p = strstr(split_lines[i], FLAG_SSID);
+ if (p != NULL)
+ {
+ inner_copy_ssid(curr_state->ap->ap_ssid, p + strlen(FLAG_SSID), sizeof (curr_state->ap->ap_ssid));
+ ret = 0;
+ continue;
+ }
+ p = strstr(split_lines[i], FLAG_KEY_MGMT);
+ if (p != NULL)
+ {
+ curr_state->ap->auth = convert_auth_from_key_mgmt(p + strlen(FLAG_KEY_MGMT));
+ RLOGD("inner_get_status_info: key_mgmt %d, -- %s\n", curr_state->ap->auth, p);
+ ret = 0;
+ continue;
+ }
+ p = strstr(split_lines[i], FLAG_FREQ);
+ if (p != NULL)
+ {
+ curr_state->ap->band = convert_band_from_freq(atoi( p + strlen(FLAG_FREQ)));
+ ret = 0;
+ continue;
+ }
+ p = strstr(split_lines[i], FLAG_IPADDR);
+ if (p != NULL)
+ {
+ strncpy(curr_state->ap->ap_ip, p + strlen(FLAG_IPADDR), sizeof(curr_state->ap->ap_ip));
+ ret = 0;
+ continue;
+ }
+ } // end if (ap != NULL)
+ if (curr_state->state != NULL)
+ {
+ p = strstr(split_lines[i], FLAG_STATE);
+ if (p != NULL)
+ {
+ strcpy(curr_state->state, p + strlen(FLAG_STATE));
+ ret = 0;
+ continue;
+ }
+
+ } //end else if (state != NULL)
+ if ((p = strstr(split_lines[i], FLAG_ID)) == split_lines[i])
+ {
+ ret = 0;
+ curr_state->net_no = atoi(p + strlen(FLAG_ID));
+ RLOGD("inner_get_status_info:net_no %d, -- %s\n", curr_state->net_no, p);
+ }
+ }
+
+ if (ret == 0 && curr_state->ap != NULL && curr_state->net_no >= 0) // auth may not right when add wpa3
+ {
+ inner_get_network_auth(interface, curr_state->net_no, &curr_state->ap->auth);
+ }
+
+ return ret;
+}
+
+int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid)
+{
+ RLOGD("enter lynq_wifi_ap_ssid_set");
+ char lynq_wifi_ssid_cmd[80]={0};
+
+ if (ap_ssid == NULL)
+ {
+ RLOGE("Input ap_ssid is NULL");
+ return -1;
+ }
+ else
+ {
+ RLOGD("[lynq_wifi_ap_ssid_set]idx:%d ap_ssid : %s\n", idx, ap_ssid);
+ }
+
+ if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+ {
+ RLOGE("Do check ap network_number fail");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", AP_NETWORK_0, ap_ssid);
+
+ DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ RLOGD("[lynq_wifi_ap_ssid_set] set ssid succeed %d",__LINE__);
+ return 0;
+
+}
+
+int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx, char* ap_ssid)
+{
+ RLOGD("enter lynq_wifi_ap_ssid_get");
+ CHECK_IDX(idx, CTRL_AP);
+ return inner_get_param(CTRL_AP, AP_NETWORK_0, "ssid", ap_ssid);
+}
+
+/*****
+ *frequency <------>channel
+ *
+ *frequency 1 2 3 4 5 6 7 8 9 10 11 12 13 36 40 44 48 149 153 157 161 165
+ *
+ *
+ *channel 2412,2417,2422,2427,2532,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825
+ *
+ *
+ * */
+static int lynq_check_set_frequency(int input_frequency){
+ int legitimate_frequency[]={2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825};
+ int i;
+ int arr_len = sizeof(legitimate_frequency) / sizeof(int);
+
+ for(i = 0; i < arr_len; i++)
+ {
+ if(input_frequency == legitimate_frequency[i])
+ break;
+ }
+
+ if(i == arr_len)
+ {
+ RLOGE("[lynq_check_set_frequency]input frequency is --->%d,please check it\n", input_frequency);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int lynq_check_frequencyby_country_code(int input_frequency)
+{
+ char str_cnc[]="CN";
+ char str_dest[20]="";
+
+ if( lynq_get_country_code(1,str_dest) != 0 )
+ {
+ RLOGE("get country_code error\n");
+ return -1;
+ }
+ if( strncmp(str_dest,str_cnc,2) != 0 )
+ {
+ return 0;
+ }else if( 2473 < input_frequency && input_frequency < 5744)
+ {
+ RLOGE("input frequency is bad\n");
+ return -1;
+ }
+ return 0;
+}
+int lynq_wifi_ap_frequency_set(lynq_wifi_index_e idx,int lynq_wifi_frequency)
+{
+ int check;
+ char lynq_wifi_frequency_cmd[128]={0};
+ char lynq_cmd_mode[128]={0};
+ char lynq_cmd_slect[128]={0};
+ RLOGD("enter %s %d input frequency:%d",__func__,__LINE__,lynq_wifi_frequency);
+ //@do check input frequency
+ check = lynq_check_set_frequency(lynq_wifi_frequency);
+ if(check != 0)
+ {
+ RLOGE("do check frequency error");
+ return -1;
+ }
+ check = lynq_check_frequencyby_country_code(lynq_wifi_frequency);
+ if(check != 0)
+ {
+ RLOGE("do check frequency error");
+ return -1;
+ }
+
+ if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+ {
+ RLOGE("[set ap frequecny][lynq_check_network_number] error");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ sprintf(lynq_wifi_frequency_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, lynq_wifi_frequency);
+ sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+ sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(cmd_disconnect);
+ DO_OK_FAIL_REQUEST(lynq_wifi_frequency_cmd);
+ DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+}
+
+int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency)
+{
+ char lynq_frequency_str[MAX_RET] = {0};
+ RLOGD("enter lynq_wifi_ap_frequency_get and input idx is %d",idx);
+ CHECK_IDX(idx, CTRL_AP);
+
+ if (inner_get_param(CTRL_AP, AP_NETWORK_0, "frequency", lynq_frequency_str) != 0)
+ {
+ RLOGE("[wifi error][lynq_wifi_ap_frequency_get]get frequency from device fail");
+ return -1;
+ }
+ *lynq_wifi_frequency = atoi(lynq_frequency_str);
+
+ return 0;
+}
+
+int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth)
+{
+ RLOGD("enter lynq_wifi_ap_bandwidth_set");
+ CHECK_IDX(idx, CTRL_AP);
+ switch(bandwidth){
+ case LYNQ_WIFI_BANDWIDTH_HT10:
+ {
+ RLOGE("bandwith [%d] not support now\n", bandwidth);
+ return -1;
+ }
+ case LYNQ_WIFI_BANDWIDTH_HT20:
+ {
+ char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 6";
+ system("wl down");
+ if (system(lynq_cmd_bandwith) != 0 )
+ {
+ RLOGE("lynq_wifi_ap_bandwidth_set erro");
+ return -1;
+ }
+ system("wl up");
+ break;
+ }
+ case LYNQ_WIFI_BANDWIDTH_HT40:
+ {
+ char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/40";
+ sprintf(lynq_cmd_bandwith, "wl chanspec ");
+ system("wl down");
+ if (system(lynq_cmd_bandwith) != 0 )
+ {
+ RLOGE("lynq_wifi_ap_bandwidth_set erro");
+ return -1;
+ }
+ system("wl up");
+ break;
+ }
+ case LYNQ_WIFI_BANDWIDTH_HT80:
+ {
+ char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/80";
+ system("wl down");
+ if (system(lynq_cmd_bandwith) != 0 )
+ {
+ RLOGE("lynq_wifi_ap_bandwidth_set erro");
+ return -1;
+ }
+ system("wl up");
+ break;
+ }
+ default:
+ {
+ RLOGE("auth type [%d] not support now\n", bandwidth);
+ return -1;
+ }
+ }
+
+
+ return 0;
+}
+
+int lynq_wifi_ap_bandwidth_get(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m* bandwidth)
+{
+ int count = 0;
+ int index = 0;
+ char *split_words[128] = {0};
+ const char *lynq_chanspec_cmd = "DRIVER chanspec\n";
+ RLOGD("enter lynq_wifi_ap_bandwidth_get");
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ DO_REQUEST(lynq_chanspec_cmd);
+
+ count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+ for(;index < count; index++) {
+ if (strncmp(split_words[index], "bw", 2) != 0) {
+ continue;
+ }
+
+ index++;
+ if (index >= count) {
+ return -1;
+ }
+
+ RLOGD("bw %s\n", split_words[index]);
+ *bandwidth = convert_bandwidth_from_bw(atoi(split_words[index]));
+ return 0;
+ }
+ RLOGE("[wifi error]lynq_wifi_ap_bandwidth_get");
+ return -1;
+}
+
+int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel)
+{
+ char lynq_cmd_channel[MAX_CMD]={0};
+ RLOGD("enter lynq_wifi_ap_channel_set and input channel is %d",channel);
+ CHECK_IDX(idx, CTRL_AP);
+
+ sprintf(lynq_cmd_channel, "wl channel %d", channel);
+
+ if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+ {
+ return -1;
+ }
+
+ system("wl down");
+ if (system(lynq_cmd_channel) != 0 ){
+ RLOGE("lynq_wifi_ap_channel_set erro");
+ return -1;
+ }
+ system("wl up");
+ return 0;
+}
+
+int lynq_wifi_ap_channel_get( lynq_wifi_index_e idx,int* channel)
+{
+ int count = 0;
+ int index = 0;
+ char *split_words[128] = {0};
+ char lynq_chanspec_cmd[]="DRIVER chanspec\n";
+ RLOGD("enter lynq_wifi_ap_channel_get");
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ DO_REQUEST(lynq_chanspec_cmd);
+
+ count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+ for(;index < count; index++)
+ {
+ RLOGD("[lynq_wifi_ap_channel_get]---- %s\n",split_words[index]);
+ if (strncmp(split_words[index], "channel", 2) != 0) {
+ continue;
+ }
+
+ index++;
+ if (index >= count)
+ {
+ return -1;
+ }
+
+ *channel = atoi(split_words[index]);
+ return 0;
+ }
+ RLOGE("[lynq_wifi_ap_channel_get] function fail");
+ return -1;
+}
+
+
+int lynq_wifi_ap_auth_set(lynq_wifi_index_e idx, lynq_wifi_auth_s auth)
+{
+ char ssid[MAX_CMD] = {0};
+ int freq = 0;
+ char lynq_auth_cmd[64]={0};
+ char lynq_auth_alg_cmd[64]={0};
+ char lynq_psk_cmd[64]={0};
+ char lynq_pairwise_cmd[64]={0};
+ char lynq_ieee80211_cmd[64]={0};
+ RLOGD("enter lynq_wifi_ap_auth_set and input idx is:%d,auth is:%d",idx,auth);
+ lynq_wifi_auth_s org_auth;
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != AP_NETWORK_0)
+ {
+ RLOGE("[wifi error][lynq_wifi_ap_auth_set] check network fail\n");
+ return -1;
+ }
+
+ if (0 == lynq_wifi_ap_auth_get(idx, &org_auth) && org_auth != -1) {
+ if (org_auth == auth) {
+ RLOGD("org_auth --- is %d\n",org_auth);
+ return 0;
+ }
+ else {
+ if (0 != lynq_wifi_ap_ssid_get(idx, ssid)) {
+ ssid[0] = '\0';
+ }
+ lynq_wifi_ap_frequency_get(idx, &freq);
+
+ DO_OK_FAIL_REQUEST(cmd_disconnect);
+ DO_OK_FAIL_REQUEST(cmd_remove_all);
+ if (ssid[0] != '\0') {
+ lynq_wifi_ap_ssid_set(idx, ssid);
+ }
+ if (freq != 0) {
+ lynq_wifi_ap_frequency_set(idx, freq);
+ }
+ }
+ }
+
+ switch(auth){
+ case LYNQ_WIFI_AUTH_OPEN:
+ {
+ RLOGD("auth == is LYNQ_WIFI_AUTH_OPEN\n");
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WEP:
+ {
+ RLOGD("auth == is LYNQ_WIFI_AUTH_WEP\n");
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+ sprintf(lynq_auth_alg_cmd,"SET_NETWORK %d auth_alg SHARED", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_auth_alg_cmd);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA_PSK:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+ sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ break;
+
+ }
+ case LYNQ_WIFI_AUTH_WPA2_PSK:
+ {
+ if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+ sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+ }
+ else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", AP_NETWORK_0);
+ sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+ }
+// sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+// sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+ sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 1", AP_NETWORK_0);
+ sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK SAE", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA3_PSK:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+ sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 2", AP_NETWORK_0);
+ sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt SAE", AP_NETWORK_0);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ break;
+ }
+ default:
+ {
+ RLOGE("auth type [%d] not support now\n", auth);
+ return -1;
+ }
+ }
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+}
+
+int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+ char lynq_auth_str[MAX_RET] = {0};
+ char lynq_auth_alg_str[MAX_RET] = {0};
+ char lynq_proto_str[MAX_RET] = {0};
+ RLOGD("enter lynq_wifi_ap_auth_get");
+ CHECK_IDX(idx, CTRL_AP);
+
+ if (inner_get_param(CTRL_AP, AP_NETWORK_0, "key_mgmt", lynq_auth_str) != 0)
+ {
+ RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network fail");
+ return -1;
+ }
+
+ if (memcmp( lynq_auth_str, "NONE", 4) == 0)
+ {
+ if (inner_get_param(CTRL_AP, AP_NETWORK_0, "auth_alg", lynq_auth_alg_str) != 0)
+ {
+ RLOGD("---auth is OPEN\n");
+ *auth = LYNQ_WIFI_AUTH_OPEN;
+ return 0;
+ }
+ else if (memcmp(lynq_auth_alg_str, "SHARED", 6) == 0)
+ {
+ RLOGD("---auth is WEP\n");
+ *auth = LYNQ_WIFI_AUTH_WEP;
+ return 0;
+ }
+ else
+ {
+ RLOGD("---auth is OPEN\n");
+ *auth = LYNQ_WIFI_AUTH_OPEN;
+ return 0;
+ }
+ }
+ else if(strcmp( lynq_auth_str, "WPA-PSK") == 0 )
+ {
+ if (inner_get_param(CTRL_AP, AP_NETWORK_0, "proto", lynq_proto_str) != 0)
+ {
+ RLOGE("---auth is -1\n");
+ *auth = -1;
+ }
+ else if (memcmp(lynq_proto_str, "RSN", 3) == 0)
+ {
+ RLOGD("---auth WPA2_PSK\n");
+ *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+ return 0;
+ }
+ else
+ {
+ RLOGD("---auth WPA_PSK\n");
+ *auth = LYNQ_WIFI_AUTH_WPA_PSK;
+ return 0;
+ }
+ }
+
+ if (inner_get_param(CTRL_AP, AP_NETWORK_0, "ieee80211w", lynq_auth_str) != 0)
+ {
+ RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network auth ieee80211w fail");
+ return -1;
+ }
+
+ if (memcmp(lynq_auth_str,"1",1) == 0 )
+ {
+ RLOGD("auth : LYNQ_WIFI_AUTH_WPA2_WPA3_PSK\n");
+ *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+ return 0;
+ }else if (memcmp(lynq_auth_str,"2",1) == 0 )
+ {
+ RLOGD("auth : LYNQ_WIFI_AUTH_WPA3_PSK\n");
+ *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+ return 0;
+ }
+ else
+ {
+ RLOGE("---auth -- -1\n");
+ *auth = -1;
+ }
+
+ return 0;
+}
+
+static int inner_check_ap_connected(lynq_wifi_index_e idx, int retry_count)
+{
+ char status[64];
+ char LYNQ_WIFI_CMD[32]={0};
+ curr_status_info curr_state;
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ memset(status, 0, sizeof (status));
+
+ curr_state.ap = NULL;
+ curr_state.state = status;
+
+ printf("inner_check_ap_connected %d\n", retry_count);
+ usleep(250*1000);
+ if (0 == inner_get_status_info(idx, &curr_state))
+ {
+ if ((strcmp(status, STATE_SCANNING) == 0)|| (strcmp(status, STATE_COMPLETED) == 0))
+ {
+ return 0;
+ }
+ else if (retry_count == 8) //not ok in 2s, do reconnect
+ {
+ DO_REQUEST("RECONNECT");
+ return inner_check_ap_connected(idx, retry_count+1);
+ }
+ else if (retry_count > 20)
+ {
+ printf("retry 10 time\n");
+ return -1;
+ }
+ else
+ {
+ if (strcmp(status, STATE_DISCONNECTED) == 0)
+ {
+ sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+ DO_REQUEST(LYNQ_WIFI_CMD);
+ }
+ return inner_check_ap_connected(idx, retry_count+1);
+ }
+ }
+ return -1;
+}
+
+int lynq_wifi_ap_start(lynq_wifi_index_e idx)
+{
+ RLOGD("enter %s %d",__func__,__LINE__);
+ char LYNQ_WIFI_CMD[128]={0};
+
+ CHECK_IDX(idx, CTRL_AP);
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ if (inner_get_ap_interface_name() == NULL)
+ {
+ RLOGE("lynq_wifi_ap_start get ap name fail");
+ return -1;
+ }
+
+
+ sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+ DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+ ret = system_call_v("%s %s", start_stop_ap_script, "start");
+ if (ret != 0)
+ {
+ RLOGE("lynq_wifi_ap_start excute script fail");
+ return -1;
+ }
+
+ if (inner_check_ap_connected(idx, 0) != 0)
+ {
+ return -1;
+ }
+
+ check_tether_and_notify();
+/*
+ if (g_ap_tmp_watcher_pid == 0)
+ {
+ if(pthread_create(&g_ap_tmp_watcher_pid,NULL,APTmpWatcherThreadProc,NULL) < 0)
+ {
+ g_ap_tmp_watcher_pid = 0;
+ RLOGE("[wifi error]create APTmpWatcherThreadProc fail");
+ return -1;
+ }
+ RLOGD("[lynq_wifi_ap_start] creat APTmpWatcherThreadProc ok");
+ }
+*/
+ RLOGD("end %s %d",__func__,__LINE__);
+ return 0;
+}
+
+int lynq_wifi_ap_restart(lynq_wifi_index_e idx)
+{
+ return lynq_wifi_ap_stop(idx) == 0 ? lynq_wifi_ap_start(idx) : -1;
+}
+
+int lynq_wifi_ap_stop(lynq_wifi_index_e idx)
+{
+ RLOGD("enter %s %d",__func__,__LINE__);
+ char LYNQ_WIFI_CMD[128]={0};
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ sprintf(LYNQ_WIFI_CMD,"DISABLE_NETWORK %d",AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+
+ ret = system_call_v("%s %s", start_stop_ap_script, "stop");
+ if (ret != 0)
+ {
+ RLOGE("lynq_wifi_ap_start excute script fail");
+ return -1;
+ }
+/*
+ g_ap_tmp_watcher_stop_flag = 1;
+ if (g_ap_tmp_watcher_pid != 0)
+ pthread_join(g_ap_tmp_watcher_pid, NULL);
+ g_ap_tmp_watcher_pid = 0;
+*/
+ RLOGD("end %s %d",__func__,__LINE__);
+ return 0;
+}
+
+int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx)
+{
+ char lynq_disable_cmd[128] = {0};
+ char lynq_select_cmd[128] = {0};
+ const char *lynq_hide_cmd = "SET HIDE_SSID 1";
+ RLOGD("enter lynq_wifi_ap_hide_ssid");
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+ sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+ sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+ DO_OK_FAIL_REQUEST(lynq_hide_cmd);
+ DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+ return 0;
+}
+
+int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx)
+{
+ char lynq_disable_cmd[128] = {0};
+ char lynq_select_cmd[128] = {0};
+ const char *lynq_unhide_cmd = "SET HIDE_SSID 0";
+ RLOGD("enter lynq_wifi_ap_unhide_ssid");
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+ sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+ DO_OK_FAIL_REQUEST(lynq_unhide_cmd);
+ DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+ return 0;
+}
+
+int lynq_ap_password_set(lynq_wifi_index_e idx,char *password)
+{
+ int pass_len;
+ char lynq_tmp_cmd[MAX_CMD] = {0};
+ char lynq_wpa2_wpa3[64] = {0};
+ char lynq_wep_tx_keyidx_cmd[MAX_CMD] = {0};
+ RLOGD("enter lynq_ap_password_set");
+ if( password == NULL )
+ {
+ RLOGE("[lynq_ap_password_set]input password is NULL");
+ return -1;
+ }
+ pass_len=strlen(password);
+ lynq_wifi_auth_s auth = -1;
+ if(pass_len < 8 || pass_len >= 64)
+ {
+ RLOGE("[lynq_ap_password_set]input password len not in rage");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ if (0 != lynq_wifi_ap_auth_get(idx, &auth))
+ {
+ RLOGE("[lynq_ap_password_set] get ap auth info error\n");
+ return -1;
+ }
+ else if (auth == LYNQ_WIFI_AUTH_OPEN)
+ {
+ RLOGD("ap auth :LYNQ_WIFI_AUTH_OPEN\n");
+ return 0;
+ }
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ if (auth == LYNQ_WIFI_AUTH_WEP)
+ {
+ RLOGD("[lynq_ap_password_set]ap auth : LYNQ_WIFI_AUTH_WEP\n");
+ sprintf(lynq_tmp_cmd,"SET_NETWORK %d wep_key0 \"%s\"",AP_NETWORK_0, password);
+ sprintf(lynq_wep_tx_keyidx_cmd,"SET_NETWORK %d wep_tx_keyidx 0",AP_NETWORK_0);
+ DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+ DO_OK_FAIL_REQUEST(lynq_wep_tx_keyidx_cmd);
+ }
+ else if (auth == LYNQ_WIFI_AUTH_WPA_PSK || auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+ {
+ RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA_PSK LYNQ_WIFI_AUTH_WPA2_PSK\n");
+ sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+ DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+ }
+ else if (auth == LYNQ_WIFI_AUTH_WPA2_WPA3_PSK || auth == LYNQ_WIFI_AUTH_WPA3_PSK)
+ {
+
+ RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA2_WPA3 LYNQ_WIFI_AUTH_WPA3_PSK\n");
+ sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+ sprintf(lynq_wpa2_wpa3,"SET_NETWORK %d sae_password \"%s\"",AP_NETWORK_0, password);
+ DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+ DO_OK_FAIL_REQUEST(lynq_wpa2_wpa3);
+
+ }
+ else
+ {
+ RLOGD("[lynq_ap_password_set]ap auth :get ap auth error\n");
+ return -1;
+ }
+
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+}
+
+int lynq_ap_password_get(lynq_wifi_index_e idx, char *password)
+{
+ FILE * fp;
+ int len, ret;
+ int count, index;
+ char *split_lines[128] = {0};
+ char *buff, *p;
+ RLOGD("enter lynq_ap_password_get");
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ fp = fopen("/data/wifi/wg870/wpa_supplicant_ap.conf", "rb");
+// fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+ if (NULL == fp)
+ {
+ RLOGE("open file fail\n");
+ return -1;
+ }
+
+ buff = alloca(MAX_RET);
+ fseek(fp, 0, SEEK_SET);
+ len = fread(buff, 1, MAX_RET, fp);
+ fclose(fp);
+
+ for(index=0; index < len; index ++)
+ {
+ if (memcmp(buff + index, "network={", 9) != 0)
+ {
+ continue;
+ }
+ p = buff + index + 9;
+ for (; index < len; index ++ )
+ {
+ if (buff[index] != '}')
+ {
+ continue;
+ }
+ buff[index] = '\0';
+ break;
+ }
+ len = buff + index - p;
+ }
+
+ count = lynq_split(p, len, '\n', split_lines);
+
+ ret = -1;
+ for(index=0; index < count; index++)
+ {
+ p = strstr(split_lines[index], "psk=");
+ if (p != NULL)
+ {
+ p += 4;
+ if (*p == '\"')
+ {
+ p++;
+ }
+ }
+ else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+ {
+ p += 9;
+ if (*p == '\"')
+ {
+ p++;
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ strcpy(password, p);
+
+ while(*password != '\0')
+ {
+ if (*password == '\"')
+ {
+ *password = '\0';
+ break;
+ }
+ password++;
+ }
+ ret = 0;
+ break;
+ } //end for(index=0; index < count; index++)
+
+ return ret;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth) {
+ char lynq_auth_str[MAX_RET] = {0};
+ char lynq_proto_str[MAX_RET] = {0};
+
+ if (inner_get_param(interface, net_no, "key_mgmt", lynq_auth_str) != 0)
+ {
+ return -1;
+ }
+
+ *auth = convert_auth_from_key_mgmt(lynq_auth_str);
+
+ if (*auth == LYNQ_WIFI_AUTH_WPA_PSK)
+ {
+ if (inner_get_param(interface, net_no, "proto", lynq_proto_str) == 0)
+ {
+ if (strcmp(lynq_proto_str, "RSN") == 0)
+ {
+ *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+ return 0;
+ }
+ else if (strcmp(lynq_proto_str, "WPA") == 0) // need compare when wpa3 supported
+ {
+ return 0;
+ }
+ }
+ }
+ else if (*auth == LYNQ_WIFI_AUTH_OPEN || *auth == LYNQ_WIFI_AUTH_WEP)
+ {
+ return 0;
+ }
+
+ if (inner_get_param(interface, net_no,"ieee80211w",lynq_auth_str) !=0)
+ {
+ RLOGE("check ieee80211w error\n");
+ return -1;
+ }
+ if ( strncmp(lynq_auth_str,"1",1) == 0 )
+ {
+
+ *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+ return 0;
+ }else if( strncmp(lynq_auth_str,"2",1) == 0 )
+ {
+
+ *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+ return 0;
+ }else
+ {
+ RLOGE("check ieee80211w error, not 1 or 2\n");
+ *auth = -1;
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password)
+{
+ RLOGD("enter lynq_sta_ssid_password_set");
+ int pass_len, net_no, count, index;
+ char lynq_tmp_cmd[300]={0};
+ int net_no_list[128];
+ lynq_wifi_auth_s net_auth;
+ pass_len=strlen(password);
+ if(pass_len < 8 || pass_len >= 64)
+ {
+ RLOGE("[lynq_sta_ssid_password_set]input psw error");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ net_no = -1;
+ count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ap->ap_ssid);
+
+ for (index=0; index < count; index++)
+ {
+ net_auth = -1;
+ if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == ap->auth)
+ {
+ net_no = net_no_list[index];
+ break;
+ }
+ }
+
+ if (net_no < 0)
+ {
+ return -1;
+ }
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",net_no, password);
+
+ DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+}
+
+/**
+* buff data
+* buff_len size of buff
+* idx sta
+* *ap ap info for find ssid && password
+* password return password
+*
+*/
+static int lynq_sta_ssid_password_auth_get(char * buff,int buff_len,lynq_wifi_index_e idx, ap_info_s *ap,char *password) { // @todo
+
+ int ret, network_len, i, ssid_len,curr_auth;
+ int count, index,org_index;
+ char *split_lines[128] = {0};
+ char *p, *ssid, *ssid_end_flag,*ptr;
+ char tmp_ssid[128]={0};
+ char tmp_auth[24]={0};
+
+ org_index = 0;
+ network_len = 0;
+ p = NULL;
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ while(1){
+ network_len = 0;
+ p == NULL;
+ for(; org_index < buff_len; org_index ++)
+ {
+ for(; org_index < buff_len; org_index ++)
+ {
+ if (memcmp(buff + org_index, "network={", 9) != 0)
+ {
+ continue;
+ }
+ p = buff + org_index + 9;
+
+ for (; org_index < buff_len; org_index ++ )
+ {
+ if (buff[org_index] != '}')
+ {
+ continue;
+ }
+ buff[org_index] = '\0';
+ break;
+ }
+ network_len = buff + org_index - p;
+ break;
+ }
+
+ if (p == NULL)
+ {
+ RLOGD("not find dest info %s(),line %dERROR",__func__,__LINE__);
+ return -1;
+ }
+
+ ssid = strstr(p, "ssid=");
+ if (ssid != NULL) {
+ ssid += strlen("ssid=");
+ if (ssid[0] == '\"')
+ {
+ if (memcmp(ssid + 1, ap->ap_ssid, strlen(ap->ap_ssid)) == 0 && ssid[strlen(ap->ap_ssid) + 1] == '\"')
+ {
+ break;
+ }
+ }
+ else
+ {
+ ssid_end_flag = strstr(ssid, "\n");
+ if (ssid_end_flag != NULL)
+ {
+ ssid_len = (ssid_end_flag - ssid) / 2;
+ for(i=0; i<ssid_len; i++)
+ {
+ tmp_ssid[i] = inner_convert_char(ssid[i*2]) << 4 | inner_convert_char(ssid[i*2 + 1]);
+ }
+ if (memcmp(tmp_ssid, ap->ap_ssid, ssid_len) == 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ if (org_index >= buff_len || NULL == p || network_len <= 0)
+ {
+
+ if (buff != NULL)
+ RLOGD("not find dest ssid %s(),line %dERROR",__func__,__LINE__);
+ return -1;
+ }
+
+ count = lynq_split(p, network_len, '\n', split_lines);
+ ret = -1;
+ for( index=0; index < count; index++ )
+ {
+ p = strstr(split_lines[index], "key_mgmt=");
+ if(p != NULL)
+ {
+ p += 9;
+ if(memcmp(p,"SAE",3) == 0)
+ {
+ curr_auth = 5;
+ }else if(memcmp(p,"WPA-PSK SAE",11) == 0)
+ {
+ curr_auth = 4;
+ }else if(memcmp(p,"WPA-PSK",7) == 0 )
+ {
+ curr_auth = 3;
+ }else if(memcmp(p,"NONE",4) == 0 )
+ {
+ curr_auth = 0;
+ }else{
+ curr_auth = 1;
+ }
+ if( curr_auth < 1 || curr_auth > 6)
+ {
+ ret = -1;
+ }
+ break;
+ }
+ }
+ if( curr_auth == 0)
+ {
+ return 0;
+ }else if(curr_auth == ap->auth || ap->auth <= 3 && curr_auth <= 3 && curr_auth != -1 )
+ {
+ for(index=0; index < count; index++)
+ {
+ /*get psw info*/
+
+ p = strstr(split_lines[index], "psk=");
+ if (p != NULL)
+ {
+ p += 4;
+ if (*p == '\"')
+ {
+ p++;
+ }
+ }
+ else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+ {
+ p += 9;
+ if (*p == '\"')
+ {
+ p++;
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ if (*p == '\"')
+ p++;
+ strncpy(password, p, 64);
+ p = password;
+ while(password - p < 64 && *password != '\0')
+ {
+ if (*password == '\"')
+ {
+ *password = '\0';
+ ret = 0;
+ break;
+ }
+ password++;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+
+int lynq_sta_ssid_password_get(lynq_wifi_index_e idx, ap_info_s *ap, char *password) { // @todo
+
+ FILE * fp;
+ int len, ret;
+ char *info_buff;
+ RLOGD("enter lynq_sta_ssid_password_get");
+
+ info_buff = NULL;
+ CHECK_IDX(idx, CTRL_STA);
+
+ if (NULL == password)
+ {
+ RLOGE("bad param\n");
+ return -1;
+ }
+
+ fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+ if (NULL == fp)
+ {
+ RLOGE("[lynq_sta_ssid_password_get] open file fail\n");
+ return -1;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ info_buff = malloc(len + 1);
+
+ if (info_buff == NULL)
+ {
+ RLOGE("[lynq_sta_ssid_password_get] malloc memory [%d] fail\n", len);
+ return -1;
+ }
+
+ fseek(fp, 0, SEEK_SET);
+ len = fread(info_buff, 1, len, fp);
+ fclose(fp);
+
+
+ ret= lynq_sta_ssid_password_auth_get(info_buff,len,0, ap,password);
+
+ if(ret == 0)
+ {
+ RLOGD("lynq_sta_ssid_password_auth_get pass return ssid :%s psw is %s",ap->ap_ssid,password);
+ free(info_buff);
+ return 0;
+ }
+ else{
+ free(info_buff);
+ return -1;
+ }
+
+}
+
+
+static int inner_set_sta_ssid(int net_no, char *sta_ssid)
+{
+ char lynq_wifi_ssid_cmd[80]={0};
+
+ if (sta_ssid == NULL)
+ {
+ RLOGE("sta_ssid is null\n");
+ return -1;
+ }
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", net_no, sta_ssid);
+
+ DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+// DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+
+}
+
+static int inner_sta_start_stop(int net_no, int start_flag, int save)
+{
+ char lynq_disable_cmd[128]={0};
+ char lynq_select_cmd[128]={0};
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ if (save != 0)
+ {
+ if (start_flag != 0)
+ {
+ sprintf(lynq_select_cmd,"ENABLE_NETWORK %d", net_no);
+ DO_OK_FAIL_REQUEST(lynq_select_cmd);
+ }
+ else
+ {
+ sprintf(lynq_select_cmd,"DISABLE_NETWORK %d", net_no);
+ DO_OK_FAIL_REQUEST(lynq_select_cmd);
+ }
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+ }
+
+ if (start_flag == 0)
+ {
+ sprintf(lynq_disable_cmd,"DISCONNECT");
+ DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+ }
+ else
+ {
+ sprintf(lynq_select_cmd,"SELECT_NETWORK %d", net_no);
+ DO_OK_FAIL_REQUEST(lynq_select_cmd);
+ }
+
+ return 0;
+}
+
+int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx, char* sta_ssid)
+{
+ RLOGD("enter lynq_sta_ssid_password_set");
+ CHECK_IDX(idx, CTRL_STA);
+
+ curr_status_info curr_state;
+ ap_info_s ap_info;
+ curr_state.ap = &ap_info;
+ curr_state.state = NULL;
+
+ if (0 == inner_get_status_info(CTRL_STA, &curr_state))
+ {
+ strncpy(sta_ssid, ap_info.ap_ssid, sizeof (ap_info.ap_ssid));
+ return 0;
+ }
+
+ return -1;
+}
+
+int lynq_wifi_get_sta_available_ap(lynq_wifi_index_e idx, ap_detail_info_s *info)
+{
+ RLOGD("[wifi] ---ernter lynq_wifi_get_sta_available_ap");
+ scan_info_s *scan_list = NULL;
+ saved_ap_info_s *save_list = NULL;
+ int scan_len=0;
+ int save_len=0;
+ int best_index = -1;
+ int best_scan_index = -1;
+ int best_rssi = 0;
+ int i, j, ret;
+
+ ret = -1;
+
+ CHECK_IDX(idx, CTRL_STA);
+ if (info == NULL)
+ {
+ return -1;
+ }
+
+ curr_status_info curr_state;
+ ap_info_s ap_info;
+ char status[64];
+
+ memset(&ap_info, 0, sizeof (ap_info));
+ memset(status, 0, sizeof (status));
+
+ curr_state.ap = &ap_info;
+ curr_state.state = status;
+
+ if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+ {
+ memcpy(&info->base_info, &ap_info, sizeof (ap_info_s));
+ if (strcmp(status, STATE_COMPLETED) == 0)
+ {
+ info->status = LYNQ_WIFI_AP_STATUS_ENABLE;
+ RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_ENABLE");
+ }
+ else
+ {
+ info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+ RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_DISABLE");
+ }
+ lynq_get_connect_ap_ip(idx, info->base_info.ap_ip);
+ lynq_get_connect_ap_rssi(idx, &info->rssi);
+ lynq_sta_ssid_password_get(idx, & info->base_info, info->base_info.psw);
+ RLOGD("[wifi] ---ent --lynq_wifi_get_sta_available_ap");
+ return 0;
+ }
+
+ lynq_wifi_sta_start_scan(idx);
+ sleep(2);
+ if (0 != lynq_get_scan_list(0, &scan_list, &scan_len))
+ {
+ if (NULL != scan_list)
+ {
+ free(scan_list);
+ }
+ return -1;
+ }
+
+ if (0 != lynq_get_sta_saved_ap(0, &save_list, &save_len))
+ {
+ if (NULL != scan_list)
+ {
+ free(scan_list);
+ }
+ if (NULL != save_list)
+ {
+ free(save_list);
+ }
+ return -1;
+ }
+
+ for (i=0; i < save_len; i++)
+ {
+ for (j=0; j < scan_len; j++)
+ {
+ if (strcmp(save_list[i].base_info.ap_ssid, scan_list[j].ssid) == 0 //@todo not finished
+ && save_list[i].base_info.auth == scan_list[j].auth)
+ {
+ if (best_rssi == 0)
+ {
+ best_index = i;
+ best_rssi = scan_list[j].rssi;
+ }
+ else if (best_rssi > scan_list[j].rssi)
+ {
+ best_index = i;
+ best_scan_index = j;
+ best_rssi = scan_list[j].rssi;
+ }
+ strncpy(save_list[i].base_info.ap_mac, scan_list[j].mac, sizeof (save_list[i].base_info.ap_mac));
+ break;
+ }
+ }
+ }
+
+ if (best_index >= 0)
+ {
+ memcpy(&info->base_info, &save_list[best_index].base_info, sizeof (ap_info_s));
+ inner_get_ip_by_mac( info->base_info.ap_mac, info->base_info.ap_ip, sizeof (info->base_info.ap_ip));
+ info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+ RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status ---> LYNQ_WIFI_AP_STATUS_ENABLE");
+ info->rssi = best_rssi;
+ ret = 0;
+ }
+
+ if (NULL != scan_list)
+ {
+ free(scan_list);
+ }
+ if (NULL != save_list)
+ {
+ free(save_list);
+ }
+
+ RLOGD("[wifi] ---end -lynq_wifi_get_sta_available_ap");
+ return ret;
+}
+
+static int inner_set_sta_auth_psw(int net_no, lynq_wifi_auth_s auth, char *password)
+{
+ char lynq_auth_cmd[128]={0};
+ char lynq_ket_mgmt_cmd[64]={0};
+ char lynq_pairwise_cmd[64]={0};
+ char lynq_psk_cmd[64]={0};
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ switch(auth)
+ {
+ case LYNQ_WIFI_AUTH_OPEN:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", net_no);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+// DO_OK_FAIL_REQUEST(cmd_save_config);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA_PSK:
+ case LYNQ_WIFI_AUTH_WPA2_PSK:
+ {
+ if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", net_no);
+ }
+ else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", net_no);
+ }
+ sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", net_no);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+
+ if (password != NULL)
+ {
+ sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+ }
+
+// DO_OK_FAIL_REQUEST(cmd_save_config);
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 1",net_no);
+ sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE WPA-PSK",net_no);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+ sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+ break;
+ }
+ case LYNQ_WIFI_AUTH_WPA3_PSK:
+ {
+ sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 2",net_no);
+ sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE",net_no);
+ sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+ sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+
+ DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+ DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+ DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+ DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int inner_get_curr_net_no(int interface) {
+ curr_status_info curr_state;
+ curr_state.ap = NULL;
+ curr_state.state = NULL;
+
+ if (0 != inner_get_status_info(interface, &curr_state))
+ {
+ return -1;
+ }
+
+ return curr_state.net_no;
+}
+
+int lynq_wifi_get_sta_auth(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+ int net_no;
+ CHECK_IDX(idx, CTRL_STA);
+
+ net_no = inner_get_curr_net_no(CTRL_STA);
+
+ if (net_no < 0)
+ {
+ return -1;
+ }
+
+ return inner_get_network_auth(CTRL_STA, net_no, auth);
+}
+
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout)
+{
+ int count, net_no, index;
+ int net_no_list[128];
+ char rm_net_cmd[128];
+ lynq_wifi_auth_s net_auth;
+ curr_status_info curr_state;
+ ap_info_s ap_info;
+ char status[64];
+
+ if (ssid == NULL || *ssid == '\0')
+ {
+ RLOGE("bad ssid\n");
+ return -1;
+ }
+
+ if (LYNQ_WIFI_AUTH_OPEN != auth)
+ {
+ if (psw == NULL || strlen(psw) < 8 || strlen(psw) >= 64)
+ {
+ RLOGE("bad password\n");
+ return -1;
+ }
+ }
+
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ if (s_sta_status != INNER_STA_STATUS_INIT)
+ {
+ s_sta_status = INNER_STA_STATUS_CANCEL;
+ pthread_cond_signal(&s_global_check_cond);
+ }
+ pthread_mutex_unlock(&s_global_check_mutex);
+
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ net_no = -1;
+ memset(&ap_info, 0, sizeof (ap_info));
+ memset(status, 0, sizeof (status));
+
+ curr_state.ap = &ap_info;
+ curr_state.state = status;
+
+ if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+ {
+ if (strcmp(status, STATE_COMPLETED) == 0 && strcmp(ap_info.ap_ssid, ssid) ==0 && ap_info.auth == auth)
+ {
+ net_no = curr_state.net_no;
+ if (0 == lynq_sta_ssid_password_get(idx, &ap_info, ap_info.psw)
+ && strcmp(ap_info.psw, psw) == 0)
+ {
+ RLOGD("already connected\n");
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_sta_status = INNER_STA_STATUS_CONNECTED;
+ lynq_sta_removeElement(net_no);
+ pthread_cond_signal(&s_global_check_cond);
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return 0;
+ }
+ }
+ }
+
+ if (net_no == -1)
+ {
+ count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+ for (index=0; index < count; index++)
+ {
+ net_auth = -1;
+ if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+ {
+ net_no = net_no_list[index];
+ break;
+ }
+ }
+
+ if (net_no < 0)
+ {
+ count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+ for ( index = 0; index < (count - STA_MAX_SAVED_AP_NUM + 1 ) ;index++) //+1 is for add new network
+ {
+ sprintf(rm_net_cmd,"REMOVE_NETWORK %d",net_no_list[index]);
+ RLOGD("call cmd rm_net_cmd: %s;index is %d\n",rm_net_cmd,index);
+ DO_OK_FAIL_REQUEST(rm_net_cmd);
+ }
+ net_no = lynq_add_network(CTRL_STA);
+ if (net_no == -1)
+ {
+ return -1;
+ }
+
+ RLOGD("net no is %d\n", net_no);
+ if (0 != inner_set_sta_ssid(net_no, ssid))
+ {
+ return -1;
+ }
+ }
+ }
+
+ if (0 != inner_set_sta_auth_psw(net_no, auth, psw))
+ {
+ return -1;
+ }
+
+
+ DO_OK_FAIL_REQUEST(cmd_disconnect);
+ system("echo \"\" > /tmp/wlan0_dhcpcd_router");
+ usleep(200*1000);
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ lynq_sta_removeElement(net_no);
+ pthread_mutex_unlock(&s_global_check_mutex);
+
+ ret = inner_sta_start_stop(net_no, 1, 1);
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_sta_status = INNER_STA_STATUS_CONNECTING;
+ g_sta_conncet_status_flag = 1;
+ strcpy(s_sta_current_connecting_ssid, ssid);
+ struct timeval now;
+ gettimeofday(&now,NULL);
+ s_sta_connect_timeout.tv_sec = now.tv_sec + timeout;
+ s_sta_connect_timeout.tv_nsec = now.tv_usec*1000;
+ pthread_cond_signal(&s_global_check_cond);
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return ret;
+}
+
+int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw)
+{
+ return lynq_wifi_sta_connect_timeout(idx, ssid, auth, psw, MAX_CONNNECT_TIME);
+}
+
+int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx, char *ssid)
+{
+ ap_info_s ap;
+ curr_status_info curr_state;
+ ap.ap_ssid[0] = '\0';
+
+ if (ssid == NULL || *ssid == '\0')
+ {
+ RLOGE("input ssid is NULL\n");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ curr_state.ap = ≈
+ curr_state.state = NULL;
+
+ if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+ {
+ return 0;
+ }
+
+ if (strcmp(ap.ap_ssid, ssid) != 0)
+ {
+ return 0;
+ }
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return inner_sta_start_stop(curr_state.net_no, 0, 0);
+}
+
+int lynq_wifi_sta_disconnect_ap(lynq_wifi_index_e idx, char *ssid)
+{
+ int i,check_history_idx_flag;
+ ap_info_s ap;
+ curr_status_info curr_state;
+ ap.ap_ssid[0] = '\0';
+ check_history_idx_flag = 0;
+
+ if (ssid == NULL || *ssid == '\0')
+ {
+ RLOGE("input ssid is NULL\n");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+
+ curr_state.ap = ≈
+ curr_state.state = NULL;
+
+ if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+ {
+ return 0;
+ }
+
+ if (strcmp(ap.ap_ssid, ssid) != 0)
+ {
+ return 0;
+ }
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+ RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_valid_num is %d",g_history_disconnect_valid_num);
+ for( i = 0; i< g_history_disconnect_valid_num ; i++)
+ {
+ RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_net[%d] is %d,current disconnet network is %d",i,g_history_disconnect_net[i],curr_state.net_no);
+ if( g_history_disconnect_net[i] == curr_state.net_no)
+ {
+ RLOGD("current disconenct ap idx is %d && last aready into g_history_disconenct_net",curr_state.net_no);
+ check_history_idx_flag = 1;
+ break;
+ }
+ }
+ if ( check_history_idx_flag == 0)
+ {
+ RLOGD("current need add ap idx is %d ,g_history_disconnect_valid_num is %d line %d",curr_state.net_no,g_history_disconnect_valid_num,__LINE__);
+ g_history_disconnect_net[g_history_disconnect_valid_num] = curr_state.net_no;
+ g_history_disconnect_valid_num++;
+ }
+ RLOGD("%s %d",__func__,__LINE__);
+ print_disconnect_list();
+ pthread_mutex_unlock(&s_global_check_mutex);
+ return lynq_wifi_sta_stop_network(idx, curr_state.net_no);
+
+}
+
+
+int lynq_wifi_sta_start(lynq_wifi_index_e idx)
+{
+ RLOGD("enter %s %d func",__func__,__LINE__);
+ const char *lynq_enable_sta_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 enable_net all";
+ const char *lynq_reconnect_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 reconnect";
+
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ ret = system_call_v("%s %s", start_stop_sta_script, "start");
+ if (ret != 0)
+ {
+ RLOGE("lynq_wifi_sta_start excute script fail %s %d",__func__,__LINE__);
+ return -1;
+ }
+
+ system(lynq_enable_sta_cmd);
+ system(lynq_reconnect_cmd);
+ pthread_mutex_lock(&s_global_check_mutex);
+ g_history_disconnect_valid_num = 0; //clean history_disconenct_list info
+ s_sta_status = INNER_STA_STATUS_INIT;
+ pthread_mutex_unlock(&s_global_check_mutex);
+ RLOGD("end %s %d func",__func__,__LINE__);
+ return 0;
+}
+
+static int inner_get_status_info_state (int interface, char *state) {
+ curr_status_info curr_state;
+ curr_state.ap = NULL;
+ curr_state.state = state;
+ return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_wifi_sta_start_auto(lynq_wifi_index_e idx)
+{
+
+ RLOGD("[wifi]enter lynq_wifi_sta_start_auto start");
+ int tmp_open_idx[128];
+ int len;
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ s_sta_status = INNER_STA_STATUS_INIT;
+ lynq_two_arr_merge(g_history_disconnect_net,g_history_disconnect_valid_num,tmp_open_idx,&len);
+ pthread_mutex_unlock(&s_global_check_mutex);
+ if(lynq_tmp_enable_network(idx,tmp_open_idx,len) != 0 )
+ {
+ RLOGD("[wifi]lynq_tmp_enable_network error");
+ }
+
+ RLOGD("[wifi]enter lynq_wifi_sta_start_auto end");
+ return 0;
+}
+
+
+int lynq_wifi_sta_stop(lynq_wifi_index_e idx)
+{
+ RLOGD("enter %s %d",__func__,__LINE__);
+ int i=0;
+ char state[MAX_CMD];
+
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ DO_OK_FAIL_REQUEST(cmd_disconnect);
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ ret = system_call_v("%s %s", start_stop_sta_script, "stop");
+ if (ret != 0)
+ {
+ RLOGE("lynq_wifi_sta_stop excute script fail %s %d",__func__,__LINE__);
+ return -1;
+ }
+
+ for (i=0; i < 30; i++) // to check if sta is realy stoped
+ {
+ if (inner_get_status_info_state(idx, state) != 0)
+ {
+ break;
+ }
+
+ if (memcmp(state, STATE_DISCONNECTED, strlen (STATE_DISCONNECTED)) == 0)
+ {
+ break;
+ }
+ RLOGD("lynq_wifi_sta_stop curr state %s %s %d", state,__func__,__LINE__);
+ usleep(SLEEP_TIME_ON_IDLE);
+ }
+ pthread_mutex_lock(&s_global_check_mutex);
+ g_history_disconnect_valid_num = 0; //clean history_disconenct_list info
+ pthread_mutex_unlock(&s_global_check_mutex);
+ RLOGD("end %s %d",__func__,__LINE__);
+ return 0;
+// return system("connmanctl disable wifi");
+}
+int lynq_wifi_sta_stop_net(lynq_wifi_index_e idx,int networkid)
+{
+ char LYNQ_DISABLE_CMD[128]={0};
+ CHECK_IDX(idx, CTRL_STA);
+ CHECK_WPA_CTRL(CTRL_STA);
+ sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+ RLOGD("LYNQ_DISABLE_CMD is:%d\n",LYNQ_DISABLE_CMD);
+ DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+ return 0;
+}
+
+//static int inner_get_sta_info(lynq_wifi_index_e idx, const char * bssid, device_info_s *dev) {
+// int i, count;
+// char *p;
+// const char * FLAG_SSID = "ssid=";
+// const char * FLAG_SBSID = "bssid=";
+// const char * FLAG_KEY_MGMT = "key_mgmt=";
+// const char * FLAG_FREQ = "freq=";
+// char lynq_sta_cmd[MAX_CMD];
+// char *split_lines[128] = {0};
+
+// CHECK_WPA_CTRL(CTRL_AP);
+
+// sprintf(lynq_sta_cmd, "STA %s", bssid);
+
+// DO_REQUEST(lynq_sta_cmd);
+
+// count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+// for(i=0; i < count; i++) {
+// p = strstr(split_lines[i], FLAG_SSID);
+// if (p != NULL) {
+// strcpy(ap->ap_ssid, p + strlen(FLAG_SSID));
+// continue;
+// }
+// }
+
+// lynq_get_interface_ip(idx, ap->ap_ip);
+// lynq_ap_password_set(idx, ap->psw);
+
+// return 0;
+//}
+
+static int inner_get_status_info_ap (int interface, ap_info_s *ap) {
+ curr_status_info curr_state;
+ curr_state.ap = ap;
+ curr_state.state = NULL;
+ return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_get_ap_device_list(lynq_wifi_index_e idx, ap_info_s **ap, device_info_s ** list,int * len)
+{
+ RLOGD("[wifi]-----enter lynq_get_ap_device_list");
+ int index, line_count;
+ device_info_s *dev_info;
+ const char *lynq_first_sta_cmd = "STA-FIRST";
+ char lynq_next_sta_cmd[MAX_CMD];
+ char *bssid[1024] = {0};
+ char *split_lines[128] = {0};
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ // ap_info_s * tmp_ap;
+ // device_info_s * tmp_list;
+ if (ap == NULL || list == NULL || len == NULL)
+ {
+ RLOGE("bad input param");
+ return -1;
+ }
+
+ // ap = &tmp_ap;
+ // list = &tmp_list;
+ *ap = malloc(sizeof (ap_info_s));
+ memset(*ap, 0, sizeof (ap_info_s));
+
+ if (inner_get_status_info_ap (CTRL_AP, *ap) != 0 || (*ap)->ap_ssid[0] == '\0')
+ {
+ RLOGE("inner_get_status_info_ap !=0 or ap_ssid is empty\n");
+ return -1;
+ }
+
+ lynq_get_interface_ip(idx, (*ap)->ap_ip);
+ lynq_ap_password_get(idx, (*ap)->psw);
+
+ DO_REQUEST(lynq_first_sta_cmd);
+
+ index = 0;
+ while (reply_len > 0)
+ {
+ if (memcmp(cmd_reply, "FAIL", 4) == 0)
+ {
+ break;
+ }
+ line_count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+ bssid[index] = malloc(strlen(split_lines[0]) + 1);
+ strcpy(bssid[index], split_lines[0]);
+ index++;
+ sprintf(lynq_next_sta_cmd, "STA-NEXT %s", split_lines[0]);
+ reply_len = MAX_RET;
+ cmd_reply[0] = '\0';
+ ret = local_wpa_ctrl_request(lynq_wpa_ctrl, lynq_next_sta_cmd, strlen(lynq_next_sta_cmd), cmd_reply, &reply_len, NULL);
+ if (ret != 0 || memcmp(cmd_reply, "FAIL", 4) == 0)
+ {
+ RLOGD("run %s fail \n", lynq_next_sta_cmd);
+ break;
+ }
+ }
+
+ *len = index;
+
+ *list = malloc(sizeof(device_info_s) * (*len));
+ for (index=0; index < *len; index++)
+ {
+ dev_info = &(*list)[index];
+ memset(dev_info, 0, sizeof(device_info_s));
+ strncpy(dev_info->sta_mac, bssid[index], sizeof (dev_info->sta_mac));
+ inner_get_ip_by_mac(dev_info->sta_mac, dev_info->sta_ip, sizeof (dev_info->sta_ip));
+ inner_get_hostname_by_ip(dev_info->sta_ip, dev_info->hostname);
+ dev_info->status = LYNQ_WIFI_STATUS_CONNECT;
+ free(bssid[index]);
+ }
+ RLOGD("[wifi]-----end lynq_get_ap_device_list");
+ return 0;
+}
+
+int lynq_get_scan_list(lynq_wifi_index_e idx, scan_info_s ** list,int * len)
+{
+ int i, count, index, count_words;
+ const char *lynq_scan_result_cmd = "SCAN_RESULTS";
+ char *split_lines[128] = {0};
+ char *split_words[128] = {0};
+ scan_info_s * p;
+
+ if (list == NULL || len == NULL)
+ {
+ return -1;
+ }
+
+ for (i =0; i < 50 && g_sta_scan_finish_flag == 0; i++)
+ {
+ usleep(100 * 1000);
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ DO_REQUEST(lynq_scan_result_cmd);
+
+ count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+ *len = count - 1;
+ *list = malloc(sizeof (scan_info_s) * *len);
+
+ count_words = lynq_split(split_lines[0], strlen(split_lines[0]), '/', split_words); //@todo get with header
+ for (index=0; index <count_words; index++)
+ {
+ RLOGD("----header: %s\n", split_words[index]);
+ }
+
+ for(index = 1;index < count; index++)
+ {
+ RLOGD("---- %s\n",split_lines[index]);
+ memset(split_words, 0 , sizeof (split_words));
+ count_words = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+ if (count_words < 4)
+ continue;
+ RLOGD("count: %d, %s\n", count_words, split_words[0]);
+ //bssid / frequency / signal level / flags / ssid
+ p = (*list) + index - 1;
+ strcpy(p->mac, split_words[0]);
+ p->band = convert_band_from_freq(atoi(split_words[1]));
+ p->rssi = -1 * atoi( split_words[2]);
+ p->auth = convert_max_auth_from_flag(split_words[3]);
+ if (count_words == 4) // ssid hided
+ {
+ p->ssid[0] = '\0';
+ }
+ else
+ {
+ inner_copy_ssid(p->ssid, split_words[4], sizeof (p->ssid));
+ }
+ }
+
+ return 0;
+}
+
+int lynq_sta_forget_ap(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth)
+{
+ int count, net_no, index;
+ int net_no_list[128];
+ lynq_wifi_auth_s net_auth;
+
+ char lynq_remove_cmd[MAX_CMD];
+
+ if (ssid == NULL || *ssid == '\0')
+ {
+ RLOGD("bad ssid\n");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ net_no = -1;
+ count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+ for (index=0; index < count; index++)
+ {
+ net_auth = -1;
+ if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+ {
+ net_no = net_no_list[index];
+ break;
+ }
+ }
+
+ if (net_no < 0)
+ {
+ return 0;
+ }
+
+ sprintf(lynq_remove_cmd, "REMOVE_NETWORK %d", net_no);
+
+ DO_OK_FAIL_REQUEST(lynq_remove_cmd);
+
+ RLOGD("WIFI[lynq_sta_forget_ap][check_history_disconenct_ap_list] input net_no is %d",net_no);
+
+ pthread_mutex_lock(&s_global_check_mutex);
+ lynq_sta_removeElement(net_no);
+ pthread_mutex_unlock(&s_global_check_mutex);
+
+ RLOGD("%s %d",__func__,__LINE__);
+ print_disconnect_list();
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+
+ return 0;
+}
+
+int lynq_get_sta_saved_ap(lynq_wifi_index_e idx, saved_ap_info_s ** list, int * len)
+{
+ int count, index;
+ int net_no_list[128];
+ char freq[16];
+ RLOGD("enter lynq_get_sta_saved_ap api\n");
+ if (list == NULL || len == NULL)
+ {
+ RLOGE("bad param,please check!");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+// CHECK_WPA_CTRL(CTRL_STA);
+
+ count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+ RLOGD("[lynq_get_sta_saved_ap]count is %d\n", count);
+
+ if (count < 0)
+ {
+ RLOGE("list network fail");
+ return count;
+ }
+ else if (count == 0)
+ {
+ *list = NULL;
+ *len = 0;
+ return 0;
+ }
+
+ *list = malloc(sizeof (saved_ap_info_s) * count);
+ memset(*list, 0, sizeof (saved_ap_info_s) * count);
+ *len = count;
+
+ for (index=0; index < count; index++)
+ {
+ inner_get_param(CTRL_STA, net_no_list[index], "ssid", (*list)[index].base_info.ap_ssid);
+ inner_get_param(CTRL_STA, net_no_list[index], "bssid", (*list)[index].base_info.ap_mac);
+ inner_get_network_auth(CTRL_STA, net_no_list[index], &(*list)[index].base_info.auth);
+ if (inner_get_param(CTRL_STA, net_no_list[index], "frequency", freq) == 0)
+ {
+ (*list)[index].base_info.band = convert_band_from_freq(atoi(freq));
+ }
+ else
+ {
+ (*list)[index].base_info.band = -1;
+ }
+ RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get psw");
+ lynq_sta_ssid_password_get(idx, & (*list)[index].base_info, (*list)[index].base_info.psw);
+ }
+ RLOGD("[lynq_get_sta_saved_ap] return ok");
+ return 0;
+}
+
+int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx)
+{
+ if ( s_sta_status == INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0 )
+ {
+ RLOGD("current sta is autoconnecting dest ap,fake scan result");
+ g_sta_fake_scan_finish_flag = 1;
+ return 0;
+ }
+ else if (g_sta_conncet_status_flag != 0)
+ {
+ RLOGD("current sta is connecting dest ap, don't scan");
+ return 1;
+ }
+
+ const char *clean_last_re ="wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 bss_flush";
+ const char *lynq_scan_cmd = "SCAN";
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ CHECK_WPA_CTRL(CTRL_STA);
+
+ if (g_sta_scan_finish_flag == 1 && s_sta_status == INNER_STA_STATUS_INIT) // temp add
+ {
+ RLOGD("tmp clear scanlist");
+ system(clean_last_re);
+ }
+ g_sta_scan_finish_flag = 0;
+ DO_REQUEST(lynq_scan_cmd);
+ if (reply_len >=9 && memcmp(cmd_reply, "FAIL-BUSY", 9) == 0 )
+ {
+ return 0;
+ } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0)
+ {
+ g_sta_scan_finish_flag = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int lynq_reg_ap_event_callback(void * priv, AP_CALLBACK_FUNC_PTR cb) {
+ if (cb == NULL)
+ {
+ RLOGE("lynq_reg_ap_event_callback ptr is NULL,plese check!\n");
+ return -1;
+ }
+
+ pthread_mutex_lock(&s_ap_callback_mutex);
+ g_ap_callback_priv = priv;
+ g_ap_callback_func = cb;
+ pthread_mutex_unlock(&s_ap_callback_mutex);
+
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ if (g_ap_watcher_pid == 0 )
+ {
+ if(pthread_create(&g_ap_watcher_pid,NULL,APWatcherThreadProc,NULL) < 0)
+ {
+ g_ap_watcher_pid = 0;
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGE("[wifi error]creat APWatcherThreadProc fail");
+ return -1;
+ }
+ }
+
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGD("creat APWatcherTheradProc succeed");
+
+ return 0;
+}
+
+int lynq_unreg_ap_event_callback(void * priv) {
+ RLOGD("enter %s %d",__func__,__LINE__);
+ pthread_mutex_lock(&s_ap_callback_mutex);
+ if (g_ap_callback_priv == priv)
+ {
+ g_ap_callback_func = NULL;
+ g_ap_callback_priv = NULL;
+ pthread_mutex_unlock(&s_ap_callback_mutex);
+ RLOGD("unreg ap callback pass %s %d",__func__,__LINE__);
+ return 0;
+ }
+ pthread_mutex_unlock(&s_ap_callback_mutex);
+ RLOGE("unreg ap callback fail %s %d",__func__,__LINE__);
+ return -1;
+}
+
+int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb){
+ if (cb == NULL)
+ {
+ RLOGE("lynq_reg_sta_event_callback ptr is NULL,plese check!\n");
+ return -1;
+ }
+
+ pthread_mutex_lock(&s_sta_callback_mutex);
+ g_sta_callback_priv = priv;
+ g_sta_callback_func = cb;
+ pthread_mutex_unlock(&s_sta_callback_mutex);
+
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ if (g_sta_watcher_pid == 0 ) {
+ if(pthread_create(&g_sta_watcher_pid,NULL,STAWatcherThreadProc,NULL) < 0)
+ {
+ g_sta_watcher_pid = 0;
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+ return -1;
+ }
+ }
+
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGD("creat STAWatcherTheradProc succeed");
+ return 0;
+}
+
+int lynq_unreg_sta_event_callback(void * priv) {
+ RLOGD("enter %s %d",__func__,__LINE__);
+ pthread_mutex_lock(&s_sta_callback_mutex);
+ if (g_sta_callback_priv == priv)
+ {
+ g_sta_callback_func = NULL;
+ g_sta_callback_priv = NULL;
+ pthread_mutex_unlock(&s_sta_callback_mutex);
+ RLOGD("unreg sta callback pass %s %d",__func__,__LINE__);
+ return 0;
+ }
+ pthread_mutex_unlock(&s_sta_callback_mutex);
+ RLOGE("unreg sta callback fail %s %d",__func__,__LINE__);
+ return -1;
+}
+
+int lynq_reg_sta_auto_event_callback(void * priv, STA_AUTO_CALLBACK_FUNC_PTR cb){
+ if (cb == NULL)
+ {
+ RLOGE("lynq_reg_sta_auto_event_callback ptr is NULL,plese check!\n");
+ return -1;
+ }
+ pthread_mutex_lock(&s_sta_auto_callback_mutex);
+ g_sta_auto_callback_priv = priv;
+ g_sta_auto_callback_func = cb;
+ pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+ pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+ if (g_sta_auto_watcher_pid == 0 ) {
+ if(pthread_create(&g_sta_auto_watcher_pid,NULL,STAAutoWatcherThreadProc,NULL) < 0) //create STAAutoWatcherThreadProc
+ {
+ g_sta_auto_watcher_pid = 0;
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+ return -1;
+ }
+ }
+ pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+ RLOGD("creat STAWatcherTheradProc succeed");
+ return 0;
+}
+int lynq_unreg_sta_auto_event_callback(void * priv) {
+ pthread_mutex_lock(&s_sta_auto_callback_mutex);
+ if (g_sta_auto_callback_priv == priv)
+ {
+ g_sta_auto_watcher_stop_flag = 1;
+ if (g_sta_auto_watcher_pid != 0)
+ {
+ pthread_join(g_sta_auto_watcher_pid, NULL);
+ }
+ g_sta_auto_watcher_pid = 0;
+ g_sta_auto_callback_func = NULL;
+ g_sta_auto_callback_priv = NULL;
+ pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+ return 0;
+ }
+ pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+ return -1;
+}
+int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status)
+{
+ char state[MAX_CMD];
+ RLOGD("enter lynq_get_ap_status\n");
+ CHECK_IDX(idx, CTRL_AP);
+
+ if (inner_get_status_info_state(CTRL_AP, state) != 0)
+ {
+ *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+ return 0;
+ }
+
+ if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+ {
+ *ap_status = LYNQ_WIFI_AP_STATUS_ENABLE;
+ }
+ else
+ {
+ *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+ }
+
+ return 0;
+}
+
+int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status) {
+ char state[MAX_CMD];
+ RLOGD("enter lynq_get_sta_status\n");
+ CHECK_IDX(idx, CTRL_STA);
+
+ if (inner_get_status_info_state(CTRL_STA, state) != 0)
+ {
+ *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+ return 0;
+ }
+
+ if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+ {
+ *sta_status = LYNQ_WIFI_STA_STATUS_ENABLE;
+ }
+ else
+ {
+ *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+ }
+
+ return 0;
+}
+
+int lynq_get_country_code(lynq_wifi_index_e idx, char * country_code) {
+// CHECK_IDX(idx, CTRL_AP);
+// int ret = 0;
+// size_t reply_len = MAX_RET;
+// char cmd_reply[MAX_RET]={0};
+// const char * cmd_str = "GET country";
+// struct wpa_ctrl *s_lynq_wpa_ctrl = NULL;
+// do{
+// if (NULL == s_lynq_wpa_ctrl) {
+// s_lynq_wpa_ctrl = wpa_ctrl_open("/var/run/wpa_wlan0_cmd");
+// if (NULL == s_lynq_wpa_ctrl ) {
+// printf("wpa_ctrl_open fail\n");
+// return -1;
+// }
+// }
+// }while(0);
+
+// do {
+// reply_len = MAX_RET;
+// cmd_reply[0] = '\0';
+// printf("to call [%s]\n", cmd_str);
+// ret = local_wpa_ctrl_request(s_lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL);
+// if (ret != 0) {
+// RLOGE("call ##cmd_str fail %d\n", ret);
+// return ret;
+// }
+// cmd_reply[reply_len+1] = '\0';
+// RLOGD("cmd replay [ %s ]\n", cmd_reply);
+// }while(0);
+
+ FILE *fp;
+ size_t i = 0;
+ char lynq_cmd_ret[MAX_RET]={0};
+
+// CHECK_IDX(idx, CTRL_AP);
+
+ if((fp=popen("wl country","r"))==NULL)
+ {
+ perror("popen error!");
+ return -1;
+ }
+ if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+ {
+ perror("fread fail!");
+ return -1;
+ }
+
+ for(i=0; i < strlen(lynq_cmd_ret); i++)
+ {
+ if (lynq_cmd_ret[i] == ' ')
+ {
+ lynq_cmd_ret[i] = '\0';
+ break;
+ }
+ }
+
+ strcpy(country_code,lynq_cmd_ret);
+ RLOGD("---country code %s\n", country_code);
+
+ int ret=pclose(fp);
+ if(ret==-1)
+ {
+ perror("close file faild");
+ }
+
+ return 0;
+}
+
+
+static int check_and_init_uci_config(char * country_code)
+{
+ FILE * fp;
+ int is_different = 0;
+ const char * check_uci_cmd ="uci show | grep lynq_wifi_country_code";
+ const char * create_uci_cmd ="uci set lynq_uci.lynq_wifi_country_code='lynq_wifi_country_code'";
+ const char * commit_uci_cmd ="uci commit";
+ char set_country_cmd[MAX_CMD];
+ char lynq_cmd_ret[MAX_CMD]={0};
+
+ sprintf(set_country_cmd, "uci set lynq_uci.lynq_wifi_country_code.code='%s'",country_code);
+
+ if (0 != system(check_uci_cmd))
+ {
+ if (0 != system(create_uci_cmd))
+ {
+ RLOGE("creat_uci_cmd fail");
+ return -1;
+ }
+ is_different = 1;
+ }
+
+ if((fp=popen("uci get lynq_uci.lynq_wifi_country_code.code","r"))==NULL)
+ {
+ RLOGE("popen error!");
+ return -1;
+ }
+
+ if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0 )
+ {
+ RLOGE("fread fail!");
+ fclose(fp);
+ return -1;
+ }
+
+ if ( strncmp(lynq_cmd_ret,country_code,2) != 0 )
+ {
+ RLOGE("get country code for uci %s,input cpuntry code is:%s\n",lynq_cmd_ret,country_code);
+ is_different = 1;
+ }
+
+ fclose(fp);
+
+ if (is_different)
+ {
+ if ( 0 != system(set_country_cmd))
+ {
+ RLOGE("set_country_cmd fail");
+ return -1;
+ }
+ if (0 != system(commit_uci_cmd))
+ {
+ RLOGE("commmit fail");
+ }
+ }
+
+ return is_different;
+}
+
+int lynq_set_country_code(lynq_wifi_index_e idx, char * country_code) {
+ char check_current_code[10];
+ const char * support_country[] = {"CN", "EU"};
+
+ int ret,is_different, i, cc_count;
+
+ if (country_code == NULL || country_code[0] == '\0')
+ {
+ RLOGE("bad country code\n");
+ return -1;
+ }
+
+ cc_count = sizeof (support_country) / sizeof (char*);
+ for(i=0; i < cc_count; i++)
+ {
+ if (strcmp(support_country[i], country_code) == 0)
+ {
+ break;
+ }
+ }
+
+ if (i >= cc_count)
+ {
+ RLOGE("unspported country code %s\n", country_code);
+ return -1;
+ }
+
+ is_different = check_and_init_uci_config(country_code);
+ if( is_different < 0 )
+ {
+ RLOGE("init set uci fail\n");
+ return -1;
+ }
+
+ ret = lynq_get_country_code(idx,check_current_code);
+ if( ret == 0 && (is_different == 1 || strcmp(check_current_code, country_code) != 0))
+ {
+ ret = lynq_wifi_disable();
+ if(ret != 0 )
+ {
+ RLOGE("berfore set country,find bcmdhd insmod,remod fail\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac)
+{
+ RLOGD("enter lynq_get_connect_ap_mac\n");
+ if (mac == NULL)
+ {
+ RLOGE("input ptr is NULL,please check\n");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+ ap_info_s ap;
+ ap.ap_mac[0] = '\0';
+
+ if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+ {
+ return -1;
+ }
+ strcpy(mac, ap.ap_mac);
+
+ return 0;
+}
+
+int lynq_get_interface_ip(lynq_wifi_index_e idx, char *ip)
+{
+ RLOGD("enter lynq_get_interface_ip\n");
+ struct ifaddrs *ifaddr_header, *ifaddr;
+ struct in_addr * ifa;
+ const char * ifaName = "wlan0";
+ if (ip == NULL)
+ {
+ RLOGE("[lynq_get_interface_ip]input erro,input is NULL ptr,please check\n");
+ return -1;
+ }
+
+ if (idx == 1)
+ {
+ ifaName = inner_get_ap_interface_name();
+ if (ifaName == NULL)
+ {
+ RLOGE("[lynq_get_interface_ip] ap name get fail");
+ return -1;
+ }
+ }
+ else if (idx != 0)
+ {
+ return -1;
+ }
+
+ if (getifaddrs(&ifaddr_header) == -1)
+ {
+ perror("getifaddrs");
+ return -1;
+ //exit(EXIT_FAILURE);
+ }
+
+
+ for (ifaddr = ifaddr_header; ifaddr != NULL; ifaddr = ifaddr->ifa_next)
+ {
+ if (ifaddr->ifa_addr == NULL)
+ continue;
+ if((strcmp(ifaddr->ifa_name,ifaName)==0))
+ {
+ if (ifaddr->ifa_addr->sa_family==AF_INET) // check it is IP4
+ {
+ // is a valid IP4 Address
+ ifa=&((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr;
+ inet_ntop(AF_INET, ifa, ip, INET_ADDRSTRLEN);
+ RLOGD("[lynq_get_interface_ip]:%s IP Address %s/n", ifaddr->ifa_name, ip);
+ freeifaddrs(ifaddr_header);
+ RLOGD("ip %s\n", ip);
+ return 0;
+ }
+ }
+ }
+ freeifaddrs(ifaddr_header);
+ RLOGE("[lynq_get_interface_ip] can't find interface | other erro\n");
+ return -1;
+}
+
+int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac)
+{
+ RLOGD("enter lynq_get_interface_mac\n");
+ int count;
+ size_t i;
+ int WIFI_INTERFACE_MAC_LEN = 17;
+ char *split_words[128] = {0};
+ const char *lynq_get_mac_cmd = "DRIVER MACADDR";
+
+ CHECK_WPA_CTRL(idx);
+
+ DO_REQUEST(lynq_get_mac_cmd);
+
+ if (memcmp(cmd_reply, "FAIL", 4) == 0)
+ {
+ RLOGE("[lynq_get_interface_mac]do request cmd --DRIVER MACADDR-- reply FAIL\n");
+ return -1;
+ }
+
+ count = lynq_split(cmd_reply, reply_len, '=', split_words);
+
+ if (count < 2)
+ {
+ return -1;
+ }
+
+ for (i=0; i < strlen(split_words[1]); i++ )
+ {
+ if (split_words[1][i] != ' ')
+ {
+ break;
+ }
+ }
+
+ strncpy(mac, split_words[1] + i, WIFI_INTERFACE_MAC_LEN);
+
+ return 0;
+}
+
+int lynq_get_connect_ap_rssi(lynq_wifi_index_e idx,int * rssi)
+{
+// int count;
+// char *split_words[128] = {0};
+// const char *lynq_get_rssi_cmd = "DRIVER RSSI";
+
+// if (rssi == NULL) {
+// return -1;
+// }
+
+// CHECK_IDX(idx, CTRL_STA);
+
+// CHECK_WPA_CTRL(CTRL_STA);
+
+// DO_REQUEST(lynq_get_rssi_cmd);
+
+// if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+// return -1;
+// }
+
+// count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+
+// if (count < 2) {
+// return -1;
+// }
+
+// *rssi = atoi(split_words[1]) * -1;
+
+ char lynq_cmd_ret[MAX_RET]={0};
+
+/*******change other cmd to get rssi*******
+ *
+ *wl rssi ---> wl -i wlan0 rssi
+ *
+ ***** change by qs.xiong 20221011*******/
+ if (0 != exec_cmd("wl -i wlan0 rssi", lynq_cmd_ret, MAX_RET))
+ {
+ RLOGE("[lynq_get_connect_ap_rssi] exec cmd [ wl -i wlan0 rssi ] fail");
+ return -1;
+ }
+ *rssi = atoi(lynq_cmd_ret) * -1;
+/****** if got rssi is 0,means sta didn't connected any device****/
+ if(*rssi == 0)
+ {
+ RLOGE("[lynq_get_connect_ap_rssi]sta didn't connected any ap device,please check connection\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int lynq_get_connect_ap_band(lynq_wifi_index_e idx, lynq_wifi_band_m * band)
+{
+ RLOGD("enter lynq_get_connect_ap_band\n");
+ if (band == NULL)
+ {
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+ ap_info_s ap;
+ ap.band = -1;
+
+ if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+ {
+ return -1;
+ }
+ *band = ap.band;
+
+ return 0;
+}
+
+int lynq_get_connect_ap_ip(lynq_wifi_index_e idx, char *ip)
+{
+ int ret;
+ char *p;
+ char bssid[1024] = {0};
+
+ if (ip == NULL)
+ {
+ RLOGE("[lynq_get_connect_ap_ip]invalid param ptr ip,input ptr is NULL\n");
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_STA);
+
+ if (lynq_get_connect_ap_mac(idx, bssid) != 0)
+ {
+ return -1;
+ }
+
+ ip[0] = '\0';
+ ret = inner_get_ip_by_mac(bssid, ip, 32); //better input by user
+ if (ret != 0)
+ {
+ RLOGE("[lynq_get_connect_ap_ip] inner_get_ip_by_mac return fail");
+ }
+
+ if (ip[0] == '\0' || strchr(ip, ':') != NULL) //temp change, not ok
+ {
+ ip[0] = '\0';
+ ret = exec_cmd("grep \"new_router\" /tmp/wlan0_dhcpcd_router | awk '{print $2}'| tail -1", ip, 32);
+ if (ret != 0)
+ {
+ ip[0] = '\0';
+ return 0;
+ }
+ else
+ {
+ p = strchr(ip, '\n');
+ if (p != NULL)
+ {
+ *p = '\0';
+ }
+ }
+ }
+ return 0;
+}
+
+int lynq_get_sta_connected_dns(lynq_wifi_index_e idx, char *dns)
+{
+ RLOGD("[wifi]--enter--lynq_get_sta_connected_dns");
+ return lynq_get_connect_ap_ip(idx,dns); //> not 100 % get dns info
+}
+
+int lynq_ap_connect_num(int sta_number)
+{
+ char lynq_limit_cmd[32]={0};
+ int ret;
+ if((sta_number < 1 ) && (sta_number > 15))
+ {
+ RLOGE("sta_number: not in range\n",sta_number);
+ return -1;
+ }
+ sprintf(lynq_limit_cmd,"wl maxassoc %d", sta_number);
+ ret = system(lynq_limit_cmd);
+ if(ret != 0)
+ {
+ RLOGE("cmd of limit ap devices number error\n");
+ }
+ return 0;
+}
+
+int lynq_enable_acs(lynq_wifi_index_e idx,int acs_mode)
+{
+
+ char lynq_wifi_acs_cmd[128]={0};
+ char lynq_cmd_mode[128]={0};
+ char lynq_cmd_slect[128]={0};
+
+ if((acs_mode != 2) && (acs_mode != 5))
+ {
+ PRINT_AND_RETURN_VALUE("set acs_mode is error",-1);
+ }
+
+ if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+ {
+ return -1;
+ }
+
+ CHECK_IDX(idx, CTRL_AP);
+
+ CHECK_WPA_CTRL(CTRL_AP);
+
+ sprintf(lynq_wifi_acs_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, acs_mode);
+ sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+ sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+ DO_OK_FAIL_REQUEST(cmd_disconnect);
+ DO_OK_FAIL_REQUEST(lynq_wifi_acs_cmd);
+ DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+ DO_OK_FAIL_REQUEST(cmd_save_config);
+ DO_OK_FAIL_REQUEST(lynq_cmd_slect);
+
+ return 0;
+}
+//you.chen add for tv-box start
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len) {
+ FILE *fp;
+ //printf("to exec cmd:%s\n", str_cmd);
+ if((fp=popen(str_cmd,"r"))==NULL)
+ {
+ perror("popen error!");
+ return -1;
+ }
+ if((fread(str_cmd_ret,max_len,1,fp))<0)
+ {
+ perror("fread fail!");
+ fclose(fp);
+ return -1;
+ }
+ fclose(fp);
+ return 0;
+}
+
+static int get_netmask_length(const char* mask)
+{
+ int masklen=0, i=0;
+ int netmask=0;
+
+ if(mask == NULL)
+ {
+ return 0;
+ }
+
+ struct in_addr ip_addr;
+ if( inet_aton(mask, &ip_addr) )
+ {
+ netmask = ntohl(ip_addr.s_addr);
+ }else
+ {
+ netmask = 0;
+ return 0;
+ }
+
+ while(0 == (netmask & 0x01) && i<32)
+ {
+ i++;
+ netmask = netmask>>1;
+ }
+ masklen = 32-i;
+ return masklen;
+}
+
+static int get_tether_route_str(char *str_cmd_ret, size_t max_len) {
+ int mask_len;
+ char *p;
+ char tmp[64] = {0};
+ sprintf(tmp, "ifconfig %s | grep Mask", s_ap_iterface_name);
+ if (exec_cmd(tmp, str_cmd_ret, max_len) != 0)
+ return -1;
+ p = strstr(str_cmd_ret, "Mask:");
+ if (p == NULL)
+ return -1;
+ mask_len = get_netmask_length(p + 5);
+ if (mask_len == 0)
+ return -1;
+ p = strstr(str_cmd_ret, "inet addr:");
+ if (p == NULL)
+ return -1;
+ strcpy(tmp, p + 10);
+ p = strstr(tmp, " ");
+ if (p != NULL)
+ *p = '\0';
+ sprintf(str_cmd_ret, "%s/%d", tmp, mask_len);
+ return 0;
+}
+
+static void GBWWatchThreadProc() {
+ int i,n, nloop, nmax, ncheckcount, nidlecount;
+ unsigned long long lastAP1Bytes, lastAP2Bytes, currAP1Bytes, currAP2Bytes;
+ unsigned int lastAP1Drop,lastAP2Drop, currAP1Drop, currAP2Drop;
+ unsigned int setAP1Speed, setAP2Speed, lastAP1Speed, lastAP2Speed, currAP1Speed, currAP2Speed,currSetAP1Speed;
+ char *results[16] = {0};
+ char str_cmd[256] = {0};
+ char str_cmd_ret[128] = {0};
+ char dest_ip[32] = {0};
+ lastAP1Bytes = lastAP2Bytes = 0;
+ lastAP1Drop = lastAP2Drop = 0;
+ lastAP1Speed = lastAP2Speed = 0;
+ setAP1Speed = 50;
+ setAP2Speed = 80;
+ nloop = 0;
+ nmax = 6;
+ ncheckcount = nidlecount = 0;
+
+ if (inner_get_ap_interface_name() == NULL)
+ {
+ RLOGE("------gbw thread run\n");
+ return;
+ }
+
+ RLOGD("------gbw thread run\n");
+ sprintf(str_cmd, "ip neigh | grep %s | awk '{print $1}'", g_gbw_mac);
+ while (dest_ip[0] == '\0') {
+ sleep(1);
+ str_cmd_ret[0] = '\0';
+ exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret));
+ for(n = 0; n < (int)sizeof(str_cmd_ret) && str_cmd_ret[n] != '\0'; n++) {
+ if (str_cmd_ret[n] == '\n'){
+ str_cmd_ret[n] = '\0';
+ break;
+ }
+ }
+ if (str_cmd_ret[0] != '\0')
+ {
+ strcpy(dest_ip, str_cmd_ret);
+ }
+ }
+
+ system_call_v("tc qdisc del dev %s root > /dev/null 2>&1", s_ap_iterface_name);
+ system_call_v("tc qdisc add dev %s root handle 1: htb r2q 1", s_ap_iterface_name);
+ system_call_v("tc class add dev %s parent 1: classid 1:1 htb rate 50Mbit ceil 70Mbit prio 2 quantum 3000", s_ap_iterface_name);
+ if (get_tether_route_str(str_cmd_ret, sizeof (str_cmd_ret)) != 0)
+ {
+ RLOGD("not get tether info\n");
+ return;
+ }
+ system_call_v("tc filter add dev %s parent 1: protocol ip prio 16 u32 match ip dst %s flowid 1:1", s_ap_iterface_name, str_cmd_ret);
+ system_call_v("tc class add dev %s parent 1: classid 1:2 htb rate 80Mbit ceil 100Mbit prio 0 quantum 3000000", s_ap_iterface_name);
+ system_call_v("tc filter add dev %s parent 1: protocol ip prio 1 u32 match ip dst %s flowid 1:2", s_ap_iterface_name, dest_ip);
+
+ while (1) {
+ sleep(1);
+ memset(str_cmd, 0, sizeof(str_cmd));
+ memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+ sprintf(str_cmd, "tc -s class show dev %s classid 1:1 | grep Sent", s_ap_iterface_name);
+ if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+ continue;
+ //printf("ap1 --- %s\n", str_cmd);
+ n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+ if (n > 9) {
+ if (strcmp(results[1], "Sent") == 0) {
+ currAP1Bytes = atoll(results[2]);
+ }
+ if (strcmp(results[6], "(dropped") == 0) {
+ currAP1Drop = atoi(results[7]);
+ }
+ }
+
+ memset(str_cmd, 0, sizeof(str_cmd));
+ memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+ sprintf(str_cmd, "tc -s class show dev %s classid 1:2 | grep Sent", s_ap_iterface_name);
+ if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+ continue;
+ //printf("ap2 --- %s\n", str_cmd);
+ n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+ if (n > 9) {
+ if (strcmp(results[1], "Sent") == 0) {
+ currAP2Bytes = atoll(results[2]);
+ }
+ if (strcmp(results[6], "(dropped") == 0) {
+ currAP2Drop = atoi(results[7]);
+ }
+ }
+
+ //printf("ap1 %llu- %u, ap2 %llu-%u\n", currAP1Bytes, currAP1Drop, currAP2Bytes, currAP2Drop);
+ if (currAP1Bytes < lastAP1Bytes || currAP2Bytes < lastAP2Bytes) {
+ lastAP1Bytes = currAP1Bytes;
+ lastAP2Bytes = currAP2Bytes;
+ continue;
+ }
+
+ currAP1Speed = (currAP1Bytes - lastAP1Bytes) / 128 / 1024;
+ currAP2Speed = (currAP2Bytes - lastAP2Bytes) / 128 / 1024;
+ //printf("ap1 speed %d mb, ap2 speed %d mb\n", currAP1Speed, currAP2Speed);
+ lastAP1Speed = currAP1Speed;
+ lastAP2Speed = currAP2Speed;
+ lastAP1Bytes = currAP1Bytes;
+ lastAP2Bytes = currAP2Bytes;
+
+ currSetAP1Speed = setAP1Speed;
+ if ((currAP2Speed < 30 && currAP2Speed > 5) && currAP1Speed > 5) {
+ ncheckcount++;
+ if (ncheckcount > 3) {
+ ncheckcount = 0;
+ currSetAP1Speed = 5;
+ }
+ }
+ else {
+ ncheckcount = 0;
+ if (currAP1Speed < 5)
+ nidlecount++;
+ else
+ nidlecount = 0;
+
+ }
+
+ if (nidlecount > 60 ){
+ currSetAP1Speed = 50;
+ }
+
+ if (currSetAP1Speed != setAP1Speed) {
+ setAP1Speed = currSetAP1Speed;
+ system_call_v(str_cmd, "tc class replace dev %s parent 1: classid 1:1 htb rate %dMbit ceil %dMbit prio 2 quantum 3000",
+ s_ap_iterface_name, setAP1Speed, (int)(setAP1Speed*1.4));
+ }
+ }
+}
+
+int enableGBW(const char* mac) {
+ int i,len;
+ char get_ipaddr_cmd[128]={0};
+ ap_info_s *ap;
+ device_info_s * list;
+
+ if (mac == NULL || g_gbw_enabled == 1)
+ return -1;
+ len = strlen(mac);
+ g_gbw_mac = malloc(len + 1);
+ for(i=0;i<len;i++) {
+ if (mac[i] >= 'A' && mac[i] <= 'Z')
+ {
+ g_gbw_mac[i] = 'a' + (mac[i] - 'A');
+ }
+ else
+ g_gbw_mac[i] = mac[i];
+ }
+ g_gbw_mac[i] = '\0';
+ g_gbw_enabled = 1;
+
+ sprintf(get_ipaddr_cmd, "ip neigh | grep %s", g_gbw_mac);
+ if (system(get_ipaddr_cmd) == 0) {
+ //startGBW();
+ if ( 0 ==lynq_get_ap_device_list(1, &ap, &list,&len) ) {
+ for (i=0;i<len;i++) {
+ //printf("--mac:%s, name:%s\n",list[i].sta_mac, list[i].hostname);
+ if (strcmp(g_gbw_mac, list[i].sta_mac) == 0)
+ startGBW();
+ }
+ free(ap);
+ free(list);
+ }
+ }
+ return 0;
+}
+
+int disableGBW() {
+ stopGBW();
+ free(g_gbw_mac);
+ g_gbw_mac = NULL;
+ g_gbw_enabled = 1;
+ return 0;
+}
+
+static int startGBW() {
+ if (g_gbw_watcher_pid != 0) {
+ stopGBW();
+ }
+ pthread_create(&g_gbw_watcher_pid,NULL,GBWWatchThreadProc,NULL);
+}
+
+static int stopGBW() {
+ void* retval;
+ char cmd[64] = {0};
+ pthread_cancel(g_gbw_watcher_pid);
+ pthread_join(g_gbw_watcher_pid, &retval);
+ g_gbw_watcher_pid = 0;
+ sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+ if (s_ap_iterface_name[0] != '\0')
+ {
+ sprintf(cmd, "tc qdisc del dev %s root", s_ap_iterface_name);
+ system(cmd);
+ }
+}
+//you.chen add for tv-box end
diff --git a/IC_src/mtk/lib/liblynq-wifi6/makefile b/IC_src/mtk/lib/liblynq-wifi6/makefile
new file mode 100755
index 0000000..e7a3ca8
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/makefile
@@ -0,0 +1,63 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -Os \
+ -flto \
+ -fpermissive \
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I./include \
+ -I$(LOCAL_PATH)/include \
+ -I$(ROOT)$(includedir)/glib-2.0 \
+ -I$(ROOT)$(libdir)/glib-2.0/include \
+
+
+
+LOCAL_LIBS := \
+ -L. \
+ -L./lib \
+ -llog \
+ -lpthread \
+ -lwpa_client
+
+SOURCES = $(wildcard *.c wildcard *.h )
+
+EXECUTABLE = liblynq-wifi6.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/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh
new file mode 100755
index 0000000..4dc8717
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+ echo "wlan0"
+elif [ "$1" == "1" ]; then
+ echo "ap0"
+else
+ exit 1
+fi
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh
new file mode 100755
index 0000000..829303e
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/sta_status_change.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh
new file mode 100755
index 0000000..441a0ee
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_ap.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+ ifconfig ap0 192.168.15.1 netmask 255.255.255.240
+
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+ mkdir -p /run/wg870/dnsmasq.d
+ conf_file="/run/wg870/dnsmasq.conf"
+ echo "port=0" > $conf_file
+ echo "interface=ap0" >> $conf_file
+ echo "listen-address=192.168.15.1" >> $conf_file
+ echo "bind-interfaces" >> $conf_file
+ echo "localise-queries" >> $conf_file
+ echo "no-ping" >> $conf_file
+ echo "dhcp-authoritative" >> $conf_file
+ echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h" >> $conf_file
+ echo "dhcp-option=3,192.168.15.1" >> $conf_file
+ echo "dhcp-option=6,192.168.15.1,114.114.114.114" >> $conf_file
+ echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h" >> $conf_file
+ echo "dhcp-leasefile=/run/wg870/ap0.lease" >> $conf_file
+ ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep
+ if [ $? != 0 ]; then
+ /usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid -7 /run/wg870/dnsmasq.d --local-service -C $conf_file -r /run/wg870 --dhcp-broadcast
+ fi
+
+elif [ "$1" == "stop" ]; then
+ ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep | awk '{print "kill "$1}' | sh
+ ifconfig ap0 down
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+else
+ exit 2
+fi
+
+exit 0
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh
new file mode 100755
index 0000000..25ab126
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_stop_sta.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+ ifconfig wlan0 up
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+ ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep
+ if [ $? != 0 ]; then
+ echo "" > /tmp/wlan0_dhcpcd_router
+ mkdir -p /run/wg870/
+ hook_script="/run/wg870/wlan0_dhcpcd_run_hooks.sh"
+ echo "#!/bin/sh" > $hook_script
+ echo "if [ \"\$reason\" == \"BOUND\" -o \"\$reason\" == \"RENEW\" -o \"\$reason\" == \"REBIND\" ]; then" >> $hook_script
+ echo " if [ \"\$new_routers\" != \"\" ]; then" >> $hook_script
+ echo " for x in \$new_routers; do" >> $hook_script
+ echo " echo \"new_router \$x\" > /tmp/wlan0_dhcpcd_router" >> $hook_script
+ echo " ping -c2 \$x &" >> $hook_script
+ echo " done" >> $hook_script
+ echo " fi" >> $hook_script
+ echo "fi" >> $hook_script
+ chmod +x $hook_script
+ dhcpcd wlan0 -t 0 -o domain_name_servers --noipv4ll -4 -B -G -c $hook_script &
+ fi
+elif [ "$1" == "stop" ]; then
+ ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep | awk '{print "kill "$1}' | sh
+ ifconfig wlan0 0.0.0.0
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+else
+ exit 2
+fi
+
+exit 0
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh
new file mode 100755
index 0000000..27aaf10
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts/start_wg870_service.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+for ((i=0; i < 10; i++)); do
+ state=`systemctl is-active wg870_drv_insmod.service`
+ if [ "$state" == "active" ]; then
+ break
+ elif [ "$state" != "activating" ]; then
+ echo "to start now"
+ systemctl start wg870_drv_insmod.service
+ fi
+ usleep 100000
+done
+
+if [ "$state" != "active" ]; then
+ exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+if [ "$state" != "PONG" ]; then
+ for ((i=0; i < 50; i++)); do
+ usleep 100000
+ state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+ echo "$state"
+ if [ "$state" == "PONG" ]; then
+ service_started=1
+ break
+ fi
+ done
+else
+ service_started=1
+fi
+
+if [ "$service_started" != "1" ];then
+ exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep wlan0`
+if [ $? != 0 ]; then
+ state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add wlan0 /data/wifi/wg870/wpa_supplicant.conf nl80211`
+ if [ "$state" != "OK" ]; then
+ exit 2
+ fi
+ wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep ap0`
+if [ $? != 0 ]; then
+ wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+ state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add ap0 /data/wifi/wg870/wpa_supplicant_ap.conf nl80211`
+
+ if [ "$state" != "OK" ]; then
+ exit 3
+ fi
+ ifconfig ap0 down
+fi
+
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 log_level INFO`
+if [ "$state" != "OK" ]; then
+ state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 log_level INFO`
+
+ if [ "$state" != "OK" ]; then
+ echo "change wpa_cli log_level to INFO FAIL"
+ fi
+fi
+
+
+exit 0
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
new file mode 100755
index 0000000..61b44d9
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+ echo "wlan0"
+elif [ "$1" == "1" ]; then
+ echo "tether"
+else
+ exit 1
+fi
+
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
diff --git a/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
new file mode 100755
index 0000000..303a075
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+for ((i=0; i < 10; i++)); do
+ state=`systemctl is-active wg870_drv_insmod.service`
+ if [ "$state" == "active" ]; then
+ break
+ elif [ "$state" != "activating" ]; then
+
+ systemctl start wg870_drv_insmod.service
+ fi
+ usleep 100000
+done
+
+if [ "$state" != "active" ]; then
+ exit 1
+fi
+
+for ((i=0; i < 10; i++)); do
+ connmanctl technologies | grep -q "/net/connman/technology/wifi"
+ if [ $? == 0 ]; then
+ connman_started=1
+ break
+ fi
+done
+
+if [ "$connman_started" == ""]; then
+ exit 2
+fi
+
+ifconfig | grep -q wlan0
+
+if [ $? != 0 ]; then
+ connmanctl enable wifi
+
+ for ((i=0; i < 5; i++)); do
+ usleep 100000
+ ifconfig | grep -q wlan0
+ if [ $? == 0 ]; then
+ wlan0_started=1
+ wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+ break
+ fi
+ done
+else
+ wlan0_started=1
+fi
+
+
+if [ "$wlan0_started" == ""]; then
+ exit 3
+fi
+
+ifconfig | grep -q ap0
+
+if [ $? != 0 ]; then
+ wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+ connmanctl tether wifi on lynq 1qaz@WSX#$%^
+
+ for ((i=0; i < 5; i++)); do
+ usleep 100000
+ ifconfig | grep -q ap0
+ if [ $? == 0 ]; then
+ ap0_started=1
+ wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 disconnect
+ break
+ fi
+ done
+else
+ ap0_started=1
+fi
+
+
+if [ "$ap0_started" == ""]; then
+ exit 4
+fi
+
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/LICENSE b/IC_src/mtk/lib/liblynq_logdata_handle/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/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/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h
new file mode 100644
index 0000000..e2de89c
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_deal_logrotate.h
@@ -0,0 +1,30 @@
+#ifndef __LYNQ_DEAL_LOGROTATE_H__
+#define __LYNQ_DEAL_LOGROTATE_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum
+{
+ SYSLOG_1 = 1,
+ SYSLOG_2,
+ SYSLOG_3,
+ SYSLOG_4,
+ SYSLOG_5,
+ SYSLOG_MAX
+}SYSLOG_PATH;
+
+
+int lynq_read_logdata(int fd,unsigned char* dest, unsigned int start, unsigned int size);
+int lynq_get_syslog_path(SYSLOG_PATH syslog_path,char *file_path);
+int lynq_get_mculog_path(char *file_path);
+int lynq_get_current_mtklog_path(char *file_path);
+int lynq_get_current_syslog_path(char *file_path);
+int lynq_get_current_mculog_path(char *file_path);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__LYNQ_DEAL_LOGROTATE_H__
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h
new file mode 100644
index 0000000..9aa2c57
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/include/lynq_logdata_handle.h
@@ -0,0 +1,21 @@
+#ifndef __LYNQ_LOGDATA_HANDLE__H_
+#define __LYNQ_LOGDATA_HANDLE__H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum
+{
+ MD_LOG = 0,
+ AP_LOG,
+ MCU_LOG,
+ LOG_MD_MAX
+}MODULE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__LYNQ_LOG_SERVER__H_
\ No newline at end of file
diff --git a/IC_src/mtk/lib/liblynq_logdata_handle/makefile b/IC_src/mtk/lib/liblynq_logdata_handle/makefile
new file mode 100755
index 0000000..8cce434
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/makefile
@@ -0,0 +1,91 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -std=gnu++14 \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -fpermissive \
+
+$(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$(ROOT)$(includedir)/logger \
+ -I$(LOCAL_PATH)/include \
+ -I$(ROOT)$(includedir)/liblog \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lpthread \
+ -llynq-log \
+ -llog \
+
+SOURCES = $(wildcard *.c wildcard *.h src/*.c)
+
+EXECUTABLE = liblynq-logdata-handle.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/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c b/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c
new file mode 100755
index 0000000..12e0c77
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq_logdata_handle/src/lynq_deal_logrotate.c
@@ -0,0 +1,176 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include<sys/stat.h>
+#include<fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "lynq_deal_logrotate.h"
+
+//lt add @2021.7.28 for get file data
+int lynq_read_logdata(int fd,unsigned char* dest, unsigned int start, unsigned int size)
+{
+ int ret,err;
+
+ if (lseek(fd, start, SEEK_SET) < 0) {
+ err = errno;
+ printf("mtk_device_wrap_seek read block err\n");
+ }
+
+ do {
+
+ ret = read(fd, dest, size);
+
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ err = -errno;
+ printf("Error reading metadata file\n");
+
+ close(fd);
+
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+
+ close(fd);
+ return ret;
+
+}
+
+//lt add @2021.7.28 for get syslog file path
+int lynq_get_syslog_path(SYSLOG_PATH syslog_path,char *file_path) //
+{
+ char syslog_file_path[64] = {0};
+ int fd;
+ int ret = 0;
+ switch(syslog_path)
+ {
+ case SYSLOG_1:
+ sprintf(syslog_file_path,"/var/log/syslog.log.1.gz");
+ break;
+ case SYSLOG_2:
+ sprintf(syslog_file_path,"/var/log/syslog.log.2.gz");
+ break;
+ case SYSLOG_3:
+ sprintf(syslog_file_path,"/var/log/syslog.log.3.gz");
+ break;
+ case SYSLOG_4:
+ sprintf(syslog_file_path,"/var/log/syslog.log.4.gz");
+ break;
+ case SYSLOG_5:
+ sprintf(syslog_file_path,"/var/log/syslog.log.5.gz");
+ break;
+ default :
+ ret = -1;
+ break;
+ }
+
+ if(ret == 0)
+ {
+ fd = open(syslog_file_path,O_RDONLY);
+ ret = fd;
+ close(fd);
+ }
+
+ if(ret >= 0)
+ {
+ memcpy(file_path,syslog_file_path,sizeof(syslog_file_path));
+ }
+ return ret;
+}
+
+//lt add @2021.7.28 for get mculog file path
+int lynq_get_mculog_path(char *file_path)
+{
+ char mculog_file_path[64] = {0};
+ int fd;
+ int ret = 0;
+ sprintf(mculog_file_path,"/var/log/mculog.log.1.gz");
+
+ fd = open(mculog_file_path,O_RDONLY);
+ ret = fd;
+ close(fd);
+
+ if(ret >= 0)
+ {
+ memcpy(file_path,mculog_file_path,sizeof(mculog_file_path));
+ }
+
+ return ret;
+}
+
+//lt add @2021.7.28 for get current mtklog file path
+int lynq_get_current_mtklog_path(char *file_path)
+{
+ char mtklog_file_path[64] = {0};
+ int fd;
+ int ret = 0;
+
+ system("tar -zcvf /var/log/mtklog.tar.gz /var/log/mtklog");
+// system("echo -n "" > /var/log/mtklog");
+ sprintf(mtklog_file_path,"/var/log/mtklog.tar.gz");
+
+ fd = open(mtklog_file_path,O_RDONLY);
+ ret = fd;
+ close(fd);
+
+ if(ret >= 0)
+ {
+ memcpy(file_path,mtklog_file_path,sizeof(mtklog_file_path));
+ }
+ return ret;
+}
+
+
+//lt add @2021.7.28 for get current syslog file path
+int lynq_get_current_syslog_path(char *file_path)
+{
+ char syslog_file_path[64] = {0};
+ int fd;
+ int ret = 0;
+
+ system("tar -zcvf /var/log/syslog.tar.gz /var/log/syslog.log");
+ system("echo -n "" > /var/log/syslog.log");
+ sprintf(syslog_file_path,"/var/log/syslog.tar.gz");
+
+ fd = open(syslog_file_path,O_RDONLY);
+ ret = fd;
+ close(fd);
+
+ if(ret >= 0)
+ {
+ memcpy(file_path,syslog_file_path,sizeof(syslog_file_path));
+ }
+ return ret;
+}
+
+
+//lt add @2021.7.28 for get current mculog file path
+int lynq_get_current_mculog_path(char *file_path)
+{
+ char mculog_file_path[64] = {0};
+ int fd;
+ int ret = 0;
+
+ system("tar -zcvf /var/log/mculog.tar.gz /var/log/mculog.log");
+ system("echo -n "" > /var/log/mculog.log");
+ sprintf(mculog_file_path,"/var/log/mculog.tar.gz");
+
+ fd = open(mculog_file_path,O_RDONLY);
+ ret = fd;
+ close(fd);
+
+ if(ret >= 0)
+ {
+ memcpy(file_path,mculog_file_path,sizeof(mculog_file_path));
+ }
+ return ret;
+}
\ No newline at end of file
diff --git a/IC_src/mtk/lib/libpoweralarm/LICENSE b/IC_src/mtk/lib/libpoweralarm/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/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/IC_src/mtk/lib/libpoweralarm/format_change.c b/IC_src/mtk/lib/libpoweralarm/format_change.c
new file mode 100644
index 0000000..8d3e3b1
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/format_change.c
@@ -0,0 +1,133 @@
+#include"format_change.h"
+#include<log/log.h>
+
+
+/*****************************************************************************
+* Prototype : format_change
+* Description : convert the incoming fixed format string into the corresponding alarm seconds
+* Input : char *buffer ; input format : 2022-04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or 1200 ( seconds )
+* Output : None
+* Return Value : -1: match error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+ssize_t format_change(char *buffer)
+{
+ time_t rawtime;
+ time_t alarm_tamp;
+ struct tm *info = NULL;
+ struct tm *set_alarm = NULL;
+ char *time_buff = NULL;
+
+ char ebuff[256];
+ regex_t reg_alm,reg_sec;
+ char *pattern_setalm = "^20[0-9][0-9]-[01]?[1-9]-[0-3]?[0-9]-[0-2]?[0-9]-[0-5]?[0-9]-[0-5]?[0-9]$";//regular expression 1 , in order that match alarm time string eg:Mon-Day-Hour-Min-Sec
+ char *pattern_setsec = "^[1-9][0-9]*$";//regular expression 2 , in order that match seconds
+ int cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;//POSIX extend,not care up and low letters,not store result
+
+ int ret;
+ ssize_t sec;
+
+ ret = regcomp(®_alm,pattern_setalm,cflags); //匹配规则1:\d\d\d\d\d-\d\d-\d\d-\d\d-\d\d-\d\d
+ if(ret) // judge error code : 0 symbolize success ; other value symbolizes fail
+ {
+ regerror(ret,®_alm,ebuff,256);
+ ALOGI(ebuff);
+ regfree(®_alm); //free mattch pattern
+ regfree(®_sec);
+ return -1;
+ }
+
+ ret = regcomp(®_sec,pattern_setsec,cflags); //匹配规则2:^\d\d*$
+ if(ret)// judge error code : 0 symbolize success ; other value symbolizes fail
+ {
+ regerror(ret,®_sec,ebuff,256);
+ ALOGI(ebuff);
+ regfree(®_alm); //free mattch pattern
+ regfree(®_sec);
+ return -1;
+ }
+
+ time(&rawtime); //获取自1970年到现在一共过去了几秒,赋值给rawtime
+
+ info =localtime(&rawtime); //转换为UTC时间
+
+ bool leap_flag = (bool)(((info->tm_year%4==0)&&(info->tm_year%100!=0)) || (info->tm_year%400 == 0)); //判断当前是否为闰年
+ int day_array[13] = {0,31, leap_flag?29:28,31,30,31,30,31,31,30,31,30,31}; //设置每个月的天数
+
+ if((ret = regexec(®_alm,buffer,0,NULL,0)) == 0) //Retrieve the incoming buffer string according to matching rule 1
+ {
+ set_alarm = (struct tm *)malloc(sizeof(struct tm));
+ memset(set_alarm,0,sizeof(struct tm));
+ memcpy(set_alarm,info,sizeof(struct tm)); //拷贝当前时间信息
+
+ ret = sscanf(buffer,"%d-%d-%d-%d-%d-%d",&(set_alarm->tm_year),&(set_alarm->tm_mon),&(set_alarm->tm_mday),&(set_alarm->tm_hour),&(set_alarm->tm_min),&(set_alarm->tm_sec));//read data form formatted string
+
+ if(ret == -1) //sscanf no mattch
+ {
+ ALOGI("sscanf error code -1\n");
+ free(set_alarm);
+ return -1;
+ }
+ else if(ret == 6) //Success mattch
+ {
+ if((set_alarm->tm_hour > 23) || (set_alarm->tm_hour < 0)) //judge hour
+ {
+ ALOGI("hour error\n");
+ ret = -1;
+ }
+ if((set_alarm->tm_mon > 12) || (set_alarm->tm_mon < 1)) //judge month
+ {
+ ALOGI("mon error\n");
+ ret = -1;
+ }
+ if((set_alarm->tm_mday > day_array[set_alarm->tm_mon]) || (set_alarm->tm_mday < 1)) //judge day
+ {
+ ALOGI("day error\n");
+ ret = -1;
+ }
+ if(ret == -1) //Error setting alarm time
+ {
+ free(set_alarm);
+ return -1;
+ }
+
+ set_alarm->tm_mon -= 1;
+ sprintf(ebuff,"set alarm is %s\n",asctime(set_alarm)); //print log
+ ALOGI(ebuff);
+ alarm_tamp = mktime(set_alarm); //struct tm transform struct time_t
+ time(&rawtime);
+ //printf("tamp: %ld\n",alarm_tamp);
+ sec = alarm_tamp - rawtime; //set second
+ free(set_alarm);
+
+ if(sec <= 0) //the current alarm time is less than the current system time
+ {
+ ALOGI("sec <= 0 setalarm error\n");
+ return -1;
+ }
+ }
+ else //sscanf mattch fail
+ {
+ ALOGI("sscanf error other\n");
+ free(set_alarm);
+ return -1;
+ }
+ }
+ else if ((ret = regexec(®_sec,buffer,0,NULL,0)) == 0) //Retrieve the incoming buffer string according to matching rule 2
+ {
+ sec = (ssize_t)atoi(buffer); //string convert ssize_t
+ }
+ else //matching rule 1 and 2 all fail
+ {
+ regerror(ret,®_sec,ebuff,256); //free memony
+ ALOGI(ebuff);
+ regfree(®_alm);
+ regfree(®_sec);
+ return -1;
+ }
+
+ regfree(®_alm);
+ regfree(®_sec);
+
+ return sec;
+}
diff --git a/IC_src/mtk/lib/libpoweralarm/format_change.h b/IC_src/mtk/lib/libpoweralarm/format_change.h
new file mode 100644
index 0000000..e84c985
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/format_change.h
@@ -0,0 +1,15 @@
+#ifndef _FORMAT_CHANGE_H_
+#define _FORMAT_CHANGE_H_
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<regex.h>
+#include<stdbool.h>
+#include<time.h>
+#include<string.h>
+
+
+ssize_t format_change(char *buffer);
+
+
+#endif
diff --git a/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h b/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h
new file mode 100644
index 0000000..b72e0f0
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/include/lynq_alarm.h
@@ -0,0 +1,27 @@
+#ifndef _LYNQ_ALARM_H_
+#define _LYNQ_ALARM_H_
+
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<regex.h>
+#include<stdbool.h>
+#include<time.h>
+#include<string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ssize_t wakealarm(char *buffer);
+
+ssize_t poweralarm(char *buffer);
+
+int cancel_wakealarm(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c b/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c
new file mode 100755
index 0000000..aeb3933
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/libpoweralarm.c
@@ -0,0 +1,124 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<unistd.h>
+#include<stdbool.h>
+#include<log/log.h>
+#include"./include/lynq_alarm.h"
+#include"format_change.h"
+
+#define LOG_TAG "libpoweralarm"
+#define RTCFILE_POWERALARM "/sys/class/rtc/rtc0/poweralarm"
+
+#define RTCFILE_WAKEALARM "/sys/class/rtc/rtc0/wakealarm"
+
+
+/*****************************************************************************
+*
+* Prototype : poweralarm
+* Description : set shutdown wake-up alarm clock
+* Input : char *buffer ; input format : 04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or 1200 ( seconds )
+* Output : None
+* Return Value : -1: error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+
+ssize_t poweralarm(char *buffer)
+{
+ ssize_t sec;
+ char *time_buff = NULL;
+
+ sec = format_change(buffer); //computing seconds for shutdown alarm
+ if(sec < 60)
+ {
+ ALOGI("No Mattch\n");
+ return -1;
+ }
+
+ time_buff = (char*)malloc(100);
+ bzero(time_buff,100);
+
+ sprintf(time_buff,"echo +%ld > %s",sec,RTCFILE_POWERALARM); //write formatted data into time_buff
+ system(time_buff);
+ ALOGI(time_buff);
+
+ free(time_buff);
+
+ return sec; // wake-up devices after sec seconds
+}
+
+
+/*****************************************************************************
+* Prototype : wakealarm
+* Description : set the wake-up alarm clock in low power mode
+* Input : char *buffer ; input format : 04-23-15-30-00 ( Mon-Day-Hour-Min-Sec ) Or 1200 ( seconds )
+* Output : None
+* Return Value : -1: error ; >0: set to wake up the devices after seconds
+*
+*****************************************************************************/
+ssize_t wakealarm(char *buffer)
+{
+ ssize_t sec;
+ char *time_buff = NULL;
+ int ret;
+ sec = format_change(buffer); //computing seconds for lowpower alarm
+ if(sec < 60)
+ {
+ ALOGI("No Mattch\n");
+ return -1;
+ }
+ ret = system("echo +0 > /sys/class/rtc/rtc0/wakealarm");
+ RLOGD("close wakealarm ret= %d\n", ret);
+ time_buff = (char*)malloc(100);
+ bzero(time_buff,100);
+
+ sprintf(time_buff,"echo +%ld > %s",sec,RTCFILE_WAKEALARM); //write formatted data into time_buff
+ system(time_buff);
+ ALOGI(time_buff);
+
+ free(time_buff);
+
+ return sec; // wake-up devices after sec seconds
+}
+
+
+/*****************************************************************************
+* Prototype : cancel wakealarm
+* Description : cancel the wake-up alarm clock in low power mode
+* Input : void
+* Output : int
+* Return Value : -1: error ; 0: cannel wakealarm success
+*
+*****************************************************************************/
+
+int cancel_wakealarm(void)
+{
+ int ret;
+ ret = system("echo +0 > /sys/class/rtc/rtc0/wakealarm");
+ ret = system("echo +315360000 > /sys/class/rtc/rtc0/wakealarm");
+ RLOGD("close wakealarm ret= %d\n", ret);
+ return ret;
+
+}
+
+/*****************************************************************************
+* Prototype : check wake up by rtc
+* Description : check weather AP is waked up by RTC
+* Input : void
+* Output : int
+* Return Value : 1: AP is waked up by rtc ; 0: AP is not waked up by rtc
+*
+*****************************************************************************/
+
+int check_wakeupbydtr(void)
+{
+ FILE *fp;
+ char buf[4];
+ int ret;
+ fp = popen("cat /proc/driver/rtc_wakeup","r");
+ fgets(buf, sizeof(buf), fp);
+ RLOGD("buf=%s\n", buf);
+ ret=atoi(buf);
+ pclose(fp);
+ return ret;
+
+}
diff --git a/IC_src/mtk/lib/libpoweralarm/makefile b/IC_src/mtk/lib/libpoweralarm/makefile
new file mode 100644
index 0000000..3cdf04f
--- /dev/null
+++ b/IC_src/mtk/lib/libpoweralarm/makefile
@@ -0,0 +1,69 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -std=gnu++14 \
+ -g -Os \
+ -flto \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -fPIC \
+ -DKEEP_ALIVE \
+ -DECALL_SUPPORT \
+
+
+
+
+$(warning ################# libautosuspend ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/liblog \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lstdc++ \
+ -llog \
+ -lcutils \
+ -lutils \
+ -lbinder \
+ -lpthread \
+ -llynq-log \
+
+
+SOURCES = $(wildcard *.c)
+
+EXECUTABLE = libpoweralarm.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
+ $(CXX) $(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)
+ -find . -name "*.o" -delete