Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers d7a_alp.cpp Source File

d7a_alp.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "dbg.h"
00004 #include "d7a.h"
00005 #include "d7a_com.h"
00006 #include "d7a_common.h"
00007 #include "d7a_fs.h"
00008 #include "d7a_modem.h"
00009 #include "d7a_sys.h"
00010 #include "d7a_alp.h"
00011 #include "sha.h"
00012 #include "d7a_typedefs.h"
00013 
00014 #if 1
00015     #define ALP_DPRINT(...)         DPRINT(__VA_ARGS__)
00016     #define ALP_DPRINT_DATA(...)    DPRINT_DATA(__VA_ARGS__)
00017     #define ALP_FPRINT(...)         FPRINT(__VA_ARGS__)
00018 #else
00019     #define ALP_DPRINT(...);
00020     #define ALP_DPRINT_DATA(...);
00021     #define ALP_FPRINT(...);
00022 #endif
00023 
00024 #define ALP_CMD_MAX_LENGHT          (256)
00025 #define MAX_RESPONSES               (32)
00026 
00027 static uint8_t                      g_alp_tag;
00028 static uint8_t                      g_alp_root_key_size;
00029 static uint8_t                      g_alp_buffer[ALP_CMD_MAX_LENGHT];
00030 static UnsolicitedMsgFunction       g_alp_uns_msg;
00031 
00032 static OS_Queue<d7a_com_rx_msg_t, 8>   g_alp_pkt_queue;
00033 static OS_Queue<d7a_com_rx_msg_t, 8>   g_alp_pl_queue;
00034 static OS_Thread                       g_alp_thread(osPriorityHigh, 512, NULL);
00035 
00036 void d7a_alp_thread();
00037 
00038 d7a_errors_t d7a_alp_open(UnsolicitedMsgFunction uns_msg)
00039 {
00040     ALP_FPRINT("\r\n");
00041 
00042     g_alp_uns_msg = uns_msg;
00043     g_alp_root_key_size = D7A_ROOT_KEY_SIZE;
00044     
00045     osStatus err = g_alp_thread.start(d7a_alp_thread);
00046     ASSERT(err == osOK, "Failed to start d7a_alp_thread (err: %d)\r\n", err);
00047     
00048     return D7A_ERR_NONE;
00049 }
00050 
00051 d7a_errors_t d7a_alp_close(void)
00052 {
00053     ALP_FPRINT("\r\n");
00054 
00055     g_alp_thread.terminate();
00056     
00057     return D7A_ERR_NONE;
00058 }
00059 
00060 void d7a_alp_new_pkt(d7a_com_rx_msg_t* pkt)
00061 {
00062     ALP_FPRINT("\r\n");
00063     ASSERT(g_alp_pkt_queue.put(pkt) == osOK, "ALP queue full!\r\n");
00064 }
00065 
00066 static void d7a_alp_new_pl(d7a_com_rx_msg_t* pl)
00067 {
00068     ALP_FPRINT("\r\n");
00069     ASSERT(g_alp_pl_queue.put(pl) == osOK, "ALP PL queue full!\r\n");
00070 }
00071 
00072 static d7a_com_rx_msg_t* d7a_alp_wait_pkt(uint32_t millisec)
00073 {
00074     ALP_FPRINT("\r\n");
00075     osEvent evt = g_alp_pkt_queue.get(millisec);
00076     return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
00077 }
00078 
00079 static d7a_com_rx_msg_t* d7a_alp_wait_pl(uint32_t millisec)
00080 {
00081     ALP_FPRINT("\r\n");
00082     osEvent evt = g_alp_pl_queue.get(millisec);
00083     return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
00084 }
00085 
00086 static uint32_t d7a_ctf_to_ti(d7a_ctf_t ctf)
00087 {
00088     return ((1 << (2*ctf.bf.exp)) * ctf.bf.mant);
00089 }
00090 
00091 static uint32_t d7a_alp_encode_length(uint8_t* p, uint32_t len)
00092 {
00093     if (len <= 0x3F)
00094     {
00095         *p++ = len;
00096         return 1;
00097     }
00098     else if (len <= 0x3FFF)
00099     {
00100         *p++ = 0x40 + (uint8_t)(len >> 8);
00101         *p++ =        (uint8_t)(len & 0xFF);
00102         return 2;
00103     }
00104     else if (len <= 0x3FFFFF)
00105     {
00106         *p++ = 0x80 + (uint8_t) (len >> 16);
00107         *p++ =        (uint8_t)((len >> 8) & 0xFF);
00108         *p++ =        (uint8_t) (len       & 0xFF);
00109         return 3;
00110     }
00111     else
00112     {
00113         *p++ = 0xC0 + (uint8_t) (len >> 24);
00114         *p++ =        (uint8_t)((len >> 16) & 0xFF);
00115         *p++ =        (uint8_t)((len >>  8) & 0xFF);
00116         *p++ =        (uint8_t) (len        & 0xFF);
00117         return 4;
00118     }
00119 }
00120 
00121 static uint32_t alp_decode_length(uint8_t* p, uint32_t* len)
00122 {
00123     uint32_t tmp = 0;
00124     switch ((*p) & 0xC0)
00125     {
00126         case 0xC0: // 0xCx xx xx xx
00127             tmp  =  (*p++ & 0x3F) << 24;
00128             tmp +=   *p++         << 16;
00129             tmp +=   *p++         <<  8;
00130             tmp +=   *p++         <<  0;
00131             *len = tmp;
00132             return 4;
00133         case 0x80: // 0x8x xx xx : 16384 <= Len <4194303
00134             tmp  =  (*p++ & 0x3F) << 16;
00135             tmp +=   *p++         <<  8;
00136             if (tmp == 0)            {
00137                 // 0x8000 ActP special ActP code
00138                 // Do not fetch the extra byte
00139                 tmp = 2;
00140             }
00141             else
00142             {
00143                 tmp += *p++       <<  0;
00144             }
00145             *len = tmp;
00146             return 3;
00147         case 0x40: // 0x4x xx : 64 <= Len < 16383
00148             tmp  =  (*p++ & 0x3F)  <<  8;
00149             tmp +=   *p++          <<  0;
00150             if (tmp == 0)
00151             {
00152                 // 0x4000 ActP special ActP code
00153                 tmp = 1;
00154             }
00155             *len = tmp;
00156             return 2;
00157         case 0: // Len <63
00158             tmp  = (*p++ & 0x3F) <<  0;
00159             *len = tmp;
00160             return 1;
00161     }
00162     
00163     return 0;
00164 }
00165 
00166 static uint32_t d7a_alp_add(uint8_t* p, const uint8_t* data, uint32_t len)
00167 {
00168     memcpy(p, data, len);
00169     
00170     return len;
00171 }
00172 
00173 void d7a_alp_free_msg(d7a_msg_t* msg)
00174 {
00175     ALP_FPRINT("\r\n");
00176     
00177     if (msg->data)
00178     {
00179         FREE(msg->data);
00180     }
00181     FREE(msg);
00182 }
00183 
00184 static d7a_msg_t* d7a_alp_new_msg(void)
00185 {
00186     ALP_FPRINT("\r\n");
00187     
00188     d7a_msg_t* msg = (d7a_msg_t*)MALLOC(sizeof(d7a_msg_t));
00189     memset(msg, 0, sizeof(d7a_msg_t));
00190     msg->err = D7A_ERR_NONE;
00191     
00192     return msg;
00193 }
00194 
00195 static d7a_alp_rsp_t* d7a_alp_parse_pl(d7a_com_rx_msg_t* pkt)
00196 {
00197     ALP_FPRINT("\r\n");
00198     
00199     if (pkt == NULL)
00200     {
00201         return NULL;
00202     }
00203     
00204     uint8_t* p = pkt->buffer;
00205     uint8_t* t = p;
00206     uint8_t len = pkt->blen;
00207 
00208     d7a_alp_rsp_t* rsp = (d7a_alp_rsp_t*)MALLOC(sizeof(d7a_alp_rsp_t));
00209     rsp->tag = NO_TAG;
00210     rsp->eop = false;
00211     rsp->msg = d7a_alp_new_msg();
00212     
00213     while ((p - t) < len)
00214     {
00215         uint8_t ctrl = *p++;
00216         switch (ctrl & 0x3F)
00217         {
00218             case ALP_OPCODE_RSP_STATUS:
00219                 if (ctrl & ALP_OPCODE_INDIRECT)
00220                 {
00221                     // ITF Type
00222                     uint8_t type = *p++;
00223                     // Length
00224                     uint32_t length;
00225                     p += alp_decode_length(p, &length);
00226                     // Data
00227                     d7a_sp_res_t* res = (d7a_sp_res_t*)p;
00228                     p += length;
00229                     
00230                     // Fill corresponding fields
00231                     rsp->msg->lb = res->lb; // Get Link Budget
00232                     rsp->msg->rxlev = res->rxlev; // Get RXLEV
00233                     memcpy(rsp->msg->id, res->addressee.id, D7A_UID_LEN); // Get UID
00234                     
00235                     ALP_DPRINT("ALP RSP ISTATUS type:%02X lb: %3d ", type, rsp->msg->lb);
00236                     ALP_DPRINT_DATA("UID:", "%02X", rsp->msg->id, D7A_UID_LEN, "\r\n");
00237                 }
00238                 else
00239                 {
00240                     uint8_t aid = *p++; // Action ID
00241                     rsp->msg->err = *p++; // Status
00242                     ALP_DPRINT("ALP RSP STATUS aid:%d Status:%d\r\n", aid, rsp->msg->err);
00243                 }
00244                 break;
00245             case ALP_OPCODE_RSP_TAG:
00246                 rsp->eop = !!(ctrl & ALP_CTRL_EOP);
00247                 rsp->tag = *p++; // TAG
00248                 ALP_DPRINT("ALP RSP TAG %d EOP %d\r\n", rsp->tag, rsp->eop);
00249                 break;
00250             case ALP_OPCODE_RSP_F_DATA:
00251                 uint8_t fid;
00252                 uint32_t offset;
00253                 uint32_t length;
00254                 fid = *p++; // File ID
00255                 p += alp_decode_length(p, &offset); // offset
00256                 p += alp_decode_length(p, &length); // length
00257                 rsp->msg->data = (d7a_data_t*)MALLOC(sizeof(d7a_data_t) - 1 + length);
00258                 rsp->msg->data->fid = fid;
00259                 rsp->msg->data->offset = offset;
00260                 rsp->msg->data->length = length;
00261                 p += d7a_alp_add(rsp->msg->data->buf, p, length);
00262                 ALP_DPRINT("ALP RSP F_DATA f:%d o:%d s:%d\r\n", fid, offset, length);
00263                 //ALP_DPRINT_DATA("DATA: ", "%02X ", (uint8_t*)rsp->data, rsp->data_len, "\r\n");
00264                 break;
00265             default:
00266                 WARNING(false, "ALP Untreated OP %d\r\n", ctrl);
00267                 break;
00268         }
00269     }
00270     
00271     ASSERT((p - t) == len, "Payload wrong size: %d expected %d\r\n", (p - t), len);
00272 
00273     return rsp;
00274 }
00275 
00276 
00277 static uint32_t d7a_alp_tag(uint8_t* p, bool eop)
00278 {
00279     uint8_t* t = p;
00280     
00281     *p++ = ALP_OPCODE_TAG + ((eop)? ALP_CTRL_EOP : 0);
00282     *p++ = ++g_alp_tag;
00283     
00284     return (uint32_t)(p - t);
00285 }
00286 
00287 static uint32_t d7a_alp_forward_action(uint8_t* p, d7a_itf_t* itf, bool resp)
00288 {
00289     uint8_t* t = p;
00290     
00291     uint32_t itf_size = sizeof(d7a_itf_t);
00292     switch (itf->cfg.addressee.ctrl.bf.idf)
00293     {
00294         case D7A_ID_NBID:
00295             itf_size -= 7;
00296             break;
00297         case D7A_ID_NOID:
00298             itf_size -= 8;
00299             break;
00300         case D7A_ID_UID:
00301             break;
00302         case D7A_ID_VID:
00303             itf_size -= 4;
00304             break;
00305         default:
00306             break;
00307     }
00308     
00309     *p++ = ALP_OPCODE_FORWARD + ((resp)? ALP_CTRL_RESP : 0);
00310     p += d7a_alp_add(p, (uint8_t*)itf, itf_size);
00311     
00312     return (uint32_t)(p - t);
00313 }
00314 
00315 static uint32_t d7a_alp_write_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, bool resp)
00316 {
00317     uint8_t* t = p;
00318     
00319     *p++ = ALP_OPCODE_F_WR_DATA + ((resp)? ALP_CTRL_RESP : 0);
00320     *p++ = file_id;
00321     p += d7a_alp_encode_length(p, offset);
00322     p += d7a_alp_encode_length(p, size);
00323     p += d7a_alp_add(p, buf, size);
00324     
00325     return (uint32_t)(p - t);
00326 }
00327 
00328 static uint32_t d7a_alp_read_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, bool resp)
00329 {
00330     uint8_t* t = p;
00331     
00332     *p++ = ALP_OPCODE_F_RD_DATA + ((resp)? ALP_CTRL_RESP : 0);
00333     *p++ = file_id;
00334     p += d7a_alp_encode_length(p, offset);
00335     p += d7a_alp_encode_length(p, size);
00336     
00337     return (uint32_t)(p - t);
00338 }
00339 
00340 static uint32_t d7a_alp_perm_request_action(uint8_t* p, uint8_t* req, uint32_t req_size, const uint8_t* root_key, bool resp)
00341 {
00342     uint8_t* t = p;
00343     uint8_t hash[32];
00344     
00345     *p++ = ALP_OPCODE_PERM_REQ + ((resp)? ALP_CTRL_RESP : 0);
00346     *p++ = 1; // ROOT request
00347     *p++ = 42; // Auth protocol ID
00348     sha256_init();
00349     sha256_update(req, req_size);
00350     sha256_update((uint8_t*)root_key, g_alp_root_key_size);
00351     sha256_final(hash);
00352     //PRINT_DATA("Req  : ", "%02X ", (uint8_t*)req, req_size, "\r\n");
00353     //PRINT_DATA("Key  : ", "%d ", (uint8_t*)root_key, g_alp_root_key_size, "\r\n");
00354     //PRINT_DATA("Token: ", "%02X", hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE, "\r\n");
00355     p += d7a_alp_add(p, hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE);
00356     
00357     return (uint32_t)(p - t);
00358 }
00359 
00360 static uint32_t d7a_alp_flush_action(uint8_t* p, uint8_t fid, bool resp)
00361 {
00362     uint8_t* t = p;
00363     
00364     *p++ = ALP_OPCODE_F_FLUSH + ((resp)? ALP_CTRL_RESP : 0);
00365     *p++ = fid;
00366     
00367     return (uint32_t)(p - t);
00368 }
00369 
00370 static void d7a_alp_construct_resp(d7a_msg_t** ret, uint8_t current_tag)
00371 {
00372     ALP_FPRINT("\r\n");
00373     
00374     int i = 0;
00375     d7a_alp_rsp_t* pl = NULL;
00376     d7a_com_rx_msg_t* pkt = NULL;
00377     int32_t time;
00378     Timer timeout;
00379     
00380     timeout.start();
00381     
00382     // Parse responses
00383     do
00384     {
00385         time = D7A_ALP_RESP_TO - timeout.read_ms();
00386         if (time < 0) time = 0;
00387         
00388         pkt = d7a_alp_wait_pl(time);
00389         
00390         if (pkt == NULL)
00391         {
00392             ret[i] = d7a_alp_new_msg();
00393             ret[i]->err = D7A_ERR_CMD_TO;
00394             break;
00395         }
00396         
00397         pl = d7a_alp_parse_pl(pkt);
00398 
00399         // Check TAG
00400         if (pl->tag == NO_TAG)
00401         {
00402             WARNING(false, "No tag in payload expected %d\r\n", current_tag);
00403             FREE(pkt);
00404             d7a_alp_free_msg(pl->msg);
00405             FREE(pl);
00406             ret[i] = d7a_alp_new_msg();
00407             ret[i]->err = D7A_ERR_UNKNOWN;
00408             break;
00409         }
00410         
00411         if (pl->tag != current_tag)
00412         {
00413             WARNING(false, "Ingnoring tag %d expecting %d\r\n", pl->tag, current_tag);
00414             d7a_alp_free_msg(pl->msg);
00415             FREE(pl);
00416             d7a_alp_new_pl(pkt);
00417             continue;
00418         }
00419         
00420         FREE(pkt);
00421         
00422         // Check for END OF PAYLOAD
00423         if (pl->eop)
00424         {
00425             ALP_DPRINT("EOP\r\n");
00426             
00427             // If tag only
00428             if (!pl->msg->data && !pl->msg->lb && i != 0)
00429             {
00430                 // Ignore response
00431                 d7a_alp_free_msg(pl->msg);
00432             }
00433             else
00434             {
00435                 ALP_DPRINT("last response (err %d)\r\n", pl->msg->err);
00436                 ret[i] = pl->msg;
00437             }
00438             
00439             FREE(pl);
00440             break;
00441         }
00442         // Wait for new msg
00443         else
00444         {
00445             ALP_DPRINT("next response (err %d)\r\n", pl->msg->err);
00446             
00447             if (i > MAX_RESPONSES)
00448             {
00449                 WARNING(false, "Too much responses! max: %d\r\n", MAX_RESPONSES);
00450                 FREE(pl->msg);
00451             }
00452             else
00453             {
00454                 ret[i] = pl->msg;
00455                 i++;
00456             }
00457             
00458             FREE(pl);
00459         }
00460         
00461     } while (1);
00462 }
00463 
00464 static uint32_t d7a_alp_construct_itf(uint8_t* p, d7a_addressee_t* addressee, uint8_t retry, bool resp)
00465 {
00466     bool broadcast = false;
00467     
00468     if (addressee)
00469     {
00470         if (addressee->ctrl.bf.idf == D7A_ID_NBID || addressee->ctrl.bf.idf == D7A_ID_NOID)
00471         {
00472             broadcast = true;
00473         }
00474 
00475         // Construct interface
00476          d7a_itf_t itf = {
00477             // Dash7 interface
00478             .type = 0xD7,
00479             // Switch response type if broadcast
00480             .cfg.qos.bf.resp = (broadcast)? D7A_RESP_ALL : D7A_RESP_ANY,
00481             .cfg.qos.bf.retry = retry,
00482             .cfg.qos.bf.record = 0,
00483             .cfg.qos.bf.stop_on_err = 0,
00484             .cfg.to.byte = 0,
00485             .cfg.te.byte = 0,
00486         };
00487         memcpy(&itf.cfg.addressee, addressee, sizeof(d7a_addressee_t));
00488         
00489         // Forward action
00490         return d7a_alp_forward_action(p, &itf, true);
00491     }
00492     
00493     return 0;
00494 }
00495 
00496 d7a_msg_t** d7a_alp_init_ret(void)
00497 {
00498     d7a_msg_t** ret = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * (MAX_RESPONSES + 1));
00499     for (uint32_t i = 0; i < (MAX_RESPONSES + 1); i++)
00500     {
00501         ret[i] = NULL;
00502     }
00503     
00504     return ret;
00505 }
00506 
00507 d7a_msg_t** d7a_alp_write_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry, bool resp)
00508 {
00509     ALP_FPRINT("\r\n");
00510     
00511     // Get command buffer
00512     uint8_t* p = &g_alp_buffer[0];
00513     // Save initial position of the command buffer
00514     uint8_t* t = p;
00515     
00516     uint8_t current_tag;
00517     d7a_msg_t** ret = NULL;
00518     
00519     // malloc and init pointer array
00520     ret = d7a_alp_init_ret();
00521     
00522     // Tag action
00523     p += d7a_alp_tag(p, true);
00524     
00525     // Eventual forward
00526     p += d7a_alp_construct_itf(p, addressee, retry, resp);
00527     
00528     // get tag
00529     current_tag = g_alp_tag;
00530        
00531     // Ask for root permissions
00532     if (root_key)
00533     {
00534         uint8_t req[100];
00535         uint8_t req_size = d7a_alp_write_action(req, file_id, offset, size, buf, resp);
00536         p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
00537     }
00538    
00539     // Write action
00540     p += d7a_alp_write_action(p, file_id, offset, size, buf, resp);
00541     
00542     // Send command
00543     d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
00544     
00545     // Parse responses
00546     d7a_alp_construct_resp(ret, current_tag);
00547     
00548     return ret;
00549 }
00550 
00551 d7a_msg_t** d7a_alp_read_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry)
00552 {
00553     ALP_FPRINT("\r\n");
00554     
00555     // Get command buffer
00556     uint8_t* p = &g_alp_buffer[0];
00557     // Save initial position of the command buffer
00558     uint8_t* t = p;
00559     
00560     uint8_t current_tag;
00561     d7a_msg_t** ret = NULL;
00562     
00563     // malloc and init pointer array
00564     ret = d7a_alp_init_ret();
00565         
00566     // Tag action
00567     p += d7a_alp_tag(p, true);
00568     
00569     // Eventual forward
00570     p += d7a_alp_construct_itf(p, addressee, retry, true);
00571 
00572     // get tag
00573     current_tag = g_alp_tag;
00574            
00575     // Ask for root permissions
00576     if (root_key)
00577     {
00578         uint8_t req[100];
00579         uint8_t req_size = d7a_alp_read_action(req, file_id, offset, size, true);
00580         p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
00581     }
00582     
00583     // Read action
00584     p += d7a_alp_read_action(p, file_id, offset, size, true);
00585     
00586     // Send command
00587     d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
00588     
00589     // Parse responses
00590     d7a_alp_construct_resp(ret, current_tag);
00591     
00592     return ret;
00593 }
00594 
00595 
00596 d7a_msg_t** d7a_alp_flush_file(const uint8_t file_id, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry, bool resp)
00597 {
00598     ALP_FPRINT("\r\n");
00599     
00600     // Get command buffer
00601     uint8_t* p = &g_alp_buffer[0];
00602     // Save initial position of the command buffer
00603     uint8_t* t = p;
00604     
00605     uint8_t current_tag;
00606     d7a_msg_t** ret = NULL;
00607     
00608     // malloc and init pointer array
00609     ret = d7a_alp_init_ret();
00610     
00611     // Tag action
00612     p += d7a_alp_tag(p, true);
00613     
00614     // Eventual forward
00615     p += d7a_alp_construct_itf(p, addressee, retry, resp);
00616     
00617     // get tag
00618     current_tag = g_alp_tag;
00619                
00620     // Ask for root permissions
00621     if (root_key)
00622     {
00623         uint8_t req[100];
00624         uint8_t req_size = d7a_alp_flush_action(req, file_id, resp);
00625         p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
00626     }
00627     
00628     // Flush action
00629     p += d7a_alp_flush_action(p, file_id, resp);
00630     
00631     // Send command
00632     d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
00633     
00634     // Parse responses
00635     d7a_alp_construct_resp(ret, current_tag);
00636     
00637     return ret;
00638 }
00639 
00640 void d7a_alp_set_root_key_size(uint8_t size)
00641 {
00642     g_alp_root_key_size = size;
00643 }
00644 
00645 void d7a_alp_thread()
00646 {
00647     ALP_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
00648     d7a_com_rx_msg_t* pkt;
00649     
00650     while (true)
00651     {
00652         pkt = d7a_alp_wait_pkt();
00653         ASSERT(pkt != NULL, "ALP NULL pkt\r\n");
00654 
00655         switch(pkt->id)
00656         {
00657             case KAL_COM_FLOW_AT_RESP:
00658                 ALP_DPRINT("KAL_COM_FLOW_AT_RESP\r\n");
00659 
00660                 d7a_alp_new_pl(pkt);
00661                 
00662                 break;
00663             case KAL_COM_FLOW_AT_UNS:
00664                 ALP_DPRINT("KAL_COM_FLOW_AT_UNS\r\n");
00665                 if (g_alp_uns_msg)
00666                 {
00667                     d7a_msg_t** uns = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * 2);
00668                     
00669                     d7a_alp_rsp_t* pl = d7a_alp_parse_pl(pkt);
00670                     
00671                     uns[0] = pl->msg;
00672                     uns[1] = NULL;
00673                     
00674                     FREE(pl);
00675                     
00676                     // Callback
00677                     g_alp_uns_msg(uns);
00678                 }
00679 
00680                 FREE(pkt);
00681                 break;
00682             default:
00683                 EPRINT("ALP Unknown Flow ID 0x%02X\r\n", pkt->id);
00684                 FREE(pkt);
00685                 break;
00686         }
00687     }
00688 }