Browse Source

T555_V03019
1、语速最小值为1
2、添加消息通知菜单
3、学习录音结果显示改为分数
4、添加学习组显示
5、添加对讲组及成员前缀显示
6、添加留音功能
7、固件更新为N58-R07-STD-OE_V20-008
注意,修改了uiMenuInit接口防止死机出现

wangjianlin 3 years ago
parent
commit
67ad819314

BIN
Released/AuthToolNew.exe


BIN
Released/T555_V03019.rar


+ 74 - 61
Released/releasenote.txt

@@ -1,61 +1,74 @@
-
-V03007
-1、POC库更新为03002版本
-2、添加GT模式和TM模式状态显示
-3、设置POC参数时,也把PWD字段设置进去
-
-V03008
-1、POC库更新到03003(固件更新exit接口重复了)
-2、禁止卡1管脚检测的拔插功能
-3、修改学习任务和学习排名图标
-4、GT模式后屏幕常亮
-5、长按开机后看到红灯闪一下后可以松开(开机成功)
-注:若版本为此前版本,更新当前版本要更新固件
-
-V03009
-1、添加耳机插入/拔出检测及相关处理
-2、PIN79配置由no-pull改为pull-up(测试拉不起来)
-
-V03010
-1、在获取任务简表时,free申请的buffer时死机了(暂未分析出结果),暂时使用静态buffer
-
-V03011
-1、修复获取任务简表free时死机问题,恢复使用动态内存分配
-
-V03012
-1、调整TTS音量
-2、调整pwm频率
-3、添加宏切换测试模式
-4、调整mic增益
-
-V03013
-1、处理低功耗问题
-
-V03014
-1、更改开机界面图片
-2、更改开机播放语(修改配置文件实现)
-3、调整完全刷完开机图片后才点亮屏幕
-4、适当延长开机图片显示时间
-5、休眠后主动关机LCD电源
-6、调整pwm频率及音量等级效果
-7、调整ptt响应tone音
-
-V03015
-1、POC库更新到03005
-2、优化授权
-3、MIC增益修由8修改为6,同时加大SPK设置
-4、修改EQ
-5、修复白屏概率问题
-6、时间添加冒号闪烁
-7、在N58-R07-STD-OE_V20-03D-T1的SDK下编译
-
-V03016
-1、SPK增益配置由64改为125
-2、"公网集群对讲系统"改为"加速度到语音系统"
-3、音量进度条改为喇叭加数字显示,最大最小时也显示状态出来
-
-V03017
-1、优化对讲显示及图标
-2、密码参数设置接收空设置
-3、POC库更新到03006(固件更新)
-4、在N58-R07-STD-OE_V20-005_T1固件上编译
+
+V03007
+1、POC库更新为03002版本
+2、添加GT模式和TM模式状态显示
+3、设置POC参数时,也把PWD字段设置进去
+
+V03008
+1、POC库更新到03003(固件更新exit接口重复了)
+2、禁止卡1管脚检测的拔插功能
+3、修改学习任务和学习排名图标
+4、GT模式后屏幕常亮
+5、长按开机后看到红灯闪一下后可以松开(开机成功)
+注:若版本为此前版本,更新当前版本要更新固件
+
+V03009
+1、添加耳机插入/拔出检测及相关处理
+2、PIN79配置由no-pull改为pull-up(测试拉不起来)
+
+V03010
+1、在获取任务简表时,free申请的buffer时死机了(暂未分析出结果),暂时使用静态buffer
+
+V03011
+1、修复获取任务简表free时死机问题,恢复使用动态内存分配
+
+V03012
+1、调整TTS音量
+2、调整pwm频率
+3、添加宏切换测试模式
+4、调整mic增益
+
+V03013
+1、处理低功耗问题
+
+V03014
+1、更改开机界面图片
+2、更改开机播放语(修改配置文件实现)
+3、调整完全刷完开机图片后才点亮屏幕
+4、适当延长开机图片显示时间
+5、休眠后主动关机LCD电源
+6、调整pwm频率及音量等级效果
+7、调整ptt响应tone音
+
+V03015
+1、POC库更新到03005
+2、优化授权
+3、MIC增益修由8修改为6,同时加大SPK设置
+4、修改EQ
+5、修复白屏概率问题
+6、时间添加冒号闪烁
+7、在N58-R07-STD-OE_V20-03D-T1的SDK下编译
+
+V03016
+1、SPK增益配置由64改为125
+2、"公网集群对讲系统"改为"加速度到语音系统"
+3、音量进度条改为喇叭加数字显示,最大最小时也显示状态出来
+
+V03017
+1、优化对讲显示及图标
+2、密码参数设置接收空设置
+3、POC库更新到03006(固件更新)
+4、在N58-R07-STD-OE_V20-005_T1固件上编译
+
+V03018
+1、优化录音音量显示
+2、优化待机页面显示及其它
+
+V03019
+1、语速最小值为1
+2、添加消息通知菜单
+3、学习录音结果显示改为分数
+4、添加学习组显示
+5、添加对讲组及成员前缀显示
+6、添加留音记录
+7、固件更新为N58-R07-STD-OE_V20-008

+ 9 - 0
Released/简单说明.txt

@@ -0,0 +1,9 @@
+AuthToolNew.exe 用于对讲机授权
+
+1、生产的对讲机如果未授权过,如T555,开机后会提示未授权
+2、此时使用USB线连接对讲机及电脑
+3、打开AuthToolNew.exe工具,端口连接Neoway USB OPEN_CON口,点击打开
+4、服务器连接上
+5、点击授权按键
+6、授权通过后即可重启使用
+注,当前AuthToolNew.exe工具对USB虚拟出来的COM口通讯可能不是很好,后面会优化更新版本。

+ 9 - 4
app/Interface/ManageMessage.c

@@ -163,7 +163,7 @@ uint16_t MessageEditShow(SUT_MESSAGE_EDIT *p,char *def)
 	}
 	p->buffer1[item]=0;
 	guiShowStr(p->x,p->y+page++*16,p->buffer1,FONT_MODE_12X12,REVERSED_NO,COLOR_BLACK,guiGetBackColor());
-#else//英文/12中文显示, 动态计算每行显示,尽可能每行显示多内容
+#else//英文/12中文显示, 动态计算每行显示,尽可能每行显示多内容 遇到0x0a则换行显示
 	uint16_t index=0;
 	unsigned short x;
 	char *temp =def;
@@ -175,6 +175,7 @@ uint16_t MessageEditShow(SUT_MESSAGE_EDIT *p,char *def)
 	int dotLen;
 	int xWidth;
 	int yHeight=p->ylen+3;//字体上下间隔3
+	int extlen=0;//换行长度
 	//guiClearArea(p->x,p->y,p->x+p->xlen,p->y+p->ylen,guiGetBackColor()); 
 	memset(p->buffer1,0,sizeof(p->buffer1));
 	x=GLCD_WIDTH-p->x-1;
@@ -195,8 +196,11 @@ uint16_t MessageEditShow(SUT_MESSAGE_EDIT *p,char *def)
 				dotLen -= p->xlen;
 			}else
 				write = 1;
