00001
00002 #include <stdio.h>
00003 #include <check.h>
00004
00005 #include <sbp.h>
00006
00007
00008 int DUMMY_MEMORY_FOR_CALLBACKS = 0xdeadbeef;
00009 int DUMMY_MEMORY_FOR_IO = 0xdead0000;
00010
00011 u32 dummy_wr = 0;
00012 u32 dummy_rd = 0;
00013 u8 dummy_buff[1024];
00014 void* last_io_context;
00015
00016 void dummy_reset()
00017 {
00018 dummy_rd = dummy_wr = 0;
00019 memset(dummy_buff, 0, sizeof(dummy_buff));
00020 }
00021
00022 u32 dummy_write(u8 *buff, u32 n, void* context)
00023 {
00024 last_io_context = context;
00025 u32 real_n = n;
00026 memcpy(dummy_buff + dummy_wr, buff, real_n);
00027 dummy_wr += real_n;
00028 return real_n;
00029 }
00030
00031 u32 dummy_read(u8 *buff, u32 n, void* context)
00032 {
00033 last_io_context = context;
00034 u32 real_n = n;
00035 memcpy(buff, dummy_buff + dummy_rd, real_n);
00036 dummy_rd += real_n;
00037 return real_n;
00038 }
00039
00040 u32 dummy_read_single_byte(u8 *buff, u32 n, void* context)
00041 {
00042 (void)n;
00043 last_io_context = context;
00044 memcpy(buff, dummy_buff + dummy_rd, 1);
00045 dummy_rd += 1;
00046 return 1;
00047 }
00048
00049 u32 dummy_write_single_byte(u8 *buff, u32 n, void* context)
00050 {
00051 (void)n;
00052 last_io_context = context;
00053 memcpy(dummy_buff + dummy_wr, buff, 1);
00054 dummy_wr += 1;
00055 return 1;
00056 }
00057
00058 void printy_callback(u16 sender_id, u8 len, u8 msg[], void* context)
00059 {
00060 (void)context;
00061 printf("MSG id: 0x%04X, len: %d\n", sender_id, len);
00062 if (len > 0) {
00063 for (u8 i=0; i<len; i++)
00064 printf("0x%02X ", msg[i]);
00065 }
00066 printf("\n");
00067 }
00068
00069 u32 n_callbacks_logged;
00070 u16 last_sender_id;
00071 u8 last_len;
00072 u8 last_msg[256];
00073 void* last_context;
00074
00075
00076 void logging_reset()
00077 {
00078 n_callbacks_logged = 0;
00079 last_context = 0;
00080 memset(last_msg, 0, sizeof(last_msg));
00081 }
00082
00083 void logging_callback(u16 sender_id, u8 len, u8 msg[], void* context)
00084 {
00085 n_callbacks_logged++;
00086 last_sender_id = sender_id;
00087 last_len = len;
00088 last_context = context;
00089 memcpy(last_msg, msg, len);
00090
00091
00092 }
00093
00094 void test_callback(u16 sender_id, u8 len, u8 msg[], void* context)
00095 {
00096
00097 (void)sender_id;
00098 (void)len;
00099 (void)msg;
00100 (void)context;
00101 }
00102 void test_callback2(u16 sender_id, u8 len, u8 msg[], void* context)
00103 {
00104
00105 (void)sender_id;
00106 (void)len;
00107 (void)msg;
00108 (void)context;
00109 }
00110
00111 START_TEST(test_sbp_process)
00112 {
00113
00114
00115 sbp_state_t s;
00116 sbp_state_init(&s);
00117 sbp_state_set_io_context(&s, &DUMMY_MEMORY_FOR_IO);
00118
00119 static sbp_msg_callbacks_node_t n;
00120 static sbp_msg_callbacks_node_t n2;
00121
00122 sbp_register_callback(&s, 0x2269, &logging_callback, &DUMMY_MEMORY_FOR_CALLBACKS, &n);
00123
00124 u8 test_data[] = { 0x01, 0x02, 0x03, 0x04 };
00125
00126 dummy_reset();
00127 sbp_send_message(&s, 0x2269, 0x42, sizeof(test_data), test_data, &dummy_write);
00128
00129 while (dummy_rd < dummy_wr) {
00130 fail_unless(sbp_process(&s, &dummy_read) >= SBP_OK,
00131 "sbp_process threw an error!");
00132 }
00133
00134 fail_unless(n_callbacks_logged == 1,
00135 "one callback should have been logged");
00136 fail_unless(last_sender_id == 0x42,
00137 "sender_id decoded incorrectly");
00138 fail_unless(last_len == sizeof(test_data),
00139 "len decoded incorrectly");
00140 fail_unless(memcmp(last_msg, test_data, sizeof(test_data))
00141 == 0,
00142 "test data decoded incorrectly");
00143 fail_unless(last_context == &DUMMY_MEMORY_FOR_CALLBACKS,
00144 "context pointer incorrectly passed");
00145
00146 sbp_register_callback(&s, 0x2270, &logging_callback, &DUMMY_MEMORY_FOR_CALLBACKS, &n2);
00147 fail_unless(sbp_find_callback(&s, 0x2270) != 0,
00148 "second callback not found");
00149
00150 logging_reset();
00151 sbp_send_message(&s, 0x2269, 0x4243, 0, 0, &dummy_write);
00152
00153 fail_unless(last_io_context == &DUMMY_MEMORY_FOR_IO,
00154 "io context pointer incorrectly passed");
00155
00156 last_io_context = 0;
00157
00158 while (dummy_rd < dummy_wr) {
00159 fail_unless(sbp_process(&s, &dummy_read) >= SBP_OK,
00160 "sbp_process threw an error! (2)");
00161 }
00162
00163 fail_unless(last_io_context == &DUMMY_MEMORY_FOR_IO,
00164 "io context pointer incorrectly passed");
00165
00166
00167 fail_unless(n_callbacks_logged == 1,
00168 "one callback should have been logged (2)");
00169 fail_unless(last_sender_id == 0x4243,
00170 "sender_id decoded incorrectly (2)");
00171 fail_unless(last_len == 0,
00172 "len decoded incorrectly (2)");
00173
00174 logging_reset();
00175 sbp_send_message(&s, 0x22, 0x4243, 0, 0, &dummy_write);
00176
00177 s8 ret = 0;
00178 while (dummy_rd < dummy_wr) {
00179 ret |= sbp_process(&s, &dummy_read);
00180 }
00181
00182 fail_unless(ret == SBP_OK_CALLBACK_UNDEFINED,
00183 "sbp_process should have returned SBP_OK_CALLBACK_UNDEFINED "
00184 "if no cb was registered for that message type");
00185
00186 fail_unless(n_callbacks_logged == 0,
00187 "no callbacks should have been logged");
00188
00189 u8 awesome_message[] = {0x55, 0x33, 0x22, 0x77, 0x66,
00190 0x02, 0x22, 0x33, 0x8A, 0x33};
00191 logging_reset();
00192 dummy_reset();
00193 dummy_rd = 0;
00194 dummy_wr = sizeof(awesome_message);
00195 memcpy(dummy_buff, awesome_message, sizeof(awesome_message));
00196
00197 static sbp_msg_callbacks_node_t m;
00198 sbp_register_callback(&s, 0x2233, &logging_callback, 0, &m);
00199
00200 while (dummy_rd < dummy_wr) {
00201 fail_unless(sbp_process(&s, &dummy_read) >= SBP_OK,
00202 "sbp_process threw an error! (3)");
00203 }
00204
00205 fail_unless(n_callbacks_logged == 1,
00206 "one callback should have been logged (3)");
00207 fail_unless(last_sender_id == 0x6677,
00208 "sender_id decoded incorrectly (3)");
00209 fail_unless(last_len == 2,
00210 "len decoded incorrectly (3)");
00211 fail_unless(memcmp(last_msg, &awesome_message[6], 2)
00212 == 0,
00213 "test data decoded incorrectly (3)");
00214
00215 awesome_message[4] = 0xAA;
00216 logging_reset();
00217 dummy_reset();
00218 dummy_rd = 0;
00219 dummy_wr = sizeof(awesome_message);
00220 memcpy(dummy_buff, awesome_message, sizeof(awesome_message));
00221
00222 ret = 0;
00223 while (dummy_rd < dummy_wr) {
00224 ret |= sbp_process(&s, &dummy_read);
00225 }
00226
00227 fail_unless(ret == SBP_CRC_ERROR,
00228 "sbp_process should have returned SBP_CRC_ERROR "
00229 "for malformed message");
00230
00231 fail_unless(n_callbacks_logged == 0,
00232 "no callbacks should have been logged (2)");
00233
00234
00235
00236 u8 awesome_message2[] = {0x55, 0x33, 0x22, 0x77, 0x66,
00237 0x02, 0x22, 0x33, 0x8A, 0x33};
00238 logging_reset();
00239 dummy_reset();
00240 sbp_clear_callbacks(&s);
00241 dummy_rd = 0;
00242 dummy_wr = sizeof(awesome_message2);
00243 memcpy(dummy_buff, awesome_message2, sizeof(awesome_message2));
00244
00245 static sbp_msg_callbacks_node_t p;
00246 sbp_register_callback(&s, 0x2233, &logging_callback, 0, &p);
00247
00248 while (dummy_rd < dummy_wr) {
00249 fail_unless(sbp_process(&s, &dummy_read_single_byte) >= SBP_OK,
00250 "sbp_process threw an error! (3)");
00251 }
00252
00253 fail_unless(n_callbacks_logged == 1,
00254 "one callback should have been logged (3)");
00255 fail_unless(last_sender_id == 0x6677,
00256 "sender_id decoded incorrectly (3)");
00257 fail_unless(last_len == 2,
00258 "len decoded incorrectly (3)");
00259 fail_unless(memcmp(last_msg, &awesome_message2[6], 2)
00260 == 0,
00261 "test data decoded incorrectly (3)");
00262
00263
00264
00265
00266 u8 crappy_then_awesome_message[] = {0x99, 0x88, 0x77, 0x66, 0x55, 0x33, 0x22, 0x77, 0x66,
00267 0x02, 0x22, 0x33, 0x8A, 0x33};
00268 logging_reset();
00269 dummy_reset();
00270 sbp_clear_callbacks(&s);
00271 dummy_rd = 0;
00272 dummy_wr = sizeof(crappy_then_awesome_message);
00273 memcpy(dummy_buff, crappy_then_awesome_message, sizeof(crappy_then_awesome_message));
00274
00275 static sbp_msg_callbacks_node_t q;
00276 sbp_register_callback(&s, 0x2233, &logging_callback, 0, &q);
00277
00278 while (dummy_rd < dummy_wr) {
00279 fail_unless(sbp_process(&s, &dummy_read_single_byte) >= SBP_OK,
00280 "sbp_process threw an error! (3)");
00281 }
00282
00283 fail_unless(n_callbacks_logged == 1,
00284 "one callback should have been logged (3)");
00285 fail_unless(last_sender_id == 0x6677,
00286 "sender_id decoded incorrectly (3)");
00287 fail_unless(last_len == 2,
00288 "len decoded incorrectly (3)");
00289 fail_unless(memcmp(last_msg, &crappy_then_awesome_message[10], 2)
00290 == 0,
00291 "test data decoded incorrectly (3)");
00292
00293 }
00294 END_TEST
00295
00296 START_TEST(test_sbp_send_message)
00297 {
00298
00299
00300 sbp_state_t s;
00301 sbp_state_init(&s);
00302
00303
00304 u8 smsg[] = { 0x22, 0x33 };
00305
00306 fail_unless(sbp_send_message(&s, 0x2233, 0x4455, 0, smsg, 0) == SBP_NULL_ERROR,
00307 "sbp_send_message should return an error if write is NULL");
00308
00309 dummy_reset();
00310 fail_unless(sbp_send_message(&s, 0x2233, 0x4455, 1, 0, &dummy_write)
00311 == SBP_NULL_ERROR,
00312 "sbp_send_message should return an error if payload is NULL and len != 0");
00313
00314 dummy_reset();
00315 fail_unless(sbp_send_message(&s, 0x2233, 0x4455, 0, 0, &dummy_write)
00316 == SBP_OK,
00317 "sbp_send_message should return OK if payload is NULL and len == 0");
00318
00319 u8 zero_len_message[] = {0x55, 0x33, 0x22, 0x55, 0x44, 0x00, 0x2C, 0x4C};
00320
00321 fail_unless(memcmp(dummy_buff, zero_len_message, sizeof(zero_len_message))
00322 == 0,
00323 "sbp_send_message encode error for len = 0");
00324
00325 dummy_reset();
00326 sbp_send_message(&s, 0x2233, 0x6677, sizeof(smsg), smsg, &dummy_write);
00327
00328 u8 awesome_message[] = {0x55, 0x33, 0x22, 0x77, 0x66,
00329 0x02, 0x22, 0x33, 0x8A, 0x33};
00330
00331 fail_unless(memcmp(dummy_buff, awesome_message, sizeof(awesome_message))
00332 == 0,
00333 "sbp_send_message encode error for test message");
00334 }
00335 END_TEST
00336
00337 START_TEST(test_callbacks)
00338 {
00339
00340 sbp_state_t s;
00341 sbp_state_init(&s);
00342
00343
00344 sbp_clear_callbacks(&s);
00345
00346 fail_unless(sbp_find_callback(&s, 0x1234) == 0,
00347 "sbp_find_callback should return NULL if no callbacks registered");
00348
00349 fail_unless(sbp_register_callback(&s, 0x2233, &test_callback, 0, 0) == SBP_NULL_ERROR,
00350 "sbp_register_callback should return an error if node is NULL");
00351
00352
00353
00354 static sbp_msg_callbacks_node_t n;
00355
00356 int NUMBER = 42;
00357
00358 fail_unless(sbp_register_callback(&s, 0x2233, 0, 0, &n) == SBP_NULL_ERROR,
00359 "sbp_register_callback should return an error if cb is NULL");
00360
00361 fail_unless(sbp_register_callback(&s, 0x2233, &test_callback, &NUMBER, &n) == SBP_OK,
00362 "sbp_register_callback should return success if everything is groovy");
00363
00364 fail_unless(sbp_register_callback(&s, 0x2233, &test_callback, 0, &n)
00365 == SBP_CALLBACK_ERROR,
00366 "sbp_register_callback should return SBP_CALLBACK_ERROR if a callback "
00367 "of the same type is already registered");
00368
00369 fail_unless(sbp_find_callback(&s, 0x1234) == 0,
00370 "sbp_find_callback should return NULL if callback not registered");
00371
00372 fail_unless(sbp_find_callback(&s, 0x2233) == &n,
00373 "sbp_find_callback didn't return the correct callback node pointer");
00374
00375 fail_unless(sbp_find_callback(&s, 0x2233)->context == &NUMBER,
00376 "sbp_find_callback didn't return the correct context pointer");
00377
00378
00379
00380 static sbp_msg_callbacks_node_t m;
00381
00382 int NUMBER2 = 84;
00383
00384 fail_unless(sbp_register_callback(&s, 0x1234, &test_callback2, &NUMBER2, &m) == SBP_OK,
00385 "sbp_register_callback should return success if everything is groovy (2)");
00386
00387 fail_unless(sbp_find_callback(&s, 0x2233) == &n,
00388 "sbp_find_callback didn't return the correct callback function pointer (2)");
00389
00390 fail_unless(sbp_find_callback(&s, 0x2233)->context == &NUMBER,
00391 "sbp_find_callback didn't return the correct context pointer");
00392
00393 fail_unless(sbp_find_callback(&s, 0x1234) == &m,
00394 "sbp_find_callback didn't return the correct callback function pointer (3)");
00395
00396 fail_unless(sbp_find_callback(&s, 0x1234)->context == &NUMBER2,
00397 "sbp_find_callback didn't return the correct context pointer");
00398
00399 fail_unless(sbp_register_callback(&s, 0x1234, &test_callback, 0, &n)
00400 == SBP_CALLBACK_ERROR,
00401 "sbp_register_callback should return SBP_CALLBACK_ERROR if a callback "
00402 "of the same type is already registered (2)");
00403
00404 fail_unless(sbp_find_callback(&s, 0x7788) == 0,
00405 "sbp_find_callback should return NULL if callback not registered (2)");
00406
00407
00408 sbp_clear_callbacks(&s);
00409
00410 fail_unless(sbp_find_callback(&s, 0x1234) == 0,
00411 "sbp_find_callback should return NULL if no callbacks registered (2)");
00412
00413 fail_unless(sbp_find_callback(&s, 0x2233) == 0,
00414 "sbp_find_callback should return NULL if no callbacks registered (3)");
00415
00416 }
00417 END_TEST
00418
00419 Suite* sbp_suite(void)
00420 {
00421 Suite *s = suite_create("SBP");
00422
00423 TCase *tc_core = tcase_create("Core");
00424
00425
00426 tcase_add_test(tc_core, test_callbacks);
00427 tcase_add_test(tc_core, test_sbp_send_message);
00428 tcase_add_test(tc_core, test_sbp_process);
00429
00430 suite_add_tcase(s, tc_core);
00431
00432 return s;
00433 }
00434