SCOM Serial Communication Protocol  0.5.2
scom_utils.c
Go to the documentation of this file.
1 
10 #define HAL_LOG_CHANNEL SCOM
11 #define HAL_LOG_SUBCHANNEL UTIL
12 
13 #include "hal.h"
14 #include "scom.h"
15 #include "scom_filtering.h"
16 #include "scom_frame_type_filter.h"
17 #include <string.h>
18 
19 
20 // -----------------------------------------------------------------------------
21 // SCOM_GetIdentity
22 // -----------------------------------------------------------------------------
24  HAL_ASSERT_AND_EXECUTE(scom != NULL) {
25  HAL_ASSERT_AND_EXECUTE(identity != NULL) {
26  SCOMResult result = SCOM_ERROR;
27  memset(identity, 0x00, sizeof(SCOMIdentity)); // Clear the identity struct
28  // initialize the frame-match filter
30  if (SCOM_RESULT_OK == SCOM_InitializeFrameTypeMatchFilter(&filter, identity, sizeof(SCOMIdentity))) {
31  // set-up the filter to catch the IDENTIFY response
33  // insert filter into SCOM
34  if(SCOM_RESULT_OK == SCOM_InsertFilter(scom, &filter.filter)) {
35  // send the IDENTIFY request
36  if (SCOM_RESULT_OK == SCOM_SendFrame(scom, 1, SCOM_FRAMETYPE_IDENTIFY, NULL, 0)) {
37  // frame stored successfully, now we must wait for the response
39  } else {
40  // unable to send identify request
42  }
43  SCOM_RemoveFilter(scom, &filter.filter); // remove the filter
44  } else {
45  result = SCOM_FILTER_ERROR;
46  }
47  } else {
48  result = SCOM_FILTER_LIST_FULL;
49  }
50  SCOM_DeinitializeFrameTypeMatchFilter(&filter); // deinitialize the filter
51  } else {
52  result = SCOM_FILTER_ERROR;
53  }
54  return result;
55  }
56  }
57  return SCOM_RESULT_ERROR;
58 } /* SCOM_GetIdentity */
59 
60 
61 // -----------------------------------------------------------------------------
62 // SCOM_WaitForDevice
63 // -----------------------------------------------------------------------------
64 SCOMResult SCOM_WaitForDevice(SCOMDataLink scom, uint32_t expectedDeviceClass, uint32_t expectedDeviceClassMask, uint32_t probeInterval, uint32_t timeout, SCOMIdentity* identity) {
65  SCOMIdentity tempIdentity;
67  SCOMResult result = SCOM_ERROR;
68  uint32_t startTime;
69  bool found = false;
70 
71  HAL_ASSERT_AND_EXECUTE(scom != NULL) {
72  // clear the identity struct
73  memset(&tempIdentity, 0x00, sizeof(SCOMIdentity));
74 
75  // initialize the frame-match filter
76  if (SCOM_RESULT_OK == SCOM_InitializeFrameTypeMatchFilter(&filter, &tempIdentity, sizeof(SCOMIdentity))) {
77  // set-up the filter to catch the IDENTIFY response
79  // insert filter into SCOM
80  if(SCOM_RESULT_OK == SCOM_InsertFilter(scom, &filter.filter)) {
81  // mark start time
82  startTime = scom->clockSource();
83 
84  while ((!found) && (scom->clockSource() < startTime + timeout)) {
85  // send the IDENTIFY request
86  HAL_LOG_INFO("SCOM_WaitForDevice: Sending identify request with no ACK");
88  // frame stored successfully, now we must wait for the response
89  if (SCOM_RESULT_OK == SCOM_WaitForFrameTypeFilter(&filter, probeInterval)) {
90  // got response
91  if ((tempIdentity.deviceClass & expectedDeviceClassMask) == (expectedDeviceClass & expectedDeviceClassMask)) {
92  // device class matches
93  HAL_LOG_INFO("SCOM_WaitForDevice: Got matching response: DeviceClass=0x%" PRIX32);
94  if (identity) {
95  memcpy(identity, &tempIdentity, sizeof(SCOMIdentity));
96  }
97  found = true;
98  result = SCOM_RESULT_OK;
99  } else {
100  HAL_LOG_WARNING("SCOM_WaitForDevice: Got non-matching response. Will try again");
101  }
102  } else {
103  HAL_LOG_WARNING("SCOM_WaitForDevice: Got no response. Will try again");
104  result = SCOM_NO_DEVICE;
105  }
106  }
107  }
108  // remove the filter
109  SCOM_RemoveFilter(scom, &filter.filter);
110  } else {
111  // unable to set-up frame match filter
112  result = SCOM_FILTER_ERROR;
113  }
114  } else {
115  // unable to insert filter
116  result = SCOM_FILTER_LIST_FULL;
117  }
118  // deinitialize the filter
120  } else {
121  // unable to initialize the frame-match filter
122  result = SCOM_FILTER_ERROR;
123  }
124  }
125 
126  return result;
127 
128 } /* SCOM_WaitForDevice */
129 
130 
131 // -----------------------------------------------------------------------------
132 // SCOM_ScanAndRun
133 // -----------------------------------------------------------------------------
134 unsigned int SCOM_ScanAndRun(void (*initProc)(IODevice iodevice, const char* deviceName),
135  bool (*userProc)(SCOMDataLink scom, SCOMIdentity* identity, const char* deviceName),
136  uint32_t responseTimeout)
137 {
138  unsigned int deviceCount, deviceNo, validDeviceCounter;
139  IODevice iodev;
140  SCOMDataLink scom;
141  SCOMFrameBuffer* frameBuffer;
142  SCOMIdentity identity;
143 
144  // used to count SCOM valid devices found
145  validDeviceCounter = 0;
146 
147  // enumerate all serial ports
148  deviceCount = IOSERIAL_Enumerate();
149 
150  // for each serial port found
151  for (deviceNo = 0; deviceNo < deviceCount; deviceNo++) {
152 
153  // create IODevice (actually IOSerialDevice)
154  iodev = IOSERIAL_Create(IOSERIAL_GetEnumeratedDeviceName(deviceNo));
155  if (iodev) {
156 
157  // initialize the IODevice
158  if (HALRESULT_OK == IODEV_Init(iodev)) {
159  IOSERIAL_SetBaudrate(iodev, 115200);
160  HAL_LOG_INFO("ScanAndRun working on %s", IOSERIAL_GetEnumeratedDeviceName(deviceNo));
161 
162  IODEV_EnableWrite(iodev);
163  IODEV_EnableRead(iodev);
164 
165  // call user initialization proc
166  if (initProc) {
167  initProc(iodev, IOSERIAL_GetEnumeratedDeviceName(deviceNo));
168  }
169 
170 
171  // create SCOM object
172  scom = SCOM_Create();
173  if (scom) {
174  // create SCOM frame buffer
175  frameBuffer = SCOM_CreateFrameBuffer(16, 16);
176 
177  // initialize SCOM
178  SCOM_Init(scom, iodev, frameBuffer, OS_GetSystemTime, 1000, 0, 0, 0, NULL);
179  SCOM_InitFiltering(scom);
180  // run SCOM threads
183  // try to identify the remote SCOM device
184  if (SCOM_RESULT_OK == SCOM_WaitForDevice(scom, 0, 0, 1000, responseTimeout, &identity)) {
185  // identity was retrieved successfully, this is a valid SCOM device
186  if (userProc) {
187  // run the user function
188  if (userProc(scom, &identity, IOSERIAL_GetEnumeratedDeviceName(deviceNo))) {
189  // if user function returns true, we count this device as valid
190  validDeviceCounter++;
191  }
192  } else {
193  // the user function was not provided, we count this device as valid anyway
194  validDeviceCounter++;
195  }
196  }
197  // deinitialize SCOM
200  SCOM_DeinitFiltering(scom);
201  SCOM_Deinit(scom);
202  // destroy SCOM object
203  SCOM_Destroy(scom);
204  }
205  // deinitialize the IODevice
206  IODEV_Deinit(iodev);
207  }
208  // destroy the IODevice
209  IOSERIAL_Destroy(iodev);
210  }
211  }
212 
213  return validDeviceCounter;
214 } /* SCOM_ScanAndRun */
SCOMResult SCOM_DeinitializeFrameTypeMatchFilter(SCOMFrameTypeMatchFilter *frameMatchFilter)
Main API file.
Packet type definition: IDENTIFY.
Definition: scom_frame.h:49
void SCOM_StopFilteringThread(SCOMDataLink scom)
SCOM version record.
Definition: scom.h:81
SCOMResult SCOM_WaitForDevice(SCOMDataLink scom, uint32_t expectedDeviceClass, uint32_t expectedDeviceClassMask, uint32_t probeInterval, uint32_t timeout, SCOMIdentity *identity)
Definition: scom_utils.c:64
SCOMResult SCOM_Deinit(SCOMDataLinkDesc *const scom)
Definition: scom.c:343
Packet filtering API.
SCOMResult SCOM_SendFrame(SCOMDataLinkDesc *const scom, uint8_t framePriority, uint8_t frameType, const void *frameData, uint8_t frameDataSize)
Definition: scom.c:493
Packet filter based on frame type.
SCOMResult SCOM_WaitForFrameTypeFilter(SCOMFrameTypeMatchFilter *frameMatchFilter, OSTime timeout)
SCOMResult SCOM_RemoveFilter(SCOMDataLink scom, SCOMFilter filter)
unsigned int SCOM_ScanAndRun(void(*initProc)(IODevice iodevice, const char *deviceName), bool(*userProc)(SCOMDataLink scom, SCOMIdentity *identity, const char *deviceName), uint32_t responseTimeout)
Definition: scom_utils.c:134
SCOMDataLinkDesc * SCOM_Create(void)
Definition: scom.c:146
SCOMResult SCOM_InitializeFrameTypeMatchFilter(SCOMFrameTypeMatchFilter *frameMatchFilter, void *data, size_t max_data_size)
SCOMFrameBuffer * SCOM_CreateFrameBuffer(size_t rxBuffSize, size_t txBuffSize)
Definition: scom.c:174
SCOMResult SCOM_RunFilteringThread(SCOMDataLink scom)
SCOMResult
Definition: scom.h:211
SCOMResult SCOM_GetIdentity(SCOMDataLinkDesc *const scom, SCOMIdentity *const identity)
Definition: scom_utils.c:23
SCOMResult SCOM_InitFiltering(SCOMDataLink scom)
uint32_t deviceClass
Device class.
Definition: scom.h:90
SCOMResult SCOM_DeinitFiltering(SCOMDataLink scom)
SCOMResult SCOM_InsertFilter(SCOMDataLink scom, SCOMFilter filter)
SCOMResult SCOM_Init(SCOMDataLink scom, IODevice iodevice, SCOMFrameBuffer *frameBuffer, SCOMClockSource clockSource, uint32_t ackTimeout, uint32_t deviceClass, uint8_t *deviceUID, uint8_t numberOfServices, uint8_t *serviceIDs)
Definition: scom.c:230
void SCOM_StopProcessingThread(SCOMDataLink scom)
Definition: scom.c:420
SCOMResult SCOM_SendFrameWithoutAck(SCOMDataLink scom, uint8_t framePriority, uint8_t frameType, const void *frameData, uint8_t frameDataSize)
Definition: scom.c:530
SCOMResult SCOM_SetupFrameTypeMatchFilter(SCOMFrameTypeMatchFilter *frameMatchFilter, uint8_t frame_type)
void SCOM_Destroy(SCOMDataLinkDesc *const scom)
Definition: scom.c:161
SCOMResult SCOM_RunProcessingThread(SCOMDataLinkDesc *const scom)
Definition: scom.c:403
Definition of the frame buffer used by SCOM.
Definition: scom.h:63
SCOMFilterDesc filter
Native SCOM filter descriptor.