This is a mbed 5.2 Release

Dependencies:   USBDevice

Fork of mbed-os-test by Jerry Bradshaw

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RpcServer.cpp Source File

RpcServer.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 #include "RpcServer.h"
00034 #include "StringInOut.h"
00035 #include "StringHelper.h"
00036 #include "MAX30001_RPC.h"
00037 #include "MAX30101_RPC.h"
00038 #include "LIS2DH_RPC.h"
00039 #include "Logging_RPC.h"
00040 #include "Peripherals.h"
00041 #include "I2C_RPC.h"
00042 #include "BMP280_RPC.h"
00043 #include "MAX30205_RPC.h"
00044 #include "HspLed_RPC.h"
00045 #include "S25FS512_RPC.h"
00046 #include "Testing_RPC.h"
00047 #include "MAX14720_RPC.h"
00048 #include "RpcDeclarations.h"
00049 #include "Device_Logging.h"
00050 
00051 /// define the version string that is reported with a RPC "ReadVer" command
00052 #define FW_VERSION_STRING "HSP FW Version 3.0.0 10/14/16"
00053 
00054 char args[32][32];
00055 char results[32][32];
00056 
00057 /// define a fifo for incoming USB data
00058 static fifo_t fifo;
00059 /// define a buffer for incoming USB data
00060 static uint8_t fifoBuffer[128];
00061 /// define stream out fifo
00062 static fifo_t fifoStreamOut;
00063 /// allocate a large fifo buffer for streaming out
00064 static uint32_t streamOutBuffer[0xC000 / 4];
00065 
00066 /// define a device log for the BMP280, keeps track of mission and loggin status
00067 Device_Logging *bmp280_Logging;
00068 /// define a device log for the MAX30205 (instance 0), keeps track of mission
00069 /// and loggin status
00070 Device_Logging *MAX30205_0_Logging;
00071 /// define a device log for the MAX30205 (instance 1), keeps track of mission
00072 /// and loggin status
00073 Device_Logging *MAX30205_1_Logging;
00074 
00075 //******************************************************************************
00076 fifo_t *GetUSBIncomingFifo(void) { return &fifo; }
00077 
00078 //******************************************************************************
00079 fifo_t *GetStreamOutFifo(void) { return &fifoStreamOut; }
00080 
00081 //******************************************************************************
00082 int System_ReadVer(char argStrs[32][32], char replyStrs[32][32]) {
00083   strcpy(replyStrs[0], FW_VERSION_STRING);
00084   strcpy(replyStrs[1], "\0");
00085   return 0;
00086 }
00087 
00088 //******************************************************************************
00089 int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]) {
00090   // strcpy(replyStrs[0],buildTime);
00091   // strcpy(replyStrs[1],"\0");
00092   return 0;
00093 }
00094 
00095 //******************************************************************************
00096 int System_SystemCoreClock(char argStrs[32][32], char replyStrs[32][32]) {
00097   sprintf(replyStrs[0], "SystemCoreClock = %d", SystemCoreClock);
00098   strcpy(replyStrs[1], "\0");
00099   return 0;
00100 }
00101 
00102 //******************************************************************************
00103 int System_GetTimestamp(char argStrs[32][32], char replyStrs[32][32]) {
00104   sprintf(replyStrs[0], "GetTimestamp = %d", 0);
00105   strcpy(replyStrs[1], "\0");
00106   return 0;
00107 }
00108 
00109 static struct RPC_Object RPC_Procedures = {NULL, NULL};
00110 
00111 //******************************************************************************
00112 void RPC_addProcedure(struct RPC_registeredProcedure *procedure) {
00113   struct RPC_Object *obj = &RPC_Procedures;
00114   if (obj->last != NULL) {
00115     obj->last->next = procedure;
00116   }
00117   if (obj->head == NULL) {
00118     obj->head = procedure;
00119   }
00120   procedure->next = NULL;
00121   obj->last = procedure;
00122 }
00123 
00124 //******************************************************************************
00125 void RPC_init(void) {
00126   bmp280_Logging = new Device_Logging();
00127   MAX30205_0_Logging = new Device_Logging();
00128   MAX30205_1_Logging = new Device_Logging();
00129 
00130   fifo_init(&fifo, fifoBuffer, sizeof(fifoBuffer));
00131   fifo_init(&fifoStreamOut, streamOutBuffer,
00132             sizeof(streamOutBuffer) / sizeof(uint32_t));
00133 
00134   // I2c
00135   RPC_addProcedure(&Define_I2c_WriteRead);
00136 
00137   // MAX30101
00138   RPC_addProcedure(&Define_MAX30101_WriteReg);
00139   RPC_addProcedure(&Define_MAX30101_ReadReg);
00140   RPC_addProcedure(&Define_MAX30101_SpO2mode_Init);
00141   RPC_addProcedure(&Define_MAX30101_HRmode_Init);
00142   RPC_addProcedure(&Define_MAX30101_Multimode_init);
00143   RPC_addProcedure(&Define_MAX30101_SpO2mode_InitStart);
00144   RPC_addProcedure(&Define_MAX30101_HRmode_InitStart);
00145   RPC_addProcedure(&Define_MAX30101_Multimode_InitStart);
00146   RPC_addProcedure(&Define_MAX30101_SpO2mode_stop);
00147   RPC_addProcedure(&Define_MAX30101_HRmode_stop);
00148   RPC_addProcedure(&Define_MAX30101_Multimode_stop);
00149 
00150   // MAX30001
00151   RPC_addProcedure(&Define_MAX30001_WriteReg);
00152   RPC_addProcedure(&Define_MAX30001_ReadReg);
00153   RPC_addProcedure(&Define_MAX30001_Start);
00154   RPC_addProcedure(&Define_MAX30001_Stop);
00155   RPC_addProcedure(&Define_MAX30001_Enable_ECG_LeadON);
00156   RPC_addProcedure(&Define_MAX30001_Enable_BIOZ_LeadON);
00157   RPC_addProcedure(&Define_MAX30001_Read_LeadON);
00158   RPC_addProcedure(&Define_MAX30001_StartTest);
00159   RPC_addProcedure(&Define_MAX30001_INT_assignment);
00160   RPC_addProcedure(&Define_MAX30001_Rbias_FMSTR_Init);
00161   RPC_addProcedure(&Define_MAX30001_CAL_InitStart);
00162   RPC_addProcedure(&Define_MAX30001_ECG_InitStart);
00163   RPC_addProcedure(&Define_MAX30001_ECGFast_Init);
00164   RPC_addProcedure(&Define_MAX30001_PACE_InitStart);
00165   RPC_addProcedure(&Define_MAX30001_BIOZ_InitStart);
00166   RPC_addProcedure(&Define_MAX30001_RtoR_InitStart);
00167   RPC_addProcedure(&Define_MAX30001_Stop_ECG);
00168   RPC_addProcedure(&Define_MAX30001_Stop_PACE);
00169   RPC_addProcedure(&Define_MAX30001_Stop_BIOZ);
00170   RPC_addProcedure(&Define_MAX30001_Stop_RtoR);
00171   RPC_addProcedure(&Define_MAX30001_Stop_Cal);
00172 
00173   // Logging
00174   RPC_addProcedure(&Define_Logging_StartMissionDefine);
00175   RPC_addProcedure(&Define_Logging_AppendMissionCmd);
00176   RPC_addProcedure(&Define_Logging_EndMissionDefine);
00177   RPC_addProcedure(&Define_Logging_WriteMission);
00178   RPC_addProcedure(&Define_Logging_ReadMission);
00179   RPC_addProcedure(&Define_Logging_EraseMission);
00180   RPC_addProcedure(&Define_Logging_EraseWrittenSectors);
00181   RPC_addProcedure(&Define_Logging_StartLoggingUsb);
00182   RPC_addProcedure(&Define_Logging_StartLoggingFlash);
00183   RPC_addProcedure(&Define_Logging_GetLastWrittenPage);
00184   RPC_addProcedure(&Define_Logging_Start);
00185 
00186   // LIS2HD
00187   RPC_addProcedure(&Define_LIS2DH_InitStart);
00188   RPC_addProcedure(&Define_LIS2DH_ReadReg);
00189   RPC_addProcedure(&Define_LIS2DH_WriteReg);
00190   RPC_addProcedure(&Define_LIS2DH_Stop);
00191 
00192   // BMP280
00193   RPC_addProcedure(&Define_BMP280_InitStart);
00194 
00195   // MAX30205 and MAX31725 Alias
00196   RPC_addProcedure(&Define_MAX30205_1_InitStart);
00197   RPC_addProcedure(&Define_MAX30205_2_InitStart);
00198   RPC_addProcedure(&Define_MAX31725_1_InitStart);
00199   RPC_addProcedure(&Define_MAX31725_2_InitStart);
00200 
00201   // led
00202   RPC_addProcedure(&Define_Led_On);
00203   RPC_addProcedure(&Define_Led_Off);
00204   RPC_addProcedure(&Define_Led_BlinkHz);
00205   RPC_addProcedure(&Define_Led_BlinkPattern);
00206 
00207   // S25FS512
00208   RPC_addProcedure(&Define_S25FS512_ReadId);
00209   RPC_addProcedure(&Define_S25FS512_ReadPagesBinary);
00210   RPC_addProcedure(&Define_S25FS512_Reset);
00211   RPC_addProcedure(&Define_S25FS512_EnableHWReset);
00212   RPC_addProcedure(&Define_S25FS512_SpiWriteRead);
00213   RPC_addProcedure(&Define_S25FS512_SpiWriteRead4Wire);
00214 
00215   // Testing
00216   RPC_addProcedure(&Define_Testing_Test_S25FS512);
00217   RPC_addProcedure(&Define_Testing_Test_BMP280);
00218   RPC_addProcedure(&Define_Testing_Test_LIS2DH);
00219   RPC_addProcedure(&Define_Testing_Test_LSM6DS3);
00220   RPC_addProcedure(&Define_Testing_Test_MAX30205_1);
00221   RPC_addProcedure(&Define_Testing_Test_MAX30205_2);
00222   RPC_addProcedure(&Define_Testing_Test_MAX30101);
00223   RPC_addProcedure(&Define_Testing_Test_MAX30001);
00224   RPC_addProcedure(&Define_Testing_Test_EM9301);
00225 
00226   // System
00227   RPC_addProcedure(&Define_System_ReadVer);
00228   RPC_addProcedure(&Define_System_ReadBuildTime);
00229 
00230   // MAX14720
00231   RPC_addProcedure(&Define_MAX14720_ReadBoostVSet);
00232   RPC_addProcedure(&Define_MAX14720_WriteBoostVSet);
00233   RPC_addProcedure(&Define_MAX14720_ReadReg);
00234   RPC_addProcedure(&Define_MAX14720_WriteReg);
00235 }
00236 
00237 //******************************************************************************
00238 struct RPC_registeredProcedure *RPC_lookup(char *objectName, char *methodName) {
00239   struct RPC_registeredProcedure *ptr;
00240   // lookup all registered methods
00241   ptr = RPC_Procedures.head;
00242   while (ptr != NULL) {
00243     if (strcmp(ptr->objectName, objectName) == 0 &&
00244         strcmp(ptr->methodName, methodName) == 0) {
00245       // we found a match... return with it
00246       return ptr;
00247     }
00248     ptr = ptr->next;
00249   }
00250   return NULL;
00251 }
00252 
00253 //******************************************************************************
00254 char *GetToken(char *inStr, char *outStr, int start, char ch) {
00255   int i;
00256   int index = 0;
00257   int length = strlen(inStr);
00258   for (i = start; i < length; i++) {
00259     if (inStr[i] != ch) {
00260       outStr[index++] = inStr[i];
00261     } else {
00262       break;
00263     }
00264   }
00265   outStr[index++] = 0;
00266   return outStr;
00267 }
00268 
00269 //******************************************************************************
00270 void SendCommandList(char *reply) {
00271   struct RPC_registeredProcedure *ptr;
00272   reply[0] = 0;
00273   ptr = RPC_Procedures.head;
00274   while (ptr != NULL) {
00275     strcat(reply, "/");
00276     strcat(reply, ptr->objectName);
00277     strcat(reply, "/");
00278     strcat(reply, ptr->methodName);
00279     strcat(reply, ",");
00280     ptr = ptr->next;
00281   }
00282   strcat(reply, "\r\n");
00283 }
00284 
00285 //******************************************************************************
00286 int CheckForDoubleQuote(char *str) {
00287   int doubleQuoteFound;
00288   // scan through arguments, see if there is a double quote for a string
00289   // argument
00290   doubleQuoteFound = 0;
00291   while (*str != 0) {
00292     if (*str == '\"') {
00293       doubleQuoteFound = 1;
00294       break;
00295     }
00296     str++;
00297   }
00298   return doubleQuoteFound;
00299 }
00300 
00301 //******************************************************************************
00302 void ExtractDoubleQuoteStr(char *src, char *dst) {
00303   int start;
00304 
00305   dst[0] = 0;
00306   start = 0;
00307   while (*src != 0) {
00308     // look for start
00309     if ((*src == '\"') && (start == 0)) {
00310       start = 1;
00311       src++;
00312       continue;
00313     }
00314     // look for end
00315     if ((*src == '\"') && (start == 1)) {
00316       *dst = 0; // terminate the string
00317       break;
00318     }
00319     if (start == 1) {
00320       *dst = *src;
00321       dst++;
00322     }
00323     src++;
00324   }
00325 }
00326 
00327 //******************************************************************************
00328 void RPC_call_test(void) {
00329   int doubleQuoteFound;
00330   char doubleQuoteStr[64];
00331   char *request = "/Logging/AppendMissionCmd \"BMP280 InitStart 1\"";
00332 
00333   // scan through arguments, see if there is a double quote for a string
00334   // argument
00335   doubleQuoteFound = CheckForDoubleQuote(request);
00336   if (doubleQuoteFound) {
00337     ExtractDoubleQuoteStr(request, doubleQuoteStr);
00338   }
00339 }
00340 
00341 //******************************************************************************
00342 void RPC_call(char *request, char *reply) {
00343   const char slash[2] = "/";
00344   const char space[2] = " ";
00345   char *objectName;
00346   char *methodName;
00347   char doubleQuoteStr[64];
00348   char requestCpy[128];
00349   char *token;
00350   int argIndex;
00351   int resultIndex;
00352   int doubleQuoteFound;
00353   struct RPC_registeredProcedure *procedurePtr;
00354 
00355   // clear out the reply
00356   reply[0] = 0;
00357   // copy the request for scanning and extraction later
00358   strcpy(requestCpy, request);
00359   // check for beginning forward slash
00360   if (request[0] != '/') {
00361     return;
00362   }
00363   // check for only a forward slash
00364   if (request[0] == '/' && request[1] == 0) {
00365     SendCommandList(reply);
00366     return;
00367   }
00368   strcat(request, " ");
00369   // get the object name
00370   token = strtok(request, slash);
00371   // token = GetToken(request, tokenBuffer, 1, '/');
00372   objectName = token;
00373   if (objectName == NULL)
00374     return; // must have an object name
00375   // get the method name
00376   token = strtok(NULL, space);
00377   methodName = token;
00378   if (methodName == NULL)
00379     return; // must have a method name
00380 
00381   // scan through arguments, see if there is a double quote for a string
00382   // argument
00383   doubleQuoteFound = CheckForDoubleQuote(requestCpy);
00384 
00385   if (doubleQuoteFound == 0) {
00386     // walk through arguments
00387     argIndex = 0;
00388     token = strtok(NULL, space);
00389     while (token != NULL) {
00390       // save this arg in array
00391       strcpy(args[argIndex++], token);
00392       // read next token arg if any
00393       token = strtok(NULL, space);
00394     }
00395     // terminate the end of the string array with an empty string
00396     strcpy(args[argIndex], "\0");
00397     strcpy(results[0], "\0");
00398   } else {
00399     // grab out the double quote string
00400     ExtractDoubleQuoteStr(requestCpy, doubleQuoteStr);
00401     argIndex = 0;
00402     // token = strtok(NULL, quote);
00403     strcpy(args[argIndex++], doubleQuoteStr);
00404   }
00405 
00406   //
00407   // alias the MAX30001 and MAX30003 names
00408   //
00409   if (strcmp(objectName, MAX30003_NAME) == 0) {
00410     strcpy(objectName, MAX30001_NAME);
00411   }
00412 
00413   procedurePtr = RPC_lookup(objectName, methodName);
00414   if (procedurePtr != NULL) {
00415     // printf("RPC_call: %s processing\n",requestCpy);
00416     procedurePtr->func(args, results);
00417   } else {
00418     printf("RPC_call: %s not found\n", requestCpy);
00419     // printf("Unable to lookup %s %s", objectName, methodName);
00420   }
00421 
00422   // loop while (if) there are results to return
00423   resultIndex = 0;
00424   strcpy(reply, "\0");
00425   while (results[resultIndex][0] != '\0') {
00426     strcat(reply, results[resultIndex++]);
00427     strcat(reply, " ");
00428   }
00429   strcat(reply, "\r\n");
00430 }
00431 
00432 //******************************************************************************
00433 void RPC_ProcessCmds(char *cmds) {
00434   char cmd[32 * 32];
00435   char *ptrCmds;
00436   char reply[512];
00437   ptrCmds = cmds;
00438 
00439   while (*ptrCmds != 0) {
00440     ptrCmds = ParseUntilCRLF(ptrCmds, cmd, sizeof(cmd));
00441     if (*cmd != 0) {
00442       RPC_call(cmd, reply);
00443     }
00444   }
00445 }