Esempio n. 1
0
void hfp_parse(hfp_connection_t * context, uint8_t byte){
    int value;
    
    // TODO: handle space inside word        
    if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return;

    if (!hfp_parser_found_separator(context, byte)){
        hfp_parser_store_byte(context, byte);
        return;
    }
    if (hfp_parser_is_end_of_line(byte)) {
        if (hfp_parser_is_buffer_empty(context)){
            context->parser_state = HFP_PARSER_CMD_HEADER;
        }
    }
    if (hfp_parser_is_buffer_empty(context)) return;


    switch (context->parser_state){
        case HFP_PARSER_CMD_HEADER: // header
            // printf(" parse header 1 \n");
            if (byte == '='){
                context->keep_separator = 1;
                hfp_parser_store_byte(context, byte);
                return;
            }
            
            if (byte == '?'){
                context->keep_separator = 0;
                hfp_parser_store_byte(context, byte);
                return;
            }
            // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
            if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){
                // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
                process_command(context);
            }
            break;

        case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes
            switch (context->command){
                case HFP_CMD_CONFIRM_COMMON_CODEC:
                    context->remote_codec_received = atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_SUPPORTED_FEATURES:
                    context->remote_supported_features = atoi((char*)context->line_buffer);
                    printf("Parsed supported feature %d\n", context->remote_supported_features);
                    break;
                case HFP_CMD_AVAILABLE_CODECS:
                    printf("Parsed codec %s\n", context->line_buffer);
                    context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer);
                    context->parser_item_index++;
                    context->remote_codecs_nr = context->parser_item_index;
                    break;
                case HFP_CMD_INDICATOR:
                    if (context->retrieve_ag_indicators == 1){
                        strcpy((char *)context->ag_indicators[context->parser_item_index].name,  (char *)context->line_buffer);
                        context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1;
                        printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer);
                    }

                    if (context->retrieve_ag_indicators_status == 1){ 
                        printf("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer);
                        context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer);
                        context->parser_item_index++;
                        break;
                    }
                    break;
                case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
                    context->parser_item_index++;
                    if (context->parser_item_index != 4) break;
                    printf("Parsed Enable indicators: %s\n", context->line_buffer);
                    value = atoi((char *)&context->line_buffer[0]);
                    context->enable_status_update_for_ag_indicators = (uint8_t) value;
                    break;
                case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
                    printf("Parsed Support call hold: %s\n", context->line_buffer);
                    if (context->line_size > 2 ) break;
                    strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name,  (char *)context->line_buffer);
                    context->remote_call_services_nr++;
                    break;
                case HFP_CMD_GENERIC_STATUS_INDICATOR:
                    printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n", 
                            context->list_generic_status_indicators, 
                            context->retrieve_generic_status_indicators,
                            context->retrieve_generic_status_indicators_state);
                    if (context->retrieve_generic_status_indicators == 1 || context->list_generic_status_indicators == 1){
                        printf("Parsed Generic status indicator: %s\n", context->line_buffer);
                        context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer);
                        context->parser_item_index++;
                        context->generic_status_indicators_nr = context->parser_item_index;
                        break;    
                    }
                    printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 2\n");
                    if (context->retrieve_generic_status_indicators_state == 1){
                        // HF parses inital AG gen. ind. state
                        printf("Parsed List generic status indicator %s state: ", context->line_buffer);
                        context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer);
                        break;
                    }
                    break;
    
                case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
                    // AG parses new gen. ind. state
                    printf("Parsed Enable ag indicator state: %s\n", context->line_buffer);
                    value = atoi((char *)&context->line_buffer[0]);
                    if (!context->ag_indicators[context->parser_item_index].mandatory){
                        context->ag_indicators[context->parser_item_index].enabled = value;
                    }
                    context->parser_item_index++;
                    break;
                case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
                    // indicators are indexed starting with 1
                    context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1;
                    printf("Parsed status of the AG indicator %d, status ", context->parser_item_index);
                    break;
                case HFP_CMD_QUERY_OPERATOR_SELECTION:
                    if (context->operator_name_format == 1){
                        if (context->line_buffer[0] == '3'){
                            printf("Parsed Set network operator format : %s, ", context->line_buffer);
                            break;
                        }
                        // TODO emit ERROR, wrong format
                        printf("ERROR Set network operator format: index %s not supported\n", context->line_buffer);
                        break;
                    }

                    if (context->operator_name == 1) {
                        context->network_operator.mode = atoi((char *)&context->line_buffer[0]);
                        printf("Parsed network operator mode: %d, ", context->network_operator.mode);
                        break;
                    }
                    break;
                case HFP_CMD_ERROR:
                    break;
                case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
                    context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
                    context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer);
                    context->send_ok = 1;
                    context->extended_audio_gateway_error = 0;
                    break;
                default:
                    break;
            }
            break;

        case HFP_PARSER_SECOND_ITEM:
            switch (context->command){
                case HFP_CMD_QUERY_OPERATOR_SELECTION:
                    if (context->operator_name_format == 1) {
                        printf("format %s \n", context->line_buffer);
                        context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
                        break;
                    }
                    if (context->operator_name == 1){
                        printf("format %s, ", context->line_buffer);
                        context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
                    }
                    break;
                case HFP_CMD_GENERIC_STATUS_INDICATOR:
                    context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
                    context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer);
                    context->ag_indicators[context->parser_item_index].status_changed = 1;
                    break;
                case HFP_CMD_INDICATOR:
                    if (context->retrieve_ag_indicators == 1){
                        context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer);
                        printf("%s, ", context->line_buffer);
                    }
                    break;
                default:
                    break;
            }
            break;

        case HFP_PARSER_THIRD_ITEM:
             switch (context->command){
                case HFP_CMD_QUERY_OPERATOR_SELECTION:
                    if (context->operator_name == 1){
                        strcpy(context->network_operator.name, (char *)context->line_buffer);
                        printf("name %s\n", context->line_buffer);
                    }
                    break;
                case HFP_CMD_INDICATOR:
                    if (context->retrieve_ag_indicators == 1){
                        context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer);
                        context->parser_item_index++;
                        context->ag_indicators_nr = context->parser_item_index;
                        printf("%s)\n", context->line_buffer);
                    }
                    break;
                default:
                    break;
            }
            break;
    }
    hfp_parser_next_state(context, byte);
}
Esempio n. 2
0
void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){
    int value;
    
    // TODO: handle space inside word        
    if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return;

    if (!hfp_parser_found_separator(context, byte)){
        hfp_parser_store_byte(context, byte);
        return;
    }
    if (hfp_parser_is_end_of_line(byte)) {
        if (hfp_parser_is_buffer_empty(context)){
            context->parser_state = HFP_PARSER_CMD_HEADER;
        }
    }
    if (hfp_parser_is_buffer_empty(context)) return;


    switch (context->parser_state){
        case HFP_PARSER_CMD_HEADER: // header
            if (byte == '='){
                context->keep_separator = 1;
                hfp_parser_store_byte(context, byte);
                return;
            }
            
            if (byte == '?'){
                context->keep_separator = 0;
                hfp_parser_store_byte(context, byte);
                return;
            }
            // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
            if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){
                // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
                char * line_buffer = (char *)context->line_buffer;
                context->command = parse_command(line_buffer, isHandsFree);
                
                /* resolve command name according to context */
                if (context->command == HFP_CMD_UNKNOWN){
                    switch(context->state){
                        case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
                            context->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS;
                            break;
                        case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
                            context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS;
                            break;
                        case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
                            context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE;
                            break;
                        case HFP_W4_RETRIEVE_INDICATORS_STATUS:
                            context->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
                            break;
                        case HFP_W4_RETRIEVE_INDICATORS:
                            context->command = HFP_CMD_RETRIEVE_AG_INDICATORS;
                            break;
                        default:
                            break;
                    }
                }
            }
            break;

        case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes
            switch (context->command){
                case HFP_CMD_HF_CONFIRMED_CODEC:
                    context->codec_confirmed = atoi((char*)context->line_buffer);
                    log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed);
                    break;
                case HFP_CMD_AG_SUGGESTED_CODEC:
                    context->suggested_codec = atoi((char*)context->line_buffer);
                    log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec);
                    break;
                case HFP_CMD_SUPPORTED_FEATURES:
                    context->remote_supported_features = atoi((char*)context->line_buffer);
                    log_info("Parsed supported feature %d\n", context->remote_supported_features);
                    break;
                case HFP_CMD_AVAILABLE_CODECS:
                    log_info("Parsed codec %s\n", context->line_buffer);
                    context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer);
                    context->parser_item_index++;
                    context->remote_codecs_nr = context->parser_item_index;
                    break;
                case HFP_CMD_RETRIEVE_AG_INDICATORS:
                    strcpy((char *)context->ag_indicators[context->parser_item_index].name,  (char *)context->line_buffer);
                    context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1;
                    log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer);
                    break;
                case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
                    log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer);
                    context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer);
                    context->parser_item_index++;
                    break;
                case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
                    context->parser_item_index++;
                    if (context->parser_item_index != 4) break;
                    log_info("Parsed Enable indicators: %s\n", context->line_buffer);
                    value = atoi((char *)&context->line_buffer[0]);
                    context->enable_status_update_for_ag_indicators = (uint8_t) value;
                    break;
                case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
                    log_info("Parsed Support call hold: %s\n", context->line_buffer);
                    if (context->line_size > 2 ) break;
                    strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name,  (char *)context->line_buffer);
                    context->remote_call_services_nr++;
                    break;
                case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
                case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
                    log_info("Parsed Generic status indicator: %s\n", context->line_buffer);
                    context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer);
                    context->parser_item_index++;
                    context->generic_status_indicators_nr = context->parser_item_index;
                    break;
                case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
                    // HF parses inital AG gen. ind. state
                    log_info("Parsed List generic status indicator %s state: ", context->line_buffer);
                    context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
                    // AG parses new gen. ind. state
                    log_info("Parsed Enable ag indicator state: %s\n", context->line_buffer);
                    value = atoi((char *)&context->line_buffer[0]);
                    if (!context->ag_indicators[context->parser_item_index].mandatory){
                        context->ag_indicators[context->parser_item_index].enabled = value;
                    }
                    context->parser_item_index++;
                    break;
                case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
                    // indicators are indexed starting with 1
                    context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1;
                    printf("Parsed status of the AG indicator %d, status ", context->parser_item_index);
                    break;
                case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
                    context->network_operator.mode = atoi((char *)&context->line_buffer[0]);
                    log_info("Parsed network operator mode: %d, ", context->network_operator.mode);
                    break;
                case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
                    if (context->line_buffer[0] == '3'){
                        log_info("Parsed Set network operator format : %s, ", context->line_buffer);
                        break;
                    }
                    // TODO emit ERROR, wrong format
                    log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer);
                    break;
                case HFP_CMD_ERROR:
                    break;
                case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
                    context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
                    context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer);
                    context->ok_pending = 1;
                    context->extended_audio_gateway_error = 0;
                    break;
                default:
                    break;
            }
            break;

        case HFP_PARSER_SECOND_ITEM:
            switch (context->command){
                case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
                    printf("format %s, ", context->line_buffer);
                    context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
                    break;
                case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
                    printf("format %s \n", context->line_buffer);
                    context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
                    break;
                case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
                case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
                case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
                    context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer);
                    break;
                case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
                    context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer);
                    printf("%d \n", context->ag_indicators[context->parser_item_index].status);
                    context->ag_indicators[context->parser_item_index].status_changed = 1;
                    break;
                case HFP_CMD_RETRIEVE_AG_INDICATORS:
                    context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer);
                    log_info("%s, ", context->line_buffer);
                    break;
                default:
                    break;
            }
            break;

        case HFP_PARSER_THIRD_ITEM:
             switch (context->command){
                case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
                    strcpy(context->network_operator.name, (char *)context->line_buffer);
                    log_info("name %s\n", context->line_buffer);
                    break;
                case HFP_CMD_RETRIEVE_AG_INDICATORS:
                    context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer);
                    context->parser_item_index++;
                    context->ag_indicators_nr = context->parser_item_index;
                    log_info("%s)\n", context->line_buffer);
                    break;
                default:
                    break;
            }
            break;
    }
    hfp_parser_next_state(context, byte);
}