-		}
-		else
+		}else if(*temp==0x0a){
+			temp ++;
+			write=1;
+			extlen=1;
+		}else
 		{
 			if(dotLen>=8)
 			{
@@ -213,8 +217,9 @@ uint16_t MessageEditShow(SUT_MESSAGE_EDIT *p,char *def)
 			write=0;
 			p->buffer1[item]=0;
 			guiShowStr(p->x,p->y+page++*yHeight,p->buffer1,p->font,REVERSED_NO,COLOR_BLACK,guiGetBackColor());
-			index += item;
+			index += item+extlen;
 			item=0;
+			extlen=0;
 			dotLen=x;
 			if(p->y+(page+1)*yHeight >=UI_BOTTOM_LINE_Y) return index;
 			if(page>=5) return index;

+ 15 - 10
app/Interface/uiMenu.c

@@ -63,7 +63,7 @@ static void uiMenuShow(SUT_MENU *p, FONT_MODEENUM fontMode){
 	else guiClearArea(x,y-8-2,19,8,guiGetBackColor());
 }
 
-void uiMenuInit(SUT_MENU *p, const char **item, FONT_MODEENUM fontMode){
+void uiMenuInit(SUT_MENU *p, const char **item, FONT_MODEENUM fontMode,bool status){
 	unsigned char i,ch,index;
 	UI_STACKDEF *uiPtr=uiMenuGetStack();
 	p->item=item;
@@ -79,18 +79,23 @@ void uiMenuInit(SUT_MENU *p, const char **item, FONT_MODEENUM fontMode){
 
 	if(p->pagenum%UI_MENU_ROW) p->pagenum ++;
 	if(UI_MENU_KEY_ESC==uiMenuGetKey() || uiPtr->ok_back){
-		index=uiPullStack();
-		if(index>9){
-			p->page=2;
-			p->handle=index;
-		}else if(index>4){
-			p->page=1;
-			p->handle=index;
+		if(status==true){
+			index=uiPullStack();
+			if(index>9){
+				p->page=2;
+				p->handle=index;
+			}else if(index>4){
+				p->page=1;
+				p->handle=index;
+			}else{
+				p->page=0;
+				p->handle=index;
+			}
+			uiPtr->ok_back=0;
 		}else{
 			p->page=0;
-			p->handle=index;
+			p->handle=0;
 		}
-		uiPtr->ok_back=0;
 	}else{
 		p->page=0;
 		p->handle=0;

+ 2 - 2
app/Interface/uiMenu.h

@@ -6,7 +6,7 @@
 #define UI_MENU_ROW  	5
 #define UI_MENU_SPACE 	4
 #define UI_MENU_BAR_LEN	140
-
+#include "stdbool.h"
 #include "gui.h"
 #pragma pack(push)
 #pragma pack(1)
@@ -19,7 +19,7 @@ typedef struct{
 }SUT_MENU;
 #pragma pack(pop)
 
-void uiMenuInit(SUT_MENU *p, const char **item, FONT_MODEENUM fontMode);
+void uiMenuInit(SUT_MENU *p, const char **item, FONT_MODEENUM fontMode,bool status);
 unsigned short uiMenuResponse(SUT_MENU *p);
 
 #endif

+ 4 - 0
app/app.c

@@ -148,6 +148,7 @@ void appRun(void){
 	msgAtSend("AT+POC_VER\r\n");
 	msgAtSend("AT+GMR\r\n");//查询模块版本
 	msgAtSend("AT+MIC=6\r\n");
+	msgAtSend("AT+VSW=1\r\n");//打开留音功能
 	//msgAtSend("AT+CACCP=0,1,0,\"04000B00\"\r\n");
 #ifndef ENABLE_PWM_BEEP
 	if(newPara.KeySound!=0) msgAtSend("AT+TONES=1\r\n");
@@ -177,6 +178,7 @@ void appRun(void){
 		pocProCtl(APP_SUB_DIV_TIME);
 		HookGroupUserInfo();
 		HookVolToutCheck();
+		LearnUsrInfoCheck(APP_SUB_DIV_TIME);
 		IncomingSMS();
 		if(isSleepReady()==0) nwy_sleep(APP_TASK_SLEEP_TIME);
 
@@ -185,6 +187,8 @@ void appRun(void){
 			stopKeyTimer();
 			subTimerCtl(1);//切换为休眠状态定时器
 			sutApp.appStatus=1;
+			CTL_LED2_GREEN(0);
+			CTL_LED1_RED(0);
 		#ifdef ENABLE_DEEP_SLEEP
 			pwmDeInitToSleep();
 			lcdDrvPowerCtl(false);

+ 14 - 0
app/app.h

@@ -20,12 +20,25 @@ typedef enum{
 	ASLEEP_GUSER,//用于获取成员列表时不要休眠
 	ASLEEP_LEARN,//用于学习录音/播放时不要休眠使用
 }ASLEEP_ENUM;
+#define VOICE_ITEM_NUM 3
 #pragma pack(push)
 #pragma pack(1)
 typedef struct{
 	unsigned int psn;
 	char password[30];
 }ACCOUNT_DEF;
+typedef struct{
+	unsigned char index;
+	char info[30];//显示的信息
+}VOICE_INFO_DEF;
+typedef struct{
+	unsigned char update;
+	unsigned char voiceStatus;
+	unsigned char aNum;
+	unsigned char vNum;
+	unsigned char voiceValidNum;
+	VOICE_INFO_DEF info[VOICE_ITEM_NUM];
+}VOICE_DEF;
 typedef struct{
 	unsigned char guiStatus:1;//gui是否初始化完成
 	unsigned char pocInitStatus:1;//poc是否启动完成
@@ -53,6 +66,7 @@ typedef struct{
 	char modemVer[30];
 	unsigned char pcant;
 	unsigned char lcdReconfigCnt;
+	VOICE_DEF voiceInfo;
 }APP_DEF;
 
 #pragma pack(pop)

+ 2 - 1
app/appAuth.c

@@ -140,10 +140,11 @@ bool handshake=false;
 void localAuthNow(void){
 	static char showFlag=0;
 	static unsigned int cnt=0;
+#if 0
 	//test
 	sutApp.authReady=1;
 	return;
-	
+#endif
 	sutApp.authReady=0;
 	for(;;){
 		if(true==localAuthOk()) break;

+ 4 - 40
app/learn/learnHttp.c

@@ -110,7 +110,7 @@ static void learnEntry(void *param){
 		if(OHPOC_EVENT_HTTP==event.id) break;
 	}
 	if(httpinfo.lteStatus==HTTP_STATUS_DNSERR) goto HTTP_END;
-	if(httpinfo.httpType==UHTTP_TASK_GET || httpinfo.httpType==UHTTP_RANK_GET){
+	if(httpinfo.httpType==UHTTP_FILE_GET){
 		httpinfo.lteStatus=HTTP_STATUS_GET;//start get
 		result = nwy_http_get(keepalive, 0, GET_FILE_MAX_SIZE, http_https);
 		if(result!=0){
@@ -267,11 +267,11 @@ static void nwy_http_result_cb(nwy_ftp_result_t *param){
 	switch(param->event){
 		case NWY_HTTP_DATA_RECVED:
 			//MSG_INFO(1, "httpRecv:%d,%s", param->data_len, param->data);
-			if(httpinfo.httpType==UHTTP_TASK_GET){//发HTTP_GET指令时的响应处理
+			if(httpinfo.httpType==UHTTP_FILE_GET){//发HTTP_GET指令时的响应处理
 				if(httpinfo.processStatus==HPROC_START){//响应第一包,需要获取总长度,有效数据长度等信息
 					//检测是否是HTTP/头或非首包
 					if(false==isHttpRecvValid(param->data)){
-						MSG_WARN(1, "UHTTP_TASK_GET Recv Ack Not 200");
+						MSG_WARN(1, "UHTTP_FILE_GET Recv Ack Not 200");
 						break;
 					}
 					//获取有效数据总长度
@@ -327,7 +327,7 @@ static void nwy_http_result_cb(nwy_ftp_result_t *param){
 					}
 				}
 			}else if(httpinfo.httpType==UHTTP_POST){//HTTP_POST时的响应处理接口
-				MSG_INFO(1, "httpRecv:%d,%s", param->data_len, param->data);
+				//MSG_INFO(1, "httpRecv:%d,%s", param->data_len, param->data);
 				//检测是否是HTTP/头或非首包
 				if(false==isHttpRecvValid(param->data)){
 					MSG_WARN(1, "UHTTP_POST Recv Ack Not 200");
@@ -336,42 +336,6 @@ static void nwy_http_result_cb(nwy_ftp_result_t *param){
 				}
 				MSG_INFO(1, "http post get done ack");
 				httpinfo.lteStatus=HTTP_STATUS_POST_DONE;
-			}else if(httpinfo.httpType==UHTTP_RANK_GET){//获取排名
-				//检测是否是HTTP/头或非首包
-				if(false==isHttpRecvValid(param->data)){
-					MSG_WARN(1, "UHTTP_RANK_GET Recv Ack Not 200");
-					break;
-				}
-				//获取有效数据总长度
-				ptr=strstr(param->data, LEN_SEG);
-				if(NULL==ptr){//没有字段,无法提取
-					MSG_ERR(1, "No '%s' seg!",LEN_SEG);
-					learn_http_set_status_false(HTTP_STATUS_GET_ERR_FSIZE);
-					break;
-				}
-				dlen=atoi(ptr+strlen(LEN_SEG));//
-				if(dlen<=0 || dlen>GET_FILE_MAX_SIZE || dlen==param->data_len){
-					MSG_ERR(1, "data len invalid:%d",dlen);
-					learn_http_set_status_false(HTTP_STATUS_GET_FSIZE_OVER);
-					break;
-				}
-				MSG_INFO(1, "total data len:%d", dlen);
-				//获取有效数据开始索引
-				ptr=strstr(param->data,"\r\n\r\n");
-				if(NULL==ptr){
-					MSG_ERR(1, "data offset err");
-					learn_http_set_status_false(HTTP_STATUS_GET_ERR_OFFSET);
-					break;
-				}
-				httpinfo.fsize=dlen;
-				httpinfo.offset=0;
-				//提取本包中的有效数据
-				ptr += 4;
-				i=param->data_len-(ptr-(char *)param->data);
-				//排名一次就能获取完成了
-				httpinfo.lteStatus=HTTP_STATUS_GET_OK;
-				httpinfo.recvCb(ptr, i);
-				httpinfo.processStatus=HPROC_OK;
 			}
 			break;
 		case NWY_HTTP_DNS_ERR:httpinfo.lteStatus=HTTP_STATUS_DNSERR;break;

+ 1 - 2
app/learn/learnHttp.h

@@ -3,8 +3,7 @@
 #define __LEARN_HTTP_H_
 
 typedef enum{
-	UHTTP_TASK_GET,
-	UHTTP_RANK_GET,
+	UHTTP_FILE_GET,
 	UHTTP_POST
 }UHTTP_ENUM;
 

+ 781 - 35
app/learn/learnTask.c

@@ -6,6 +6,8 @@
 #define LEARN_LIST "learnLists"  //任务简表总表
 #define LEARN_LIST_TMP "learnListsTmp"   //临时任务简表总表
 #define LEARN_RANK "learnRank"   //排名临时表,不需要删除
+#define LEARN_CLASS "learnClass"
+#define LEARN_NOTICE "learnNotice"
 #define LEARN_UPDATE_MAX 10  //一次性最多拉取任务个数
 #define SHOW_TABLE_MAX_BYTES 40
 
@@ -22,6 +24,9 @@
 #define OBJECT_NNAME "nickname"
 #define OBJECT_TYPE "type"
 #define OBJECT_TOKEN "token"
+#define OBJECT_CONTENT_DETAIL "content"
+#define OBJECT_SPEED_PARAM "scoreSpeedParam"
+#define OBJECT_VOLUME_PARAM	"scoreVolumeParam"
 
 static void httpCallBack(char *msg, int len);
 typedef enum{
@@ -45,7 +50,11 @@ typedef enum{
 	LEARN_END,
 	
 	
-	LEARN_RANK_GET_DETAIL
+	LEARN_RANK_GET_DETAIL,
+	LEARN_CLASS_GET_DETAIL,
+	LEARN_NOTICE_GET_DETAIL,
+	LEARN_NOTICE_GET_DETAIL_SHOW,
+	LEARN_GET_PARAM,
 }LEARN_STATUS;
 static unsigned char charaNum;//单词个数
 static unsigned int taskID[LEARN_UPDATE_MAX];
@@ -99,6 +108,7 @@ void sdCardCtl(bool status){
 	}else{
 		nwy_sdk_sdcard_unmount();
 		CTL_SD_PWR(0);
+		MSG_INFO(1, "SD card unmount");
 	}
 }
 static void learnUpdateStatus(LEARN_STATUS newStatus){
@@ -168,6 +178,9 @@ void learnGetNextPage(short direction){
 }
 /*********************从文件中获取用户信息******************************/
 typedef struct{
+	bool paramReady;
+	double scoreSpeedParam;
+	double scoreVolumeParam;
 	bool ready;
 	unsigned char type;
 	unsigned int uid;
@@ -176,9 +189,10 @@ typedef struct{
 	char nname[30];
 	char token[20];
 }USER_INFO;
-USER_INFO usr={false,0xff};
-unsigned long getLearnUid(void){return usr.uid;}
-unsigned long getLearnGid(void){return usr.gid;}
+USER_INFO usr={false,1,1,false,0xff};
+unsigned int getLearnUid(void){return usr.uid;}
+unsigned int getLearnGid(void){return usr.gid;}
+char *getLearnGName(void){return usr.gname;}
 char *getLearnToken(void){return usr.token;}
 bool isUserInfoReady(void){return usr.ready;}
 void learnUserInfoClear(void){usr.ready=false;}
@@ -218,35 +232,35 @@ bool cJSONProcessUinfo(char *msg){
 	return true;
 }
 /*************************从文件中获取用户信息******************************/
-bool learnTaskUpdate(LEARN_STATUS type, void *para1, void *para2){
+bool learnTaskUpdate(LEARN_STATUS type, void *para1, void *para2, bool needShow){
 	char url[200],tmp[10];
 	unsigned char *msg=NULL;
 	unsigned int len=0,i;
 	UHTTP_ENUM httpType;
 	//触发获取任务列表操作
 	if(sutApp.pocPpp==0 || sutPocStatus.logined==0){
-		showInfoBox("无网络/未登录",2000);
+		if(true==needShow) showInfoBox("无网络/未登录",2000);
 		learnUpdateStatus(LEARN_END);
 		return false;
 	}
 	if(type==LEARN_DB_GET_INFO){//获取用户信息
-		httpType=UHTTP_TASK_GET;
+		httpType=UHTTP_FILE_GET;
 		snprintf(url, sizeof(url), "%s/api/cai/UserInfo?account=%d&password=%s", LEARN_HTTP_URL, sutApp.account.psn, sutApp.account.password);
 		MSG_INFO(1, "Learn get user info");
 	}else if(type==LEARN_GET_LIST){//获取任务列表
-		httpType=UHTTP_TASK_GET;
+		httpType=UHTTP_FILE_GET;
 		snprintf(url, sizeof(url), "%s/api/cai/BriefTask?gid=%d&uid=%d&token=%s", LEARN_HTTP_URL, getLearnGid(),getLearnUid(),getLearnToken());
 		MSG_INFO(1, "Learn get total list");
 	}else if(type==LEARN_DB_SYNC_ADD_PAGE_WAIT){//根据页获取详细表
 		int *page=(int *)para1;
 		int *size=(int *)para2;
-		httpType=UHTTP_TASK_GET;
+		httpType=UHTTP_FILE_GET;
 		snprintf(url, sizeof(url), "%s/api/cai/DetailedTask?gid=%d&uid=%d&page=%d&size=%d&token=%s", LEARN_HTTP_URL, getLearnGid(),getLearnUid(),*page,*size,getLearnToken());
 		MSG_INFO(1, "Learn get detail,page:%d,size:%d", *page,*size);
 	}else if(type==LEARN_DB_SYNC_ADD_SOME_WAIT){//根据tid获取详细表
 		unsigned int *tids=(unsigned int *)para1;
 		unsigned char *num=(unsigned char *)para2;
-		httpType=UHTTP_TASK_GET;
+		httpType=UHTTP_FILE_GET;
 		snprintf(url, sizeof(url), "%s/api/cai/DetailedTask?gid=%d&uid=%d&token=%s&tids=[%d", LEARN_HTTP_URL,getLearnGid(),getLearnUid(),getLearnToken(),tids[0]);
 		for(i=1;i<*num;i++){
 			snprintf(tmp, sizeof(tmp),",%d", tids[i]);
@@ -261,12 +275,29 @@ bool learnTaskUpdate(LEARN_STATUS type, void *para1, void *para2){
 		snprintf(url, sizeof(url), "%s/api/cai/HandIn",LEARN_HTTP_URL);
 		MSG_INFO(1, "Learn upload audio:%d bytes", len);
 	}else if(type==LEARN_RANK_GET_DETAIL){
-		httpType=UHTTP_RANK_GET;
+		httpType=UHTTP_FILE_GET;
 		unsigned char *rankType=(unsigned char *)para1;
 		snprintf(url, sizeof(url), "%s/api/cai/%slyRanking?uid=%d&gid=%d&token=%s", LEARN_HTTP_URL,(*rankType==0)?"Month":"Week" ,getLearnUid(),getLearnGid(),getLearnToken());
 		MSG_INFO(1, "Learn get %s rank", (*rankType==0)?"month":"week");
+	}else if(type==LEARN_CLASS_GET_DETAIL){
+		httpType=UHTTP_FILE_GET;
+		snprintf(url, sizeof(url), "%s/api/cai/Timetable?uid=%d&gid=%d&token=%s", LEARN_HTTP_URL, getLearnUid(), getLearnGid(), getLearnToken());
+		MSG_INFO(1, "Learn get class detail");
+	}else if(type==LEARN_NOTICE_GET_DETAIL){
+		httpType=UHTTP_FILE_GET;
+		snprintf(url, sizeof(url), "%s/api/cai/NotificationBrief?uid=%d&gid=%d&token=%s", LEARN_HTTP_URL, getLearnUid(), getLearnGid(), getLearnToken());
+		MSG_INFO(1, "Learn get notice detail");
+	}else if(type==LEARN_NOTICE_GET_DETAIL_SHOW){
+		int *id=(int *)para1;
+		httpType=UHTTP_FILE_GET;
+		snprintf(url, sizeof(url), "%s/api/cai/NotificationContent?uid=%d&id=%d&token=%s", LEARN_HTTP_URL, getLearnUid(), *id, getLearnToken());
+		MSG_INFO(1, "Learn get notice detail show");
+	}else if(type==LEARN_GET_PARAM){
+		httpType=UHTTP_FILE_GET;
+		snprintf(url, sizeof(url), "%s/api/cai/Config?uid=%d&token=%s", LEARN_HTTP_URL, getLearnUid(), getLearnToken());
+		MSG_INFO(1, "Learn get param");
 	}
-	showInfoBox("请稍候",5000);
+	if(true==needShow) showInfoBox("请稍候",5000);
 	learnHttpStart(httpType,url, LEARN_PORT, httpCallBack,msg, len);
 	return true;
 }
@@ -282,23 +313,22 @@ void uiShowLearnTask(char update){
 		uiMenuShowBottomLine();
 		guiShowMessageBox("请稍候");
 		uiMenuShowBottomIndacitor("查看", "返回");
-		if(needUpdate) sdCardCtl(true);
+		sdMount();
 	#if 1
 		if(isUserInfoReady()==false){
-			if(true==learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL)) learnUpdateStatus(LEARN_DB_WAIT_INFO);
+			if(true==learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL,true)) learnUpdateStatus(LEARN_DB_WAIT_INFO);
 		}else{
 			if(needUpdate!=0){
 				MSG_INFO(1, "learn task need sync");
-				if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL)) learnUpdateStatus(LEARN_WAIT_LIST);
+				if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL,true)) learnUpdateStatus(LEARN_WAIT_LIST);
 			}else learnUpdateStatus(LEARN_DB_SYNC_DONE);//子菜单返回时,直接读取显示,不去同步
 		}
 		needUpdate=0;
 	#else
 		if(needUpdate!=0){
 			MSG_INFO(1, "learn task need sync");
-			if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL)) learnUpdateStatus(LEARN_WAIT_LIST);
+			if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL,true)) learnUpdateStatus(LEARN_WAIT_LIST);
 		}else learnUpdateStatus(LEARN_DB_SYNC_DONE);//子菜单返回时,直接读取显示,不去同步
-		needUpdate=0;
 	#endif
 	}
 	
@@ -484,7 +514,7 @@ static void LearnTaskProcess(void){
 				MSG_INFO(1, "LEARN_DB_WAIT_INFO:%d",ret);
 				switch(ret){
 					case 0://获取用户信息成功,获取简表信息
-						if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL)) learnUpdateStatus(LEARN_WAIT_LIST);
+						if(true==learnTaskUpdate(LEARN_GET_LIST,NULL, NULL,true)) learnUpdateStatus(LEARN_WAIT_LIST);
 						else{
 							showInfoBox("更新失败",2000);
 							learnUpdateStatus(LEARN_END);
@@ -611,7 +641,7 @@ static void LearnTaskProcess(void){
 				learnAddNum=0;
 				learnUpdateStatus(LEARN_DB_SYNC_ADD_PAGE_WAIT);
 				learnDetailEnd=false;//检测是否下载完毕使用
-				learnTaskUpdate(LEARN_DB_SYNC_ADD_PAGE_WAIT,(void *)&page, (void *)&size);
+				learnTaskUpdate(LEARN_DB_SYNC_ADD_PAGE_WAIT,(void *)&page, (void *)&size,true);
 				uTimerStart(&learnTick, 2000);
 			}else{//根据两个简表,添加回LEARN_LIST中没有,但LEARN_LIST_TMP中有的任务
 				for(i=0;i<LEARN_UPDATE_MAX;i++) tidTable[i]=0;
@@ -664,7 +694,7 @@ static void LearnTaskProcess(void){
 				//发起新的文件获取(根据任务ID获取)
 				//文件ID表在tidTable中,个数为learnAddNum个
 				learnUpdateStatus(LEARN_DB_SYNC_ADD_SOME_WAIT);
-				learnTaskUpdate(LEARN_DB_SYNC_ADD_SOME_WAIT,(void *)tidTable, (void *)&learnAddNum);
+				learnTaskUpdate(LEARN_DB_SYNC_ADD_SOME_WAIT,(void *)tidTable, (void *)&learnAddNum,true);
 				MSG_ERR(1, "update tids:%d", learnAddNum);
 			}
 			break;
@@ -777,13 +807,13 @@ static void LearnTaskProcess(void){
 				releaseBuf(&sutJson.bufTask[i]);
 				releaseJson(&sutJson.jsonTask[i]);
 			}
-			sdCardCtl(false);
+			sdUnmount();
 			uISetNextStatus(UIS_MENU_MAIN);
 			needUpdate=1;
 			break;
 		case LEARN_END:
 			if(uTimerExpired(&learnTick)){
-				sdCardCtl(false);
+				sdUnmount();
 				uISetNextStatus(UIS_MENU_MAIN);
 				needUpdate=1;
 			}
@@ -839,6 +869,14 @@ static void httpCallBack(char *msg, int len){
 		cJSONSaveTaskFile(msg);
 	}else if(ret==LEARN_RANK_GET_DETAIL){
 		cJSONSaveFile(LEARN_RANK, msg,outLen);
+	}else if(ret==LEARN_CLASS_GET_DETAIL){
+		cJSONSaveFile(LEARN_CLASS, msg, outLen);
+	}else if(ret==LEARN_NOTICE_GET_DETAIL){
+		cJSONSaveFile(LEARN_NOTICE, msg, outLen);
+	}else if(ret==LEARN_NOTICE_GET_DETAIL_SHOW){
+		cJSONTakeContent(msg, outLen);
+	}else if(ret==LEARN_GET_PARAM){
+		cJSONTakeParam(msg, outLen);
 	}
 	MSG_INFO(1, "httpCallBack end");
 }
@@ -1230,7 +1268,7 @@ void uiShowLearnTaskDetailResponse(void){
 				pcm=learnGetTmpAudioBuf();
 				plen=learnGetTmpAudioLength();
 				learnRecSetStatus(LEARN_RECORD_UPLOAD);
-				learnTaskUpdate(LEARN_RECORD_UPLOAD,(void *)pcm, (void *)&plen);
+				learnTaskUpdate(LEARN_RECORD_UPLOAD,(void *)pcm, (void *)&plen,true);
 				break;
 		}
 	}else if(MKEY_VALUE_DOWN==key){
@@ -1255,11 +1293,16 @@ void uiShowLearnTaskDetailResponse(void){
 		}
 	}
 }
-static void learnShowResult(void){	
-	char info1[30],info2[30];
-	snprintf(info1, sizeof(info1), "Volume:%d", learnGetRecordMaxVolume());
-	snprintf(info2, sizeof(info2), "Speed:%d", learnGetRecordRecSpeed());
-	guiShowTwoMessage(info1, info2);
+static void learnShowResult(void){
+	double score;
+	char info[30];
+	unsigned char speed=learnGetRecordRecSpeed();
+	if(speed<=0) speed=1;
+	score=usr.scoreSpeedParam*speed+usr.scoreVolumeParam*learnGetRecordMaxVolume();
+	snprintf(info, sizeof(info), "Score:%f", score);
+	MSG_INFO(1, "sparam:%f,speed:%d,vparam:%f,volume:%d,scroe:%f",usr.scoreSpeedParam,speed,usr.scoreVolumeParam,learnGetRecordMaxVolume(),score);
+	guiShowMessageBox(info);
+	//guiShowTwoMessage(info1, info2);
 }
 static void learnRecordDoneProcess(void){
 	
@@ -1285,20 +1328,18 @@ void uiShowLearnRank(char update){
 	};
 	char Freatrue[2]={0,1};
 	if(update){
-		if(needUpdate) sdCardCtl(true);
+		sdMount();
 		guiClearAll(guiGetBackColor());
 		guiShowCaption(0,"学习排名",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
 		uiMenuShowBottomLine();
 		ListBoxInit(&sutListBox, rankMode, 0, learnIcon, Freatrue);
 		uiMenuShowBottomIndacitor("查看", "返回");
-		needUpdate=0;
 	}
 }
 void LearnRankSelResponse(void){
 	unsigned short key=ListBoxResponse(&sutListBox);
 	if(MKEY_VALUE_ESC==key){
-		needUpdate=1;
-		sdCardCtl(false);
+		sdUnmount();
 		uISetNextStatus(UIS_MENU_MAIN);
 	}else if(MKEY_VALUE_MENU==key){
 		if(sutListBox.handle==0){
@@ -1395,11 +1436,11 @@ void uiShowLearnRankDetail(char update){
 		if(isUserInfoReady()==false){//如果未获取用户信息,先获取用户信息
 			needGetUinfo=true;
 			learnUpdateStatus(LEARN_DB_WAIT_INFO);
-			learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL);
+			learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL,true);
 		}else{//否则可以直接获取排名
 			needGetUinfo=false;
 			learnUpdateStatus(LEARN_RANK_GET_DETAIL);
-			learnTaskUpdate(LEARN_RANK_GET_DETAIL,(void*)&rankType, NULL);
+			learnTaskUpdate(LEARN_RANK_GET_DETAIL,(void*)&rankType, NULL,true);
 			MSG_ERR(1, "update rank detail %s", (rankType==0)?"month":"week");
 		}
 	}
@@ -1412,7 +1453,7 @@ void uiShowLearnRankDetail(char update){
 					if(needGetUinfo==true){
 						needGetUinfo=false;
 						learnUpdateStatus(LEARN_RANK_GET_DETAIL);
-						learnTaskUpdate(LEARN_RANK_GET_DETAIL,(void*)&rankType, NULL);
+						learnTaskUpdate(LEARN_RANK_GET_DETAIL,(void*)&rankType, NULL,true);
 						MSG_ERR(1, "update rank detail %s", (rankType==0)?"month":"week");
 					}else{
 						rankShowReady=true;
@@ -1429,6 +1470,7 @@ void uiShowLearnRankDetail(char update){
 					break;
 				}
 			nwy_sleep(1500);
+			getStackStruct()->ok_back=1;
 			uISetNextStatus(UIS_MENU_RANK_SEL);
 		}
 	}
@@ -1447,6 +1489,316 @@ void LearnRankDetailSelResponse(void){
 	}
 }
 
+typedef struct{
+	int week;
+	char time[15];
+	char subject[30*2];
+}CLASS_DEF;
+typedef struct{
+	unsigned int item;//rankResult实际使用的个数
+	unsigned int num;//rankResult分配的个数(释放时使用)
+	CLASS_DEF **classResult;
+}CLASS_RESULT_DEF;
+CLASS_RESULT_DEF classes={0,0,0,NULL};
+bool classShowReady;
+static void classInfoDetailShow(unsigned char direction){
+	static int tIndex=0;
+	
+	if(classes.item==0){
+		guiShowMessageBox("无数据");
+		return;
+	}else if(classes.item==1) tIndex=0;
+	else{
+		if(direction==0) tIndex=0;
+		else if(direction==1){
+			if(++tIndex>=classes.item) tIndex=0;
+		}else if(direction==2){
+			if(tIndex==0) tIndex=classes.item-1;
+			else tIndex--;
+		}
+	}
+	guiClearRect(0,UI_CONTENT_SHOW_Y,GLCD_WIDTH-1,UI_BOTTOM_SHOW_Y-2,guiGetBackColor());
+	//显示
+	if(classes.classResult==NULL){
+		MSG_WARN(1, "class no data");
+		return;
+	}
+	char info[50];
+	int x=1,y=UI_CONTENT_SHOW_Y;
+	//显示week
+	snprintf(info, sizeof(info), "week:%d", classes.classResult[tIndex]->week);
+	guiShowStr(x, y, info, FONT_MODE_16X16, REVERSED_NO, COLOR_BLACK, guiGetBackColor());
+	y+=17;
+	//显示time
+	snprintf(info, sizeof(info), "time:%s", classes.classResult[tIndex]->time);
+	guiShowStr(x, y, info, FONT_MODE_16X16, REVERSED_NO, COLOR_BLACK, guiGetBackColor());
+	y+=17;
+	//显示subject
+	snprintf(info, sizeof(info), "subject:%s", classes.classResult[tIndex]->subject);
+	guiShowStr(x, y, info, FONT_MODE_16X16, REVERSED_NO, COLOR_BLACK, guiGetBackColor());
+}
+static void getClassShowMessage(void);
+/*课程表*/
+void uiShowLearnClassDetail(char update){
+	int ret;
+	static bool needGetUinfo=false;
+	if(update){
+		guiClearAll(guiGetBackColor());
+		guiShowCaption(0,"课程表",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
+		uiMenuShowBottomLine();
+		uiMenuShowBottomIndacitor(NULL, "返回");
+		if(sutApp.pocPpp==0){
+			guiShowMessageBox("无网络");
+			nwy_sleep(1500);
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+			return;
+		}
+		classShowReady=false;
+		showInfoBox("请稍候",3000);
+		sdMount();
+		if(isUserInfoReady()==false){//如果未获取用户信息,先获取用户信息
+			needGetUinfo=true;
+			learnUpdateStatus(LEARN_DB_WAIT_INFO);
+			learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL,true);
+		}else{//否则可以直接获取课程表
+			needGetUinfo=false;
+			learnUpdateStatus(LEARN_CLASS_GET_DETAIL);
+			learnTaskUpdate(LEARN_CLASS_GET_DETAIL,NULL, NULL,true);
+			MSG_ERR(1, "update class detail");
+		}
+	}
+	if(false==classShowReady){
+		ret=getHttpLearnStatus();
+		if(uTimerExpired(&learnTick) || ret!=1){
+			MSG_INFO(1, "WAIT CLASS:%d",ret);
+			switch(ret){
+				case 0://功获取到了信息
+					if(needGetUinfo==true){
+						needGetUinfo=false;
+						learnUpdateStatus(LEARN_CLASS_GET_DETAIL);
+						learnTaskUpdate(LEARN_CLASS_GET_DETAIL,NULL, NULL,true);
+						MSG_ERR(1, "update class detail");
+					}else{//处理
+						MSG_INFO(1, "class info get ok");
+						classShowReady=true;
+						getClassShowMessage();
+						classInfoDetailShow(0);
+					}
+					return;
+				case 2://获取失败
+					guiShowMessageBox("获取失败");
+					break;
+				default://获取超时
+					hearnHttpOverTime();
+					guiShowMessageBox("获取超时");
+					break;
+				}
+			nwy_sleep(1500);
+			getStackStruct()->ok_back=1;
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+		}
+	}
+}
+static void learnClassReleaseDB(void);
+void LearnClassDetailResponse(void){
+	if(classShowReady==true){
+		switch(getKeyValue()){
+			case MKEY_VALUE_ESC:
+				learnClassReleaseDB();
+				uISetNextStatus(UIS_MENU_LOCATION_SEL);
+				break;
+			case MKEY_VALUE_DOWN:classInfoDetailShow(1);break;
+			case MKEY_VALUE_UP:classInfoDetailShow(2);break;
+		}
+	}
+}
+
+typedef struct{
+	int id;
+	char time[15];
+	char title[30];
+}NOTICE_DEF;
+typedef struct{
+	unsigned int item;//rankResult实际使用的个数
+	unsigned int num;//rankResult分配的个数(释放时使用)
+	NOTICE_DEF **noticeResult;
+}NOTICE_RESULT_DEF;
+NOTICE_RESULT_DEF notices={0,0,0,NULL};
+bool noticeShowReady;
+static int noticetIndex=0;
+static void noticeInfoDetailShow(unsigned char direction){
+	if(notices.item==0){
+		guiShowMessageBox("无数据");
+		return;
+	}else if(notices.item==1) noticetIndex=0;
+	else{
+		if(direction==0) noticetIndex=0;
+		else if(direction==1){
+			if(++noticetIndex>=notices.item) noticetIndex=0;
+		}else if(direction==2){
+			if(noticetIndex==0) noticetIndex=notices.item-1;
+			else noticetIndex--;
+		}
+	}
+	guiClearRect(0,UI_CONTENT_SHOW_Y,GLCD_WIDTH-1,UI_BOTTOM_SHOW_Y-2,guiGetBackColor());
+	//显示
+	if(notices.noticeResult==NULL){
+		MSG_WARN(1, "notice no data");
+		return;
+	}
+	char info[50];
+	int x=1,y=UI_CONTENT_SHOW_Y;
+	//显示title
+	snprintf(info, sizeof(info), "title:%s", notices.noticeResult[noticetIndex]->title);
+	guiShowStr(x, y, info, FONT_MODE_16X16, REVERSED_NO, COLOR_BLACK, guiGetBackColor());
+	y+=17;
+	//显示time
+	snprintf(info, sizeof(info), "time:%s", notices.noticeResult[noticetIndex]->time);
+	guiShowStr(x, y, info, FONT_MODE_16X16, REVERSED_NO, COLOR_BLACK, guiGetBackColor());
+}
+static void getNoticeShowMessage(void);
+/*消息通知*/
+void uiShowLearnNoticeDetail(char update){
+	int ret;
+	static bool needGetUinfo=false;
+	if(update){
+		guiClearAll(guiGetBackColor());
+		guiShowCaption(0,"消息通知",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
+		uiMenuShowBottomLine();
+		uiMenuShowBottomIndacitor("阅读", "返回");
+		if(sutApp.pocPpp==0){
+			guiShowMessageBox("无网络");
+			nwy_sleep(1500);
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+			return;
+		}
+		if(noticeShowReady==false){
+			showInfoBox("请稍候",3000);
+			sdMount();
+			if(isUserInfoReady()==false){//如果未获取用户信息,先获取用户信息
+				needGetUinfo=true;
+				learnUpdateStatus(LEARN_DB_WAIT_INFO);
+				learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL,true);
+			}else{//否则可以直接获取课程表
+				needGetUinfo=false;
+				learnUpdateStatus(LEARN_NOTICE_GET_DETAIL);
+				learnTaskUpdate(LEARN_NOTICE_GET_DETAIL,NULL, NULL,true);
+				MSG_ERR(1, "update notice detail");
+			}
+		}
+	}
+	if(false==noticeShowReady){
+		ret=getHttpLearnStatus();
+		if(uTimerExpired(&learnTick) || ret!=1){
+			MSG_INFO(1, "WAIT NOTICE:%d",ret);
+			switch(ret){
+				case 0://功获取到了信息
+					if(needGetUinfo==true){
+						needGetUinfo=false;
+						learnUpdateStatus(LEARN_NOTICE_GET_DETAIL);
+						learnTaskUpdate(LEARN_NOTICE_GET_DETAIL,NULL, NULL,true);
+						MSG_ERR(1, "update notice detail");
+					}else{//处理
+						MSG_INFO(1, "notice info get ok");
+						noticeShowReady=true;
+						getNoticeShowMessage();
+						noticeInfoDetailShow(0);
+					}
+					return;
+				case 2://获取失败
+					guiShowMessageBox("获取失败");
+					break;
+				default://获取超时
+					hearnHttpOverTime();
+					guiShowMessageBox("获取超时");
+					break;
+				}
+			nwy_sleep(1500);
+			getStackStruct()->ok_back=1;
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+		}
+	}
+}
+static void learnNoticeReleaseDB(void);
+unsigned char noticeHandle;
+void LearnNoticeResponse(void){
+	if(noticeShowReady==true){
+		switch(getKeyValue()){
+			case MKEY_VALUE_ESC:
+				learnNoticeReleaseDB();
+				noticeShowReady=false;
+				uISetNextStatus(UIS_MENU_LOCATION_SEL);
+				break;
+			case MKEY_VALUE_DOWN:noticeInfoDetailShow(1);break;
+			case MKEY_VALUE_UP:noticeInfoDetailShow(2);break;
+			case MKEY_VALUE_MENU:
+				uISetNextStatus(UIS_MENU_LOCATION_NOTICE_DETAIL);
+				break;
+		}
+	}
+}
+bool noticeDetailReady=false;
+/*消息通知详情*/
+void uiShowLearnNoticeDetailShow(char update){
+	int ret;
+
+	if(update){
+		guiClearAll(guiGetBackColor());
+		guiShowCaption(0,notices.noticeResult[noticetIndex]->title,UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
+		uiMenuShowBottomLine();
+		uiMenuShowBottomIndacitor(NULL, "返回");
+		if(sutApp.pocPpp==0){
+			guiShowMessageBox("无网络");
+			nwy_sleep(1500);
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+			return;
+		}
+		showInfoBox("请稍候",3000);
+		sdMount();
+		noticeDetailReady=false;
+		learnUpdateStatus(LEARN_NOTICE_GET_DETAIL_SHOW);
+		learnTaskUpdate(LEARN_NOTICE_GET_DETAIL_SHOW,(void *)&notices.noticeResult[noticetIndex]->id, NULL,true);
+		MSG_ERR(1, "update notice detail show");
+	}
+	if(false==noticeDetailReady){
+		ret=getHttpLearnStatus();
+		if(uTimerExpired(&learnTick) || ret!=1){
+			MSG_INFO(1, "WAIT NOTICE SHOW:%d",ret);
+			switch(ret){
+				case 0://功获取到了信息
+					//处理
+					noticeDetailReady=true;
+					MSG_INFO(1, "notice info get ok");
+					noticeInfoDetailShowContent(0);
+					return;
+				case 2://获取失败
+					guiShowMessageBox("获取失败");
+					break;
+				default://获取超时
+					hearnHttpOverTime();
+					guiShowMessageBox("获取超时");
+					break;
+				}
+			nwy_sleep(1500);
+			noticeShowReady=false;
+			getStackStruct()->ok_back=1;
+			uISetNextStatus(UIS_MENU_LOCATION_SEL);
+		}
+	}
+}
+
+void LearnNoticeDetailResponse(void){
+	if(noticeDetailReady==true){
+		switch(getKeyValue()){
+			case MKEY_VALUE_ESC:
+				noticeShowReady=false;
+				uISetNextStatus(UIS_MENU_LOCATION_NOTICE);
+				break;
+			case MKEY_VALUE_DOWN:noticeInfoDetailShowContent(1);break;
+			//case MKEY_VALUE_UP:noticeInfoDetailShowContent(2);break;
+		}
+	}
+}
 
 #define OBJECT_AVG_NAME 	"avg"
 #define OBJECT_SCORE_NAME 	"score"
@@ -1611,6 +1963,400 @@ static void getRankShowMessage(unsigned char ranktype){
 		}
 }
 
+#define OBJECT_WEEK_NAME 	"week"
+#define OBJECT_TIME_NAME 	"time"
+#define OBJECT_SUBJECT_NAME "subject"
+
+static char *classBuffer=NULL;
+cJSON* classJson=NULL;
+static void learnClassReleaseDB(void){
+	int i;
+	releaseBuf(&classBuffer);
+	if(NULL!=classes.classResult){
+		for(i=0;i<classes.num;i++){
+			if(classes.classResult[i]!=NULL) releaseBuf(&classes.classResult[i]);
+		}
+		releaseBuf(&classes.classResult);
+	}
+	releaseJson(&classJson);
+}
+
+static void getClassShowMessage(void){
+	//从LEARN_CLASS文件中读取内容出来解析
+	CLASS_DEF **classPtr=NULL;
+	int fd=-1,i=0;
+	char info[50];
+	
+	ranks.item=0;
+	snprintf(info, sizeof(info), "%s/%s", SD_TOKEN,LEARN_CLASS);
+	fd=nwy_sdk_fopen(info, NWY_RDONLY);
+	if(fd<0){
+		MSG_WARN(1, "Class file open failed");
+		goto R_EXIT;
+	}
+	long size=nwy_sdk_fsize_fd(fd);
+	if(size<=0){
+		MSG_WARN(1, "Class file data error");
+		goto R_EXIT;
+	}
+	releaseBuf(&classBuffer);
+	classBuffer=(char *)createBuf(size);
+	//classBuffer=(char *)malloc(size);
+	if(NULL == classBuffer){
+		MSG_ERR(1, "class buffer malloc error");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "[mem malloc]%x", classBuffer);
+	memset(classBuffer, 0, size);
+	nwy_sdk_fread(fd, classBuffer, size);
+	nwy_sdk_fclose(fd);
+	fd=-1;
+	//解析json
+	MSG_INFO(1, "Class data analyse len:%d",size);
+	if(NULL!=classes.classResult){
+		for(i=0;i<classes.num;i++){
+			if(classes.classResult[i]!=NULL) releaseBuf(&classes.classResult[i]);
+		}
+		releaseBuf(&classes.classResult);
+	}
+	classes.num=0;
+
+	classJson = createJson(classBuffer);
+	//classJson = cJSON_Parse(classBuffer);
+	if(NULL==classJson){
+		MSG_WARN(1, "class json null");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "class json:%x", classJson);
+	cJSON* item = cJSON_GetObjectItem(classJson, OBJECT_LIST);
+	if(NULL==item){
+		MSG_ERR(1, "class json failed");
+		goto R_EXIT;
+	}
+	int num=cJSON_GetArraySize(item);
+	if(num<=0){
+		MSG_WARN(1, "class array num:%d",num);
+		goto R_EXIT;
+	}
+	MSG_INFO(1, "class num:%d",num);
+	classPtr=(CLASS_DEF **)createBuf(sizeof(CLASS_DEF *)*num);
+	//classPtr=(CLASS_DEF **)malloc(sizeof(CLASS_DEF *)*num);
+	if(NULL==classPtr){
+		MSG_ERR(1,"class malloc failed");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "[mem malloc]%x", classPtr);
+	classes.num=num;
+	for(i=0;i<num;i++) classPtr[i]=NULL;
+	for(i=0;i<num;i++){
+		classPtr[i]=(CLASS_DEF *)createBuf(sizeof(CLASS_DEF));
+		//classPtr[i]=(CLASS_DEF *)malloc(sizeof(CLASS_DEF));
+		if(NULL==classPtr[i]){
+			MSG_ERR(1, "class[%d] malloc failed", i);
+			goto R_EXIT;
+		}
+		//MSG_INFO(1, "[mem malloc %d]%x", i, classPtr[i]);
+	}
+	cJSON* element,*t;
+	i=0;
+	for(;;){
+		element=cJSON_GetArrayItem(item,i);
+		if(NULL==element) break;
+		//week
+		t=cJSON_GetObjectItem(element, OBJECT_WEEK_NAME);
+		if(NULL==t) classPtr[i]->week=-1;
+		else classPtr[i]->week=atoi(t->valuestring);
+		//time
+		t=cJSON_GetObjectItem(element, OBJECT_TIME_NAME);
+		if(NULL==t) classPtr[i]->time[0]='\0';
+		else snprintf(classPtr[i]->time, sizeof(classPtr[i]->time), "%s", t->valuestring);
+		//subject
+		t=cJSON_GetObjectItem(element, OBJECT_SUBJECT_NAME);
+		if(NULL==t) classPtr[i]->subject[0]='\0';
+		else snprintf(classPtr[i]->subject, sizeof(classPtr[i]->subject), "%s", t->valuestring);
+		i++;
+	}
+	classes.item=i;
+	classes.classResult=classPtr;
+	MSG_INFO(1, "class valid num:%d",i);
+	return;
+	
+	R_EXIT:
+		releaseJson(&classJson);
+		releaseBuf(&classBuffer);
+		if(fd>0) nwy_sdk_fclose(fd);
+		if(classPtr != NULL){
+			for(i=0;i<num;i++) releaseBuf(&classPtr[i]);
+			releaseBuf(&classPtr);
+		}
+}
+
+#define OBJECT_ID_NAME 	"id"
+#define OBJECT_TITLE_NAME 	"title"
+
+static char *noticeBuffer=NULL;
+cJSON* noticeJson=NULL;
+static void learnNoticeReleaseDB(void){
+	int i;
+	releaseBuf(&noticeBuffer);
+	if(NULL!=notices.noticeResult){
+		for(i=0;i<notices.num;i++){
+			if(notices.noticeResult[i]!=NULL) releaseBuf(&notices.noticeResult[i]);
+		}
+		releaseBuf(&notices.noticeResult);
+	}
+	releaseJson(&noticeJson);
+}
+
+static void getNoticeShowMessage(void){
+	//从LEARN_CLASS文件中读取内容出来解析
+	NOTICE_DEF **noticePtr=NULL;
+	int fd=-1,i=0;
+	char info[50];
+	
+	notices.item=0;
+	snprintf(info, sizeof(info), "%s/%s", SD_TOKEN,LEARN_NOTICE);
+	fd=nwy_sdk_fopen(info, NWY_RDONLY);
+	if(fd<0){
+		MSG_WARN(1, "Notice file open failed");
+		goto R_EXIT;
+	}
+	long size=nwy_sdk_fsize_fd(fd);
+	if(size<=0){
+		MSG_WARN(1, "Notice file data error");
+		goto R_EXIT;
+	}
+	releaseBuf(&noticeBuffer);
+	noticeBuffer=(char *)createBuf(size);
+	//noticeBuffer=(char *)malloc(size);
+	if(NULL == noticeBuffer){
+		MSG_ERR(1, "notice buffer malloc error");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "[mem malloc]%x", noticeBuffer);
+	memset(noticeBuffer, 0, size);
+	nwy_sdk_fread(fd, noticeBuffer, size);
+	nwy_sdk_fclose(fd);
+	fd=-1;
+	//解析json
+	MSG_INFO(1, "Notice data analyse len:%d",size);
+	if(NULL!=notices.noticeResult){
+		for(i=0;i<notices.num;i++){
+			if(notices.noticeResult[i]!=NULL) releaseBuf(&notices.noticeResult[i]);
+		}
+		releaseBuf(&notices.noticeResult);
+	}
+	notices.num=0;
+
+	noticeJson = createJson(noticeBuffer);
+	//noticeJson = cJSON_Parse(noticeBuffer);
+	if(NULL==noticeJson){
+		MSG_WARN(1, "notice json null");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "notice json:%x", noticeJson);
+	cJSON* item = cJSON_GetObjectItem(noticeJson, OBJECT_LIST);
+	if(NULL==item){
+		MSG_ERR(1, "notice json failed");
+		goto R_EXIT;
+	}
+	int num=cJSON_GetArraySize(item);
+	if(num<=0){
+		MSG_WARN(1, "notice array num:%d",num);
+		goto R_EXIT;
+	}
+	MSG_INFO(1, "notice num:%d",num);
+	noticePtr=(NOTICE_DEF **)createBuf(sizeof(NOTICE_DEF *)*num);
+	//noticePtr=(NOTICE_DEF **)malloc(sizeof(NOTICE_DEF *)*num);
+	if(NULL==noticePtr){
+		MSG_ERR(1,"notice malloc failed");
+		goto R_EXIT;
+	}
+	//MSG_INFO(1, "[mem malloc]%x", noticePtr);
+	notices.num=num;
+	for(i=0;i<num;i++) noticePtr[i]=NULL;
+	for(i=0;i<num;i++){
+		noticePtr[i]=(NOTICE_DEF *)createBuf(sizeof(NOTICE_DEF));
+		//noticePtr[i]=(CLASS_DEF *)malloc(sizeof(CLASS_DEF));
+		if(NULL==noticePtr[i]){
+			MSG_ERR(1, "notice[%d] malloc failed", i);
+			goto R_EXIT;
+		}
+		//MSG_INFO(1, "[mem malloc %d]%x", i, noticePtr[i]);
+	}
+	cJSON* element,*t;
+	i=0;
+	for(;;){
+		element=cJSON_GetArrayItem(item,i);
+		if(NULL==element) break;
+		//id
+		t=cJSON_GetObjectItem(element, OBJECT_ID_NAME);
+		if(NULL==t) noticePtr[i]->id=-1;
+		else noticePtr[i]->id=atoi(t->valuestring);
+		//time
+		t=cJSON_GetObjectItem(element, OBJECT_TIME_NAME);
+		if(NULL==t) noticePtr[i]->time[0]='\0';
+		else snprintf(noticePtr[i]->time, sizeof(noticePtr[i]->time), "%s", t->valuestring);
+		//title
+		t=cJSON_GetObjectItem(element, OBJECT_TITLE_NAME);
+		if(NULL==t) noticePtr[i]->title[0]='\0';
+		else snprintf(noticePtr[i]->title, sizeof(noticePtr[i]->title), "%s", t->valuestring);
+		i++;
+	}
+	notices.item=i;
+	notices.noticeResult=noticePtr;
+	MSG_INFO(1, "notice valid num:%d",i);
+	return;
+	
+	R_EXIT:
+		releaseJson(&noticeJson);
+		releaseBuf(&noticeBuffer);
+		if(fd>0) nwy_sdk_fclose(fd);
+		if(noticePtr != NULL){
+			for(i=0;i<num;i++) releaseBuf(&noticePtr[i]);
+			releaseBuf(&noticePtr);
+		}
+}
+
+char *noticeDetailContent=NULL;
+//char *testShowData="这是一条测试信息,长度为100,然后呢就一直显示吧,我也不知道能显示多少,所以只能临时搞一段文字来显示看看效果如何了,然后再给100000000000元作者吧,作为酬劳,我也不知道是否足够呢。";
+void noticeInfoDetailShowContent(char direction){
+	int x=1,y=UI_CONTENT_SHOW_Y;
+	char *ptr=noticeDetailContent;
+	static int showlen,showIndex,len;
+	if(direction==0){
+		showlen=strlen(ptr);
+		showIndex=0;
+	}
+	guiClearRect(0,UI_CONTENT_SHOW_Y,GLCD_WIDTH-1,UI_BOTTOM_SHOW_Y-2,guiGetBackColor());
+	MessageEditInit(&sutMEdit, x, y+2 , ptr, FONT_MODE_16X16);
+	len=MessageEditShow(&sutMEdit,ptr+showIndex);
+	if(len !=0) showIndex+=len;
+	else showIndex=0;
+}
+void cJSONTakeContent(char *msg, int len){
+	//msg={"id":"7","content":"通知测试2"}
+	//提取"content"内容项到noticeInfoDetailShowContent中
+	releaseBuf(&noticeDetailContent);
+	cJSON* nJson=NULL;
+	nJson = createJson(msg);
+	if(NULL==nJson){
+		MSG_WARN(1, "notice detail show json null");
+		goto R_EXIT;
+	}
+	cJSON* item = cJSON_GetObjectItem(nJson, OBJECT_CONTENT_DETAIL);
+	if(NULL==item){
+		MSG_ERR(1, "notice detail show json failed");
+		goto R_EXIT;
+	}
+	int length=strlen(item->valuestring)+1;
+	char *ptr=(char *)createBuf(len*sizeof(char));
+	if(ptr==NULL){
+		MSG_ERR(1, "notice detail show malloc err");
+		goto R_EXIT;
+	}
+	memcpy(ptr, item->valuestring, len);
+	ptr[len]=0;
+	noticeDetailContent=ptr;
+	R_EXIT:
+	releaseJson(&nJson);
+}
+
+void cJSONTakeParam(char *msg, int len){
+	//msg={"scoreSpeedParam": "1.0","scoreVolumeParam": "1.0"}
+	bool sparamOk=false;
+	bool vparamOk=false;
+	cJSON* nJson=NULL;
+	nJson = createJson(msg);
+	if(NULL==nJson){
+		MSG_WARN(1, "param detail json null");
+		goto R_EXIT;
+	}
+	cJSON* item = cJSON_GetObjectItem(nJson, OBJECT_SPEED_PARAM);
+	
+	if(NULL==item) MSG_ERR(1, "param speed json failed");
+	else{
+		usr.scoreSpeedParam=atof(item->valuestring);
+		sparamOk=true;
+	}
+	
+	item = cJSON_GetObjectItem(nJson, OBJECT_VOLUME_PARAM);
+	
+	if(NULL==item) MSG_ERR(1, "param volume json failed");
+	else{
+		usr.scoreVolumeParam=atof(item->valuestring);
+		vparamOk=true;
+	}
+	if(sparamOk==true && vparamOk==true){
+		MSG_INFO(1, "sparam:%f, vparam:%f", usr.scoreSpeedParam, usr.scoreVolumeParam);
+		usr.paramReady=true;
+	}
+	R_EXIT:
+	releaseJson(&nJson);
+}
+//没获取账户信息,则定时尝试获取
+void LearnUsrInfoCheck(unsigned int interval){
+	static char step=0;
+	static unsigned int waitTimer;
+	unsigned char ret;
+	if(sutPocStatus.logined==0) return;
+	if(true==isUserInfoReady() && true==usr.paramReady){
+		if(step!=0) step=0;
+		return;
+	}
+	switch(step){
+		case 0://发起获取账户信息请求
+			step=1;
+			learnUpdateStatus(LEARN_DB_WAIT_INFO);
+			learnTaskUpdate(LEARN_DB_GET_INFO,NULL, NULL,false);
+			uTimerStart(&waitTimer, 5000);
+			break;
+		case 1://等待获取结果
+			ret=getHttpLearnStatus();
+			if(uTimerExpired(&waitTimer) || ret !=1){
+				MSG_INFO(1, "Wait user account:%d", ret);
+				if(ret==0) step=2;
+				else step=0;//重新获取
+			}
+			break;
+		case 2://发起参数获取请求
+			step=3;
+			learnUpdateStatus(LEARN_GET_PARAM);
+			learnTaskUpdate(LEARN_GET_PARAM,NULL, NULL,false);
+			uTimerStart(&waitTimer, 5000);
+			break;
+		case 3://等待获取结果
+			ret=getHttpLearnStatus();
+			if(uTimerExpired(&waitTimer) || ret !=1){
+				MSG_INFO(1, "Wait param:%d", ret);
+				if(ret==0) step=4;//停止
+				else step=2;//重新获取
+			}
+			break;
+		case 4://IDLE
+			break;
+	}
+}
+void uiShowLearnGroup(char type){
+	static unsigned int gid=0xffffffff;
+	if(false==isUserInfoReady()) return;
+	if(type) goto S_NOW;
+	if(gid == getLearnGid()) return;
+	gid=getLearnGid();
+	S_NOW:
+		uiShowLearnGName(getLearnGName());
+}
+static bool sdMountStatus=false;
+void sdUnmount(void){
+	sdCardCtl(false);
+	sdMountStatus=false;
+}
+void sdMount(void){
+	if(sdMountStatus==false){
+		sdCardCtl(true);
+		sdMountStatus=true;
+	}
+}
 bool sdCardTest(void){
 	const char *table="sdTest.txt";
 	char file[50];

+ 6 - 0
app/learn/learnTask.h

@@ -34,4 +34,10 @@ char *learnGetTid(void);
 bool isLearnBusy(void);
 bool sdCardTest(void);
 void learnUserInfoClear(void);
+
+void LearnUsrInfoCheck(unsigned int interval);
+void uiShowLearnGroup(char type);
+
+void sdUnmount(void);
+void sdMount(void);
 #endif

+ 1 - 1
app/message.c

@@ -673,7 +673,7 @@ void MessageOptionShow(char update)
 		guiClearAll(guiGetBackColor());
 		guiShowCaption(0,"Îı¾Ñ¡Ïî",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
 		uiMenuShowBottomLine();
-		uiMenuInit(&sutMenuSysSetup,apcMenuSysSetup, FONT_MODE_12X12);
+		uiMenuInit(&sutMenuSysSetup,apcMenuSysSetup, FONT_MODE_12X12,true);
 		uiMenuShowBottomIndacitor("È·¶¨", "·µ»Ø");
 	}
 }

+ 1 - 1
app/ohpoc.h

@@ -7,7 +7,7 @@
 #define OHPOC_APP_NAME "T555"
 //#define OHPOC_APP_NAME "RTL-TEST"
 
-#define OHPOC_VERSION "03018"  //外部OCPU 应用维护
+#define OHPOC_VERSION "03019"  //外部OCPU 应用维护
 #define OHPOC_MODLE	"N58" //作为OPEN时,此值用于FOTA升级标识使用
 #define OHPOC_CUST OHPOC_APP_NAME //作为OPEN时,此值用于FOTA升级标识使用
 

+ 124 - 10
app/uiBlock.c

@@ -3,6 +3,7 @@
 /****************************状态栏显示部分开始***********************************/
 #define MIN_PWR_LEVEL 315  //低于此电压后不工作
 #define WARN_PWR_LEVEL 325 //提示请充电电压
+static const char *NullPtr="";
 
 //显示信号强度
 static void ShowSingle(int CSQ){
@@ -103,7 +104,7 @@ static void ShowBatttery(int bat,unsigned int exeInterval){
 			flag=1;
 		}else{
 			flag=0;
-			guiClearRect(x,y-2,x+21,y-2+1+12,COLOR_STATUS_BAR);
+			guiClearRect(x,y-2,x+21,y-2+1+11,COLOR_STATUS_BAR);
 		}
 	}else if(bat<355){//340<x<=355 1格
 		guiShowBmp(x,y,"VBAT1.bmp");//3
@@ -298,8 +299,13 @@ void uiShowMainInterface(char status,unsigned int exeInterval){
 	}
 
 	if(Flag>0){//已登录
-		if(Flag != lastFlag && (lastFlag==-1 || ME_NO_LOGIN==lastFlag)) uiShowGUName(1);
-		else uiShowGUName(0);
+		if(Flag != lastFlag && (lastFlag==-1 || ME_NO_LOGIN==lastFlag)){
+			uiShowGUName(1);
+			uiShowLearnGroup(1);
+		}else{
+			uiShowGUName(0);
+			uiShowLearnGroup(0);
+		}
 	}else{//未登录
 		snprintf(info, sizeof(info),"请等待网络连接.");
 		switch(siCt){//not finished yet
@@ -367,6 +373,12 @@ static void uiShowGUName(int update){
 		uiShowUser(name);
 	}
 }
+void uiShowLearnGName(const char *name){
+	guiShowBmp(2, UI_LEARN_SHOW_Y, "Group2.bmp");
+	guiClearRect(2+16, UI_LEARN_SHOW_Y, GLCD_WIDTH-1, UI_LEARN_SHOW_Y+16, guiGetBackColor());
+	guiShowStr(2+16, UI_LEARN_SHOW_Y, "学习组:", FONT_MODE_16X16, REVERSED_NO,guiGetForeColor(),guiGetBackColor());
+	guiShowStr(2+16+56, UI_LEARN_SHOW_Y,name, FONT_MODE_16X16, REVERSED_NO,guiGetForeColor(),guiGetBackColor());
+}
 static void uiShowGuaDuan(unsigned char danhu){
 	if(danhu==0) guiClearArea(GLCD_WIDTH-32, UI_BOTTOM_SHOW_Y, 32, 14, guiGetBackColor());
 	else guiShowStr(GLCD_WIDTH-32, UI_BOTTOM_SHOW_Y, "挂断", FONT_MODE_12X12, REVERSED_NO, COLOR_STATUS_BAR,guiGetBackColor());
@@ -379,12 +391,14 @@ static void uiShowGroup(const char* info){
 		color=COLOR_RED;
 	}
 	guiClearRect(2+16, UI_GROUP_SHOW_Y, GLCD_WIDTH-1, UI_GROUP_SHOW_Y+16, guiGetBackColor());
-	guiShowStr(2+16, UI_GROUP_SHOW_Y,info, FONT_MODE_16X16, REVERSED_NO,color,guiGetBackColor());
+	guiShowStr(2+16, UI_GROUP_SHOW_Y, "对讲组:", FONT_MODE_16X16, REVERSED_NO,color,guiGetBackColor());
+	guiShowStr(2+16+56, UI_GROUP_SHOW_Y,info, FONT_MODE_16X16, REVERSED_NO,color,guiGetBackColor());
 }
 static void uiShowUser(const char* info){
 	guiShowBmp(2, UI_USER_SHOW_Y, "people2.bmp");
 	guiClearRect(2+16, UI_USER_SHOW_Y, GLCD_WIDTH-1, UI_USER_SHOW_Y+16, guiGetBackColor());
-	guiShowStr(2+16, UI_USER_SHOW_Y,info, FONT_MODE_16X16, REVERSED_NO,guiGetForeColor(),guiGetBackColor());
+	guiShowStr(2+16, UI_USER_SHOW_Y,"昵称:", FONT_MODE_16X16, REVERSED_NO,guiGetForeColor(),guiGetBackColor());
+	guiShowStr(2+16+40, UI_USER_SHOW_Y,info, FONT_MODE_16X16, REVERSED_NO,guiGetForeColor(),guiGetBackColor());
 }
 static void uiShowHuaQuan(const char* info,char type){
 	unsigned int color=guiGetForeColor();
@@ -461,13 +475,14 @@ void uiShowMenuMain(char update){
 		"考勤信息",
 		"群组选择",
 		"成员选择",
+		"定位设置",
 #else
 		"学习任务",
 		"学习排名",
 		"班级选择",
 		"同学选择",
+		"消息通知",
 #endif
-		"定位设置",
 		"系统信息",
 		""
 	};
@@ -670,7 +685,6 @@ static void ReFlashItemGU(char type){
 	static char *icons[3];
 	int i;
 	unsigned short timeout;
-	static const char *NullGU="";
 	static char *GUName[POC_ALL_GROUPS_NUM+1];	//5
 	static char GUFeatures[POC_ALL_GROUPS_NUM+1];//5
 	
@@ -683,7 +697,7 @@ static void ReFlashItemGU(char type){
 	}
 	icons[2]=accIconFileName[4];
 	for(i=0;i<=POC_ALL_GROUPS_NUM;i++){
-		GUName[i]=NullGU;
+		GUName[i]=NullPtr;
 		GUFeatures[i]=0;
 	}
 	for(i=0;i<sutPocStatus.ListFillIndex;i++){
@@ -720,6 +734,7 @@ void uiShowMenuSysSetup(char flash){
 		"7,提示音设置",
 		"8,终端信息",
 		"9,SD卡检测",
+		"10,留音记录",
 		""
 	};
 	if(flash){
@@ -728,7 +743,7 @@ void uiShowMenuSysSetup(char flash){
 		guiShowCaption(0,"系统设置",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
 		uiMenuShowBottomLine();
 		uiMenuShowBottomIndacitor("确认", "返回");
-		uiMenuInit(&sutMenuSysSetup,apcPtr,FONT_MODE_12X12);
+		uiMenuInit(&sutMenuSysSetup,apcPtr,FONT_MODE_12X12,true);
 	}
 }
 
@@ -765,8 +780,11 @@ void sysTemSetResponse(void){
 			case 8://SD卡检测
 				uISetNextStatus(UIS_MENU_SYS_SD);
 				break;
+			case 9://留音记录设置
+				uISetNextStatus(UIS_MENU_SYS_VOICE);
+				break;
 		}
-		if(sutMenuSysSetup.handle<=8) uiPushStack(sutMenuSysSetup.handle);
+		if(sutMenuSysSetup.handle<=9) uiPushStack(sutMenuSysSetup.handle);
 	}else if(MKEY_VALUE_ESC==key) uISetNextStatus(UIS_MENU_MAIN);
 }
 /*****************************系统设置部分结束*********************************/
@@ -776,6 +794,7 @@ unsigned char tempGpsIndex;
 static locationTimeFlash(char type);
 static locationXYFlash(char flash);
 void uiShowMenuLocationSel(char flash){
+#ifdef MAKE_IT_COMMON_VERSION
 	if(flash){
 		guiClearAll(guiGetBackColor());
 		guiShowCaption(0,"定位设置",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
@@ -791,8 +810,23 @@ void uiShowMenuLocationSel(char flash){
 		locationTimeFlash(0);
 	}
 	if(newPara.gpsEnable!=0) locationXYFlash(flash);
+#else
+	static const char *apcPtr[]={
+		"1,课程表",
+		"2,通知简报",
+		""
+	};
+	if(flash){
+		guiClearAll(guiGetBackColor());
+		guiShowCaption(0,"消息通知",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
+		uiMenuShowBottomLine();
+		uiMenuShowBottomIndacitor("确认", "返回");
+		uiMenuInit(&sutMenuSysSetup,apcPtr,FONT_MODE_12X12,true);
+	}
+#endif
 }
 void loationSetResponse(void){
+#ifdef MAKE_IT_COMMON_VERSION
 	unsigned short key;
 	
 	key=getKeyValue();
@@ -808,6 +842,25 @@ void loationSetResponse(void){
 		}
 		uISetNextStatus(UIS_MENU_MAIN);
 	}
+#else
+	unsigned short key;
+	
+	key=uiMenuResponse(&sutMenuSysSetup);
+	if(MKEY_VALUE_MENU==key){
+		switch(sutMenuSysSetup.handle){
+			case 0://课程表
+				uISetNextStatus(UIS_MENU_LOCATION_CLASS);
+				break;
+			case 1://消息通知
+				uISetNextStatus(UIS_MENU_LOCATION_NOTICE);
+				break;
+		}
+		if(sutMenuSysSetup.handle<=1) uiPushStack(sutMenuSysSetup.handle);
+	}else if(MKEY_VALUE_ESC==key){
+		sdUnmount();
+		uISetNextStatus(UIS_MENU_MAIN);
+	}
+#endif
 }
 static locationTimeFlash(char type){
 	unsigned short gpsTimeValue;
@@ -931,6 +984,67 @@ void uiShowInformationResponse(void){
 }
 /*****************************终端信息结束**********************************/
 
+/*******************************留音记录开始**********************************/
+void uiShowVoiceInfo(char update){
+	static unsigned int timer;
+	static char *showInfo[3+1];
+	static char empty;
+	int i;
+	if(update){
+		guiClearAll(guiGetBackColor());
+		guiShowCaption(0,"留音记录",UI_STATUS_BAR_HEIGH,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
+		uiMenuShowBottomLine();
+		uiMenuShowBottomIndacitor("播放", "返回");
+		sutApp.voiceInfo.update=0;
+		sutApp.voiceInfo.aNum=0;
+		sutApp.voiceInfo.vNum=0;
+		sutApp.voiceInfo.voiceValidNum=0;
+		sutApp.voiceInfo.voiceStatus=1;
+		empty=0;
+		msgAtSend("AT+VINFO?\r\n");
+		guiShowMessageBox("请稍后");
+		uTimerStart(&timer, 2000);
+	}
+	switch(sutApp.voiceInfo.voiceStatus){
+		case 1:
+			if(sutApp.voiceInfo.update!=0){
+				sutApp.voiceInfo.voiceStatus=2;
+				break;
+			}
+			if(uTimerExpired(&timer)){
+				showInfo[0]="空";
+				sutApp.voiceInfo.voiceStatus=2;
+				empty=1;
+				//MSG_INFO(1, "==>Empty");
+			}
+			break;
+		case 2:
+			if(empty==0) for(i=0;i<sutApp.voiceInfo.voiceValidNum;i++) showInfo[i]=sutApp.voiceInfo.info[i].info;
+			else i=1;
+			showInfo[i]=NullPtr;
+			guiFillRect(0,UI_CONTENT_SHOW_Y,GLCD_WIDTH-1,UI_BOTTOM_SHOW_Y-1,guiGetBackColor());
+			uiMenuInit(&sutMenuSysSetup,showInfo,FONT_MODE_12X12,false);
+			sutApp.voiceInfo.voiceStatus=3;
+			break;
+	}
+}
+
+void uiShowVoiceInfoResponse(void){
+	char cmd[30];
+	unsigned short key;
+	
+	if(sutApp.voiceInfo.voiceStatus!=3) return;
+	key=uiMenuResponse(&sutMenuSysSetup);
+	if(MKEY_VALUE_ESC==key) uISetNextStatus(sutUIstatus.LastStatus);
+	else if(MKEY_VALUE_MENU==key){
+		if(sutApp.voiceInfo.voiceValidNum!=0){
+			snprintf(cmd, sizeof(cmd), "AT+VPLAY=%c\r\n", sutApp.voiceInfo.info[sutMenuSysSetup.handle].index);
+			msgAtSend(cmd);
+		}
+	}
+}
+/*****************************留音记录结束**********************************/
+
 /*****************************SD卡检测***************************************/
 void uiShowSD(char update){
 	static unsigned int timer;

+ 1 - 1
app/uiBlock.h

@@ -63,6 +63,6 @@ void uiShowVersionSel(char StatusUpdate);
 void uiShowVersionSelResponse(void);
 
 void pwrModeAckHandler(unsigned char seg1, unsigned char seg2);
-
+void uiShowLearnGName(const char *name);
 unsigned short getSmsXAddr(void);
 #endif

+ 35 - 1
app/uiEntry.c

@@ -139,6 +139,10 @@ void uiLoop(unsigned int exeInterval){
 		case UIS_MENU_SYS_SD:
 			uiShowSD(StatusUpdate);
 			break;
+		/***********1.4.10级:留音记录界面显示入口*************/
+		case UIS_MENU_SYS_VOICE:
+			uiShowVoiceInfo(StatusUpdate);
+			break;
 			
 		/****************1.1.1(学习任务)任务查看*/
 		case UIS_MENU_TASK_QUERY:
@@ -148,6 +152,19 @@ void uiLoop(unsigned int exeInterval){
 		case UIS_MENU_RANK_DETAIL:
 			uiShowLearnRankDetail(StatusUpdate);
 			break;
+			
+		/****************课程表************************/
+		case UIS_MENU_LOCATION_CLASS:
+			uiShowLearnClassDetail(StatusUpdate);
+			break;
+		/****************消息通知************************/	
+		case UIS_MENU_LOCATION_NOTICE:
+			uiShowLearnNoticeDetail(StatusUpdate);
+			break;
+		/****************消息通知详情************************/	
+		case UIS_MENU_LOCATION_NOTICE_DETAIL:
+			uiShowLearnNoticeDetailShow(StatusUpdate);
+			break;
 	}
 }
 /********************************UI响应功能********************************/
@@ -213,7 +230,7 @@ void uiResponse(unsigned int exeInterval){
 		case UIS_MENU_SYS_SEL:
 			sysTemSetResponse();
 			break;
-			
+		
 		/****************1.3级:文本消息界面响应*************/
 		case UIS_MENU_MAIL_SEL:
 			MessageResponse();
@@ -272,6 +289,10 @@ void uiResponse(unsigned int exeInterval){
 		case UIS_MENU_SYS_INFO:
 			uiShowInformationResponse();
 			break;
+		/***********1.4.10级:留音记录信息界面响应*************/
+		case UIS_MENU_SYS_VOICE:
+			uiShowVoiceInfoResponse();
+			break;
 			
 		/****************1.1.1(学习任务)任务查看*/
 		case UIS_MENU_TASK_QUERY:
@@ -282,6 +303,19 @@ void uiResponse(unsigned int exeInterval){
 		case UIS_MENU_RANK_DETAIL:
 			LearnRankDetailSelResponse();
 			break;
+			
+		/****************课程表************************/
+		case UIS_MENU_LOCATION_CLASS:
+			LearnClassDetailResponse();
+			break;
+		/****************消息通知************************/
+		case UIS_MENU_LOCATION_NOTICE:
+			LearnNoticeResponse();
+			break;
+		/****************消息通知详情************************/
+		case UIS_MENU_LOCATION_NOTICE_DETAIL:
+			LearnNoticeDetailResponse();
+			break;
 	}
 }
 

+ 10 - 2
app/uiEntry.h

@@ -30,6 +30,7 @@ typedef enum{
 	UIS_MENU_SYS_NOTE,		//1.4.7:系统设置提示音
 	UIS_MENU_SYS_INFO,		//1.4.8:终端信息菜单
 	UIS_MENU_SYS_SD,		//1.4.9:终端设置SD卡检测
+	UIS_MENU_SYS_VOICE,		//1.4.10:留音记录菜单
 	
 	UIS_MENU_TASK_QUERY,	//1.1.1:(学习任务)查看任务内容
 	
@@ -38,7 +39,11 @@ typedef enum{
 	UIS_MENU_SYS_SERVER,	//1.4.5.1:服务器设置
 	
 	
-	UIS_MENU_MAIL_SEL
+	UIS_MENU_MAIL_SEL,
+	
+	UIS_MENU_LOCATION_CLASS,//课程表
+	UIS_MENU_LOCATION_NOTICE,//消息通知
+	UIS_MENU_LOCATION_NOTICE_DETAIL,//通知详情
 }UIS_ENUM;
 
 #pragma pack(push)
@@ -77,7 +82,10 @@ extern UI_STACKDEF uiStack;
 #define UI_LOGIN_SHOW_Y			(UI_STATUS_BAR_HEIGH+UI_STATUS_ITEM_HEIGH+2)
 //群组信息显示所在的
 
-#define UI_GROUP_SHOW_Y			(UI_STATUS_BAR_HEIGH+UI_STATUS_ITEM_HEIGH+5)
+#define UI_LEARN_SHOW_Y         (UI_STATUS_BAR_HEIGH+UI_STATUS_ITEM_HEIGH+5)
+//学习组信息显示所在
+
+#define UI_GROUP_SHOW_Y			(UI_LEARN_SHOW_Y+2+16)
 //成员信息显示所在的
 
 #define UI_USER_SHOW_Y			(UI_GROUP_SHOW_Y+2+16)

BIN
lib/libohpoc.a


BIN
preset/Palace4.bmp