luat_cmux.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /**
  2. LuatOS cmux
  3. */
  4. #include "lua.h"
  5. #include "luat_base.h"
  6. #include "luat_msgbus.h"
  7. #include "luat_malloc.h"
  8. #define LUAT_LOG_TAG "cmux"
  9. #include "luat_log.h"
  10. #ifdef LUAT_USE_MCU
  11. #include "luat_mcu.h"
  12. #endif
  13. #include "luat_shell.h"
  14. #include "luat_str.h"
  15. #include "luat_cmux.h"
  16. extern uint8_t echo_enable;
  17. extern uint8_t cmux_state;
  18. uint8_t cmux_main_state = 0;
  19. uint8_t cmux_shell_state = 0;
  20. uint8_t cmux_log_state = 0;
  21. uint8_t cmux_dbg_state = 0;
  22. const uint8_t cmux_crctable[256] = {
  23. 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75,
  24. 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
  25. 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69,
  26. 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
  27. 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D,
  28. 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
  29. 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51,
  30. 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
  31. 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05,
  32. 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
  33. 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19,
  34. 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
  35. 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D,
  36. 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
  37. 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21,
  38. 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
  39. 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95,
  40. 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
  41. 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89,
  42. 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
  43. 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD,
  44. 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
  45. 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1,
  46. 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
  47. 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5,
  48. 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
  49. 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9,
  50. 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
  51. 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD,
  52. 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
  53. 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1,
  54. 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF};
  55. uint8_t cmux_frame_check(const uint8_t *input, int length){
  56. uint8_t fcs = 0xFF;
  57. int i;
  58. for (i = 0; i < length; i++){
  59. fcs = cmux_crctable[fcs ^ input[i]];
  60. }
  61. return (0xFF - fcs);
  62. }
  63. void uih_main_manage(unsigned char*buff,size_t len){
  64. }
  65. void uih_shell_manage(unsigned char*buff,size_t len){
  66. char send_buff[128] = {0};
  67. char *data = (char *)luat_heap_malloc(buff[3]>>1);
  68. memcpy(data, buff+4, buff[3]>>1);
  69. if (echo_enable)
  70. {
  71. sprintf(send_buff, "%s\r\n", data);
  72. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,send_buff, strlen(send_buff));
  73. memset(send_buff, 0, 128);
  74. }
  75. if (memcmp("AT\r", data, 3) == 0){
  76. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  77. }else if (memcmp("ATI", data, 3) == 0){
  78. #ifdef LUAT_BSP_VERSION
  79. sprintf(send_buff, "LuatOS-SoC_%s_%s\r\n", LUAT_BSP_VERSION, luat_os_bsp());
  80. #else
  81. sprintf(send_buff, "LuatOS-SoC_%s_%s\r\n", luat_version_str(), luat_os_bsp());
  82. #endif
  83. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,send_buff, strlen(send_buff));
  84. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  85. }else if (memcmp("AT+LUAFLASHSIZE?", data, 16) == 0){
  86. #ifdef FLASH_FS_REGION_SIZE
  87. sprintf(send_buff, "+LUAFLASHSIZE: 0X%x\r\n",FLASH_FS_REGION_SIZE);
  88. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,send_buff, strlen(send_buff));
  89. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  90. #endif
  91. }else if (memcmp("AT+LUACHECKSUM=", data, 15) == 0){
  92. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"+LUAFLASHSIZE: 0\r\n", 18);
  93. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  94. }else if (memcmp("AT+RESET", data, 8) == 0){
  95. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  96. luat_os_reboot(0);
  97. }else if (memcmp("ATE0\r", data, 5) == 0 || memcmp("ate1\r", data, 5) == 0) {
  98. echo_enable = 0;
  99. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  100. }
  101. // 回显开启
  102. else if (memcmp("ATE1\r", data, 5) == 0 || memcmp("ate1\r", data, 5) == 0) {
  103. echo_enable = 1;
  104. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,"OK\r\n", 4);
  105. }
  106. luat_heap_free(data);
  107. }
  108. void uih_dbg_manage(unsigned char*buff,size_t len){
  109. // char *data = (char *)luat_heap_malloc(len-3);
  110. // memset(data, 0, len-3); // 确保填充为0
  111. // memcpy(data, buff+4, len-4);
  112. char data[128] = {0};
  113. if(cmux_dbg_state == 1)
  114. memcpy(data, buff+4, len-4);
  115. else
  116. memcpy(data, buff, len);
  117. if (strcmp("dbg",strtok(data, " ")) == 0){
  118. char *command = strtok(NULL, " ");
  119. if (memcmp("start", command, 5) == 0){
  120. luat_dbg_set_hook_state(2);
  121. }else if(memcmp("continue",command,8) == 0){
  122. luat_dbg_set_hook_state(2);
  123. }else if(memcmp("next",command,4) == 0 || memcmp("step",command,4) == 0){
  124. luat_dbg_set_hook_state(4);
  125. }else if(memcmp("stepIn",command,6) == 0 || memcmp("stepin",command,6) == 0){
  126. luat_dbg_set_hook_state(5);
  127. }else if(memcmp("stepOut",command,7) == 0 || memcmp("stepout",command,7) == 0){
  128. luat_dbg_set_hook_state(6);
  129. }else if(memcmp("bt",command,2) == 0){
  130. char *params = strtok(NULL, " ");
  131. if (params != NULL){
  132. luat_dbg_set_runcb(luat_dbg_backtrace, (void*)atoi(params));
  133. }else{
  134. luat_dbg_set_runcb(luat_dbg_backtrace, (void*)-1);
  135. }
  136. }else if(memcmp("vars",command,4) == 0){
  137. char *params = strtok(NULL, " ");
  138. if (params != NULL){
  139. luat_dbg_set_runcb(luat_dbg_vars, (void*)atoi(params));
  140. }else{
  141. luat_dbg_set_runcb(luat_dbg_vars, (void*)0);
  142. }
  143. }else if(memcmp("gvars",command,5) == 0){
  144. luat_dbg_gvars((void*)0);
  145. }else if(memcmp("jvars",command,5) == 0){
  146. luat_dbg_jvars(strtok(NULL, " "));
  147. }else if(memcmp("break",command,5) == 0){
  148. char *sub_command = strtok(NULL, " ");
  149. if (memcmp("clr",sub_command,3) == 0){
  150. luat_dbg_breakpoint_clear(strtok(NULL, " "));
  151. }else if (memcmp("add",sub_command,3) == 0){
  152. luat_dbg_breakpoint_add(strtok(NULL, " "),atoi(strtok(NULL, " ")));
  153. }else if (memcmp("del",sub_command,3) == 0){
  154. char *params = strtok(NULL, " ");
  155. if (params != NULL){
  156. luat_dbg_breakpoint_clear(params);
  157. }else{
  158. luat_dbg_breakpoint_clear(NULL);
  159. }
  160. }
  161. }else {
  162. }
  163. }
  164. // luat_heap_free(data);
  165. }
  166. LUAT_WEAK void luat_cmux_log_set(uint8_t state) {
  167. }
  168. void cmux_frame_manage(unsigned char*buff,size_t len){
  169. // for (size_t i = 0; i < 20; i++){
  170. // LLOGD("buff[%d]:%02X",i,buff[i]);
  171. // }
  172. if (CMUX_ADDRESS_DLC(buff)==LUAT_CMUX_CH_MAIN){
  173. if (CMUX_CONTROL_ISSABM(buff)){
  174. cmux_main_state = 1;
  175. luat_cmux_write(LUAT_CMUX_CH_MAIN, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  176. }else if(CMUX_CONTROL_ISDISC(buff)){
  177. cmux_state = 0;
  178. cmux_main_state = 0;
  179. cmux_log_state = 0;
  180. cmux_dbg_state = 0;
  181. luat_cmux_write(LUAT_CMUX_CH_MAIN, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  182. }else if(CMUX_CONTROL_ISUIH(buff) && cmux_main_state == 1){
  183. uih_main_manage(buff,len);
  184. }
  185. }else if (CMUX_ADDRESS_DLC(buff)==LUAT_CMUX_CH_SHELL){
  186. if (CMUX_CONTROL_ISSABM(buff)){
  187. cmux_shell_state = 1;
  188. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  189. }else if(CMUX_CONTROL_ISDISC(buff)){
  190. cmux_shell_state = 0;
  191. luat_cmux_write(LUAT_CMUX_CH_SHELL, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  192. }else if(CMUX_CONTROL_ISUIH(buff) && cmux_shell_state == 1){
  193. uih_shell_manage(buff,len);
  194. }
  195. }else if (CMUX_ADDRESS_DLC(buff)==LUAT_CMUX_CH_LOG){
  196. if (CMUX_CONTROL_ISSABM(buff)){
  197. cmux_log_state = 1;
  198. luat_cmux_log_set(cmux_log_state);
  199. luat_cmux_write(LUAT_CMUX_CH_LOG, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  200. }else if(CMUX_CONTROL_ISDISC(buff)){
  201. cmux_log_state = 0;
  202. luat_cmux_log_set(cmux_log_state);
  203. luat_cmux_write(LUAT_CMUX_CH_LOG, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  204. }
  205. }else if (CMUX_ADDRESS_DLC(buff)==LUAT_CMUX_CH_DBG){
  206. if (CMUX_CONTROL_ISSABM(buff)){
  207. cmux_dbg_state = 1;
  208. luat_cmux_write(LUAT_CMUX_CH_DBG, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  209. }else if(CMUX_CONTROL_ISDISC(buff)){
  210. cmux_dbg_state = 0;
  211. luat_cmux_write(LUAT_CMUX_CH_DBG, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  212. }else if(CMUX_CONTROL_ISUIH(buff) && cmux_dbg_state == 1){
  213. uih_dbg_manage(buff,len);
  214. }
  215. }else if (CMUX_ADDRESS_DLC(buff)==LUAT_CMUX_CH_DOWNLOAD){
  216. if (CMUX_CONTROL_ISSABM(buff)){
  217. luat_cmux_write(LUAT_CMUX_CH_DOWNLOAD, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  218. }else if(CMUX_CONTROL_ISDISC(buff)){
  219. luat_cmux_write(LUAT_CMUX_CH_DOWNLOAD, CMUX_FRAME_UA | CMUX_CONTROL_PF,NULL, 0);
  220. }
  221. }
  222. }
  223. void luat_cmux_write(int port, uint8_t control,char* buff, size_t len) {
  224. char prefix[5] = {CMUX_HEAD_FLAG_BASIC, CMUX_ADDRESS_EA | CMUX_ADDRESS_CR, 0, 0, 0};
  225. char postfix[2] = {0xFF, CMUX_HEAD_FLAG_BASIC};
  226. int prefix_length = 4;
  227. prefix[0] = CMUX_HEAD_FLAG_BASIC;
  228. prefix[1] = prefix[1] | ((CMUX_DHCL_MASK & port) << 2);
  229. prefix[2] = control;
  230. if (len > CMUX_DATA_MASK){
  231. prefix_length = 5;
  232. prefix[3] = ((CMUX_DATA_MASK & len) << 1);
  233. prefix[4] = (CMUX_HIGH_DATA_MASK & len) >> 7;
  234. }else{
  235. prefix[3] = 1 | (len << 1);
  236. }
  237. luat_shell_write(prefix, prefix_length);
  238. postfix[0] = cmux_frame_check((const uint8_t*)(prefix+1), prefix_length - 1);
  239. if (len > 0)luat_shell_write(buff, len);
  240. luat_shell_write(postfix, 2);
  241. }
  242. //0 成功解析 1 解析头 -1 解析错误丢弃
  243. static int luat_cmux_parse(unsigned char* cmux_buff, int* start, int* end, int cmux_buff_offset){
  244. // LLOGD("luat_cmux_parse start %d",*start);
  245. int length_needed = 5; /* channel, type, length, fcs, flag */
  246. if (cmux_buff[*start]==CMUX_HEAD_FLAG_BASIC&&cmux_buff[*start+1]==CMUX_HEAD_FLAG_BASIC){
  247. (*start)++;
  248. }
  249. if(cmux_buff[*start]==CMUX_HEAD_FLAG_BASIC ){
  250. uint8_t len = (cmux_buff[*start+3]& 254) >> 1;
  251. // if ((cmux_buff[*start+3] & 1) == 0){
  252. // INC_BUF_POINTER(buffer,data);
  253. // frame->data_length += (*data*128);
  254. // fcs = cmux_crctable[fcs^*data];
  255. // length_needed++;
  256. // LOG_D("len_need: %d, frame_data_len: %d.", length_needed, frame->data_length);
  257. // }
  258. len += length_needed;
  259. // for (size_t i = 0; i < 15; i++){
  260. // LLOGD("buff[%d]:%02X",i,cmux_buff[i]);
  261. // }
  262. // LLOGD("luat_cmux_parse start %d",*start);
  263. // LLOGD("cmux_buff[*start+len] %02X",cmux_buff[*start+len]);
  264. if(*start+len<cmux_buff_offset){
  265. if(cmux_buff[*start+len]==CMUX_HEAD_FLAG_BASIC && cmux_frame_check(cmux_buff+*start+1,3) == cmux_buff[*start+len-1]){
  266. *end = *start+len;
  267. // LLOGD("luat_cmux_parse OK");
  268. return 0;
  269. }else{
  270. return -1;
  271. }
  272. }
  273. // LLOGD("luat_cmux_parse start %d",*start);
  274. return 1;
  275. }
  276. return -1;
  277. }
  278. static unsigned char cmux_buff[CMUX_BUFFER_SIZE];
  279. static int cmux_buff_offset = 0;
  280. void luat_cmux_read(unsigned char* buff,size_t len){
  281. if (cmux_buff_offset + len >= CMUX_BUFFER_SIZE) {
  282. printf("cmux overflow!!!\r\n");
  283. cmux_buff_offset = 0;
  284. return;
  285. }
  286. memcpy(cmux_buff + cmux_buff_offset, buff, len);
  287. cmux_buff_offset += len;
  288. cmux_buff[cmux_buff_offset] = 0x00;
  289. // int offset = 0;
  290. int start = 0;
  291. int end = 0;
  292. // LLOGD("cmux_buff_offset %d",cmux_buff_offset);
  293. while (start < cmux_buff_offset) {
  294. // 解析
  295. int ret = luat_cmux_parse(cmux_buff, &start, &end, cmux_buff_offset);
  296. // int ret = 0; // 因为没有luat_cmux_parse
  297. // end = cmux_buff_offset;//
  298. if (ret == 0) {
  299. // 读取ok, 是完整的一帧, 让luat_cmux_exec按帧格式进行执行
  300. // 把luat_cmux_read2 当exec用
  301. // luat_cmux_read2(cmux_buff + start, end+1 - start);
  302. // unsigned char* sendcmux_frame_buf = (unsigned char*)luat_heap_malloc(end+1-start-2);
  303. // memmove(sendcmux_frame_buf, cmux_buff + start, end+1-start-2);
  304. // cmux_frame_manage(sendcmux_frame_buf,end+1-start-2);
  305. // luat_heap_free(sendcmux_frame_buf);
  306. cmux_frame_manage(cmux_buff + start,end+1-start-2);
  307. // LLOGD("end %d cmux_buff_offset %d",end,cmux_buff_offset);
  308. if (end+1<cmux_buff_offset){
  309. char* transfer_buff = (char*)luat_heap_malloc(cmux_buff_offset-end);
  310. memmove(transfer_buff, cmux_buff + end, cmux_buff_offset-end);
  311. memset(cmux_buff,0,CMUX_BUFFER_SIZE);
  312. memmove(cmux_buff, transfer_buff, cmux_buff_offset-end);
  313. luat_heap_free(transfer_buff);
  314. return;
  315. }
  316. break;
  317. }
  318. else if (ret == 1) {
  319. // LLOGD("luat_cmux_parse start %d cmux_buff_offset %d",start,cmux_buff_offset);
  320. // // 缺数据
  321. // if (start!=0){
  322. // char* transfer_buff;
  323. // memmove(transfer_buff, cmux_buff + start, cmux_buff_offset-start+1);
  324. // memset(cmux_buff,0,CMUX_BUFFER_SIZE);
  325. // memmove(cmux_buff, transfer_buff, cmux_buff_offset-start+1);
  326. // LLOGD("cmux_buff %02X %02X",cmux_buff[0],cmux_buff[1]);
  327. // cmux_buff_offset = cmux_buff_offset-start+1;
  328. // }
  329. return;
  330. }
  331. else {
  332. //解析错误丢弃
  333. start++;
  334. }
  335. // LLOGD("luat_cmux_read start %d",start);
  336. // 等luat_cmux_read2改完再按情况跳出
  337. // break;
  338. }
  339. memset(cmux_buff,0,CMUX_BUFFER_SIZE);
  340. cmux_buff_offset = 0;
  341. }