main.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * Copyright (c) 2019 - 2024 Stefan Strobel <stefan.strobel@shimatta.net>
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. /**
  9. * @file main.c
  10. * @brief main module to demonstrate use of the shellmatta.
  11. * @author Stefan Strobel <stefan.strobel@shimatta.net>
  12. */
  13. #include "shellmatta.h"
  14. #include <stdint.h>
  15. #include <stdio.h>
  16. #include <stdbool.h>
  17. #include <fcntl.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. static bool exitRequest = false;
  22. int f;
  23. shellmatta_handle_t handle;
  24. static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  25. {
  26. shellmatta_printf(handle, "%s - length: %u", arguments, length);
  27. return SHELLMATTA_OK;
  28. }
  29. shellmatta_cmd_t doSomethingCmd = {"doSomething", "do", "Function does something", "use me, please", doSomething, NULL, NULL};
  30. static shellmatta_retCode_t doSome(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  31. {
  32. shellmatta_write(handle, "blubb\r\n", 7u);
  33. shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, false, '\r');
  34. (void)arguments;
  35. (void)length;
  36. return SHELLMATTA_OK;
  37. }
  38. shellmatta_cmd_t doSomeCmd = {"adoSome2", "adof2", "Function does something", "use me, please", doSome, NULL, NULL};
  39. static shellmatta_retCode_t removeCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  40. {
  41. shellmatta_printf(handle, "removing command: %s\r\n", doSomeCmd.cmd);
  42. shellmatta_removeCmd(handle, &doSomeCmd);
  43. (void)arguments;
  44. (void)length;
  45. return SHELLMATTA_OK;
  46. }
  47. shellmatta_cmd_t removeCommand = {"remove", "r", "Function removes a command", "", removeCmdFct, NULL, NULL};
  48. static shellmatta_retCode_t quit(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  49. {
  50. exitRequest = true;
  51. (void)handle;
  52. (void)arguments;
  53. (void)length;
  54. return SHELLMATTA_OK;
  55. }
  56. shellmatta_cmd_t quitCommand = {"quit", "q", "Function quits the shell", "", quit, NULL, NULL};
  57. static shellmatta_retCode_t empty(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  58. {
  59. (void)arguments;
  60. (void)length;
  61. shellmatta_printf(handle, "empty function called\r\n");
  62. shellmatta_configure(handle, SHELLMATTA_MODE_OVERWRITE, true, '\r');
  63. return SHELLMATTA_OK;
  64. }
  65. shellmatta_cmd_t emptyCommand = {"empty", NULL, NULL, NULL, empty, NULL, NULL};
  66. static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  67. {
  68. shellmatta_retCode_t ret;
  69. (void)arguments;
  70. (void)length;
  71. char option;
  72. char *argument;
  73. uint32_t argLen;
  74. bool printPrompt = false;
  75. static const shellmatta_opt_long_t options[] =
  76. {
  77. {"prompt", 'p', SHELLMATTA_OPT_ARG_REQUIRED},
  78. {NULL, '\0', SHELLMATTA_OPT_ARG_NONE}
  79. };
  80. ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
  81. while(SHELLMATTA_OK == ret)
  82. {
  83. switch(option)
  84. {
  85. case 'p':
  86. if(NULL != argument)
  87. {
  88. if(0 == strncmp("true", argument, 4u))
  89. {
  90. printPrompt = true;
  91. }
  92. }
  93. break;
  94. default:
  95. shellmatta_printf(handle, "Unknown option: %c\r\n", option);
  96. break;
  97. }
  98. ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
  99. }
  100. shellmatta_resetShell(handle, printPrompt);
  101. shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, true, '\r');
  102. return SHELLMATTA_OK;
  103. }
  104. shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [--prompt true/false]", reset, NULL, NULL};
  105. static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  106. {
  107. (void)arguments;
  108. (void)length;
  109. shellmatta_retCode_t ret = SHELLMATTA_CONTINUE;
  110. uint32_t stdinLength;
  111. char *stdinData;
  112. shellmatta_read(handle, &stdinData, &stdinLength);
  113. if(NULL != stdinData)
  114. {
  115. if('x' == stdinData[0u])
  116. {
  117. ret = SHELLMATTA_OK;
  118. }
  119. stdinData[0u] ++;
  120. shellmatta_write(handle, stdinData, stdinLength);
  121. }
  122. return ret;
  123. }
  124. shellmatta_cmd_t continuousCommand = {"continuous", "cont", "prints continously all input bytes", "continuous", continuous, NULL, NULL};
  125. static shellmatta_retCode_t busy(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  126. {
  127. (void)arguments;
  128. (void)length;
  129. static uint32_t callCnt = 0u;
  130. shellmatta_retCode_t ret = SHELLMATTA_BUSY;
  131. if(callCnt < 10u)
  132. {
  133. callCnt ++;
  134. shellmatta_printf(handle, "%s - length %u - callCnt %u\r\n", arguments, length, callCnt);
  135. }
  136. else
  137. {
  138. callCnt = 0u;
  139. ret = SHELLMATTA_OK;
  140. }
  141. return ret;
  142. }
  143. shellmatta_cmd_t busyCommand = {"busy", NULL, NULL, NULL, busy, NULL, NULL};
  144. shellmatta_retCode_t ret = SHELLMATTA_OK;
  145. void ymodemCallbackCancel() {
  146. return;
  147. }
  148. void ymodemCallbackReceivePacket() {
  149. return;
  150. }
  151. void ymodemCallbackTransmissionComplete() {
  152. ret = SHELLMATTA_OK;
  153. return;
  154. }
  155. uint8_t ymodemBuffer[1024u] = {0};
  156. uint32_t ymodemFileSize = 0;
  157. uint16_t ymodemPacketSize = 0;
  158. shellmatta_ymodem_callbacks_t ymodemCallbacks = {
  159. ymodemCallbackCancel,
  160. ymodemCallbackReceivePacket,
  161. ymodemCallbackTransmissionComplete
  162. };
  163. static shellmatta_retCode_t ymodem(shellmatta_handle_t handle, const char *arguments, uint32_t length)
  164. {
  165. (void)arguments;
  166. (void)length;
  167. shellmatta_printf(handle, "Starting ymodem session\r\n");
  168. shellmatta_ymodem(handle,
  169. ymodemBuffer,
  170. &ymodemFileSize,
  171. &ymodemPacketSize,
  172. ymodemCallbacks);
  173. return SHELLMATTA_OK;
  174. }
  175. shellmatta_cmd_t ymodemCommand = {"ymodem", NULL, NULL, NULL, ymodem, NULL, NULL};
  176. shellmatta_retCode_t writeFct(const char* data, uint32_t length)
  177. {
  178. write(f, data, length);
  179. return SHELLMATTA_OK;
  180. }
  181. int main(int argc, char **argv)
  182. {
  183. static char buffer[1024];
  184. static char historyBuffer[4096];
  185. static shellmatta_instance_t instance;
  186. if(2 != argc)
  187. {
  188. printf("%s <serial device>\n", argv[0u]);
  189. return -1;
  190. }
  191. f = open(argv[1u], O_RDWR | O_SYNC);
  192. if (f < 0)
  193. {
  194. printf("failure opening device %s %d\n", argv[1u], errno);
  195. return f;
  196. }
  197. shellmatta_doInit( &instance,
  198. &handle,
  199. buffer,
  200. sizeof(buffer),
  201. historyBuffer,
  202. sizeof(historyBuffer),
  203. "shellmatta->",
  204. NULL,
  205. writeFct);
  206. shellmatta_addCmd(handle, &doSomethingCmd);
  207. shellmatta_addCmd(handle, &doSomeCmd);
  208. shellmatta_addCmd(handle, &quitCommand);
  209. shellmatta_addCmd(handle, &removeCommand);
  210. shellmatta_addCmd(handle, &emptyCommand);
  211. shellmatta_addCmd(handle, &resetCommand);
  212. shellmatta_addCmd(handle, &continuousCommand);
  213. shellmatta_addCmd(handle, &busyCommand);
  214. shellmatta_addCmd(handle, &ymodemCommand);
  215. shellmatta_auth_user_t userList[] = {
  216. {1, false, "shimatta", "12345678"},
  217. {2, false, "not_shimatta", "87654321"}
  218. };
  219. uint32_t doSomeCmdPerms[] = {1, 2};
  220. uint32_t removeCommandPerms[] = {1};
  221. shellmatta_auth_perm_t permList[] = {
  222. {"adoSome2", doSomeCmdPerms, sizeof(doSomeCmdPerms)/sizeof(doSomeCmdPerms[0])},
  223. {"remove", removeCommandPerms, sizeof(removeCommandPerms)/sizeof(removeCommandPerms[0])}
  224. };
  225. shellmatta_auth_init(handle, userList, 2, permList, 2, false, NULL, NULL);
  226. int i = 0;
  227. while(exitRequest == false)
  228. {
  229. char c;
  230. shellmatta_retCode_t ret;
  231. int flags = fcntl(f, F_GETFL, 0);
  232. fcntl(f, F_SETFL, flags | O_NONBLOCK);
  233. int res = 0;
  234. res = read (f, &c, 1);
  235. if (res == -1)
  236. {
  237. i = (i + 1) % 10000;
  238. usleep(1);
  239. if (i != 0)
  240. {
  241. continue;
  242. }
  243. }
  244. else
  245. {
  246. fprintf(stdout, "0x%02x \n", c);
  247. fflush(stdout);
  248. }
  249. do
  250. {
  251. res = res > 0 ? res : 0;
  252. ret = shellmatta_processData(handle, &c, res);
  253. if(SHELLMATTA_BUSY == ret)
  254. {
  255. sleep(1);
  256. }
  257. } while(SHELLMATTA_BUSY == ret);
  258. }
  259. close(f);
  260. return 0;
  261. }