| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | #include "stdio.h"
 | 
					
						
							|  |  |  | #include "rtthread.h"
 | 
					
						
							|  |  |  | #include "board.h"
 | 
					
						
							|  |  |  | #include "mystdlib.h"
 | 
					
						
							|  |  |  | #include "list.h"
 | 
					
						
							|  |  |  | #include "mystring.h"
 | 
					
						
							|  |  |  | #include "signal.h"
 | 
					
						
							|  |  |  | #include "prot_uc.h"
 | 
					
						
							|  |  |  | #include "buff.h"
 | 
					
						
							|  |  |  | #include "bytearray.h"
 | 
					
						
							|  |  |  | #include "debug.h"
 | 
					
						
							|  |  |  | #include "crc.h"
 | 
					
						
							|  |  |  | #include "dev_flash.h"
 | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | #include "mymisc.h"
 | 
					
						
							|  |  |  | #include "elec_det.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  | #include "commend.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 接收buff大小
 | 
					
						
							|  |  |  | #define RECV_BUFF_SIZE  300
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-11 18:10:06 +08:00
										 |  |  | // 最大接收信号个数
 | 
					
						
							|  |  |  | #define RECV_SEM_MAX_NUM  10
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-11 18:10:06 +08:00
										 |  |  | // 接收数据超时时间
 | 
					
						
							|  |  |  | #define RECV_EXPIRE_TIME 100
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void recv_irq(void *t,uint8_t d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   p->buff[p->buff_index]=d; | 
					
						
							|  |  |  |   p->buff_index++; | 
					
						
							|  |  |  |   switch(p->buff_index){ | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |       if(p->buff[0]==0x59&&p->buff[1]==0x6d) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         p->is_big_data=0; | 
					
						
							|  |  |  |         p->num_to_recv=4; | 
					
						
							|  |  |  |       }else{ | 
					
						
							|  |  |  |         p->buff[0]=p->buff[1]; | 
					
						
							|  |  |  |         p->num_to_recv=0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         int len=p->buff[2]|(p->buff[3]<<8); | 
					
						
							|  |  |  |         if(len<65535){ | 
					
						
							|  |  |  |           p->is_big_data=0; | 
					
						
							|  |  |  |           p->num_to_recv+=len+2; | 
					
						
							|  |  |  |         }else{ | 
					
						
							|  |  |  |           p->is_big_data=1; | 
					
						
							|  |  |  |           p->num_to_recv=11; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 11: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         if(p->is_big_data==1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           int len=p->buff[7]|(p->buff[8]<<8)|(p->buff[9]<<16)|(p->buff[10]<<24); | 
					
						
							|  |  |  |           p->num_to_recv=4+len+2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // 此时一帧数据已完成
 | 
					
						
							|  |  |  |   if(p->num_to_recv>0&&p->num_to_recv==p->buff_index) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     //DBG_LOG("recv:%s",str_temp(arr_string(p->buff)));
 | 
					
						
							|  |  |  |     rt_sem_release(p->sem); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void recv_end_irq(void *t,uint32_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   p->num_to_recv=len; | 
					
						
							|  |  |  |   p->buff_index=len; | 
					
						
							| 
									
										
										
										
											2023-10-11 18:10:06 +08:00
										 |  |  |   p->sem_num++; | 
					
						
							|  |  |  |   if(p->sem_num<RECV_SEM_MAX_NUM){ | 
					
						
							|  |  |  |     rt_sem_release(p->sem); | 
					
						
							|  |  |  |     p->recv_tick=rt_tick_get(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | array_def *protu_decode_str(protu_def *p,array_def *data); | 
					
						
							|  |  |  | array_def *protu_encode_str(protu_def *p,array_def *data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 查找指定解码器
 | 
					
						
							|  |  |  | codec_item *protu_find_codec(const char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   extern const int codecstruct$$Base; | 
					
						
							|  |  |  |   extern const int codecstruct$$Limit; | 
					
						
							|  |  |  |   codec_item *start=(codec_item *)&codecstruct$$Base; | 
					
						
							|  |  |  |   codec_item *end=(codec_item *)&codecstruct$$Limit; | 
					
						
							|  |  |  |   for(codec_item *t=start;t<end;t++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(strcmp(t->name,name)==0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return t; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | // 返回正在使用的解码器
 | 
					
						
							|  |  |  | codec_item *protu_codec_inuse(protu_def *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return p->codec; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void protu_codec_set(protu_def *p,codec_item *c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   p->codec=c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 尝试解码
 | 
					
						
							|  |  |  | static array_def *protu_try_decode(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *decode_data=0; | 
					
						
							|  |  |  |   if(p->codec==0||p->codec->decode==protu_decode_str|| | 
					
						
							|  |  |  |     (decode_data=p->codec->decode(p,data),strcmp(p->str_err,"ok")!=0)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     CHECK_DO(decode_data,arr_delete); | 
					
						
							| 
									
										
										
										
											2023-11-01 23:51:19 +08:00
										 |  |  | #if defined (__CC_ARM)  
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     extern const int codecstruct$$Base; | 
					
						
							|  |  |  |     extern const int codecstruct$$Limit; | 
					
						
							|  |  |  |     codec_item *start=(codec_item *)&codecstruct$$Base; | 
					
						
							|  |  |  |     codec_item *end=(codec_item *)&codecstruct$$Limit; | 
					
						
							| 
									
										
										
										
											2023-11-02 18:25:12 +08:00
										 |  |  | #elif defined (__GNUC__)
 | 
					
						
							| 
									
										
										
										
											2023-11-01 23:51:19 +08:00
										 |  |  |     extern const int __start_codecstruct; | 
					
						
							|  |  |  |     extern const int __stop_codecstruct; | 
					
						
							|  |  |  |     codec_item *start=(codec_item *)&__start_codecstruct; | 
					
						
							|  |  |  |     codec_item *end=(codec_item *)&__stop_codecstruct; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     for(codec_item *t=start;t<end;t++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       decode_data=t->decode(p,data); | 
					
						
							|  |  |  |       if(strcmp(p->str_err,"ok")==0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         p->codec=t; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else{ | 
					
						
							|  |  |  |         arr_delete(decode_data); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(decode_data==0) | 
					
						
							|  |  |  |     decode_data=arr_creat(); | 
					
						
							|  |  |  |   return decode_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void protu_run(void *t) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   protu_def *p=t; | 
					
						
							|  |  |  |   array_def *data; | 
					
						
							|  |  |  |   array_def *decode_data; | 
					
						
							| 
									
										
										
										
											2023-10-11 18:10:06 +08:00
										 |  |  |   uint32_t tick_now; | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   while(p->run) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     rt_sem_take(p->sem,RT_WAITING_FOREVER); | 
					
						
							| 
									
										
										
										
											2023-10-11 18:10:06 +08:00
										 |  |  |     p->sem_num=0; | 
					
						
							|  |  |  |     if(p->buff_index==0){ | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     tick_now=rt_tick_get(); | 
					
						
							|  |  |  |     if(tick_now-p->recv_tick>RECV_EXPIRE_TIME){ | 
					
						
							|  |  |  |       DBG_LOG("recv data expired."); | 
					
						
							|  |  |  |       p->num_to_recv=0; | 
					
						
							|  |  |  |       p->buff_index=0; | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     //DBG_LOG("protu run");
 | 
					
						
							|  |  |  |     data=arr_creat(); | 
					
						
							|  |  |  |     arr_appends(data,p->buff,p->buff_index); | 
					
						
							|  |  |  |     p->num_to_recv=0; | 
					
						
							|  |  |  |     p->buff_index=0; | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |     //DBG_LOG("recv:%s",str_temp(arr_string(data)));
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     decode_data=protu_try_decode(p,data); | 
					
						
							|  |  |  |     //DBG_LOG("decode:%s",str_temp(arr_string(decode_data)));
 | 
					
						
							|  |  |  |     if(p->codec) | 
					
						
							|  |  |  |       emit protu_recv_signal(p,p->codec->name, p->cmd,arr_temp(decode_data),str_temp(str_duplicate(p->str_err))); | 
					
						
							|  |  |  |     arr_delete(data); | 
					
						
							|  |  |  |     irq_disable(); | 
					
						
							|  |  |  |     p->num_to_recv=0; | 
					
						
							|  |  |  |     irq_enable(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 根据设备类型初始化编解码指针
 | 
					
						
							|  |  |  | static void protu_set_endecode_fun(protu_def *u) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const sys_param_def *par=sys_param(); | 
					
						
							|  |  |  |   if(strcmp(par->device_type,"coder")==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if(strcmp(par->device_type,"checker")==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int protu_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const sys_param_def *par=sys_param(); | 
					
						
							| 
									
										
										
										
											2023-10-07 18:15:52 +08:00
										 |  |  |   const char *name="host"; | 
					
						
							| 
									
										
										
										
											2023-06-16 18:07:44 +08:00
										 |  |  |   protu_def *protu=protu_creat(dev_get(name)); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   app_variable("protu",protu,0); | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |   // 复制一个引用,用于命令行调试
 | 
					
						
							|  |  |  |   app_variable("protu2",protu,0); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | app_init_export(protu_init) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protu_def *protu_creat(uart_def *uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static uint16_t count=0; | 
					
						
							|  |  |  |   char name[20]={0}; | 
					
						
							|  |  |  |   protu_def *p=calloc(1,sizeof(protu_def)); | 
					
						
							|  |  |  |   param_check(p); | 
					
						
							|  |  |  |   p->uart=uart; | 
					
						
							|  |  |  |   sprintf(name,"protu_sem#%d",count); | 
					
						
							|  |  |  |   p->sem=rt_sem_create(name,0,RT_IPC_FLAG_FIFO); | 
					
						
							|  |  |  |   p->buff=malloc(RECV_BUFF_SIZE); | 
					
						
							|  |  |  |   p->run=1; | 
					
						
							|  |  |  |   p->cmd=0xff;// 命令字不可能是0xff
 | 
					
						
							|  |  |  |   protu_set_endecode_fun(p); | 
					
						
							|  |  |  |   sprintf(name,"protu_t#%d",count); | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  |   rt_thread_t rt_t=rt_thread_create(name,protu_run,p,1024,6,20); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   rt_thread_startup(rt_t); | 
					
						
							| 
									
										
										
										
											2023-06-14 22:15:00 +08:00
										 |  |  |   int bsp=sys_param()->uartbsp; | 
					
						
							|  |  |  |   if(bsp==9600) | 
					
						
							|  |  |  |     p->uart->init(p->uart,9600); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     p->uart->init(p->uart,0); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   //p->uart->set_irq(p->uart,recv_irq,p);
 | 
					
						
							|  |  |  |   p->uart->set_end_irq(p->uart,p->buff,RECV_BUFF_SIZE,recv_end_irq,p); | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  |   p->timer=dev_get("timer"); | 
					
						
							|  |  |  |   p->timer->init(p->timer); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   count++; | 
					
						
							|  |  |  |   return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  | int protu_send(protu_def *p,array_def *data,int timeout_ms) | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:27:06 +08:00
										 |  |  |   //DBG_LOG("send:%s",str_temp(arr_string(data)));
 | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  |   return p->uart->write(p->uart,arr_data(data),arr_length(data),timeout_ms); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct{ | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |   protu_def *p; | 
					
						
							|  |  |  |   array_def *t; | 
					
						
							|  |  |  |   int wnd_tick;// 窗口时间
 | 
					
						
							|  |  |  |   int gap;// 发送循环时间
 | 
					
						
							|  |  |  |   int send_failed_times;// 失败次数
 | 
					
						
							|  |  |  |   uint32_t send_tick_ms;// 发送时的定时器值
 | 
					
						
							|  |  |  |   uint32_t send_end_tick_ms;// 发送时的定时器值
 | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | }send_pkt_def; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void protu_send_later(void *ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   send_pkt_def *s=ptr; | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  |   protu_send(s->p,s->t,1000); | 
					
						
							|  |  |  |   // arr_delete(s->t);
 | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static send_pkt_def g_send_pkt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 在指定时间间隙中发送
 | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  | // 返回0失败
 | 
					
						
							|  |  |  | static int protu_send_ontime(protu_def *p,send_pkt_def *s) | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   uint32_t tick=p->timer->read(p->timer); | 
					
						
							| 
									
										
										
										
											2023-12-07 22:56:07 +08:00
										 |  |  |   // 根据返回的数据长度计算发送需要的时间,添加1ms的余量
 | 
					
						
							|  |  |  |   // 根据协议,每个指令从机的返回数据长度等长,所以需要的时间窗口也相等
 | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  |   // 253字节需要23ms
 | 
					
						
							|  |  |  |   // 每ms传输的字节数为253/23=11,
 | 
					
						
							|  |  |  |   // 考虑can总线自动重传保留1/3的余量
 | 
					
						
							|  |  |  |   int wnd_tick=((arr_length(s->t)+4)/5+2); | 
					
						
							| 
									
										
										
										
											2023-12-07 22:56:07 +08:00
										 |  |  |   int delay=tick%(wnd_tick*(p->num)); | 
					
						
							|  |  |  |   int gap=p->rank*wnd_tick; | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |   int ret=0; | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  |   if(delay<=gap){ | 
					
						
							|  |  |  |     delay=gap-delay; | 
					
						
							|  |  |  |   }else{ | 
					
						
							| 
									
										
										
										
											2023-12-07 22:56:07 +08:00
										 |  |  |     delay=gap+(wnd_tick*(p->num))-delay; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(p->silent!=0){ | 
					
						
							|  |  |  |     // 广播命令在指定时间窗口发送
 | 
					
						
							| 
									
										
										
										
											2023-12-22 19:05:19 +08:00
										 |  |  |     //later_execute(protu_send_later,s,delay);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |     g_send_pkt.wnd_tick=wnd_tick; | 
					
						
							|  |  |  |     g_send_pkt.gap=gap; | 
					
						
							| 
									
										
										
										
											2023-12-22 19:05:19 +08:00
										 |  |  |     while(p->timer->read(p->timer)<(tick+delay)); | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  |     // protu_send_later(s);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |     g_send_pkt.send_tick_ms=p->timer->read(p->timer); | 
					
						
							|  |  |  |     ret= protu_send(s->p,s->t,wnd_tick-1); | 
					
						
							|  |  |  |     g_send_pkt.send_end_tick_ms=p->timer->read(p->timer); | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2023-12-07 22:56:07 +08:00
										 |  |  |   }else{ | 
					
						
							|  |  |  |     // 单播命令直接发送
 | 
					
						
							|  |  |  |     protu_send_later(s); | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  |     return arr_length(s->t); | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  | static int protu_send_ontime_loop(protu_def *p,send_pkt_def *s,int retry) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // g_send_failed_times=0;
 | 
					
						
							|  |  |  |   for(int i=0;i<retry;i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(protu_send_ontime(p,s)!=0){ | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     }else{ | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |       g_send_pkt.send_failed_times++; | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   arr_delete(s->t); | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static int send_failed(list_def *argv) | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  |   cmd_print("send failed times=%d",g_send_pkt.send_failed_times); | 
					
						
							|  |  |  |   cmd_print("send_start_tick_ms=%d",g_send_pkt.send_tick_ms); | 
					
						
							|  |  |  |   cmd_print("send_end_tick_ms=%d",g_send_pkt.send_end_tick_ms); | 
					
						
							|  |  |  |   cmd_print("send_wnd_tick_ms=%d",g_send_pkt.wnd_tick); | 
					
						
							|  |  |  |   cmd_print("send_gap_ms=%d",g_send_pkt.gap); | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-13 11:52:04 +08:00
										 |  |  | commend_export(send_failed,send_failed,"print send_pkt info") | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 09:54:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | // 槽函数,回复上位机
 | 
					
						
							|  |  |  | void protu_reply_call(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   param_check(p); | 
					
						
							|  |  |  |   array_def *t=0; | 
					
						
							|  |  |  |   if(p->codec) | 
					
						
							|  |  |  |     t=p->codec->encode(p,data); | 
					
						
							|  |  |  |   // DBG_LOG("send encode:%s",arr_string(t));
 | 
					
						
							|  |  |  |   if(t){ | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  |     g_send_pkt.p=p; | 
					
						
							|  |  |  |     g_send_pkt.t=t; | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  |     protu_send_ontime_loop(p,&g_send_pkt,3); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | // 槽函数,主动上发
 | 
					
						
							|  |  |  | void protu_send_call(protu_def *p,uint8_t cmd,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *t=0; | 
					
						
							|  |  |  |   if(cmd!=0){ | 
					
						
							|  |  |  |     p->cmd=cmd; | 
					
						
							|  |  |  |     if(p->codec) | 
					
						
							|  |  |  |       t=p->codec->encode(p,data); | 
					
						
							|  |  |  |   }else if(p->cmd==0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // 命令字为0是字符串
 | 
					
						
							|  |  |  |     t=protu_encode_str(p,data); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if(t){ | 
					
						
							| 
									
										
										
										
											2023-12-05 18:39:30 +08:00
										 |  |  |     g_send_pkt.p=p; | 
					
						
							|  |  |  |     g_send_pkt.t=t; | 
					
						
							| 
									
										
										
										
											2024-01-08 18:04:05 +08:00
										 |  |  |     protu_send_ontime_loop(p,&g_send_pkt,3); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 字符串解码
 | 
					
						
							|  |  |  | array_def *protu_decode_str(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *r=arr_creat(); | 
					
						
							|  |  |  |   param_check(r); | 
					
						
							|  |  |  |   DBG_LOG("decode for command"); | 
					
						
							|  |  |  |   str_set(p->str_err,"ok"); | 
					
						
							|  |  |  |   p->cmd=0; | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |   if(str_is_print_str((const char *)arr_data(data),arr_length(data))==1) | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2023-11-15 18:11:39 +08:00
										 |  |  |     p->silent=0; | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |     arr_append(data,0); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |     arr_appends_from(r,data); | 
					
						
							|  |  |  |   }else{ | 
					
						
							|  |  |  |     DBG_WARN("data not a string"); | 
					
						
							|  |  |  |     str_set(p->str_err,"not string"); | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  |     //arr_remove(data,arr_length(data)-1,1);
 | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return r; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 字符串编码
 | 
					
						
							|  |  |  | array_def *protu_encode_str(protu_def *p,array_def *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   array_def *t=arr_creat(); | 
					
						
							|  |  |  |   param_check(t); | 
					
						
							|  |  |  |   arr_appends_from(t,data); | 
					
						
							|  |  |  |   return t; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 18:05:04 +08:00
										 |  |  | protuc_codec_export(string,protu_decode_str,protu_encode_str); | 
					
						
							| 
									
										
										
										
											2023-06-10 11:52:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |