ARPCPrint.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * void ARPCPrint (FILE * fp, void const * memory, size_t extent);
  11. *
  12. * mme.h
  13. *
  14. * print formatted VS_ARPC payload on the specified output stream;
  15. * this implementation is generic; memory is the start address of
  16. * the message data (&RDATA [RDATAOFFSET]) and extent is the data
  17. * length (RDATALENGTH); the call might look like this ...
  18. *
  19. * ARPCPrint (fp, &ARPC->RDATA [ARPC->RDATAOFFSET], LE16TOH (ARPC->RDATALENGTH) - ARPC->RDATAOFFSET);
  20. *
  21. * ... where LE16TOH () performs 16-bit host endian conversion;
  22. *
  23. * Contributor(s):
  24. * Charles Maier <cmaier@qca.qualcomm.com>
  25. * Nathaniel Houghton <nhoughto@qca.qualcomm.com>
  26. * Florian Fainelli <f.fainelli@gmail.com>
  27. *
  28. *--------------------------------------------------------------------*/
  29. #ifndef ARPCPRINT_SOURCE
  30. #define ARPCPRINT_SOURCE
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <stdint.h>
  35. #include <sys/time.h>
  36. #include "../tools/types.h"
  37. #include "../tools/endian.h"
  38. #include "../tools/memory.h"
  39. #include "../mme/mme.h"
  40. #if defined (WIN32)
  41. #define TIMEVALUE "%012ld.%06ld"
  42. #elif defined (__APPLE__)
  43. #define TIMEVALUE "%012lu.%06u"
  44. #elif defined (__linux__)
  45. #define TIMEVALUE "%012ld.%06ld"
  46. #elif defined (__OpenBSD__)
  47. #define TIMEVALUE "%012ld.%06ld"
  48. #else
  49. #error "Unknown environment"
  50. #endif
  51. //#define ENABLE_DEBUGPRINT
  52. void PrintArpcMessage (FILE * fp, const char * apFormat, const uint32_t * apArgumentList, uint32_t aArgumentCount)
  53. {
  54. char MessageBuffer [2049];
  55. uint32_t MsgIndex;
  56. char GPBuffer [128];
  57. uint32_t Len;
  58. uint32_t Index;
  59. MsgIndex = 0;
  60. memset (MessageBuffer, 0, sizeof (MessageBuffer));
  61. Len = strlen (apFormat);
  62. Index = 0;
  63. while (apFormat [Index] && Len > 0)
  64. {
  65. if (apFormat [Index] != '%')
  66. {
  67. MessageBuffer [MsgIndex] = apFormat [Index];
  68. MsgIndex++;
  69. Index++;
  70. Len--;
  71. }
  72. else if (apFormat [Index + 1] == '%')
  73. {
  74. MessageBuffer [MsgIndex] = apFormat [Index];
  75. MsgIndex++;
  76. Index += 2;
  77. Len -= 2;
  78. }
  79. else if (apFormat [Index + 1] == '\0')
  80. {
  81. MessageBuffer [MsgIndex] = apFormat [Index];
  82. MsgIndex++;
  83. Index += 2;
  84. Len -= 2;
  85. }
  86. else
  87. {
  88. uint32_t iArg = 0;
  89. char const * pArg = & apFormat [Index];
  90. while (pArg && * pArg)
  91. {
  92. switch (* pArg)
  93. {
  94. case 'c':
  95. case 'C':
  96. {
  97. GPBuffer [iArg] = 'c';
  98. GPBuffer [iArg + 1] = '\0';
  99. pArg = NULL;
  100. snprintf (& MessageBuffer [MsgIndex], sizeof (MessageBuffer) - (MsgIndex -1), GPBuffer, * apArgumentList);
  101. MsgIndex++;
  102. apArgumentList++;
  103. Index++;
  104. }
  105. break;
  106. case 'd':
  107. case 'D':
  108. {
  109. char Buf [24];
  110. GPBuffer [iArg] = 'd';
  111. GPBuffer [iArg + 1] = '\0';
  112. pArg = NULL;
  113. (void) snprintf (Buf, sizeof (Buf) -1, GPBuffer, * apArgumentList);
  114. strncat (& MessageBuffer [MsgIndex], Buf, sizeof (MessageBuffer) - (MsgIndex -1));
  115. (void) snprintf (& MessageBuffer [MsgIndex], sizeof (MessageBuffer) - (MsgIndex -1), "%s", Buf);
  116. MsgIndex += strlen (Buf);
  117. apArgumentList++;
  118. Index++;
  119. }
  120. break;
  121. case 'x':
  122. case 'X':
  123. {
  124. char Buf [24];
  125. GPBuffer [iArg] = 'x';
  126. GPBuffer [iArg + 1] = '\0';
  127. pArg = NULL;
  128. (void) snprintf (Buf, sizeof (Buf) -1, GPBuffer, * apArgumentList);
  129. strncat (& MessageBuffer [MsgIndex], Buf, sizeof (MessageBuffer) - (MsgIndex -1));
  130. (void) snprintf (& MessageBuffer [MsgIndex], sizeof (MessageBuffer) - (MsgIndex -1), "%s", Buf);
  131. MsgIndex += strlen (Buf);
  132. apArgumentList++;
  133. Index++;
  134. }
  135. break;
  136. default:
  137. GPBuffer [iArg] = * pArg;
  138. iArg++;
  139. pArg++;
  140. Index++;
  141. // pArg = &apFormat[Index];
  142. }
  143. }
  144. //MessageBuffer[MsgIndex] = apFormat[Index];
  145. //MsgIndex++;
  146. //Index++;
  147. //Len--;
  148. }
  149. }
  150. fprintf (fp, "%s", (char const *) (MessageBuffer));
  151. }
  152. void ARPCPrint (FILE * fp, void const * memory, size_t extent)
  153. {
  154. #ifndef __GNUC__
  155. #pragma pack (push,1)
  156. #endif
  157. struct __packed vs_arpc_data
  158. {
  159. uint32_t BYPASS;
  160. uint16_t ARPCID;
  161. uint16_t DATALENGTH;
  162. uint8_t DATAOFFSET;
  163. uint8_t RESERVED;
  164. uint16_t ARPCSEQNUM;
  165. }
  166. * data = (struct vs_arpc_data *) (memory);
  167. struct __packed vs_arpc_print_data
  168. {
  169. uint16_t ARGOFFSET;
  170. uint16_t STROFFSET;
  171. uint16_t ARGLENGTH;
  172. uint16_t STRLENGTH;
  173. }
  174. * vpArpcPrintData;
  175. typedef uint32_t uint32_packed_t;
  176. uint32_packed_t * vpWordPointer;
  177. uint16_t vOffsetInBytesOfArgumentList;
  178. uint16_t vLengthInBytesOfArgumentList;
  179. uint16_t vOffsetInBytesOfFormatString;
  180. #ifdef ENABLE_DEBUGPRINT
  181. uint16_t vLengthInBytesOfFormatString;
  182. #endif
  183. uint16_t argc;
  184. #ifndef __GNUC__
  185. #pragma pack (pop)
  186. #endif
  187. #ifdef ENABLE_DEBUGPRINT
  188. fprintf (fp, "BYPASS=%d ", LE32TOH (data->BYPASS));
  189. fprintf (fp, "ARPCID=%d ", LE16TOH (data->ARPCID));
  190. fprintf (fp, "DATALENGTH=%d ", LE16TOH (data->DATALENGTH));
  191. fprintf (fp, "DATAOFFSET=%d ", data->DATAOFFSET);
  192. fprintf (fp, "ARPCSEQNUM=%d ", LE16TOH (data->ARPCSEQNUM));
  193. #endif
  194. char * vpBytePointer = (char *) data;
  195. vpBytePointer += sizeof (struct vs_arpc_data);
  196. vpBytePointer += data->DATAOFFSET;
  197. vpArpcPrintData = (struct vs_arpc_print_data *) vpBytePointer;
  198. #ifdef ENABLE_DEBUGPRINT
  199. fprintf (fp, "vpArpcPrintData=%.8x ", (uint32_t) vpArpcPrintData);
  200. #endif
  201. vOffsetInBytesOfArgumentList = LE16TOH (vpArpcPrintData->ARGOFFSET);
  202. vOffsetInBytesOfFormatString = LE16TOH (vpArpcPrintData->STROFFSET);
  203. vLengthInBytesOfArgumentList = LE16TOH (vpArpcPrintData->ARGLENGTH);
  204. argc = (vLengthInBytesOfArgumentList >> 2);
  205. #ifdef ENABLE_DEBUGPRINT
  206. vLengthInBytesOfFormatString = LE16TOH (vpArpcPrintData->STRLENGTH);
  207. fprintf (fp, "ARGOFFSET=%d ", vOffsetInBytesOfArgumentList);
  208. fprintf (fp, "STROFFSET=%d ", vOffsetInBytesOfFormatString);
  209. fprintf (fp, "ARGLENGTH=%d ", vLengthInBytesOfArgumentList);
  210. fprintf (fp, "STRLENGTH=%d ", vLengthInBytesOfFormatString);
  211. #endif
  212. vpBytePointer = (char *) vpArpcPrintData;
  213. vpBytePointer += sizeof (struct vs_arpc_print_data);
  214. vpBytePointer += vOffsetInBytesOfArgumentList;
  215. vpWordPointer = (uint32_packed_t *) vpBytePointer;
  216. #ifdef ENABLE_DEBUGPRINT
  217. fprintf (fp, "vpWordPointer=%.8x ", (uint32_t) vpWordPointer);
  218. #endif
  219. vpBytePointer = (char *) vpArpcPrintData;
  220. vpBytePointer += sizeof (struct vs_arpc_print_data);
  221. vpBytePointer += vOffsetInBytesOfFormatString;
  222. #ifdef ENABLE_DEBUGPRINT
  223. fprintf (fp, "vpBytePointer=%.8x %d\n", (uint32_t) vpBytePointer, vpBytePointer [vLengthInBytesOfFormatString]);
  224. #endif
  225. if (argc == 0)
  226. {
  227. fprintf (fp, "%s", (char const *) (vpBytePointer));
  228. }
  229. else
  230. {
  231. uint32_t * argp = (uint32_t *) malloc (sizeof (uint32_t) * argc);
  232. if (argp == 0)
  233. {
  234. fprintf (fp, "ARPCPrint out of memory ");
  235. }
  236. else
  237. {
  238. uint16_t i;
  239. for (i = 0; i < argc; i++)
  240. {
  241. argp [i] = LE32TOH (* vpWordPointer);
  242. vpWordPointer++;
  243. #ifdef ENABLE_DEBUGPRINT
  244. fprintf (fp, "argp[i]=%.8x i=%d vpWordPointer=%.8x\n", argp [i], i, (uint32_t) vpWordPointer);
  245. #endif
  246. }
  247. #ifdef ENABLE_DEBUGPRINT
  248. fprintf (fp, "argument copy returns\n");
  249. #endif
  250. //there is no easy way to construct va_list across different platform
  251. PrintArpcMessage (fp, vpBytePointer, argp, argc);
  252. #ifdef ENABLE_DEBUGPRINT
  253. fprintf (fp, "vfprintf returns\n");
  254. #endif
  255. }
  256. }
  257. fprintf (fp, "\n");
  258. fflush (fp);
  259. return;
  260. }
  261. #endif