/* if we wanted to find out what we sent (i.e. when we get an ack) */
bool tsm_get_transaction_pdu(
    uint8_t invokeID,
    BACNET_ADDRESS * dest,
    BACNET_NPDU_DATA * ndpu_data,
    uint8_t * apdu,
    uint16_t * apdu_len)
{
    uint16_t j = 0;
    uint8_t index;
    bool found = false;

    if (invokeID) {
        index = tsm_find_invokeID_index(invokeID);
        /* how much checking is needed?  state?  dest match? just invokeID? */
        if (index < MAX_TSM_TRANSACTIONS) {
            /* FIXME: we may want to free the transaction so it doesn't timeout */
            /* retrieve the transaction */
            /* FIXME: bounds check the pdu_len? */
            *apdu_len = (uint16_t) TSM_List[index].apdu_len;
            for (j = 0; j < *apdu_len; j++) {
                apdu[j] = TSM_List[index].apdu[j];
            }
            npdu_copy_data(ndpu_data, &TSM_List[index].npdu_data);
            bacnet_address_copy(dest, &TSM_List[index].dest);
            found = true;
        }
    }

    return found;
}
void tsm_set_confirmed_unsegmented_transaction(
    uint8_t invokeID,
    BACNET_ADDRESS * dest,
    BACNET_NPDU_DATA * ndpu_data,
    uint8_t * apdu,
    uint16_t apdu_len)
{
    uint16_t j = 0;
    uint8_t index;

    if (invokeID) {
        index = tsm_find_invokeID_index(invokeID);
        if (index < MAX_TSM_TRANSACTIONS) {
            /* SendConfirmedUnsegmented */
            TSM_List[index].state = TSM_STATE_AWAIT_CONFIRMATION;
            TSM_List[index].RetryCount = 0;
            /* start the timer */
            TSM_List[index].RequestTimer = apdu_timeout();
            /* copy the data */
            for (j = 0; j < apdu_len; j++) {
                TSM_List[index].apdu[j] = apdu[j];
            }
            TSM_List[index].apdu_len = apdu_len;
            npdu_copy_data(&TSM_List[index].npdu_data, ndpu_data);
            bacnet_address_copy(&TSM_List[index].dest, dest);
        }
    }

    return;
}
/* frees the invokeID and sets its state to IDLE */
void tsm_free_invoke_id(
    uint8_t invokeID)
{
    uint8_t index;

    index = tsm_find_invokeID_index(invokeID);
    if (index < MAX_TSM_TRANSACTIONS) {
        TSM_List[index].state = TSM_STATE_IDLE;
        TSM_List[index].InvokeID = 0;
    }
}
Esempio n. 4
0
/** Check if the invoke ID has been made free by the Transaction State Machine.
 * @param invokeID [in] The invokeID to be checked, normally of last message sent.
 * @return True if it is free (done with), False if still pending in the TSM.
 */
bool tsm_invoke_id_free(
    uint8_t invokeID)
{
    bool status = true;
    uint8_t index;

    index = tsm_find_invokeID_index(invokeID);
    if (index < MAX_TSM_TRANSACTIONS)
        status = false;

    return status;
}
/** See if we failed get a confirmation for the message associated
 *  with this invoke ID.
 * @param invokeID [in] The invokeID to be checked, normally of last message sent.
 * @return True if already failed, False if done or segmented or still waiting
 *         for a confirmation.
 */
bool tsm_invoke_id_failed(
    uint8_t invokeID)
{
    bool status = false;
    uint8_t index;

    index = tsm_find_invokeID_index(invokeID);
    if (index < MAX_TSM_TRANSACTIONS) {
        /* a valid invoke ID and the state is IDLE is a
           message that failed to confirm */
        if (TSM_List[index].state == TSM_STATE_IDLE)
            status = true;
    }

    return status;
}
/* gets the next free invokeID,
   and reserves a spot in the table
   returns 0 if none are available */
uint8_t tsm_next_free_invokeID(
    void)
{
    uint8_t index = 0;
    uint8_t invokeID = 0;
    bool found = false;

    /* is there even space available? */
    if (tsm_transaction_available()) {
        while (!found) {
            index = tsm_find_invokeID_index(Current_Invoke_ID);
            if (index == MAX_TSM_TRANSACTIONS) {
                /* Not found, so this invokeID is not used */
                found = true;
                /* set this id into the table */
                index = tsm_find_first_free_index();
                if (index != MAX_TSM_TRANSACTIONS) {
                    TSM_List[index].InvokeID = invokeID = Current_Invoke_ID;
                    TSM_List[index].state = TSM_STATE_IDLE;
                    TSM_List[index].RequestTimer = apdu_timeout();
                    /* update for the next call or check */
                    Current_Invoke_ID++;
                    /* skip zero - we treat that internally as invalid or no free */
                    if (Current_Invoke_ID == 0) {
                        Current_Invoke_ID = 1;
                    }
                }
            } else {
                /* found! This invokeID is already used */
                /* try next one */
                Current_Invoke_ID++;
                /* skip zero - we treat that internally as invalid or no free */
                if (Current_Invoke_ID == 0) {
                    Current_Invoke_ID = 1;
                }
            }
        }
    }

    return invokeID;
}